2015-09-30 2 views
1

У меня есть массив, хранящийся на моем iPhone, который мне нужно отправить на Watch в фоновом режиме, когда он обновляется по телефону. Я следил за учебником на RayWenderlich.com, но я просто не могу заставить его работать.Почему iPhone не переносит массив на Apple Watch?

Телефонный код:

import UIKit 
import Foundation 
import WatchConnectivity 

class ViewController: UIViewController, WCSessionDelegate { 

var array1 = ["Hi", "This", "Is", "A", "Test"]() 
var array2 = ["1", "2", "3", "4", "5"]() 

var session: WCSession? 

private func startSession() { 

    if WCSession.isSupported() { 

     session = WCSession.defaultSession() 
     session?.delegate = self 
     session?.activateSession() 

    } 

} 
private func sendToWatch() { 

    if let session = session where session.reachable { 

     session.transferUserInfo(["Array1": array1]) 

    } 

    if let session = session where session.reachable { 

     session.transferUserInfo(["Array2": array2]) 

    } 

} 

sendToWatch() 

} 

И Часы Код:

import WatchKit 
import Foundation 
import WatchConnectivity 

var array1 = [String]() 

var array2 = [String]() 

class InterfaceController: WKInterfaceController, WCSessionDelegate { 

var session: WCSession? 

@IBOutlet var table: WKInterfaceTable! 

override func awakeWithContext(context: AnyObject?) { 
    super.awakeWithContext(context) 

    startSession() 

    table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

    var index = 0 

    while index < array1.count { 

     let row = table.rowControllerAtIndex(index) as! tableRowController 

     row.rowLabel.setText(array1[index]) 

     row.dateLabel.setText(array2[index]) 

     index++ 

    } 

} 

private func startSession() { 

    if WCSession.isSupported() { 

     session = WCSession.defaultSession() 
     session?.delegate = self 
     session?.activateSession() 

    } 

} 

func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) { 

    if let received1 = userInfo["Array1"] as? [String] { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      array1 = received1 
     }) 
    } 

    if let received2 = userInfo["Array2"] as? [String] { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      array2 = received2 
     }) 
    } 

} 

} 

В таблице на часы отлично работает, если я введу фиктивных данных в массивы, так что я знаю, что все настроено правильно. У меня действительно есть проблемы с Transfer/Receiving.

ВТОРАЯ ПОПЫТКА:

Я сейчас пытаюсь использовать updateApplicationContext() в отличие от transferUserInfo(). Я удалил session.reachable чек и изменил код.

код

Телефон:

private func sendToWatch() { 
do { 
     let applicationDict = ["Array1": array1] 
     let applicationDict2 = ["Array2": array2] 
     try WCSession.defaultSession().updateApplicationContext(applicationDict) 
     try WCSession.defaultSession().updateApplicationContext(applicationDict2) 
    } 

catch { 
     print(error) 
    } 
} 

Часы Код:

ТРЕТЬЯ ПОПЫТКА:

Я теперь в состоянии иногда получить либо array1 или array2 к появляются на Watch. Конечно, это приводит к сбою приложения, так как оба массива не получены успешно. Может ли кто-нибудь помочь мне в этом?

Часы Код:

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) { 

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

     if let retrievedArray1 = applicationContext["Array1"] as? [String] { 

      array1 = retrievedArray1 

      print(array1) 

     } 

     if let retrievedArray2 = applicationContext["Array2"] as? [String] { 

      array2 = retrievedArray2 

      print(array2) 

     } 

     self.table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

     var index = 0 

     while index < array1.count { 

      let row = self.table.rowControllerAtIndex(index) as! tableRowController 

      row.rowLabel.setText(array1[index]) //My crash happens either here or.... 

      row.dateLabel.setText(array2[index]) //here because both arrays aren't being received and unreceived array is out of index 

      index++ 

     } 

    } 

} 
+0

Можете ли вы опубликовать свой сеанс, настроенный для приложения iOS? – ccjensen

+0

Спасибо, я только что сделал! – bkwebhero

+0

updateApplicationContext передает только последний словарь, так он работает. Вы хотите использовать transferUserInfo или помещать как array1, так и array2 в один и тот же словарь и вызывать updateApplicationContext один раз – ccjensen

ответ

3

session.reachable будет только справедливо, когда приложение Watch находится на переднем плане (есть несколько редких исключений).

Если вы хотите отправить данные в приложение часов в фоновом режиме, вы должны использовать updateApplicationContext, transferUserInfo или transferFile (который один вы выбираете, зависит от того, что вы отправляете и его размер).

Так что-то вроде:

Обновленный код в ответ на 3-й редакции/вопрос по инициатору

Телефонный код:

private func sendToWatch() { 
do { 
     let applicationDict = ["Array1": array1, "Array2": array2] 
     try WCSession.defaultSession().updateApplicationContext(applicationDict) 
    } 

catch { 
     print(error) 
    } 
} 

Часы Код:

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) { 

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

     if let retrievedArray1 = applicationContext["Array1"] as? [String] { 

      array1 = retrievedArray1 

      print(array1) 

     } 

     if let retrievedArray2 = applicationContext["Array2"] as? [String] { 

      array2 = retrievedArray2 

      print(array2) 

     } 

     self.table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

     var index = 0 

     while index < array1.count { 

      let row = self.table.rowControllerAtIndex(index) as! tableRowController 

      row.rowLabel.setText(array1[index]) 

      row.dateLabel.setText(array2[index]) 

      index++ 

     } 

    } 
} 
+0

Я только что обновил свой вопрос. Все еще не удается получить данные. – bkwebhero

+0

Я обновил код примера, чтобы показать, как использовать контекст приложения для выполнения того, что вы пытаетесь сделать, хотя более вероятно, что transferUserInfo - это тот, который подходит вашему случаю использования. – ccjensen

4

С уважение к вашей третьей попытке:

Вы не хотите использовать updateApplicationContext - вы хотите использовать transferUserInfo, как и в других местах.

Каждый вызов updateApplicationContext перезаписывает любые предыдущие данные, которые были отправлены на часы.Когда вы отправляете dict2 сразу после dict1, первый словарь отбрасывается и заменяется на dict2. Вы не можете получить оба словаря таким образом через updateApplicationContext.

Вы должны использовать updateApplicationContext для передачи, например, настроек или параметров в вашем приложении, где важны только самые последние настройки. Например, если у вас есть флаг, который можно изменить в приложении iOS, вы должны использовать updateApplicationContext каждый раз, когда флаг был изменен в приложении iOS. Когда приложение-часы будет загружено, оно увидит только последнюю настройку флага в файле doReceiveApplicationContext.

Как ваша третья попытка настроена сейчас, первый запрос отправляется, а затем сразу же следует второй dict. Вы видите прерывистые сбои, основанные на переменном времени задержки при доставке этих двух словарей.

Если doReceiveApplicationContext вызывается до того, как второй словарь полностью перенесен, вы успешно получите словарь 1, поскольку эти данные еще не были перезаписаны. Он потерпит неудачу, когда попытается получить доступ к индексу «Массив 2», потому что его еще нет. Если второй контекст передается до того, как часы попадают на вызов «Array 1», ваше приложение не будет работать там, потому что последние данные не вводятся в поле «Array1», а скорее «Array2».

Звонки с использованием updateUserInfo не перезаписывают предшествующие вызовы. Когда приложение watch загружено, оно вызывает код didReceiveUserInfo один раз для каждого вызова. Порядок вызовов поддерживается, поэтому, если вы отправили dict1, dict2, а затем dict3 из приложения iOS, приложение watch получит их в этом порядке.

+0

Спасибо тонну. Я действительно сделал didReceiveApplicationContext для работы, объединив два моих массива в один до передачи. Но я думаю, что я собираюсь сделать это по-твоему сейчас, так как моя была вроде как работа. – bkwebhero

Смежные вопросы