Reputation: 194
I have a recursive function with an async request. I want to save in an array if the requests were successful, but i don't know how. Concrete it is a function to upload files and if the function get a folder than the files inside this folder should also be uploaded.
I thought about implement this with a completionHandler, something about this:
func uploadFiles(pathToFile: NSURL) ->[Bool]{
var suc: [Bool] = [Bool]()
self.uploadFileRec(pathToFile, suc: &suc){
(result: [Bool]) in
println(result)
}
return suc
}
func uploadFilesRec(pathToFile: NSURL, inout suc: [Bool], completionHandler: (result: [Bool]) -> Void){
var isDir: ObjCBool = ObjCBool(true)
var manager: NSFileManager = NSFileManager.defaultManager()
manager.fileExistsAtPath(pathToFile.path!, isDirectory: &isDir)
if(isDir){
var error: NSError? = nil
let contents = manager.contentsOfDirectoryAtPath(pathToFile.path!, error: &error) as! [String]
for fileName in contents {
if(fileName != ".DS_Store"){
var pathString = pathToFile.path! + "/" + fileName
var updatePathtoFile = NSURL(fileURLWithPath: pathString)
self.uploadFilesRec(updatePathtoFile!, suc: &suc, completionHandler: completionHandler)
completionHandler(result: suc)
}
}
}
else{
asyncFileUpload(...){
...
suc.append(/*successful or not*/)
}
}
}
But the problem is that println get call not only one time but as many as uploadFileRec get called inside. So if i would call an another function instead of println, the function would be also called many times. So i think the idea with completionHandler was wrong. How else can i realize this?
Upvotes: 0
Views: 1511
Reputation: 194
Ok i answer my own question.
The idea with complitionHandler was indeed false. Like I'm saying in the question, the complitionHandler is called as many times as the recursive function is called. If you want to collect the responses or like in my app collect if the upload of some files was successful you must use dispatch group. The main idea is to add all request in this group and wait until all are done.
In practice it means create group:
let group = dispatch_group_create()
Enter the group before you call the recursive function and then each time the function call itself:
dispatch_group_enter(self.group)
Leave the group when the request is done and as many time as you enter the group:
dispatch_group_leave(self.group)
And wait until all work is done:
dispatch_group_notify(group, dispatch_get_main_queue()) {
//Do work here
}
Upvotes: 1
Reputation: 1336
var isDir: ObjCBool = ObjCBool(true)
so, you treat all files as dirs by default, and when manager.fileExistsAtPath
fails you get deep recursion because isDirectory flag stays TRUE:
If path doesn’t exist, this value is undefined upon return
from Apple Doc...
var pathString = pathToFile.path! + "/" + fileName
- not sure your're getting correct path in the end. So, you getting recursion. Check your pathString
Fix that things and keep going...
Upvotes: 0