0

我正在使用以下代码“简单地”从我的手表应用程序中确定父应用程序的应用程序状态:

WatchKit 扩展:

[WKInterfaceController openParentApplication:[NSDictionary dictionary] reply:^(NSDictionary *replyInfo, NSError *error)
    {
        UIApplicationState appState =  UIApplicationStateBackground;
        if(nil != replyInfo)
            appState = (UIApplicationState)[((NSNumber*)[replyInfo objectForKey:kAppStateKey]) integerValue];

        //handle app state
    }];

主应用:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply
{
    __block UIBackgroundTaskIdentifier realBackgroundTask;

    realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        reply([NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:[[UIApplication sharedApplication] applicationState]], kAppStateKey, nil]);
        [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
    }];

    reply([NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:[[UIApplication sharedApplication] applicationState]], kAppStateKey, nil]);

    [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
}

当应用程序处于前台时,这 100% 的时间都有效。当应用程序被“最小化”或“终止”时,这可能会在 50% 的时间内工作(可能更少)。当它不起作用时,它似乎无限期地阻塞。例如,如果 1 分钟后,我启动父应用程序,调用 (openParentApplication) 立即返回状态“UIApplicationStateBackground”(在我启动应用程序之前的状态,如果我很明显应用程序不处于后台状态启动它)。

顺便说一句:我正在使用真正的硬件进行测试。

我究竟做错了什么?为什么即使我创建了后台任务,iOS 也会在接到电话后立即让我的主应用程序进入睡眠状态?这是一个完整的表演停止者。

任何想法或建议将不胜感激!!

4

1 回答 1

0

经过一些研究,这似乎是一个已知问题。例如,以下链接标识了此问题并提供了解决方案:

http://www.fiveminutewatchkit.com/blog/2015/3/11/one-weird-trick-to-fix-openparentapplicationreply

但是,此解决方案对我不起作用。结果我实现了以下解决方案(它有点草率,但这是有意帮助浓缩解决方案):

//start the timeout timer
timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kTimeOutTime target:self selector:@selector(onTimeout) userInfo:nil repeats:NO];

//make the call
messageSent = [WKInterfaceController openParentApplication:[NSDictionary dictionary] reply:^(NSDictionary *replyInfo, NSError *error)
{
  if(nil != _stateDelegate)
  {     
    UIApplicationState appState =  UIApplicationStateBackground;
    if(nil != replyInfo)
      appState = (UIApplicationState)[((NSNumber*)[replyInfo objectForKey:kAppStateKey]) integerValue];

    [_stateDelegate onOperationComplete:self timeout:false applicationState:appState];
    _stateDelegate = nil;
   }
}];

//if the message wasn't sent, then this ends now
if(!messageSent)
{
   if(nil != _stateDelegate)
   {
      //just report that the main application is inactive
      [_stateDelegate onOperationComplete:self timeout:false applicationState:UIApplicationStateInactive];
   }
   _stateDelegate = nil;
}


-(void)onTimeout
{
    timeoutTimer = nil;
    if(nil != _stateDelegate)
    {
        [_stateDelegate onOperationComplete:self timeout:true applicationState:UIApplicationStateInactive];
    }
    _stateDelegate = nil;
}

简而言之,如果计时器在我收到主应用程序的回复之前触发,我基本上会假设主应用程序已进入睡眠状态。请记住,所有挂起的调用都会在某个时候成功(例如,应用程序状态恢复为活动状态),因此,您将需要处理这种情况(如有必要)。

于 2015-07-28T01:15:43.533 回答