Reputation: 1341
I've started learning ios development a while back and I've reached the part where I'm trying to send and receive data from a server. I've ran into an issue where for example if I wanted to sign a user in or sign him up using an Asynchronous connection. Code example on a datamanager class using swiftyjson :
class func signUp() -> NSString {
var url: NSURL = NSURL(string: "http://localhost/Test/signup.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "username=Datforis&name=firas&password=123123"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
var status = "error"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(response)
if(error != nil){
//handleerror
}
else if data == nil {
println("Server could not be reached please check your internet connection")
status = "connectionerror"
}
else {
println("i'm here")
let json = JSON(data : data)
var msgint : Int = json["status"].int!
status = String(msgint)
println(status)
}
}
println(status + " is current" )
return status //returns status if sign up was successful or not
}
the code will always return "error" (default value) because the return statement is being executed before the status string is being modified. If I repeat the same code but with a synchronous connection it works fine, but everyone I ask tells me to steer clear of Synchronous connections because they freeze the UI while they execute Is there a way to handle this without having to use a Synchronous connection? Or is it the only way? And is there a better way to handle a sign up/sign in request or any request in general? Thanks
Upvotes: 0
Views: 506
Reputation: 1341
thanks to the selected answer I corrected my code
Placed in the Datamanager :
class func signUp(username : String , completion: (status : NSString)->Void) {
var url: NSURL = NSURL(string: "http://localhost/WhosIn/signup.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "username=Datforis&name=firas&password=123"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
var status = "error"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(response)
if(error != nil){
completion(status: status)
}
else if data == nil {
println("Server could not be reached please check your internet connection")
status = "connectionerror"
completion(status: status)
}
else {
println("i'm here")
let json = JSON(data : data)
var msgint : Int = json["status"].int!
status = String(msgint)
println(status)
completion(status: status)
}
}
}
Placed in the View Controller when attempting to run the function
DataManager.signUp("asdasd", completion: {
(status) in
println(status)
})
Upvotes: 0
Reputation: 5083
I would advice you to take a look at this article about Completion handlers.
Completion handlers are used instead of return statements.
The Completion handler will be called when your statement is completed instead of when it reaches the end of the function.
The link I mentioned before has the following example
func hardProcessingWithString(input: String, completion: (result: String) -> Void) {
…
completion(“we finished!”)
}
This could be used in mathematical calculations which take a long time, or in your case, URL requests. To retrieve the data you could use
hardProcessingWithString(“commands”) {
(result: String) in
println(“got back: (result)“)
}
Upvotes: 1