I have the following scenario - I have an app that needs to get some audio files from the server in background and asynchronously. The audio files are a big number - like 10000. They are 1-2 sec mp3 files (like 5-10 kb each). For each of these files I have to make a network request and get the files using its ID. There are two types of audio files - for your native language and for your learning language. So I go through all the IDs like this - 1. get me native audio with ID 1, then get me learning audio with ID 1 ---> ID+1 and again the same scenario.
The problem is that when I go like this, some of the audio files are corrupted at the end. I guess it's because I am not doing the async requests properly. Here is my code:
DispatchQueue.global(qos: .background).async {
let myGroup = DispatchGroup()
for category in arrCategories {
for library in category.libraries {
for group in library.groups {
for word in group.words {
myGroup.enter()
User.current.getAudioFile(forWord: word, language: User.current.nativeLanguage, isNative: true, callback: { (success) in
if success {
User.current.getAudioFile(forWord: word, language: User.current.learningLanguage, isNative: false, callback: { (success) in
if success {
myGroup.leave()
} else {
print("ERROR LEARNING")
myGroup.leave()
}
})
} else {
print("ERROR NATIVE")
myGroup.leave()
}
})
}
}
}
}
myGroup.notify(queue: DispatchQueue.main, execute: {
print("READY")
running = false
})
And my network request:
request(urlRequest).response { (response) in
if response.data != nil && response.error == nil {
let soundData = response.data! as NSData
let fileURL = URL(fileURLWithPath: filePath)
do {
try soundData.write(to: fileURL, options: .atomic)
callback(true)
} catch {
print(error)
callback(false)
}
} else {
print(response.error?.localizedDescription)
callback(false)
}
Can anybody tell me what's wrong with the code? Because some audio files are not playing if I use this approach. But if I download only this file without making so many requests, it plays normally.
Using a loop just starts all the async requests. Your problem lies in handling all the parallel responses.
One option is to use a mutex/semaphor to block the loop before finishing the first one (I wouldn't advice it.
The second option would be creating a list of request and whenever a request finishes start the next one.