iPhone не получает приложение Context от AppleWatch - PullRequest
0 голосов
/ 09 января 2019

Я создал программу для проверки отправки данных назад и вперед с iPhone и AppleWatch, и наоборот. Я настроил его, чтобы на AppleWatch была кнопка, а на iPhone - кнопка. При нажатии на iPhone 1 он отправит данные и переименует кнопку на AppleWatch в любую строку данных.

Затем я применил тот же код для AppleWatch для iPhone, но по какой-то причине iPhone, похоже, не получает данные. Вот код для iPhone:

//  ViewController.swift

import UIKit
import Foundation
import WatchConnectivity

class WatchManager: UIViewController, WCSessionDelegate {

    var watchSession: WCSession? {
        didSet {
            if let session = watchSession {
                session.delegate = self
                session.activate()
            }
        }
    }

    override func viewDidLoad(){
        super.viewDidLoad()

        watchSession = WCSession.default

    }

    private func sendDict(_ dict: [String: Any]) {
        do {
            try self.watchSession?.updateApplicationContext(dict)
        } catch {
            print("Error sending dictionary \(dict) to Apple Watch!")
        }
    }

    @IBOutlet weak var transferButton: UIButton!

    @IBAction func dataTransfer(_ sender: Any) {
        sendDict(["DataKey": UUID().uuidString])
        print("sent")
    }

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        print("Session activation did complete")
    }

    public func sessionDidBecomeInactive(_ session: WCSession) {
        print("session did become inactive")
    }

    public func sessionDidDeactivate(_ session: WCSession) {
        print("session did deactivate")
    }

    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
        print("phone received app context: ", applicationContext)
        if let temperature = applicationContext["DataKey"] as? String {
            self.transferButton.setTitle(temperature, for: .normal)
        }

    }

}

и AppleWatch:

//  InterfaceController.swift

import WatchKit
import Foundation
import WatchConnectivity


class InterfaceController: WKInterfaceController {

    var watchSession: WCSession? {
        didSet {
            if let session = watchSession {
                session.delegate = self
                session.activate()
            }
        }
    }


    @IBOutlet weak var temperatureLabel: WKInterfaceButton!

    private func sendDict(_ dict: [String: Any]) {
        do {
            try self.watchSession?.updateApplicationContext(dict)
        } catch {
            print("Error sending dictionary \(dict) to iPhone!")
        }
    }

    @IBAction func button() {
        let urg = ["DataKey":UUID().uuidString]
        sendDict(urg)
        print("watch sent app context \(urg)")
    }

}

extension InterfaceController: WCSessionDelegate {

    #if os(iOS)
    public func sessionDidBecomeInactive(_ session: WCSession) { }
    public func sessionDidDeactivate(_ session: WCSession) {
        session.activate()
    }
    #endif

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        print("Session activation did complete")
    }

    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
        print("watch received app context: ", applicationContext)
        if let temperature = applicationContext["DataKey"] as? String {
            self.temperatureLabel.setTitle(temperature)
        }

    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()

        watchSession = WCSession.default

    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }

}

Я попытался изменить имя ключа (не сработало), я сделал так, чтобы значение данных всегда менялось (UUID (). UuidString), и сохранил его. Другие вещи, которые я пробовал, состояли в создании ярлыка и попытке переименовать его вместо кнопки, которая не работала, и, наконец, вместо переименования кнопки, просто отправив некоторое подтверждение того, что она получила данные обратно в часы Apple, что не удалось.

Любая помощь будет принята с благодарностью, надеюсь, это не глупая ошибка.

Ответы [ 2 ]

0 голосов
/ 09 января 2019
use self.watchSession?.transferUserInfo(dict) instead of self.watchSession?.updateApplicationContext(dict) 
you'll got a call back in:
    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
}
0 голосов
/ 09 января 2019

Я думаю, updateApplicationContext - не правильный метод для ваших нужд. Из документов: Система отправляет контекстные данные, когда появляется такая возможность, с целью подготовить данные к использованию ко времени пробуждения партнера. Если вы хотите отправлять данные туда и обратно, пока оба приложения находятся на переднем плане, sendMessage должно работать.

В конце вам может потребоваться реализовать комбинацию обоих методов. Я предлагаю прочитать следующий документ: https://developer.apple.com/documentation/watchconnectivity/wcsession

Edit:

Просто, чтобы еще яснее сказать: «В конце концов вам может понадобиться реализовать комбинацию обоих методов», я добавил пример кода из одного из моих приложений.

Метод _sendData пытается отправить текущие данные через sendMessageData, если часы доступны. Если нет, он обновляет контекст приложения, чтобы данные были доступны, как некоторые, при запуске приложения наблюдения.

- (void)_sendCurrentData
{
    if ([WCSession defaultSession].isPaired && [WCSession defaultSession].isWatchAppInstalled)
    {
        if ([WCSession defaultSession].isReachable)
        {
            // Send data to watch
            [[WCSession defaultSession] sendMessageData:self.currentData
                                           replyHandler:nil
                                           errorHandler:^(NSError * _Nonnull error) {
                                               [self _updateApplicationContext];
                                           }];
        }
        else
        {
            [self _updateApplicationContext];
        }
    }
}

- (void)_updateApplicationContext
{
    if ([WCSession defaultSession].isPaired && [WCSession defaultSession].isWatchAppInstalled)
    {
        NSError* error = nil;
        [[WCSession defaultSession] updateApplicationContext:@{@"data": self.currentData}
                                                       error:&error];
        if (error != nil)
        {
            NSLog(@"error while updating application context: %@", error.localizedDescription);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...