簡體   English   中英

WatchOS2 WCSession sendMessage不會在后台喚醒iPhone

[英]WatchOS2 WCSession sendMessage doesn't wake iPhone on background

這是在模擬器和真實物理設備iphone5s上進行測試的。 我嘗試使用WCSession sendMessage從WatchOS2擴展到iPhone iOS9代碼進行通信。 當iphone應用程序在前台和后台模式下運行時,它運行良好。

但如果我殺了iPhone應用程序(根本沒有運行應用程序),那么我總是得到errorHandler超時。 所以Watch再也無法與iPhone通信了。

“錯誤域= WCErrorDomain代碼= 7012”消息回復花了太長時間。“UserInfo = {NSLocalizedDescription =消息回復花了太長時間。,NSLocalizedFailureReason =回復超時發生。}”。

我認為它應該在后台喚醒iPhone應用程序。

知道如何解決這個問題或修復它嗎? 謝謝!

AppDelegate didFinishLaunchingWithOptions方法中激活WCSession非常重要。 你還必須在那里設置WCSessionDelegate 如果您在其他地方執行此操作,則在系統在后台啟動被殺應用程序時,可能無法執行代碼。

此外,您應該通過replyHandler發送回復。 如果你嘗試發送其他東西,系統會等待永遠不會發出的回復。 因此超時錯誤。

這是一個示例,如果它被殺死喚醒應用程序:

在WatchExtension中:

設置會話。 通常在您的ExtensionDelegate中:

func applicationDidFinishLaunching() {
    if WCSession.isSupported() {
        let session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()
    }
}

然后當您需要應用程序中的某些內容時發送消息:

if WCSession.defaultSession().reachable {
    let messageDict = ["message": "hello iPhone!"]
    WCSession.defaultSession().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in
        print(replyDict)
        }, errorHandler: { (error) -> Void in
        print(error)
    }
}

在iPhone App中:

相同的會話設置,但這次也設置了委托:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    ...
    if WCSession.isSupported() {
        let session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()
    }
}

然后實現委托方法將回復發送到手表:

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    replyHandler(["message": "Hello Watch!"])
}

只要Watch和iPhone之間存在連接,此功能就可以使用。 如果應用程序未運行,系統將在后台啟動它。

我不知道系統是否會等到你從iCloud收到你的數據,但這個例子肯定會喚醒應用程序。

經過幾個小時的嘗試和@jeron的提示。 我終於弄明白了這個問題。

在我的會話中:didReceiveMessage委托方法,我有兩個調用。 1.replyHandler電話。 2.在我的情況下我運行了一個異步進程(RXPromise),它嵌套了很多RXPromise回調來從雲服務中獲取各種數據。 我沒有注意它,因為它應該立即呼叫並返回。 但是現在我已經將RXPromise塊一起注釋掉,它每次都可以在后台喚醒iOS應用程序。

最后我弄清楚麻煩是因為在RXPromise調用之后,再也不能保證重新回到主線程了。 我相信session:didReceiveMessage必須在主線程上返回。 我沒有在Apple文檔的任何地方看到這提到過。

最終解決方案

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

    replyHandler(@{ @"schedule" : @"OK" });

    dispatch_async(dispatch_get_main_queue(), ^{
      Nested RXPromise calls.....
    });

}

好吧,你可以使用transferUserInfo來排隊調用。 當app被殺死時,使用sendMessage會導致錯誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM