Search code examples
iosdebuggingnskeyedarchivernscodingad-hoc-distribution

Bug after app store deployment, unable to repro in Ad Hoc deployment


My application is involves users saving data which I store using NSCoding/NSKeyedArchiver. I supply the user with sample data objects on the first run of the app.

The expected behavior happens during regular testing, as well as through ad hoc deployment. Unfortunately, a significant bug happens when the app is downloaded through the app store.

What other environmental considerations might there be so I can reproduce (and then fix) the issue in my regular testing?

Expected behavior:

A new user may add/edit data objects in addition to the current ones. (A classic CRUD scenario).

Actual behavior:

If the user's first action is to save a new object, all of the previously loaded sample objects disappear (the elusive bug). However, If the user's first action is to edit, then all of objects persist as expected, and the user can add additional ones without issue.

Thanks for the help.

EDIT

In my most recent testing, I switched the Build Configuration to release in the "Run " scheme.

https://i.sstatic.net/D01Ix.png

App Delegate, which correctly initializes app

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    self.dataArray = nil;
    self.dataArray = [AppDelegate getArray];
    if (self.dataArray == nil) {
        self.dataArray = [[NSMutableArray alloc] init];
    }

    //First run of the app
    if (dataArray.count == 0) {
        //Add sample data to array
        //Save array
        NSString *path = [AppDelegate getDocPath];
        [NSKeyedArchiver archiveRootObject:self.dataArray toFile:path];
    }
}

+(NSString *) getDocPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsPath = [paths objectAtIndex:0];
    NSString *tempDocPath = [documentsPath stringByAppendingPathComponent:@"FilePath.dat"];
    return tempDocPath; 
}

+(NSMutableArray *)getArray {
    return [[NSKeyedUnarchiver unarchiveObjectWithFile:[AppDelegate getDocPath]] mutableCopy];
}

Object creation, which deletes preloaded data if data hasn't been edited

-(void)viewDidLoad {
    tempArray = nil;
    tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[AppDelegate getDocPath]];
    if (tempArray == nil) {
        tempArray = [[NSMutableArray alloc] init];  
    }   
}

-(void)saveObject {
    [tempArray addObject:createdData];
    [tempArray sortUsingSelector:@selector(compare:)];
    NSString *path = [AppDelegate getDocPath];
    [NSKeyedArchiver archiveRootObject:tempArray toFile:path];
    AppDelegate *dg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    dg.dataArray = tempArray;
}

Solution

  • I guess while saving the new object, you are not appending it to the existing data. You might be over-writing the previously created file. You should access the previous file and append the new data to the previous file. Sharing code would help to point out where you are going wrong.

    EDIT: Replace the following code and check if its still showing the same behaviour

    -(void)viewDidLoad {
        tempArray = nil;
        tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[AppDelegate getDocPath]mutableCopy];
        if (tempArray == nil) {
            NSLog(@"tempArray is nil"); //if tempArray doesn't get initialized by the file contents  
            tempArray = [[NSMutableArray alloc] init];
    
        }   
    }