Google Analytics iOS v2beta3 — отправка вручную не работает в applicationWillResignActive

Я работаю с Google Analytics SDK v2beta3, и у меня все работает, за исключением того, что я не могу заставить работать ручную отправку, когда приложение выходит из активного состояния. (к вашему сведению, для моего приложения мне нужно резервировать заряд батареи, поэтому я использую только «[[общий экземпляр GAI] диспетчеризацию]» для отправки данных о событии, когда пользователь заканчивает работу с приложением.)

Я пробовал несколько вещей, но в то время как диспетчерский вызов достигается и запускается во время трассировки, похоже, он ничего не делает... нет вывода журнала (у меня включен режим отладки) и данные не загружены. Он должен как минимум сообщать «GoogleAnalytics 2.0b3 -[GAIDispatcher InitialDispatch:retryNumber:] (GAIDispatcher.m:479) DEBUG: нет ожидающих обращений». или что-то в этом роде, я думаю. Но в логе ничего и данные не отправляются.

Вместо этого, когда приложение возобновляет работу в фоновом режиме, обращения затем передаются, и я вижу все операторы отладки на своей консоли, а данные успешно отправляются в мою учетную запись Google Analytics.

Ниже мой код...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    // set up Google Analytics tracker
    [GAI sharedInstance].trackUncaughtExceptions = YES; // automatically track uncaught exceptions with Google Analytics - sent with stack trace.
    [GAI sharedInstance].dispatchInterval = -1;         // set Google Analytics dispatch off, will do manually when app goes into background.
    [GAI sharedInstance].debug = YES;                   // set debug to YES for extra debugging information.
    id<GAITracker> tracker = [[GAI sharedInstance] trackerWithTrackingId:GOOGLE_ANALYTICS_TRACKING_ID_FOR_TEST];    // Create tracker instance.
    [tracker setSessionTimeout:600];                     // set min time between sessions to be 10 minutes
    [GAI sharedInstance].defaultTracker = tracker;   // reset the default tracker if needed
    [[GAI sharedInstance] setOptOut:NO];

    ...
}

 - (void)applicationWillResignActive:(UIApplication *)application
{
    UIDevice * device = [UIDevice currentDevice];
    BOOL backgroundTasksSupported = NO;

    if ([device respondsToSelector:@selector(isMultitaskingSupported)]) {
        backgroundTasksSupported = device.multitaskingSupported;
    }

    if (backgroundTasksSupported) {
        self.uploadAnalyticsBackgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{[self endBackgroundUploadTask];}];

        // Start the long-running task and return immediately.
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        // put block on Global run queue...

            [[GAI sharedInstance] dispatch];                                                    // for dispatch of collected metric/analysis data...

            [self endBackgroundUploadTask];
        });
    }
    else {
        [[GAI sharedInstance] dispatch];
    }

}

- (void) endBackgroundUploadTask
{
     if(self.uploadAnalyticsBackgroundTask != UIBackgroundTaskInvalid) {          // if background task running, end it
        [[UIApplication sharedApplication] endBackgroundTask: self.uploadAnalyticsBackgroundTask];
        self.uploadAnalyticsBackgroundTask = UIBackgroundTaskInvalid;
     }
}

Приложение достигает и выполняет отправку [[общий экземпляр GAI]]; линии, но ничего не делает. Я новичок в фоновых задачах, когда приложение переходит в фоновый режим, поэтому, возможно, я делаю что-то не так. Но в рамках своих исследований я даже упростил applicationWillResignActive до этого (который блокирует/должен блокировать)... но я получаю то же самое: никакой отладочной информации и переданных данных.

 - (void)applicationWillResignActive:(UIApplication *)application
{
    [[GAI sharedInstance] dispatch];
}

Я пробовал это с неотрицательным интервалом отправки (скажем, 15 секунд), и я получаю обычную передачу с запрошенным интервалом, но вызов ручной отправки не работает.

Вызовы ручной отправки в других частях моего кода работают. Просто кажется, что это не работает, когда приложение закрывается.

Любые мысли, советы о том, что я мог сделать неправильно и как я могу это исправить?


person Steve Mason    schedule 14.12.2012    source источник
comment
У меня такая же проблема, я думаю, мы должны отправить отчеты об ошибках в Google по этому поводу.   -  person Mason G. Zhwiti    schedule 21.02.2013
comment
Та же проблема с v2beta4 здесь. Похоже, ручная отправка на данный момент не работает.   -  person Zargony    schedule 28.02.2013


Ответы (3)


В отличие от предыдущих версий Google Analytics SDK, начиная с версии 2, механизм ручной отправки не работает синхронно, т. е. вместо ожидания выполнения отправки он возвращается немедленно. Таким образом, если вы используете диспетчеризацию непосредственно перед тем, как стать неактивным, диспетчеризация не произойдет, поскольку очередь выполнения приложения будет приостановлена ​​до того, как произойдет фактическая диспетчеризация. В качестве обходного пути я запускаю фоновую задачу, которая спит в течение нескольких секунд и поддерживает работу приложения достаточно долго для завершения отправки.

Надеемся, что Google повторно добавит метод dispatchSynchronously в будущих версиях SDK.

Кроме того, имейте в виду, что на applicationWillTerminate у вас есть только 5 секунд, пока приложение не будет уничтожено, поэтому не ждите слишком долго.

- (void)dispatchAndWait:(NSTimeInterval)waitTime {
  UIBackgroundTaskIdentifier backgroundTask = 0;
  backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
  }];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // GAI dispatch runs asynchronously and dispatches on the main
    // thread, so we're giving it some time to dispatch and keep the
    // app running in background by sleeping on a background thread
    [[GAI sharedInstance] dispatch];
    [NSThread sleepForTimeInterval:waitTime];

    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
  });
}
person Zargony    schedule 02.05.2013
comment
Я подтвердил, что этот метод, указанный в applicationWillResignActive:, отлично работает как с v.2, так и с v.3 SDK Google Analytics. Большое спасибо! - person Nimit Pattanasri; 27.12.2013

Это правильный ответ по состоянию на август 2013 года.

Пока приложение было закрыто нормально, т. е. оно получило UIApplicationWillResignActiveNotification, обращения будут отправлены при следующем открытии приложения.

Причина, по которой вы этого не видите, вероятно, заключается в том, что выход из приложения из Xcode не приводит к его нормальному закрытию. Нажатие кнопки «Домой», за которой вскоре последует остановка Xcode, закроет ее в обычном режиме, и она будет работать.

Проблема здесь в том, что даже если обращения отправляются, они отбрасываются Analytics, если они поступают после 4:00 следующего дня в часовом поясе профиля Analytics. Это немного сложно и может оправдать решение, как у Андреаса.

person Max    schedule 31.07.2013

У нас есть эта проблема, но мы смогли повысить уровень успеха до 50%. Вот как мы это сделали.

Мы ввели «код страховки», и теперь около 50% времени наши события отправляются, когда приложение переходит в фоновый режим. Остальные 50% времени события не отправляются, пока вы не вернетесь в приложение.

Код страховки, который привел нас к 50%, заключается в том, что вызов диспетчера помещается в код нажатия кнопки:

- (IBAction)goToAppStore:(id)sender
{    
    ...
    // Tracking
    // Using events (pressing on buttons)

    id <GAITracker> tracker = [[GAI sharedInstance] defaultTracker];

    [tracker sendEventWithCategory:@"App Checkout"
                        withAction:@"Checkout Button Pressed"
                        withLabel:nameApp.text
                        withValue:nil];

    [[GAI sharedInstance] dispatch];
    ...
}

Кроме того, глядя на пример кода в основном вопросе - Apple заявляет, что нужно поместить код для выполнения фоновых задач в

applicationDidEnterBackground:

вместо

applicationWillResignActive:

но не похоже, что это имело огромный эффект для нас. Вот документация Apple по этому вопросу (см. листинг 3-3).

http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

Кроме того, я разместил более длинный пост о том, что мы сделали с примерами кода, если вы хотите более подробно увидеть, как мы достигли примерно 50% успеха: Как мы отправляем события Google Analytics, когда приложение iOS переходит в фоновый режим?

На данный момент, хотя я все еще хотел бы, чтобы решение достигло 100%, если кто-то его нашел.

person Will    schedule 18.03.2013