Как вызвать тактильные оповещения, когда неактивные часы получают локальное уведомление

Я работаю над приложением таймера для Apple Watch.

В определенное время (конец таймера) iPhone запускает запланированное UILocalNotification который на неактивных Apple Watch должен вызвать тактильное предупреждение, чтобы сообщить пользователю, что таймер закончился.

Я сделал это, так как таймеры не продолжают работать на Apple Watch, когда часы неактивны.

Проблема, с которой я сталкиваюсь:

а) уведомление иногда отображается на iPhone, а не на яблочных часах (основываясь на других сообщениях, боюсь, что это нельзя изменить...)

б) тактильные предупреждения не выдаются на часы (только отображение уведомления, и это только в следующий раз, когда пользователь активирует часы, а не в тот момент, когда уведомление фактически сработало)

func sendAwakeNotification(nextTime:NSDate) {
    print("AppDelegate: - sendAwakeNotification")

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

        let localNotification = UILocalNotification()
        localNotification.fireDate = nextTime
        localNotification.timeZone = NSTimeZone.defaultTimeZone()
        localNotification.alertBody = "Finished Step"
        localNotification.alertTitle = "Alert"

        localNotification.soundName = UILocalNotificationDefaultSoundName

        localNotification.category = "myTimer"
        let userInfo: [NSObject : AnyObject] = [
            "notification_id" : "myTimerNotification"
        ]
        localNotification.userInfo = userInfo

        UIApplication.sharedApplication().scheduleLocalNotification(localNotification)

    }
}

Код в уведомлении

override func didReceiveLocalNotification(localNotification: UILocalNotification, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {

    print("received notification")

    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        let notificationCenter = NSNotificationCenter.defaultCenter()
        notificationCenter.postNotificationName(NotificationAlertFromPhone, object: nil)
    }

    completionHandler(.Custom)
}

Я пытался вызвать тактильные предупреждения прямо в NotificationController (WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification)), но это не сработало. Поэтому я вернулся, чтобы отправить уведомление, которое должно быть получено ExtensionDelegate, чтобы вызвать тактильную тактику.

Вот код в ExtensionDelegate:

private func setupNotificationCenter() {
    print("ExtensionDelegate:  - setupNotificationCenter")

    notificationCenter.addObserverForName(NotificationAlertFromPhone, object: nil, queue: nil) { (notification:NSNotification) -> Void in
        WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification)
    }
}

3 ответа

Решение

Где отображаются уведомления

а) уведомление иногда отображается на iPhone, а не на яблочных часах (основываясь на других сообщениях, боюсь, что это нельзя изменить...)

Правильно. Это зависит от iOS, чтобы определить, где показывать уведомление.

  • Если ваш iPhone разблокирован, вы получите уведомления на своем iPhone, а не на Apple Watch.

  • Если ваш iPhone заблокирован или находится в спящем режиме, вы будете получать уведомления на Apple Watch, если только ваши Apple Watch не заблокированы вашим паролем.

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

Когда уведомление обрабатывается часами

б) тактильные предупреждения не выдаются на часы (только отображение уведомления, и это только в следующий раз, когда пользователь активирует часы, а не в тот момент, когда уведомление фактически сработало)

Это правильно. Вы ожидаете didReceiveLocalNotification стрелять по часам, но это происходит только тогда, когда часы активированы:

Если локальное уведомление приходит, когда ваше приложение активно, WatchKit вызывает этот метод для доставки полезных данных уведомления. Используйте этот метод для ответа на уведомление.

Это причина, по которой ваша тактильная обратная связь не происходит, когда вы ожидаете, так как призыв к воспроизведению тактильной обратной связи не происходит позже.

Обходной путь для вашего подхода

Вы можете условно сыграть в тактику, предварительно изучив местные уведомления. fireDate, Воспроизведите свой тактильный отзыв только в том случае, если обработка уведомлений только что началась.

Лучшее решение

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

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

Сделать запрос на функцию

Реальная проблема, которую вы пытаетесь обойти, заключается в том, что только приложение Apple для таймера может планировать свои собственные локальные уведомления.

Если вы еще этого не сделали, возможно, вы захотите отправить запрос на добавление функции, в котором Apple разрешит сторонним разработчикам размещать локальные уведомления на watchOS.

Для всех, у кого есть эта проблема, также может быть, что звук не установлен. В официальной документации по Apple Watch не указано, что вам нужно добавлять звук.

Не забудьте добавить:

content.sound = UNNotificationSound.default

Установите идентификатор UUID().uuidString вместо «localNotificatoin».

      static func setLocalNotification(title: String, subtitle: String, body: String, when: Double) {
    let content = UNMutableNotificationContent()
    content.title = title
    content.subtitle = subtitle
    content.body = body
    content.sound = UNNotificationSound.default

    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: when, repeats: false)
    let request = UNNotificationRequest.init(identifier: UUID().uuidString, content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
Другие вопросы по тегам