Как я могу получить локальные настройки уведомлений пользователя в iOS? - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь создать метод, который возвращает логическое значение, указывающее, авторизовал ли пользователь уведомления. В настоящее время у меня есть это:

func notificationsAllowed() -> Bool{
            var valToRet = false
            UNUserNotificationCenter.current().getNotificationSettings() { settings in
                valToRet = (settings.authorizationStatus == .authorized)
                print(settings.authorizationStatus == .authorized)
            }
            return valToRet
        }

Я не совсем понимаю, что делает "settings in". Этот метод не работает, потому что valToRet никогда не обновляется. Моя цель состояла в том, чтобы создать метод, который будет получать эту информацию, но я вижу, что это действительно показывает некоторые серьезные пробелы в моем понимании быстрого языка, поэтому я хотел бы узнать, что на самом деле происходит. У меня проблемы с поиском ресурсов о том, как синтаксис Swift работает таким образом, любые ссылки были бы очень полезны.

1 Ответ

0 голосов
/ 03 августа 2020

Функция getNotificationSettings для UNUserNotificationCenter является asyn c и имеет обработчик завершения в качестве единственного параметра.

Сигнатура функции: func getNotificationSettings(completionHandler: @escaping (UNNotificationSettings) -> Void)

Что это означает заключается в том, что тот же вызов, что и в вашем коде, может быть записан как:

UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) -> Void in
    valToRet = (settings.authorizationStatus == .authorized)
    print(settings.authorizationStatus == .authorized)
})

Это означает, что ваша функция notificationsAllowed() возвращается до того, как getNotificationSettings() запускает свой обратный вызов, и поэтому valToRet всегда ложно.

Следовательно, ваша функция notificationsAllowed() является избыточной, и вы должны просто использовать UNUserNotificationCenter.current().getNotificationSettings() вместо нее, ожидая закрытия обработчика завершения. Я ожидаю, что вам придется реструктурировать место, где вызывается этот код, поскольку я думаю, вы сделали предположение, что это значение доступно немедленно.

Если вы вызываете это в viewDidAppear (не рекомендуется, вы всегда должны запрашивать авторизация, как только действие пользователя требует авторизации - например, они могут нажать кнопку «Подписаться»), код может быть:

func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) -> Void in
        if settings.authorizationStatus == .notDetermined {
            // Display dialog advertising benefits of push notifications
            // Encourage user to allow, then present auth prompt
            // ...
        }
    })
}

Extra

Я не совсем понимаю, какие «настройки» in "делает.

В Swift ключевое слово in используется для объявления начала закрытий (анонимных функций). Для стандартных функций у нас есть func, хотя закрытие (анонимная функция) мы должны использовать in для объявления.

Думайте об этом как «Возьмите параметр settings и используйте его in this бит кода выброса ".

Таким образом, обработчик завершения для getNotificationSettings теоретически может быть написан как стандартная функция, а не как анонимное закрытие`, например:

func myNotificationSettingsCompletionHandler(settings: UNNotificationSettings) -> Void {
    if settings.authorizationStatus == .notDetermined {
        // Display dialog advertising benefits of push notifications
        // Encourage user to allow, then present auth prompt
        // ...
    }
}

Затем мы можем использовать эту функцию в параметре completionHandler: в getNotificationSettings, например:

UNUserNotificationCenter.current().getNotificationSettings(completionHandler: myNotificationSettingsCompletionHandler)
...