Search code examples
swiftios9alamofirexcode7.3

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)
    }
}

Solution

  • 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
    }