Осложнения Apple Watch не обновляются достоверно - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть приложение для iPhone, которое отправляет данные из приложения iPhone прямо на циферблат, чтобы отобразить их как сложность.

Я использую WatchConnectivity инфраструктуру для создания WCSession для отправки данныхна часы с телефона.

Мои данные хранятся в словаре и отправляются на часы с помощью метода WCSession transferCurrentComplicationUserInfo.(Этот метод можно использовать примерно 50 раз в день, и я знаю об этом - проблема не в этом.)

Кажется, что метод transferCurrentComplicationUserInfo работает впервые, когда я пытаюсь отправить данные.

Моя проблема в том, что мое приложение для iPhone предназначено для вызова этой функции несколько раз за сеанс, и оно надежно работает только в первый раз.

Когда я отправляю второй набор данных, первый набор остается на сложности.Часто, когда я отправляю третий набор, появляется второй набор.Иногда второй набор появляется постоянно, а иногда он появляется только на короткую секунду перед отображением третьего набора.

Он несовместим, и это проблема, с которой я столкнулся.

Есть ли что-нибудьчто я настроил неправильно?

Код:

//iPhone code to send data to Apple Watch:

func sendComplication(complication: Complication) {
        guard let session = session else {
            delegate?.failedToSendComplication(reason: "Could not connect to your Apple Watch.")
            return
        }
        guard let context = convertComplicationToDictionary(complication: complication) else {
            delegate?.failedToSendComplication(reason: "Couldn't cast complication to a dictionary.")
            return
        }
        if session.remainingComplicationUserInfoTransfers > 0 {
            session.transferCurrentComplicationUserInfo(context)
            delegate?.didSendComplication()
        } else {
            delegate?.failedToSendComplication(reason: "Due to hardware limitations, you can only send a certain amount of complications in a day. You have exceeded that limit for today. You can still set complications from the Apple Watch app.")
        }
    }

// WatchKit Extension Delegate to receive and handle data sent from iPhone app

import WatchKit
import WatchConnectivity

class ExtensionDelegate: NSObject, WKExtensionDelegate {

    var session: WCSession?

    override init() {
        super.init()
        self.session = newWatchConnectivitySession()
    }

    func newWatchConnectivitySession() -> WCSession? {
        if WCSession.isSupported() {
            let session = WCSession.default
            session.delegate = self
            session.activate()
            return session
        }
        return nil
    }

    func reloadComplicationTimeline() {
        let server = CLKComplicationServer.sharedInstance()
        guard let activeComplicationFamilies = server.activeComplications else { return }
        for comp in activeComplicationFamilies {
            server.reloadTimeline(for: comp)
        }
    }

}

extension ExtensionDelegate: WCSessionDelegate {

    func sessionReachabilityDidChange(_ session: WCSession) {
        if session.activationState != .activated {
            self.session = newWatchConnectivitySession()
        }
    }

    // Receive info from iPhone app
    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
        // Parse dictionary and update data source
        reloadComplicationTimeline()
    }

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        guard let error = error else { return }
        print(error.localizedDescription)
    }
}

// ОБНОВЛЕНИЕ //

После дальнейшей проверки я теперь вижу, что шагипроисходят не по порядку.

Это последовательность событий:

  1. sendComplication вызывается из приложения iPhone
  2. ExtensionDelegate инициализируется наПриложение Watch, настраивающее WCSession
  3. Сложность обновляется (слишком рано - это до того, как WCSession получает новые данные)
  4. Вызван метод делегата WCSession didReceiveUserInfo,данные анализируются, а источник данных обновляется (слишком поздно)
  5. Сложность повторяется, но ничего не происходит (возможна проблема с бюджетом?)

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

Попробуйте следующее:

func reloadComplicationTimeline() {
    #if os(watchOS)
    let server = CLKComplicationServer.sharedInstance()
    if let activeComplicationFamilies = server.activeComplications {
    for comp in activeComplicationFamilies {
        server.reloadTimeline(for: comp)
    }
   #endif
}



func sendComplication(complication: Complication) {
        guard WCSession.default.activationState == .activated else {
            delegate?.failedToSendComplication(reason: "Could not connect to your Apple Watch.")
            return
        }
        guard let context = convertComplicationToDictionary(complication: complication) else {
            delegate?.failedToSendComplication(reason: "Couldn't cast complication to a dictionary.")
            return
        }
        #if os(iOS)
        if WCSession.default.isComplicationEnabled {
            let userInfoTranser = WCSession.default.transferCurrentComplicationUserInfo(context)
            delegate?.didSendComplication()
        } else {
            delegate?.failedToSendComplication(reason: "Due to hardware limitations, you can only send a certain amount of complications in a day. You have exceeded that limit for today. You can still set complications from the Apple Watch app.")
        }
        #endif
    }

Вот хороший пример от Apple, который может помочь вам больше: source

0 голосов
/ 02 марта 2019

Сброс настроек iPhone, Apple Watch и Mac устранил проблему.

0 голосов
/ 25 февраля 2019

Как вы описываете в своем обновлении, ваше приложение для iPhone вызывает session.transferCurrentComplicationUserInfo(context) до того, как часы настроят WCSession.Но в документах говорится:

[TransferCurrentComplicationUserInfo (_ :)] можно вызывать только в то время, когда сеанс активен, т. Е. Для свойства activState установлено значение WCSessionActivationState.activation.Вызов этого метода для неактивного или деактивированного сеанса является ошибкой программиста.

Поэтому я предлагаю вам реализовать (если вы этого еще не сделали) функцию WCSessionDelegate session(_:activationDidCompleteWith:error:) (см. здесь ) и передавать данные о сложностях только после того, как сеанс был активирован.

...