9

我的 iOS 应用程序中有指向 Apple App Store 的链接,我正在尝试将它们作为事件进行跟踪。

问题是我们无法让我的应用程序在进入后台之前正确调度 GA 事件。我们正在使用 iOS SDK v2beta4。

这是我们正在使用的代码的概述。你可以看到我们已经放入了很多我称之为“保险单”的代码,因为我们认为正确的方法是行不通的。但即使是保险单代码也并不总是在我的应用程序进入后台之前调度事件。它仅在大约 50% 的时间内有效,其余时间我必须返回应用程序以获取要调度的事件。

我们认为正确的方法是在“applicationDidEnterBackground”中调度事件,并通过“beginBackgroundTaskWithExpirationHandler”请求 iOS 额外的时间来执行此操作。我们已经在没有我的“保险单”代码的情况下自行尝试了此代码。至少我相信我们正确地注释了每一行保险代码。

注意我们设置了全局变量 UIBackgroundTaskIdentifier bgTask;在带有代码的 AppDelegate.h 头文件中

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];
}

这些都不是 100% 的。只有大约 50% 的时间。所以我们这样做了:当您重新进入应用程序时(无论是从后台还是应用程序已完全关闭都没有关系),我们发送一个调度

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

有了最后一点,事件就会被调度,但前提是用户返回到我的应用程序。虽然我不是 100% 确定是这段代码在我返回应用程序时调度事件,还是在我返回应用程序时是 GA 默认调度。

4

3 回答 3

2

利用[[GANTracker sharedTracker] dispatchSynchronous:]

dispatch方法将执行异步操作。因此它将立即返回,而无需等待调度操作完成。您的应用程序可能在实际调度操作完成之前被暂停。

- 编辑 -

看起来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;
  });
});
于 2013-03-18T22:22:41.977 回答
2

由于“dispatch_get_current_queue()”目前在 iOS 6 中已被弃用,您现在可以使用以下代码:

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;
    });
});
于 2014-11-11T15:54:18.977 回答
1

在 GoogleAnalytics 3.14 中有dispatchWithCompletionHandler:我这样使用它:

//track any event here as usual and then call:

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

它似乎工作正常。

于 2015-11-23T08:46:31.497 回答