DatForis
DatForis

Reputation: 1341

how to modify data in an asynchronous URLrequest in swift before reaching the return statement

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

Answers (2)

DatForis
DatForis

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

milo526
milo526

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

Related Questions