k4zuk0
k4zuk0

Reputation: 23

Xcode - Swift - NSURL : "fatal error: unexpectedly found nil while unwrapping an Optional value"

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

Upvotes: 2

Views: 3207

Answers (1)

Elliott Minns
Elliott Minns

Reputation: 2784

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

Upvotes: 0

Related Questions