I’d like to add a property to UIBezierPath that returns an array of the path’s elements. So I need to call the CGPathApply() function, which takes a function pointer (a closure in Swift 2.0) and calls the closure for each element in the path. My problem is: how do I get the data about the path elements out of the callback closure and stored in a Swift array? The closure can’t capture any variables (because it corresponds to a C function pointer), so I think I have to pass a pointer to a Swift array as a parameter. Thankfully, CGPathApply() takes a parameter info: UnsafeMutablePointer<Void> and passes it to the closure.
My problem is in line 10: how do I turn the UnsafeMutablePointer<Void> back into a Swift array that I can operate on inside the closure?
extension UIBezierPath {
var elements: [CGPathElementType] {
// I'm trying to reserve enough memory for the array.
// I don't know how many elements the path has, but this should be good enough for testing.
var elements = ContiguousArray<CGPathElementType>()
elements.reserveCapacity(1000)
CGPathApply(self.CGPath, &elements) { (userInfo: UnsafeMutablePointer<Void>, elementPointer: UnsafePointer<CGPathElement>) -> Void in
// I don’t know how to convert userInfo back into a Swift array
var elements = ???
let elementType = elementPointer.memory.type
elements.append(elementType)
}
return Array(elements)
}
}
I tried var elements = UnsafeMutablePointer<[CGPathElementType]>(userInfo).memory. This compiles but when I run the code on a bezier path with 5 path elements, the resulting array is empty.