0

I have created a FacebookManager singleton that gets called on a background thread when my app launches. Everything is working just fine with the facebook manager the singleton, the app etc. However, when the app first launches, it is quite a few seconds before it is useful because the facebook manager has not finished doing its thing yet. So what I want to do, is use NSKeyedArchiver to save the facebookManager and all its dictionaries so that upon launch, the app has a navigable interface while the facebook data is being updated in the background. Make sense?

All within the FacebookManager.m, first, when the manager is done updating the friends dictionaries, etc, I call the method that saves the data:

- (BOOL)saveFacebookData
{
    // returns success or failure
    NSString *path = [self archivePath]; // just a helper method

    return [NSKeyedArchiver archiveRootObject:self toFile:path];
}

Then in init, I am trying this, which doesn't seem to work. :

-(id)init
{
    self = [super init];

    NSString *path = [self archivePath];
    self = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

    // If the manager hadn't been saved previously, create a new new one

    if (!self) {


        if (_idsByNameDict == nil) {
            _idsByNameDict = [[NSMutableDictionary alloc] init];
        }

        if (_photosByNameDict == nil) {
            _photosByNameDict = [[NSMutableDictionary alloc] init];
        }

        if (_installedByNameDict == nil) {
            _installedByNameDict = [[NSMutableDictionary alloc] init];
        }

        if (_allFriendsArray == nil) {
            _allFriendsArray = [[NSArray alloc] init];
        }

        basicPermissions = NO;
        extendedPermissions = NO;

        // Create synchronous dispatch queue for all facebook activity
        if (_facebookUpdateQueue == nil) {
            _facebookUpdateQueue = dispatch_queue_create("com.facebookUpdateQueue", NULL);
        }

    }

I think my general strategy is sound but I am tripping over how to actually grab the archived version of the manager during init! Any advice?

zeeple
  • 5,509
  • 12
  • 43
  • 71

1 Answers1

1

Your class needs to implement <NSCoding> and both of its methods encodeWithCoder: to archive all of your property values and initWithCoder: to in archive them. Make sure to call super in the implementations. Generally, the class using the archived class would know about the archiving but you could hide that knowledge in init by using initForReadingWithData: to create your NSKeyedUnarchiver and then calling [self initWithCoder:...];.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • Thanks for the comment. I think my problem is more to do with how I have written the top several lines of the init, and less to do with the implementation of NSCoding. I think this because I have already implemented NSCoding and both of those methods and I can see by examining the dir structure that I am successfully archiving to disc. The problem is limited to how to unarchive during init. The good news is this: I have found another similar SO post, and that post contains a pretty good pattern which I will try using tonight when I get home: – zeeple May 20 '13 at 16:27
  • http://stackoverflow.com/questions/2981269/initwithcoder-works-but-init-seems-to-be-overwriting-my-objects-properties/2981453#2981453 – zeeple May 20 '13 at 17:25
  • Wow-wow-wow! Very dangerous suggestion! I read it and implement it as you describe. But in this case the child classes `initWithCoder` method not called! Spend all day to find what wrong! Use `[NSKeyedUnarchiver unarchiveObjectWithData:data];` – skywinder Mar 14 '14 at 15:26