Статьи

watchOS 2: общение с коллегой

Со времени выпуска Apple Watch разработчики обсуждали и представляли методы, позволяющие преодолеть ограничения watchOS 1. Разработчики задавались вопросом, например, как обеспечить надежную связь между приложением watchOS и его родительским приложением iOS, и наоборот.

Ряд решений был доступен для решения этой проблемы, таких как MMWormhole . Конечно, Apple хорошо знает об ограничениях watchOS 1, и выпуск watchOS 2 устраняет ряд ограничений watchOS 1. Например, связь между приложением watchOS 2 и его родительским приложением iOS стала намного проще благодаря к внедрению структуры Watch Connectivity .

Инфраструктура Watch Connectivity предоставляет несколько способов связи между iOS и приложением watchOS 2. С платформой Watch Connectivity вы можете обновлять информацию о коллеге, отправлять сообщения, передавать данные в фоновом режиме и даже передавать файлы. Чтобы узнать больше обо всех функциях и возможностях фреймворка, я рекомендую просмотреть документацию Apple по платформе Watch Connectivity.

В этом руководстве я покажу вам, как обмениваться данными между приложением watchOS 2 и его родительским приложением iOS, и наоборот. API, который мы будем использовать для достижения этой sendMessage(_:replyHandler:errorHandler:)sendMessage(_:replyHandler:errorHandler:) . Этот метод позволяет разработчикам передавать данные между приложением watchOS 2 и его родительским приложением iOS.

Важно отметить, что iOS и приложение watchOS 2 реагируют по-разному при sendMessage(_:replyHandler:errorHandler:) . Если этот метод вызывается приложением watchOS 2, приложение iOS будет активировано операционной системой. Однако если вы отправляете данные из родительского приложения iOS в приложение watchOS 2, последнее не проснется. Это важная деталь, о которой нужно помнить.

Поскольку это руководство посвящено разработке Apple Watch, я предполагаю, что вы уже знакомы с разработкой для iOS и языком программирования Swift. Инфраструктура Watch Connectivity доступна только в watchOS 2, что означает, что вам нужно установить последнюю версию Xcode, Xcode 7. Вы можете скачать Xcode с веб-сайта Apple для разработчиков .

Откройте Xcode и выберите New> Project … из меню File . Перейдите в watchOS> Приложение , выберите приложение iOS с шаблоном проекта WatchKit App и нажмите Далее . Назовите свое приложение SendMessageWatch , установите « Язык» на Swift и « Устройства» на iPhone . Снимите флажок « Включить сцену уведомлений» и убедитесь, что каждый флажок внизу снят. Нажмите Next и выберите место для сохранения вашего проекта.

Создание проекта Xcode

На этом этапе мы добавим ярлык и кнопку для обоих приложений. Метка будет использоваться для отображения сообщений, которые мы отправляем, в то время как кнопка отправит сообщение коллеге, приложению iOS или приложению watchOS 2.

Начнем с приложения для iOS. Откройте Main.storyboard и добавьте метку и кнопку. Затем создайте розетку для обоих элементов пользовательского интерфейса и добавьте действие для кнопки. На скриншоте ниже показан результат.

Приложение для iOS - Создание элементов управления и подключение IBOutlets и IBAction

Теперь давайте сосредоточимся на приложении watchOS 2. Откройте Interface.storyboard и добавьте метку и кнопку на сцену. Затем откройте InterfaceController.swift в помощнике редактора, создайте выход для метки и кнопки и добавьте действие для кнопки.

Приложение Watch - Создание элементов управления и подключение IBOutlets и IBAction

При наличии пользовательского интерфейса пришло время увеличить основную тему этого руководства, отправив сообщения из приложения iOS в приложение watchOS 2 и наоборот.

Использование среды Watch Connectivity для обмена сообщениями требует использования класса WCSession . Чтобы это работало, приложение iOS и приложение watchOS 2 должны создать и настроить экземпляр WCSession . Когда сеанс настроен, мы можем общаться сразу назад и вперед.

1
2
3
4
class InterfaceController: WKInterfaceController,WCSessionDelegate{
    var session : WCSession!
    …
}

Мы получаем экземпляр класса WCSession , вызывая defaultSession класса defaultSession . Это возвращает одиночный объект сеанса для устройства. Затем нам нужно установить делегат сеанса и активировать сеанс.

Прежде чем настраивать и использовать объект WCSession , нам необходимо убедиться, что класс WCSession поддерживается на устройстве. Мы делаем это, вызывая isSupported класса WCSession классе WCSession . Мы делаем все это в методе willActivate класса InterfaceController . Обратите внимание, что activateSession сгенерирует исключение, если делегат сеанса равен nil . Другими словами, порядок приведенных ниже утверждений важен.

1
2
3
4
5
6
7
8
9
override func willActivate() {
    super.willActivate()
     
    if (WCSession.isSupported()) {
        session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()
    }
}

Приложение watchOS 2 теперь может отправлять и получать сообщения. Когда сеанс активирован, нам просто нужно вызвать метод sendMessage(_:replyHandler:errorHandler:) для отправки сообщений. Первый аргумент должен быть словарем типа [String : AnyObject] и он не должен быть nil .

replyHandler — это закрытие, которое принимает словарь того же типа. Этот словарь является ответом от коллеги. errorHandler также является закрытием, которое может быть nil если вам не нужно отлавливать какие-либо ошибки.

Если мы нажмем кнопку отправки на Apple Watch, он сразу же отправит сообщение Hello iPhone, и iPhone ответит сообщением Hello Watch . После нажатия на кнопку отправки на iPhone, он отправит вопрос Привет часы, вы можете поговорить со мной? и Apple Watch ответят Да .

Вот как должна выглядеть реализация метода sendMessage в InterfaceController.swift .

01
02
03
04
05
06
07
08
09
10
11
@IBAction func sendMessage() {
    let messageToSend = [«Value»:»Hello iPhone»]
    session.sendMessage(messageToSend, replyHandler: { replyMessage in
        //handle and present the message on screen
        let value = replyMessage[«Value»] as?
        self.messageLabel.setText(value)
    }, errorHandler: {error in
        // catch any errors here
        print(error)
    })
}

Чтобы обработать сообщение на устройстве iOS, нам нужно реализовать метод session(_:didReceiveMessage:) делегата протокола WCSessionDelegate , который вызывается при получении сообщения от партнера. Вот как выглядит реализация в InterfaceController .swift .

01
02
03
04
05
06
07
08
09
10
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    //handle received message
    let value = message[«Value»] as?
    //use this to present immediately on the screen
    dispatch_async(dispatch_get_main_queue()) {
        self.messageLabel.setText(value)
    }
    //send a reply
    replyHandler([«Value»:»Yes»])
}

Реализация обоих методов выглядит очень похоже для приложения iOS. В описанных выше реализациях попробуйте, реализовав sendMessage и session(_:didReceiveMessage:replyHandler:) . Вот как должна выглядеть реализация класса ViewController .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import UIKit
import WatchConnectivity
 
class ViewController: UIViewController, WCSessionDelegate {
     
    var session: WCSession!
    @IBOutlet var messageLabel: UILabel!
    @IBOutlet var sendButton: UIButton!
    @IBAction func sendMessage(sender: AnyObject) {
        //Send Message to WatchKit
        let messageToSend = [«Value»:»Hi watch, can you talk to me?»]
        session.sendMessage(messageToSend, replyHandler: { replyMessage in
            //handle the reply
            let value = replyMessage[«Value»] as?
            //use dispatch_asynch to present immediately on screen
            dispatch_async(dispatch_get_main_queue()) {
                self.messageLabel.text = value
            }
            }, errorHandler: {error in
                // catch any errors here
                print(error)
        })
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        if (WCSession.isSupported()) {
            session = WCSession.defaultSession()
            session.delegate = self;
            session.activateSession()
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    //Swift
    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
        //handle received message
        let value = message[«Value»] as?
        dispatch_async(dispatch_get_main_queue()) {
            self.messageLabel.text = value
        }
        //send a reply
        replyHandler([«Value»:»Hello Watch»])
    }
     
}

Создайте и запустите приложения, чтобы увидеть конечный результат. При нажатии кнопки на Apple Watch на сопряженном iPhone, работающем под управлением iOS, должно появиться сообщение. При нажатии на кнопку приложения iOS на Apple Watch должно появиться сообщение с приложением watchOS 2.

Конечный результат

У метода делегата, который мы реализовали для получения сообщения, есть более простой родственный session(_:didReceiveMessage:) . Этот метод вызывается, когда sendMessage(_:replyHandler:errorHandler:) вызывается без обработчика ответа. Это просто означает, что приложение, отправляющее сообщение, не ожидает ответа.

В дополнение к отправке словаря коллеге, также возможно отправить объект NSData используя метод sendMessageData(_:replyHandler:errorHandler:) . session(_:didReceiveMessageData:) получает сообщение через session(_:didReceiveMessageData:) и session(_:didReceiveMessageData:replyHandler:) делегировать методы протокола WCSessionDelegate .

Если вам необходимо немедленно связаться с партнером, то Watch Watch Framework — лучший выбор для watchOS 2. Сообщения помещаются в очередь и доставляются в том же порядке, в котором они были отправлены.

Платформа Watch Connectivity может предложить гораздо больше, чем то, что описано в этом руководстве. В будущих уроках мы углубимся в эту новую платформу, чтобы дополнительно изучить ее возможности и возможности.