如何正确使用“openParentApplication”?和“handleWatchKitExtensionRequest”;所以“回复()”叫做? [英] How do I correctly use "openParentApplication" and "handleWatchKitExtensionRequest" so that "reply()" is called?

查看:124
本文介绍了如何正确使用“openParentApplication”?和“handleWatchKitExtensionRequest”;所以“回复()”叫做?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:我在Watch应用中使用 openParentApplication 来调用 handleWatchKitExtensionRequest 主应用程序。这在模拟器中运行良好,当iPhone应用程序处于活动/打开状态时,它也适用于实际设备(Apple Watch和iPhone)。

Situation: I use openParentApplication in the Watch app to call handleWatchKitExtensionRequest in the main app. This works nicely in the simulator and it also works on the actual devices (Apple Watch and iPhone) when the iPhone app is active/open.

问题:当我在实际设备(Apple Watch和iPhone)上运行它时, handleWatchKitExtensionRequest 不会将数据返回到 openParentApplication 当主iPhone应用程序未激活/打开时。

Problem: When I run it on the actual devices (Apple Watch and iPhone), handleWatchKitExtensionRequest does not return data to openParentApplication when the main iPhone app is not active/open.

WatchKit扩展程序中InterfaceController.m中的代码:

NSDictionary *requst = @{ @"request" : @"getData" };
[InterfaceController openParentApplication:requst
                                     reply:^( NSDictionary *replyInfo, NSError *error ) {
                                        // do something with the returned info
                                     }];

iPhone主应用程序的app代理中的代码:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
  if ( [[userInfo objectForKey:@"request"] isEqualToString:@"getData"] )
  {
    // get data
    // ...
    reply( data );
  }
}


推荐答案

iPhone上的主应用程序未激活,可能无法访问 reply(),因为之前操作系统已将后台任务杀死。

When the main app on the iPhone is not active, reply() may not be reached because the background task is killed by the OS before.

解决方案是在 handleWatchKitExtensionRequest 中显式启动后台任务/ IOS /文档/ UIKit的/参考/ UIApplicationDelegate_Protocol /#// apple_ref / OCC / intfm / UIApplicationDelegate /应用:handleWatchKitExtensionRequest:答复:>文档。如果后台任务是这样启动的,它最多可以运行180秒。这可确保iPhone上的主应用程序在发送回复之前不会被暂停。

The solution is to explicitly start a background task in handleWatchKitExtensionRequest as specified in the documentation. If a background task is initiated like this, it can run up to 180 seconds. This ensures that the main app on the iPhone is not suspended before it can send its reply.

iPhone主应用程序的app代理中的代码: / strong>

Code in the app delegate of the main app on iPhone:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
   __block UIBackgroundTaskIdentifier watchKitHandler;
   watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
                                                               expirationHandler:^{
                                                                 watchKitHandler = UIBackgroundTaskInvalid;
                                                               }];

   if ( [[userInfo objectForKey:@"request"] isEqualToString:@"getData"] )
   {
      // get data
      // ...
      reply( data );
   }

   dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1 ), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
      [[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
   } );
}

如果您需要异步获取数据,请使用以下方法确保该方法不会立即返回(没有调用回复):

In case you need to asynchroneously fetch data, use the following approach to ensure that the method does not return immediately (without calling reply):

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

    watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
                                                               expirationHandler:^{
                                                                   watchKitHandler = UIBackgroundTaskInvalid;
                                                               }];  

   NSMutableDictionary *response = [NSMutableDictionary dictionary];

   dispatch_semaphore_t sema = dispatch_semaphore_create(0);

   [ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){

        if (succeeded)
        {
            [response setObject:@"update succeded" forKey:@"updateKey"];
        }
        else
        {
            if (error)
            {
                [response setObject:[NSString stringWithFormat:@"update failed: %@", error.description] forKey:@"updateKey"]; 
            }
            else
            {
                [response setObject:@"update failed with no error" forKey:@"updateKey"];
            }
        }

        reply(response);
        dispatch_semaphore_signal(sema);
    }];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    dispatch_after(dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
  });
}

这篇关于如何正确使用“openParentApplication”?和“handleWatchKitExtensionRequest”;所以“回复()”叫做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆