Need to archive CLLocation data
Asked Answered
S

4

6

I have an array of CLLocation data that I would like to archive. Should the NSUserDefaults system be used? Otherwise, how best to archive the CLLocation data?

Starry answered 10/3, 2011 at 13:2 Comment(1)
If using Core Data, see this post for help: #3797628Gerlach
D
4

UserDefaults can only store certain types of data, and should be used to store user preference information, not arbitrary application state data.

To quote the Apple docs:

The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an application to customize its behavior to match a user’s preferences. For example, you can allow users to determine what units of measurement your application displays or how often documents are automatically saved.

More info here.

If your CLLocation data really does count as user preference info (which I'm not convinced of), you'll have to map the info inside CLLocation onto types that are compatible with NSUserDefaults. Read the docs for NSUserDefaults.

If your CLLocation data isn't user preference info, but just application data/state that you need to preserve, you have a few options; you could store it in core data, or you could use keyed archiving - see this tutorial, for example.

Dunnite answered 10/3, 2011 at 13:24 Comment(3)
thks , but cllocation value consist of 2 double values for lat long how do i encode it, .Starry
Well where do you intend to encode it to? Please accept some of the many answers people have given you and I'll write back later.Dunnite
thks found out the solution using nsarchiver as you said it worked like charm thanks, also i divided cllocation2d values ,into lat and long while encoding and recreated it while decoding thanksStarry
T
15

To correctly store a CLLocation without loss of information, use an NSKeyedArchiver like this:

CLLocation *myLocationToStore = ...; // (a CLLocation object)
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore];

This can then be archived to NSUserDefaults, and likewise decoded just as simply when you retrieve it with NSKeyedUnarchiver:

CLLocation *myStoredLocation = (CLLocation *)[NSKeyedUnarchiver unarchiveObjectWithData:locationData];

The Swift equivalent functions are:

class func archivedDataWithRootObject(_ rootObject: AnyObject) -> NSData]
class func unarchiveObjectWithData(_ data: NSData) -> AnyObject?
Thremmatology answered 8/1, 2015 at 20:4 Comment(1)
thanks a lot man! I was getting a "EXC_BAD_ACCESS code=1" error associated with trying to send a message to an already released object. In my case I was using dataWithBytes:length: and getBytes:length: to store/get a CLLocation object. I suspect the buffer:&locationObject was releasing it, which supplies the method with a memory address for the buffer, but when the bytes of data are copied to the buffer, the memory location pointer becomes a non Core Foundation pointer.Fortis
D
4

UserDefaults can only store certain types of data, and should be used to store user preference information, not arbitrary application state data.

To quote the Apple docs:

The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an application to customize its behavior to match a user’s preferences. For example, you can allow users to determine what units of measurement your application displays or how often documents are automatically saved.

More info here.

If your CLLocation data really does count as user preference info (which I'm not convinced of), you'll have to map the info inside CLLocation onto types that are compatible with NSUserDefaults. Read the docs for NSUserDefaults.

If your CLLocation data isn't user preference info, but just application data/state that you need to preserve, you have a few options; you could store it in core data, or you could use keyed archiving - see this tutorial, for example.

Dunnite answered 10/3, 2011 at 13:24 Comment(3)
thks , but cllocation value consist of 2 double values for lat long how do i encode it, .Starry
Well where do you intend to encode it to? Please accept some of the many answers people have given you and I'll write back later.Dunnite
thks found out the solution using nsarchiver as you said it worked like charm thanks, also i divided cllocation2d values ,into lat and long while encoding and recreated it while decoding thanksStarry
S
1

Found out the solution using nsarchiver as you said it worked like charm thanks. Here is what i did.

- (id)initWithCoder:(NSCoder *)aDecoder
{

    self.PlaceName=[aDecoder decodeObjectForKey:@"inapPlaceName"];

    float lat, long1;

    lat=[aDecoder decodeDoubleForKey:@"inapCoordinateLat"];

    long1=[aDecoder decodeDoubleForKey:@"inapCoordinateLong"];  

    //inapCoordinate=[[CLLocationCoordinate2D alloc] initWithLatitude:lat1 longitude:long1];
    CLLocationCoordinate2D new_coordinate = { lat, long1 };
    self.inapCoordinate=new_coordinate;

    return self;

}

- (void)encodeWithCoder:(NSCoder *)aCoder
{

    [aCoder encodeObject:PlaceName forKey:@"inapPlaceName"];

    [aCoder encodeDouble:inapCoordinate.latitude forKey:@"inapCoordinateLat"];

    [aCoder encodeDouble:inapCoordinate.longitude forKey:@"inapCoordinateLong"]; 

}
Starry answered 10/5, 2011 at 12:37 Comment(1)
Warning: this code snippet when decoding puts lat and long into float locals, which throws away a bunch of precision. (They're encoded and decoded correctly, but this will result in incorrect location data after the decode.)Hezekiah
B
1

This is the usual method.

CLLocation *myLocationToStore = ...; // (a CLLocation object)
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore];
Bozen answered 21/4, 2017 at 9:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.