So my app begins on first run by parsing all the information in a json file (included in the project) and saves that into its core data model.
This runs fine via debugging deployment with XCode however when I install the app via Testflight, it crashes immediately.
I have identified it to be the parsing of the json file that is the problem as I have created a build that does not do this & instead grabs the data straight from a web api, the only problem with this is that from the web api it will take about an hour to download all the data, from the json file, it takes about a minute.
I have tried disabling BITCODE & ensuring that the scheme is set to Release, which seems to cover most of these start up problems via Testflight. Neither has worked.
My suspicion is that the json file has not correctly been packaged with the app when distributed via Testflight, but i have no idea how to remedy this. Does anyone have any suggestions?
I am including my import function below incase the error is contained within this and not the configuration.
The json file is roughly 26mb which is very large compared to most other files in the project.
My device is an iPhone X running iOS 11.2.6 and XCode 9.2, the app also successfully runs on all simulators. I am using Objective C
-(void)ImportInitialCards:(NSManagedObjectContext *) managedObjectContext
{
_privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// Configure Managed Object Context
[_privateManagedObjectContext setParentContext:managedObjectContext];
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cardDatabase1" ofType:@"json"];
NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:filePath];
[inputStream open];
NSArray *cards = [NSJSONSerialization JSONObjectWithStream:inputStream options:kNilOptions error:nil];
float percentage = 1.0 / (float) cards.count;
for (NSDictionary *card in cards)
{
NSString *cardParticularsJson = [card valueForKey:@"cardContent"];
NSData *cardParticularsData = [cardParticularsJson dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *cardParticulars = [NSJSONSerialization JSONObjectWithData:cardParticularsData options:NSJSONReadingMutableContainers error:nil];
NSString *cardName = [cardParticulars valueForKey:@"name"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Card"];
[request setPredicate:[NSPredicate predicateWithFormat:@"name == %@", cardName]];
NSError *error = nil;
NSUInteger count = [_privateManagedObjectContext countForFetchRequest:request error:&error];
if (count > 0)
{
NSLog(@"CardMatched: %@", cardName);
//card matched
_progress += percentage;
_currentProgressDescription = @"Scanning ...";
}
else
{
_currentProgressDescription = [NSString stringWithFormat:@"Importing: %@", cardName];
NSManagedObject *newCard = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:_privateManagedObjectContext];
[self SaveCardFrom:cardParticulars to:newCard saveThumb:NO inContext:_privateManagedObjectContext];
_progress += percentage;
dispatch_async(dispatch_get_main_queue(),^ {
NSError *error = nil;
[managedObjectContext save:&error];
} );
}
}
}
I've decided to post the solution to my problem in the hope that it helps someone else that struggled like me. So while importing the JSON file I was updating a progress bar to indicate how long it would take, this was in a while loop that was maxing out the CPU, that along with the JSON import sent the CPU to approx 200% which caused the app to close.
The solution seems quite obvious really, don't make the cpu go above 100%
I now plan to only update the progress bar when the value is changed rather than constantly updating via a while loop.