0

I'm trying to save some data in a class named MyPos.h which uses the NSCoding methods:

  • (void)encodeWithCoder:(NSCoder *)aCoder
  • (id)initWithCoder:(NSCoder *)aDecoder

These two methods have been implemented in the MyPos.m file.

Now I want the application to save the data when it terminates and load data when it's finished launching. I'd like to implement the to methods in the AppDelegate.m file, but I can't get my head around how to save the instance of the MyPos class that holds the data.

This is one of the two methods in the AppDelegate.m file ... so far:

- (void)applicationWillTerminate:(UIApplication *)application {


NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

[archiver encodeObject: **HELP_HERE!** forKey:@"myPos"];
[archiver finishEncoding];

[data writeToFile:[self dataFilePath] atomically:YES];}

How can I solve this? Thanks a lot in advance.

Sam DeHaan
  • 10,246
  • 2
  • 40
  • 48
gotfunk
  • 39
  • 6
  • Do you have an instance of the MyPos class in your app delegate? Save the instance... – jmstone617 Apr 09 '12 at 16:15
  • ``applicationWillTerminate`` is sort of useless. You'd better implement your writing routines in ``applicationWillEnterBackground``, or "as soon as possible". Beginning in iOS 4, your app will not receive ``applicationWillTerminate`` when home is pressed. If your app is in background, and for some low memory reason your app is killed, you won't receive ``applicationWillTerminate``. – He Shiming Apr 09 '12 at 16:21
  • I have three classes. The AppDelegate, the MyPos and a ViewController. ViewController creates an instance of MyPos to hold the data. The AppDelegate also creates an instance of MyPos to save the object. However, if I add a NSLog in the end of applicationDidEnterBackground to check the properties of the MyPos instance, they all come out Null. I have the feeling, that I'm dealing with two different objects - or at least there is a missing link. Any thoughts? Thanks a bunch. – gotfunk Apr 09 '12 at 19:23

2 Answers2

2

Two things:

  1. But for the **HELP_HERE!**, your saving method looks fine. Replace that placeholder with a reference to the instance of MyPos that holds the data. How you refer to that instance depends on how it's otherwise referenced in your app delegate. Is it a property or ivar? Use that. Does it belong to some other object in your program (say, a view controller)? See below.

  2. Note that in most cases* on iOS 4+, your application will never see the willTerminate event -- you'll see willResignActive and didEnterBackground, but when the OS goes to terminate your app because it needs more RAM, your app will already be suspended and so you'll have no chance to react to this event. You probably want to do your saving in response to the didEnterBackground event. (Though you might also consider saving as soon as the data changes.)

Each of these "events" I've mentioned is something you can respond to either via an app delegate message or by subscribing to a notification -- use whichever is appropriate to your situation. If the data that needs saving is maintained by an object other than the app delegate (say, a view controller), it might make more sense to have that object do the saving in response to a notification.

For further details, here's a good overview of the application lifecycle events in iOS 4+.


(*) Note that you can still get willTerminate if a) you're using one of the supported background execution modes, like playing audio or VoIP service, b) your app is compiled for an SDK before 4.0, or c) you've set the UIApplicationExitsOnSuspend key to YES in your Info.plist. However, that last option means you give up the benefits of the suspend/resume feature.

rickster
  • 124,678
  • 26
  • 272
  • 326
1

I think you should write these code in "applicationWillEnterBackground" method because when app in background and user kill it then your code that is in applicationWillTerminate may not work.

Ashish Chauhan
  • 1,316
  • 15
  • 22