I'm attempting to build an application that builds and saves routes similar to map my run. I'm using the Breadcrumb sample code, specifically the CrumbPath
and CrumbPathView
as the base of my routes, from Apple. Two questions:
If I try to access the
MKMapPoint *points
object of theCrumbPath
like so:[_route lockForReading]; NSLog(@"%@", _route.points); NSLog(@"%d", _route.pointCount); [_route unlockForReading];
my app crashes, saying:
Thread 1: EXC_BAD_ACCESS (code: 1, address: 0x9450342d)
Which I have a hard time understanding, because within the
CrumbPath.m
file, the folks at apple write to the "array" by explicitly acquiring the write lock, and then unlocking it, but if I acquire the read lock and attempt to read from it, it crashes.The reason I attempt to access the
points
is in an attempt to get theMKMapPoints
, convert them toCLLocationCoordinate2D
objects, and save them so I can redraw thepolyline
at the user's request. Since I cannot get access to thepoints
, I attempt to save theCLLocationCoordinate2D
objects from mylocationManager
that I send to the_route
in an array to upload to my Parse backend, but I always get an error saying:Sending 'CLLocationCoordinate2D' to parameter of incompatible type 'id'
Which isn't making this any easier. Does anybody have any insight to why I'm getting these errors?
Location Manager Delegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if (_userLocation.longitude != manager.location.coordinate.longitude
&& _userLocation.latitude != manager.location.coordinate.latitude) {
_userLocation = manager.location.coordinate;
}
if (_isRecording) {
if (!_route) {
NSLog(@"lat: %f, lng: %f", _userLocation.latitude, _userLocation.longitude);
_route = [[CrumbPath alloc] initWithCenterCoordinate:_userLocation];
[_mapView addOverlay:_route];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(_userLocation, 2000, 2000);
[_mapView setRegion:region animated:YES];
}else {
MKMapRect updateRect = [_route addCoordinate:_userLocation];
if (!MKMapRectIsNull(updateRect)) {
MKZoomScale currentZoomScale = (CGFloat)(_mapView.bounds.size.width / _mapView.visibleMapRect.size.width);
CGFloat lineWidth = MKRoadWidthAtZoomScale(currentZoomScale);
updateRect = MKMapRectInset(updateRect, -lineWidth, -lineWidth);
[_routeView setNeedsDisplayInMapRect:updateRect];
}
}
[_routePoints addObject:_userLocation];
[_route lockForReading];
NSLog(@"%d", _route.pointCount);
NSLog(@"%@", _route.points);
[_route unlockForReading];
}
}
Stop Recording Logic
//stop recording
NSLog(@"STOP");
if (_route) {
NSLog(@"There is a route");
//Show route options toolbar
[_route lockForReading];
NSLog(@"%@", _route);
NSLog(@"%d", _route.pointCount);
NSLog(@"%@", _route.points);
PFObject *routeToSave = [PFObject objectWithClassName:@"Routes"];
//[routeToSave setObject:_route forKey:@"routePoints"];
[_route unlockForReading];
[routeToSave saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
NSLog(@"%c", succeeded);
}else {
NSLog(@"%@", error);
}
}];
}
Whatever api you're using to talk to parse is expecting an id which is a pointer to any object. A cllocationcoordinate2d is a c-struct of two doubles and not an object if I'm not mistaken. You should probably create a little wrapper object to save those two doubles and convert them to/from CLLocationCoordinate2d items.
Regarding your first issue, the crash was because of this:
It should be:
As mentioned in my comments,
%d
should be used for count and%@
will cause a crash.Regarding your second issue, you cannot add a c struct to an
NSArray
. You should wrap it inNSValue
before adding it to an array.CLLocationCoordinate2D
is a c-struct. Check the documentation here.Change this:
to:
To get the coordinate back from
NSValue
, you can use,As mentioned in your error message, you were trying to add
CLLocationCoordinate2D
to an array which expects an object.1:
Line:
NSLog(@"%@", _route.points)
; is wrong_route.points is not a String, and you are using the NSStrig formating symbol "%@".
Further:
Since CLLocationCoordinate2D is a C-Sruct and not an Objective-C Object, you probaly want to create an own GeoPoint class.