当iOS应用程序进入后台时,我们如何调度Google Analytics事件?

9
我的iOS应用里有指向苹果App Store的链接,我想追踪这些链接作为事件。问题在于,在应用进入后台之前,我们无法让应用正确调度GA事件。我们正在使用iOS SDK v2beta4。
以下是我们使用的代码概述。你可以看到,我们加入了很多所谓的“保险策略”代码,因为我们认为正确的方法并不奏效。但即使是保险策略代码也不能始终在我的应用进入后台之前调度事件。它只能在50%的时间内正常工作,而其余时间我必须返回应用程序以便事件可以被调度。
我们认为正确的方法是在“applicationDidEnterBackground”中调度事件,并通过“beginBackgroundTaskWithExpirationHandler”向iOS请求额外的时间来完成此操作。我们尝试过单独运行此代码,没有使用我所谓的“保险策略”代码。至少我相信我们已经正确注释掉了每一行保险策略代码。
请注意,在AppDelegate.h头文件中,我们使用以下代码设置全局变量UIBackgroundTaskIdentifier bgTask;
UIBackgroundTaskIdentifier  bgTask;

这里是我们认为正确的做法代码:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIApplication *app = [UIApplication sharedApplication];

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [[GAI sharedInstance] dispatch];

        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

上述代码是我们认为应该能够工作但实际上却没有。请注意:App Store不是一个普通的应用程序,而是一个网站内部的应用程序,如果这有区别的话。
为了保险起见,我们还做了其他一些事情,可以使事件被成功分发约50%的时间:
第一个[[GAI sharedInstance] dispatch]是在设置跟踪的函数中立即调用的。
源代码:
- (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];
    ...
}

我们还在 "applicationWillResignActive" 中添加了它。
- (void)applicationWillResignActive:(UIApplication *)application
{
    ...  
    [[GAI sharedInstance] dispatch];
}

最后,在您完全关闭应用程序时,会调用另一个GA分派。
- (void)applicationWillTerminate:(UIApplication *)application
{
    [[GAI sharedInstance] dispatch];
}

这些方法并不能百分之百地有效。只有大约50%的概率成功。因此,我们采取了以下措施:当您重新进入应用程序时(无论是从后台还是完全关闭应用程序),我们会发送一个调度指令。

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

在这最后一步中,事件只有在用户返回到我的应用程序时才会被分发。虽然我并不完全确定是这段代码在我返回应用程序时分发事件,还是当我返回应用程序时触发了GA默认分发。

3个回答

2

使用[[GANTracker sharedTracker] dispatchSynchronous:]

dispatch方法会执行异步操作,因此它会立即返回而不等待分派操作完成。你的应用程序可能在实际分派操作完成之前被挂起。

-- 编辑 --

最新版本的Google Analytics库中似乎已经没有dispatchSynchronous:方法了。据我所见,由于GANTrackerDelegate也已经消失,因此没有办法知道分派操作何时完成。因此,建议在预定义的超时时间后调用endBackgroundTask:方法。虽然不完美,但比在dispatch之后立即调用它要好。

你的代码应该像这样:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  [[GAI sharedInstance] dispatch];

  double dispatchTimeout = 10.0;  // 10 seconds timeout
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(dispatchTimeout * NSEC_PER_SEC));
  dispatch_after(popTime, dispatch_get_current_queue(), ^(void){
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
  });
});

啊,尽管苹果在此处的3-3清单中建议使用dispatch_Async,但是你是否已经阅读了这里的内容?http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html - Will
@Will 我指的是 GANTrackerdispatchSynchronous: 方法,但显然在库的 v2 版本中不存在。已更新答案以适应最新版本。 - murat
谢谢。我真的很感激您的帮助,我会尝试使用计时器方法。此外,我正在尝试使用dispatch_async(dispatch_get_global...而不是dispatch_async,这似乎有所改善,但这会导致意想不到的问题吗? - Will
1
@canhazbits 不,我们从未完全解决它。据我们所知,这似乎是Google SDK的一个错误/问题。至少那是我们的猜测。我不确定自那时以来Google是否更新了他们的Analytics SDK以解决这个问题。 - Will

2

由于iOS 6中'dispatch_get_current_queue()'已被弃用,因此您现在可以使用以下代码:

UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask;

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [[GAI sharedInstance] dispatch];

    double dispatchTimeout = 10.0;  // 10 seconds timeout
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(dispatchTimeout * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
});

1
在Google Analytics 3.14中,有一个名为dispatchWithCompletionHandler:的方法。我使用它的方式如下:
//track any event here as usual and then call:

GAI.sharedInstance().dispatchWithCompletionHandler({ (_) -> Void in
    UIApplication.sharedApplication().openURL(URL)
})

而且它似乎正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接