The simplest solution would just be to stroke the path twice. First with black at a bigger stroke width and then stroke the same path again using the blue color with a slightly smaller stroke width.
Edit:
If I remember correctly you can use CGPathCreateCopyByStrokingPath(...)
to create a new path that you then can both stroke and fill. Then you could use semi-transparent colors.
From the documentation:
CGPathCreateCopyByStrokingPath
Creates a stroked copy of another path.
CGPathRef CGPathCreateCopyByStrokingPath(
CGPathRef path,
const CGAffineTransform *transform,
CGFloat lineWidth,
CGLineCap lineCap,
CGLineJoin lineJoin,
CGFloat miterLimit
);
Parameters
path
The path to copy.
transform
A pointer to an affine transformation matrix, or NULL if no transformation is needed. If specified, Quartz applies the transformation to elements of the converted path before adding them to the new path.
lineWidth
The line width to use, in user space units. The value must be greater than 0.
lineCap
A line cap style constant—kCGLineCapButt (the default), kCGLineCapRound, or kCGLineCapSquare. See “CGLineCap”.
lineJoin
A line join value—kCGLineJoinMiter (the default), kCGLineJoinRound, or kCGLineJoinBevel. See “CGLineJoin”.
miterLimit
The miter limit to use.