One of the best ways (in SpriteKit / GameplayKit) to get the behavior you need is to recognize that route planning and the subsequent route should not be the same operation. GameplayKit provides tools for both - GKObstacleGraph is good for planning, and GKAgent is good for following the planned path - and they work best when you combine the strengths of each of them.
(It may be a little erroneous that GKAgent provides obstacle avoidance; do not think of it the same way as finding a route around obstacles, more like responding to sudden obstacles in your way.)
In other words, GKObstacleGraph and GKAgent are like the difference between navigating with a map and driving safely. The first is where you decided to take the CA-85 and US-101 instead of I-280. (And maybe overestimate your decision once in a while - say, to choose a different set of roads around the traffic jam.) The latter is the place where you constantly change lanes, avoid potholes, miss slow vehicles, slow down traffic for intense movements etc.
The Apple DemoBots sample code, they break it down into two stages:
Use GKObstacleGraph to plan your paths at a high level. That is, when the bad guys are “here,” and the hero is “way there,” and there are several walls between them, select a series of waypoints that approximate the route from here to there.
Use the GKAgent behavior to make the character rudely follow this path, as well as react to other factors (for example, make bad guys not step on each other and give them vaguely realistic motion curves, and not just follow the lines between waypoints).
In this code example, you can find most of the relevant material in TaskBotBehavior.swift - start with addGoalsToFollowPath and look at the places being called and the calls it makes.
Regarding the problems with "moving forever" and "angular" ...
Agent modeling is a strange combination of a motivational analogy (that is, an agent does what it takes to move it to where it "wants" within the limits) and a physical system (i.e. these movements are modeled as forces / impulses) . If you take away the agent’s goals, he doesn’t know that he needs to stop - instead, you need to stop him. (That is, the goal of speed is zero.) There may be a better model than what Apple chose here - file errors , if you have suggestions for improving the design.
Angular speed is harder. The concept of internal physical limitations of agents, which are a kind of analogue, for example, vehicles on land or boats at sea, is pretty well baked in the system. He cannot deal with such things as space fighters, which have to reorient themselves to the vector of their thrust or walking creatures, which can just as happily walk sideways or backward as forward, at least not by themselves. You can get some mileage towards changing the “feel” of the agent’s movement using the maxAcceleration property, but you are limited in that the property covers both linear and angular acceleration.
Remember, however, that the interface between what the system “wants” and what “actually happens” in your game world is under your control. The easiest way to implement GKAgentDelegate is to simply synchronize the velocity and position properties of the agent and the sprite that it represents. However, you do not have to do this - you can calculate a different force / momentum and apply it to your sprite.