2
votes

I'm trying to test an OAuth2 implementation in a Xcode Playground, using a PHP API and a Swift client. Basically, my code looks like this

let url = NSURL(string: "http://localhost:9142/account/validate")!
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody!.setValue("password", forKey: "grant_type")
// Other values set to the HTTPBody

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, error) in
    // Handle response here
}

But I keep getting this error when I instantiate the url variable :

fatal error: unexpectedly found nil while unwrapping an Optional value

I tried not unwrapping it when I instantiate it but rather when I use it, it didn't change anything, the error appears on the first time I unwrap it.

It keeps getting even weirder.. The following

let url = NSURL(string: "http://localhost:9142/account/validate")!
println(url)

outputs

http://localhost:9142/account/validate fatal error: unexpectedly found nil while unwrapping an Optional value

I really don't understand where the error can come from, as I'm really new to Swift

1
The error can easily come from request.HTTPBody! since you forced unwrapped HTTPBody. Follow this tutorial jamesonquave.com/blog/making-a-post-request-in-swift to make a post requestZell B.
Your error isn't coming from url definition. Check the request to see HTTPBody does existanasimtiaz
Wow, I commented the lines I used the HTTPBody!, and it actually came from there ! I found it was from the NSURL since Xcode put the error on this line. Thanks a lot for helping me !k4zuk0
Please note that you will get a similar error with url definition if there is a space in the string you are using, e.g. url = NSURL(string="http://test.com/something?argument=variable containing space") Kushal Ashok

1 Answers

0
votes

What is happening is you are forced unwrapping the HTTPBody which is set to nil, causing a runtime error at this line:

request.HTTPBody!.setValue("password", forKey: "grant_type")

You need to create an NSData object for your request body and then assign it to the request.HTTPBody as per the following code:

let url = NSURL(string: "http://localhost:9142/account/validate")!
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"

// Create a parameter dictionary and assign to HTTPBody as NSData
let params = ["grant_type": "password"]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: nil)

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, error) in
    // Handle response here
}

I hope this helps solves your problem.

Update:

In order to serialise data without using a JSON serializer, you can create your own similar to below:

func dataWithParameterDictionary(dict: Dictionary<String, String>) -> NSData? {
    var paramString = String()

    for (key, value) in dict {
        paramString += "\(key)=\(value)";
    }

    return paramString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
} 

and call it like such:

let dict = ["grant_type": "password"]
let data = dataWithParameterDictionary(dict)
request.HTTPBody = data