(From Kamil Kocemba on our former forum platform, 2 Nov 2016)
I have some news. Seems I was right. Doing something like this to simulate race condition:
~~~~
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *configurationPath = [[NSBundle mainBundle] pathForResource:@"adobe-development" ofType:@"json"];
[ADBMobile overrideConfigPath:configurationPath];
[ADBMobile setDebugLogging:YES];
[ADBMobile setAppGroup:@"group.sdk.test"];
[ADBMobile collectLifecycleData];
[NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer *timer) {
[ADBMobile trackAction:@"TEST" data:nil];
[ADBMobile trackingClearQueue];
}];
return YES;
}
~~~~
And putting app in background will cause the crash I am talking about. This only happens if you specify app group. Of course this is not how we are using the SDK - just trying to give you something to reproduce the issue. I've put together small sample on Github: https://github.com/kkodev/ADBSDKTest/tree/master/SDKTest. Put SDK config in `adobe-development.json`, update code signing and run on iOS 10 device. Proceed to the second screen and put the app in background. It will most likely crash so when you reopen you are back on first screen. If you navigate to Organizer you will see familiar crash log on device. I tried wrapping the calls in a background task, but seems like database is accessed asynchronously so this needs to be done inside appropriate methods of the SDK itself. If you replace:
~~~~
[NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer *timer) {
[ADBMobile trackAction:@"TEST" data:nil];
[ADBMobile trackingClearQueue];
}];
~~~~
with:
~~~~
[NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer *timer) {
__block UIBackgroundTaskIdentifier taskId = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:taskId];
taskId = UIBackgroundTaskInvalid;
}];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(queue, ^{
[ADBMobile trackAction:@"TEST" data:nil];
[ADBMobile trackingClearQueue];
// Give SDK extra time to perform async I/O
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
[application endBackgroundTask:taskId];
taskId = UIBackgroundTaskInvalid;
});
});
}];
~~~~
Then the problem goes away (at least I am no longer able to reproduce it). This is obviously a hack, but shows where the problem is. Let me know if it helps.