swift - как вернуться из закрытия обработчика завершения системной функции?

Я знаю, что это не сработает, потому что completion handler находится на background Thread, но

где я должен отправить основную очередь или что еще мне нужно сделать?

это код:

static func isNotificationNotDetermined() -> Bool{

    var isNotDetermined = false

    UNUserNotificationCenter.current().getNotificationSettings { (notificationSettings) in
        switch notificationSettings.authorizationStatus {
        case .notDetermined:
            isNotDetermined = true

        case .authorized:
            isNotDetermined = false

        case .denied:
            isNotDetermined = false

        }
    }

    return isNotDetermined
}

person Some German Developer    schedule 30.01.2018    source источник
comment
В вашем случае проблема не в фоновом потоке, все в порядке (вы ничего не делаете с пользовательским интерфейсом), а в том, что он асинхронный. Ищите Async Swift Closure. Вы будете часто получать ответы о JSON/WebAPICall, но ситуация точно такая же.   -  person Larme    schedule 30.01.2018


Ответы (2)


Вы не можете поступить таким образом; getNotificationSettings является асинхронным, поэтому вы должны передать замыкание в методе и вызвать его сразу после переключения. Что-то вроде этого:

static func isNotificationNotDetermined(completion: (Bool) -> Void) {

    UNUserNotificationCenter.current().getNotificationSettings { (notificationSettings) in
        var isNotDetermined = false
        switch notificationSettings.authorizationStatus {
        case .notDetermined:
            isNotDetermined = true

        case .authorized:
            isNotDetermined = false

        case .denied:
            isNotDetermined = false

        }

        // call the completion and pass the result as parameter
        completion(isNotDetermined)
    }

}

Затем вы вызовете этот метод следующим образом:

    YourClass.isNotificationNotDetermined { isNotDetermined in
        // do your stuff
    }
person Rico Crescenzio    schedule 30.01.2018

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

Представьте, что вы готовите ужин и спрашиваете дочь: «Твой брат будет дома к обеду?» Ваша дочь должна позвонить вашему сыну и узнать. У вас не будет ответа на вопрос, как только вы его зададите. Вам придется подождать, пока ваша дочь найдет телефон, позвонит и отчитается перед вами.

Асинхронные функции такие. Ответ неизвестен, когда функция возвращается. Вот для чего нужен обработчик завершения. Это блок кода, который выполняется после определения ответа.

person Duncan C    schedule 30.01.2018
comment
да, но я не могу поместить возврат в обработчик завершения, вот в чем проблема. - person Some German Developer; 30.01.2018
comment
Это асинхронный API. Не борись с этим. Напишите свой код, чтобы он мог реагировать на определение статуса внутри замыкания. - person Gereon; 30.01.2018
comment
Что сказал @Gereon. Вы не можете написать свою функцию, чтобы вернуть истинный/ложный ответ. Это невозможно. Вам нужно написать свою функцию так, чтобы она принимала обработчик завершения, который запускается после того, как асинхронная getNotificationSettings() функция соревнуется. - person Duncan C; 30.01.2018
comment
См. ответ @RicoCrescenzio. Он переписал вашу функцию isNotificationNotDetermined() так, чтобы она выполняла замыкание, как и должны делать вы. (проголосовали) - person Duncan C; 30.01.2018