2015-07-03 20 views
8

我正在開發一個Apple Watch應用程序,該應用程序使用openParentApplication:reply:方法與其父應用程序進行通信。我的WatchKit應用程序中openParentApplication的行爲不一致

父應用程序與Web服務進行通信,並通過調用包含數據的NSDictionary調用reply方法將其獲得的數據發回給手錶擴展。

當父應用程序在前臺或後臺打開時,該應用程序可以很好地工作。但是,如果我打開父應用程序,然後使用任務切換器終止它,則手錶分機第一次撥打電話時,它會收到以下錯誤,並且參數replyInfo以零形式出現。

UIApplicationDelegate in the iPhone App never called reply()

但每一個電話分機,使該得到恰當的反應之後。

我檢查並發現,手錶擴展名首次撥打電話時,handleWatchKitExtensionRequest:reply:永遠不會在父應用上被調用。

這可能是什麼原因?

我按照文檔中的建議在後臺任務中執行handleWatchKitExtensionRequest:reply:中的所有操作。下面是我的一些代碼: 代碼從我的延伸:從父應用

NSDictionary *params = @{@"requestCode": @(RequestGetLoggedIn)}; 

[WKInterfaceController openParentApplication:params reply:^(NSDictionary *replyInfo, NSError *error) { 
    // Do something with the result 
}]; 

代碼:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply 
{ 
    self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 
     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
    }]; 

    NSNumber* requestCode = userInfo[@"requestCode"]; 

    // Perform some request and then call reply() 

    // End the background task 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
    }); 
} 

編輯1:無論在模擬器和真正的Apple關注出現的問題。

+0

也許[我的答案在這裏](http://stackoverflow.com/questions/29750310/watchkit-handlewatchkitextensionrequest-multiple-instances/29765448#29765448)可以幫助你 – zisoft

+0

我不認爲這是這種情況,因爲一切正常在第一次通話後正確。如果'application:didFinishLaunchingWithOptions:'有問題,那麼應用程序永遠不會在後臺打開,因此調用永遠不會得到任何響應。 –

+0

爲了響應編輯#2:爲什麼在方法幫助結束時啓動後臺任務?您需要啓動後臺任務_immediately_並在其中執行您的工作。我不認爲這是iOS中的錯誤。這聽起來像你的應用程序正在被殺死(由於缺乏背景任務),纔有機會回覆。 – bgilham

回答

5

它看起來像是iOS 8.4中的一個錯誤。

我已經添加了NSLog的到的application:didFinishLaunchingWithOptions:handleWatchKitExtensionRequest:reply:開始,執行導致此問題的操作,然後檢查設備日誌,並得到這個:

--- Notice>: (Warn) WatchKit: <SPCompanionAppServer.m __91-[SPCompanionAppServer launchCompanionAppForGizmoAppWithIdentifier:withUserInfoData:reply:]_block_invoke_2:1450> Got BSActionErrorCodeResponseNotPossible for com.xyz.xyz.watchkitapp. This will translate to WatchKitApplicationDelegateWatchKitRequestReplyNotCalledError 

... Irrelevant stuff 

--- WatchKit Extension[1686] <Warning>: __59-[InformationController getNotificationListIncremental:]_block_invoke (null) 
**--- <Warning>: MY LOG: Application did launch with parameters (null)** 

此日誌顯示application:didFinishLaunchingWithOptions:得到稱爲AFTER操作系統給出了一個關於沒有得到父應用程序的響應的錯誤。如果應用程序沒有首先啓動,應用程序如何做出迴應?

我發現此問題後,通過再次調用openParentApplication:reply:方法暫時解決了該問題。

我已經實現了重試一次行爲的方式是通過創建一個包裝調用並使用該方法代替原始方法的方法。我將它作爲類方法添加到實用程序類中,但它也可以是全局函數。

+ (void)openParentApplication:(NSDictionary*)params reply:(void(^)(NSDictionary *replyInfo, NSError *error))reply 
{ 
    [WKInterfaceController openParentApplication:params reply:^(NSDictionary *replyInfo, NSError *error) { 
     if (error.domain == WatchKitErrorDomain && error.code == WatchKitApplicationDelegateWatchKitRequestReplyNotCalledError) 
     { 
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
       [WKInterfaceController openParentApplication:params reply:^(NSDictionary *replyInfo, NSError *error) { 
        reply(replyInfo, error); 
       }]; 
      }); 
     } 
     else 
      reply(replyInfo, error); 
    }]; 
} 
+0

好的呼叫。只是浪費了幾個小時試圖把這個釘住! – wprater

+0

這似乎是從iOS8.4開始的,雖然這個重試建議看起來很有效,但我最好從openParentApplication中完全移除,以支持watchkit擴展中的工作。我發現WWDC「Watchkit提示和技巧」視頻在這方面非常有幫助。由於openParentApplication在WatchOS2中被棄用,我的方法應該可以分紅。 – CSmith

+0

我想我在8.3中也經歷過同樣的行爲。 WatchKit連接在iOS 9.0之前不可用,因此除非父應用程序不支持任何先前版本的iOS,否則我們將無法使用WatchOS2,因此必須依賴openParentApplication。 –

0

我得到同樣的問題。請參閱我爲蘋果公司提供的錯誤報告而編寫的以下裸骨項目:https://www.dropbox.com/s/ayltpprjck37ins/HandleWatchkitExtensionError%202.zip?dl=0

@Cihan Tek - 你怎麼調用openParentApplication:reply:again?你在回覆塊中調用它嗎?當我這樣做時,我仍然收到錯誤。

+0

看到我編輯的答案 –

+1

謝謝@CihanTek。我注意到,如果您嘗試調用openParentApplication:reply:在applicationDidFinishLaunching完成之前,您仍然會收到錯誤。爲了確保一切都已初始化,我不得不在第二次通話中稍加延遲。 – user3091519

相關問題