Search code examples
iosobjective-cgoogle-analytics-firebase

Google Analytics Locks Main Thread in iOS App


I've a strange problem with GA. When I launch my app everything works fine, but launching it from another app (App Store, Testflight, or test launcher) leads to dead lock. GA blocks the main thread to process the UIApplicationDidBecomeActiveNotification notification with the following stack trace:

0   libsystem_kernel.dylib          0x000000018d255e1c __psynch_cvwait + 8
1   libsystem_pthread.dylib         0x000000018d31a9d0 _pthread_cond_wait + 640
2   Foundation                      0x000000018ecc1620 -[NSCondition wait] + 240
3   Foundation                      0x000000018ec84a9c -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] + 792
4   Foundation                      0x000000018ec84764 -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:] + 128
5   Search                          0x00000001005d457c -[GAIDataStore performBlockAndWait:withError:] + 260
6   Search                          0x00000001005d69f4 -[GAIDataStore save:] + 92
7   CoreFoundation                  0x000000018e22222c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
8   CoreFoundation                  0x000000018e221930 _CFXRegistrationPost + 400
9   CoreFoundation                  0x000000018e2216ac ___CFXNotificationPost_block_invoke + 60
10  CoreFoundation                  0x000000018e290b9c -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1504
11  CoreFoundation                  0x000000018e163bf4 _CFXNotificationPost + 376
12  Foundation                      0x000000018ec6a6bc -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
13  UIKit                           0x00000001941322b0 -[UIApplication _deactivateForReason:notify:] + 828
14  UIKit                           0x0000000194350470 __61-[UIApplication _sceneSettingsPreLifecycleEventDiffInspector]_block_invoke + 124
[shortened]

This only happens with each launch launch from Testflight. Opening the app from Springboard works fine.

I had a similar problem opening the app as slide over / split view app on an iPad Air. I could solve the problem with a delayed initialization of GA. This is my initialization code:

GAI *theGAI = [GAI sharedInstance];

[theGAI trackerWithTrackingId:kTrackingId];
theGAI.trackUncaughtExceptions = YES;
#ifdef DEBUG
    theGAI.logger.logLevel = kGAILogLevelVerbose;
#endif

How can I avoid this deadlock?


Solution

  • I could avoid the freeze by putting the screen tracking into a background thread. The first tracking is delayed to avoid collisions with the initialization code of GAI.

    - (void)trackScreen {
        static NSTimeInterval sDelay = 0.75;
        NSString *theName = NSStringFromClass([self class]);
        id<GAITracker> theTracker = self.tracker;
    
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(sDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [theTracker set:kGAIScreenName value:theName];
            [theTracker send:[[GAIDictionaryBuilder createScreenView] build]];
            sDelay = 1.0 / 16.0;
        });
    }