Agustin Agustin - 3 months ago 27
Swift Question

Unable to use NSURL in Alamofire response.result.value! Swift, xcode 7.3

I have a media player app that I'm working on, and I am sending an Alamofire request to obtain an URL in the form of a string... when I receive the response I do properly receive it as a string, but when I try to convert it into a NSURL, I keep getting nil.

The request is:

Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.responseString(encoding: NSUTF8StringEncoding) { response in
print("Response: \(response)")
print("Response String: \(response.result.value!)")
self.URLToPlay = response.result.value!
}


My URLString is a String, my URLToPlay is also a String.
The command I use to convert it to NSURL is

let streamingURL = NSURL(string: self.URLToPlay)


I get a valid URL-looking string in URLToPlay, in fact if I copy/paste that received string unto a browser, I am able to play the media... but when I use it to convert to NSURL, my app crashes (due to streamingURL being nil).

Now I believe this has something to do with the request being asynchronous, but I'm wondering if anyone has any idea of how to get this working?

I would greatly appreciate your help.

Edited to use a completion handler:

func connectToServer() {
print("Connecting...")

finishLoad { theUrl in

let urlString = theUrl.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
let streamingURL = NSURL(string: urlString!)

// do what i need to do

}

isConnectedToServer = true
print("Connected...")
}
func finishLoad(complete: (urlToBePlayed: String) -> ()) {
var aVar: String!
Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.responseString(encoding: NSUTF8StringEncoding) { response in
aVar = response.result.value!
complete(urlToBePlayed: aVar)
}
}

Answer

This is an Async process and no matter where you use URLToPlay OUTSIDE the .GET function of Alamofire, it is going to return nil because it will be nil as the process is async and the variable is still not updated at all. You can wrap this up in a completion handler and use like so:

func finishLoad(complete: (urlToBePlayed: String) -> ()) {
let aVar: String!
 Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
        .validate(statusCode: 200..<300)
        .responseString(encoding: NSUTF8StringEncoding)  { response in
            print("Response: \(response)")
            print("Response String: \(response.result.value!)")
            aVar = response.result.value!             
            complete(urlToBePlayed: aVar)
    }
}

Now call and use it like so:

finishLoad { theUrl in
let urlString = theUrl.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQ‌​ueryAllowedCharacter‌​Set())  //Fixes the deprecated error.
var convertToURL = NSURL(string: urlString)!     
 print(convertToURL)

//here you do what you want
}
Comments