2015-11-04 42 views
2

我想通過從watchkit擴展發送消息來喚醒iOS父應用程序。如何喚醒從complicationController sendMessage的iOS父應用程序

這雖然只在watchApp/ViewController中調用sendMessage函數時才起作用。當它從ComplicationController中調用時,會發送消息,但iOS父應用程序現在會喚醒。

任何意見讚賞。 (請在夫特任何代碼基準)

在這裏,簡化的代碼:

在AppDelegate中和ExtensionDelegate:

override init() { 
    super.init() 
    setupWatchConnectivity() 
} 

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

在ExtensionDelegate:(這裏沒有問題,發送成功消息)

func sendMessage(){ 
     let session = WCSession.defaultSession() 
     let applicationData:[String:AnyObject] = ["text":"test", "badgeValue": 100 ] 

     session.sendMessage(applicationData, replyHandler: {replyMessage in 
      print("reply received from iphone") 
      }, errorHandler: {(error) -> Void in 
       // catch any errors here 
       print("no reply message from phone") 
     }) 
    } 
    print("watch sent message") 

} 

在AppDelegate中:(沒有收到時,iOS應用程序未運行/不在前臺)

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { 
    let text = message["text"] as! String 
    let badgeValue = message["badgeValue"] as! Int 

    dispatch_async(dispatch_get_main_queue()) {() -> Void in 

     print("iphone received message from watch App") 
     self.sendNotification(text, badgeValue: badgeValue) 
     let applicationDict = ["wake": "nowAwake"] 
     replyHandler(applicationDict as [String : String]) 

    } 

} 

這是怎樣的功能是從併發症控制器稱爲(它發送消息,但還沒醒父應用程序):

func requestedUpdateDidBegin(){ 

     dispatch_async(dispatch_get_main_queue()) {() -> Void in 

      let extensionDelegate = ExtensionDelegate() 
      extensionDelegate.loadData() 

     } 
    } 
+1

我剛剛在模擬器和iPhone /手錶上測試了您的代碼。即使我從未打開它,它也會喚醒應用程序。它適用於應用程序運行時,應用程序在後臺並且應用程序完全被終止的情況。 – joern

+0

是什麼讓你覺得應用程序沒有被喚醒? – joern

+1

謝謝Joern的努力。非常感謝。只用上面的代碼進行測試,你是正確的。真奇怪。看起來問題不在於上述代碼,而在於我如何稱呼它。在我的應用程序中,我從ComplicationController調用sendMessage(它位於ExtensionDelegate中),在這種情況下會發送消息,但父應用程序不會喚醒。如果我改爲從ViewController觸發應用程序中的sendMessage,則會發送消息,並且父應用程序確實會喚醒。 (我怎麼知道是通過回覆收到或不收看) – TPeter

回答

1

的主要問題是,你要包含(嵌套) asynchronous calls within your complication data source。但是,您所請求的更新將達到其方法的末尾,並且實際上不會發生時間線更新(因爲you didn't reload or extend the timeline,即使您有,也不會在當前更新的時間內收到新數據)。

由於沒有新的數據將可用於預定的更新,你必須執行第二更新使用新的數據一次被接收。執行兩次背靠背更新不僅不必要,而且會浪費更多的日常複雜性預算。

Apple建議你fetch and cache the data in advance of the update,所以複雜性數據源可以直接將請求的數據返回到併發服務器。

數據源類的工作是儘可能快地爲ClockKit提供任何請求的數據。數據源方法的實現應該是最小的。不要使用數據源方法從網絡獲取數據,計算值或執行任何可能會延遲傳輸數據的操作。如果您需要爲複雜功能獲取或計算數據,請在您的iOS應用程序或WatchKit擴展的其他部分中執行此操作,並將數據緩存到複雜數據源可以訪問的位置。數據源方法應該做的唯一事情就是獲取緩存的數據並將其放入ClockKit所需的格式。

如何更新併發症?

這兩種方法有12只需要出現一個更新的優勢。

+0

只有當Watch應用程序打開時才能完成像transferUserInfo這樣的操作嗎? – milesper

+1

'transferUserInfo' [在後臺傳輸信息,即使應用程序或擴展暫停或終止](http://stackoverflow.com/a/34796886/4151918),因此傳輸本身將完成。數據將會等待,當應用程序打開時,'didReceiveUserInfo'將被調用。這通常提供更好的用戶體驗,因爲用戶不必等待手錶請求和接收數據。通過緩存最新的數據,它將在下一個計劃的時間線更新。 – 2016-05-01 17:34:37

+0

唯一的問題是,如果用戶從不打開應用程序,那麼我使用'transferCurrentComplicationUserInfo'來代替。 – milesper

相關問題