NSValue to CLLocationCoordinate2D in Swift

2.2k views Asked by At

I am using Contentful.com as a content-backend for my iOS app. I can not get their geo-point return to work for me in my Swift project.

The Contentful documentation says their API returns "NSData with CLLocationCoordinate2D struct."

I am approaching this with NSValue in my project, but I can not get it to work properly. Here's my code:

var locationCoord:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0,longitude: 0)

var locationData:NSData = entry.fields["location"] as NSData

var locationValue:NSValue = NSValue(bytes: locationData.bytes, objCType: "CLLocationCoordinate2D")

locationCoord = locationValue.MKCoordinateValue

However, locationCoord.latitude and locationCoord.longitude return wrong values (one of them always being 0.0).

Can someone tell me what I am doing wrong here, and how to make this work properly? Thanks.

1

There are 1 answers

1
rintaro On BEST ANSWER

I think, getBytes:length: from NSData would be sufficient:

var locationData = entry.fields["location"] as NSData
var locationCoord = CLLocationCoordinate2D(latitude: 0, longitude: 0)
locationData.getBytes(&locationCoord, length: sizeof(CLLocationCoordinate2D))

BTW, Why your code doen't work?

That is: objCType: parameter is not expecting a type name "String", but expecting "Type Encodings", in this case that is {?=dd}. In Objective-C, you have handy @encode(TypeName), but not in Swift. The easiest way to get that is to use .objCType property of NSValue.

var locationData = entry.fields["location"] as NSData
var locationCoord = CLLocationCoordinate2D(latitude: 0, longitude: 0)
var objCType = NSValue(MKCoordinate: locationCoord).objCType // <- THIS IS IT
var locationValue = NSValue(bytes: locationData.bytes, objCType: objCType)
locationCoord = locationValue.MKCoordinateValue

Moreover, It seems CDAEntry in Contentful SDK has the exact API, I think you should use this:

/**
 Retrieve the value of a specific Field as a `CLLocationCoordinate2D` for easy interaction with
 CoreLocation or MapKit.

 @param identifier  The `sys.id` of the Field which should be queried.
 @return The actual location value of the Field.
 @exception NSIllegalArgumentException If the specified Field is not of type Location.
 */
-(CLLocationCoordinate2D)CLLocationCoordinate2DFromFieldWithIdentifier:(NSString*)identifier;