У меня есть файл JSON с несколькими URL-адресами (с .mp3) для слов. Некоторые из URL недействительны (или допустимы, но возвращают ошибку, поэтому я все равно не получаю данные).
Этот URL я использую для воспроизведения произношения слова. Итак, я иду бросить 3 шага:
- Поиск URL для определенного слова. Если не можете найти, то ничего не происходит
- Используйте этот URL для инициализации AVPlayerItem и подготовки AVPlayer. Чем просто ждать, когда пользователь нажмет.
- Воспроизведение звука, когда пользователь нажимает на слово
Итак, во-первых, я готовлю свой AVPlayer, чтобы избежать задержки в игре.
Я немного запутался с многопоточностью, и я не понимаю, где я должен проверить, могу ли я воспроизвести этот звук, или нет, и я должен использовать следующий URL.
Код:
extension WordCell {
func playPronunciation() {
player?.play()
player?.seek(to: .zero)
}
func prepareForPronunciation() {
if let word = myLabel.text {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
let foundURL = self?.findURL(for: word)
if let url = foundURL {
let playerItem = AVPlayerItem(url: url)
//here "playerItem.status" always equals .unknown (cause not initialized yet)
if playerItem.status == .failed {
//self?.giveNextUrl() - will do some code there
}
self?.player = AVPlayer(playerItem: playerItem)
self?.player!.volume = 1.0
}
// this is also not correct, because networking continueing
// but i don't know where to place it
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
}
}
// right now i take URL from file, where there is only one.
// but i will use file with a few URL for one word
private func findURL(for word: String) -> URL? {
if let path = Bundle.main.path(forResource: "data", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? [String: String] {
if let url = jsonResult[word] {
return URL(string: url)
} else {
return nil
}
}
} catch {
return nil
}
}
return nil
}
}
Это файл JSON с несколькими URL на слово
"abel": [
"http://static.sfdict.com/staticrep/dictaudio/A00/A0015900.mp3",
"http://img2.tfd.com/pron/mp3/en/US/d5/d5djdgdyslht.mp3",
"http://img2.tfd.com/pron/mp3/en/UK/d5/d5djdgdyslht.mp3",
"http://www.yourdictionary.com/audio/a/ab/abel.mp3"
],
"abele": [
"http://www.yourdictionary.com/audio/a/ab/abele.mp3",
"http://static.sfdict.com/staticrep/dictaudio/A00/A0016300.mp3",
"http://www.oxforddictionaries.com/media/english/uk_pron/a/abe/abele/abele__gb_2_8.mp3",
"http://s3.amazonaws.com/audio.vocabulary.com/1.0/us/A/1B3JGI7ALNB2K.mp3",
"http://www.oxforddictionaries.com/media/english/uk_pron/a/abe/abele/abele__gb_1_8.mp3"
],
Итак, мне нужно взять первый URL и проверить его. Если не получилось, возьмите другое и проверьте ... и т. Д., Пока URL-адреса закончились, или найдите какой-нибудь действительный URL.
И все это нужно сделать до того, как AVPlayer попытается воспроизвести звук.
Как это реализовать и где?
Пожалуйста, скажите и опишите разрешение простыми словами, потому что я новичок в быстрой и многопоточности.