9

我一直在使用 Google 的 Analytics SDK v2beta3 并且一切正常,除了当应用程序离开活动状态时我无法手动调度工作。(仅供参考,对于我的应用程序,我需要保留电池电量,因此仅在用户完成应用程序时使用“[[GAI sharedinstance] dispatch]”来调度我的事件数据。)

我已经尝试了几件事,但是在跟踪期间到达并运行调度调用时,它似乎没有做任何事情......没有日志输出(我打开了调试模式)并且没有上传数据。它应该最低限度地报告“GoogleAnalytics 2.0b3 -[GAIDispatcher initialDispatch:retryNumber:] (GAIDispatcher.m:479) DEBUG: No pending hits”。或者我想的那种东西。但日志中没有任何内容,也没有发送数据。

相反,当应用程序从后台恢复时,点击会被传输,我会在控制台上看到所有调试语句,并且数据已成功发送到我的 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 sharedInstance] dispatch];” 行,但什么也不做。当应用程序进入后台时,我是一个后台任务的新手,所以也许我做错了什么。但作为我调查的一部分,我什至将 applicationWillResignActive 简化为这个(这是/应该是阻塞的)......但我得到了同样的东西:没有调试信息,也没有传输的数据。

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

我已经用非负的调度间隔(比如 15 秒)进行了尝试,并且我在请求的间隔内得到了定期传输,但是手动调度的调用不起作用。

在我的代码的其他部分调用手动调度确实有效。当应用程序关闭时,它似乎不起作用。

关于我可能做错了什么以及如何解决这个问题的任何想法建议?

4

3 回答 3

2

与以前的 Google Analytics SDK 版本不同,从 v2 开始,手动调度机制不会同步运行,即不是等待调度完成,而是立即返回。因此,如果您在变为非活动状态之前使用分派,则分派不会发生,因为应用程序的运行队列将在实际分派发生之前暂停。作为一种解决方法,我正在启动一个后台任务,该任务会休眠几秒钟,并使应用程序运行足够长的时间以完成调度。

希望 Google 会在 SDK 的未来版本中重新添加一个dispatchSynchronously方法。

另外,请注意,在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];
  });
}
于 2013-05-02T11:01:44.450 回答
1

截至 2013 年 8 月,这是正确的答案。

只要应用程序正常关闭,即它收到一个UIApplicationWillResignActiveNotification,那么下次打开应用程序时就会发送命中。

您没有看到这一点的原因可能是从 Xcode 退出应用程序并没有正常关闭它。按下主页按钮,紧接着 Xcode 的停止,将正常关闭它,它会工作。

这里的问题是,即使发送了匹配,如果它们在第二天凌晨 4 点之后到达 Analytics 配置文件的时区,它们也会被 Analytics 丢弃。这有点棘手,并且可能证明像 Andreas 的解决方案是合理的

于 2013-07-31T21:44:42.873 回答
0

我们有这个问题,但能够将成功率提高到 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% 的成功,我会发布一篇关于我们对代码示例所做的更长的帖子:当 iOS 应用程序进入后台时,我们如何调度 Google Analytics 事件?

在这一点上,如果有人找到了,我仍然想要一个 100% 的解决方案。

于 2013-03-18T20:31:23.470 回答