#ios #swift #authentication #storekit #apple-musickit
#iOS #swift #аутентификация #storekit #apple-musickit
Вопрос:
Я пытаюсь воспроизводить песни на iOS 14 с помощью Apple Music API. У меня есть токен разработчика, и я запросил разрешение на доступ к Apple Music пользователя.
Однако, когда я вызываю api requestusertoken, его закрытие никогда не вызывается, поэтому, очевидно, я ничего не получаю от запроса — даже ошибки. Это сводит меня с ума.
Вот мой код. Что я делаю не так?
func getUserToken() -> String {
var userToken = String()
let lock = DispatchSemaphore(value: 0)
SKCloudServiceController().requestUserToken(forDeveloperToken: developerToken) { (receivedToken, error) in
guard error == nil else { return }
if let token = receivedToken {
userToken = token
lock.signal()
}
}
lock.wait()
return userToken }
Комментарии:
1. Точно такая же проблема.. Вы когда-нибудь это понимали?
Ответ №1:
Я попробовал код, и возникли две основные проблемы.
Во-первых, DispatchSemaphore заставляет строку возврата выполняться слишком рано. Во-вторых, исходный токен разработчика не работает из-за последней проблемы iOS 14.3.
Итак, я сначала удалил DispatchSemaphore.
func getUserToken() {
var userToken = String()
SKCloudServiceController().requestUserToken(forDeveloperToken: developerToken) { (receivedToken, error) in
guard error == nil else { return }
if let token = receivedToken {
userToken = token
print(userToken)
}
}
}
Затем изменен токен разработчика, следующий за этим репозиторием.
Теперь он правильно печатает токен пользователя. Надеюсь, это помогло.
Ответ №2:
Я думаю, мы все застряли на одном и том же руководстве. Чтобы исправить, я поместил его в другой поток, поскольку блокировка задерживала основной поток, следовательно, предотвращая обработчик завершения.
DispatchQueue.global(qos: .background).async {
print(AppleMusicAPI().fetchStorefrontID())
}
Если это тот же учебник, это поместит методы fetchStorefrontID() и getUserToken() (который вызывается первым) в фоновый поток и позволит выполнить обработчики завершения и lock.signal() .
Если это не так, этого должно быть достаточно для ответа:
DispatchQueue.global(qos: .background).async {
getUserToken()
}
Ответ №3:
Вы удалили Bearer
из своего developerToken
?
Комментарии:
1. Привет, Ник, да, мой токен разработчика выглядит примерно так: пусть developerToken = «e *****.e *****.d ****A»
2. ОК. Потому что я не вижу остальной части вашего кода или класса / структуры. Возможно, у вас проблема со ссылкой. Если ваш класс / структура инициализируется в
func
без наличия глобальной переменной, ваш объект будет освобожден, и блок завершения никогда не вызывается.3. БОЖЕ МОЙ! Это было для меня… Я добавлял «Bearer» к своему токену разработчика при подготовке к вызову
api.music.apple.com
. Ого!
Ответ №4:
Хорошо, я знаю, что происходит — DispatchSemaphore
он блокируется сразу после его создания, поэтому он никогда не выполняет этот код. Однажды я ввел значение семафора 1
вместо 0
того, чтобы оно начало выполняться, но затем у меня возникли проблемы с остальной частью кода из-за последовательности событий.
Похоже, возможно, вы работаете с тем же учебным пособием, над которым я работал над интеграцией Apple Music SDK — если это так, я в основном изменил код, чтобы :
- загрузите токен пользователя в локальную переменную, а затем другие методы начнут ссылаться на него в своих запросах.
- Удалите блокировку семафора
getuserToken()
только в методе - Остальные снова начали работать, без необходимости изменять какие-либо другие
DispatchSemaphore
значения.
Я ни в коем случае не являюсь экспертом в том, как работает DispatchSemaphore и как использовать лучшие практики с пользовательскими токенами Apple music, но хотел хотя бы сообщить вам, почему вы столкнулись с той же стеной, что и я — без выполнения кода вообще.