2015-11-04 5 views
2

Я пытаюсь проснуться с родительским приложением iOS, отправив сообщение из расширения watchkit.как просыпаться родительское приложение iOS с sendMessage из complicationController

Это, хотя работает, только если ниже функция sendMessage вызывается из watchApp/ViewController. Когда он вызывается из ComplicationController, сообщение отправляется, но родительское приложение iOS теперь пробуждается.

Любые советы, оцененные. (Пожалуйста, любой код ссылки в Swift)

Вот упрощенный код:

В 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/Watch. Это пробуждает приложение, даже если я его никогда не открывал. Он работает, когда приложение запущено, когда приложение находится в фоновом режиме и когда приложение полностью убито. – joern

+0

Что заставляет вас думать, что приложение не проснулось? – joern

+1

благодарю вас за ваше усилие. Действительно оценен. Просто протестируйте то же самое с исключительно над кодом, и вы правы. Действительно странно. Кажется, проблема не в коде выше, а в том, как я это называю. В моем приложении я вызываю sendMessage (который находится в ExtensionDelegate) из ComplicationController, и в этом случае сообщение отправляется, но родительское приложение не пробуждается. Если я вместо этого запускаю sendMessage из приложения/из ViewController, сообщение отправляется, и родительское приложение действительно пробуждается. (как я знаю, по полученному ответу или нет) – TPeter

ответ

1

Основная проблема заключается в том, что вы пытаетесь включить (вложенная) asynchronous calls within your complication data source. Тем не менее, ваше запрошенное обновление достигнет конца своего метода, и обновление временной шкалы не произойдет (начиная с you didn't reload or extend the timeline, и даже если бы у вас не было новых данных для получения текущего обновления).

Поскольку новые данные не будут доступны для запланированного обновления, вам придется выполнить второго обновления использовать новые данные разы оно было получено. Выполнение двух back-to-back обновлений не только не нужно, но и тратит больше вашего ежедневного бюджета на осложнения.

Apple рекомендует вам fetch and cache the data in advance of the update, поэтому источник данных осложнений может напрямую возвращать запрошенные данные на сервер осложнений.

Задача вашего класса источника данных - предоставить ClockKit любые запрошенные данные как можно быстрее. Реализации ваших методов источника данных должны быть минимальными. Не используйте методы источников данных для извлечения данных из сети, вычисления значений или выполнения каких-либо действий, которые могут задержать доставку этих данных. Если вам нужно получить или вычислить данные для вашего усложнения, сделайте это в своем приложении iOS или в других частях расширения WatchKit и кешируйте данные в том месте, где ваш источник данных осложнений может получить к нему доступ. Единственное, что должны сделать ваши методы источника данных, - это взять кэшированные данные и поместить их в формат, который требуется ClockKit.

Как вы можете обновить усложнение?

  • Используйте фоновые обновления из телефона для передачи данных, чтобы быть под рукой для следующего запланированного обновления Усложнение в. transferUserInfo и updateApplicationContext подходят для этого типа обновлений.

  • Использовать transferCurrentComplicationUserInfo до immediately transfer complication data and update your timeline.

Оба эти подхода имеют преимущество только нуждаясь один обновление происходит.

+0

Не открывается ли что-то вроде transferUserInfo, когда открывается приложение Watch? – milesper

+1

'transferUserInfo' [передает информацию в фоновом режиме, даже если приложение или расширение приостановлено или завершено] (http://stackoverflow.com/a/34796886/4151918), поэтому сама передача будет завершена. Данные будут ждать, и при открытии приложения будет вызываться 'didReceiveUserInfo'. Это, как правило, обеспечивает лучший пользовательский интерфейс, так как пользователю не нужно ждать, пока часы будут запрашивать и получать данные. Кэшируя самые последние данные, он будет под рукой для следующего запланированного обновления временной шкалы. –

+0

Единственная проблема в том, что пользователь никогда не открывает приложение, поэтому вместо этого я использую 'transferCurrentComplicationUserInfo'. – milesper