如何从 Watch App(Watch OS 2)与非活动的 IOS 应用程序通信

Posted

技术标签:

【中文标题】如何从 Watch App(Watch OS 2)与非活动的 IOS 应用程序通信【英文标题】:How to communicate inactive IOS app from Watch App( Watch OS 2) 【发布时间】:2016-08-24 04:17:38 【问题描述】:

尝试将我的 Watch OS1 应用升级到 Watch OS 2。为 Watch OS 2 创建了新目标。并使用sendMessage:replyHandler:errorHandler 发送/获取来自 ios 应用的回复。仅当 IOS 应用程序正在运行时,它才能正常工作。如果 Watch app 在 iOS 应用处于非活动状态(Killed State)时尝试通信,则会出现连接错误 7001。如何从 Watch App(Watch OS 2)与非活动 IOS 应用通信?

watch 应用中的这个sendMessage:replyHandler:errorHandler 方法是否会在后台唤醒相应的 iOS 应用并使其可访问?

谢谢。

编辑1:-

iOS APP 的 App Delegate:

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

    if ([WCSession isSupported]) 
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    
 return YES;

- (void)session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)message replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * __nonnull))replyHandler 

        UIApplication *application = [UIApplication sharedApplication];
        __block UIBackgroundTaskIdentifier identifier = UIBackgroundTaskInvalid;
        dispatch_block_t endBlock = ^ 
            if (identifier != UIBackgroundTaskInvalid) 
                [application endBackgroundTask:identifier];
            
            identifier = UIBackgroundTaskInvalid;
        ;
        identifier = [application beginBackgroundTaskWithExpirationHandler:endBlock];

         if (replyHandler!=nil) 
            replyHandler(resultContainer); // my data dictionary from Iphone app to watch os as reply.
        

        if (identifier!=UIBackgroundTaskInvalid) 
            [application endBackgroundTask:identifier];
            identifier = UIBackgroundTaskInvalid;
        

观看应用:

- (void)applicationDidFinishLaunching 
    // Perform any final initialization of your application.
    if ([WCSession isSupported]) 
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    
        NSDictionary *context = @@"APP_LOADING":@"LOADING";
        [WKInterfaceController reloadRootControllersWithNames:@[WATCH_INTERFACE_LOADING] contexts:@[context]];


        NSDictionary *request = //My Request data;
        [[WCSession defaultSession] sendMessage:request
                                   replyHandler:^(NSDictionary *reply) 
                                       //handle reply from iPhone app here

                                       NSDictionary *resultDict = [reply objectForKey:WATCH_REQUEST_RESULT];
// Use reply from Phone app
                                   
                                   errorHandler:^(NSError *error) 
                                       //catch any errors here
// Getting error here 7001 Error.
                                   
         ];


【问题讨论】:

【参考方案1】:

由于 activate 方法是异步的,所以在委托方法中使用它,如下所示:

    public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?)
    print("activationDidCompleteWith")
    if activationState == WCSessionActivationState.activated 
        NSLog("Activated")
        if(WCSession.default().isReachable)

            do 
                try session.updateApplicationContext(
                    [WatchRequestKey : "updateData"]
                )
            
            catch let error as NSError 
                print("\(error.localizedDescription)")
            
        
    

    if activationState == WCSessionActivationState.inactive 
        NSLog("Inactive")
    

    if activationState == WCSessionActivationState.notActivated 
        NSLog("NotActivated")
    

【讨论】:

以上是关于如何从 Watch App(Watch OS 2)与非活动的 IOS 应用程序通信的主要内容,如果未能解决你的问题,请参考以下文章

如何将用户从 Apple Watch 通知转移到 Apple Watch App?

如何从watch os swift获取设备ID

如何在 Objective-C 中的 OS2 中将数据从 Iphone 发送到 Apple Watch

使用 CoreData 时如何与 Watch OS 2 共享数据以显示在 WKInterfaceTable 中

如何在 Watch OS 2 中引用不支持的框架

如何使用 nsobject 类共享数据(在 watch OS 2 中)