32

I have a question about the new version of Alamofire for Swift 2

Alamofire.request(.POST, urlString, parameters: parameters as? [String : AnyObject])
        .responseJSON { (request, response, result) -> Void in
            let dico = result as? NSDictionary
            for (index, value) in dico! {
                print("index : \(index)     value : \(value)")
            }
    }

In this section I would like to cast the result in to a NSDictionary. But When I compile and put a breakpoint, the debugger says that dico is nil. If I use debugDescription to print result, it is not nil and contains what I expected How can I cast the Result variable?

Javier Cadiz
  • 12,326
  • 11
  • 55
  • 76
Edgar Georgel
  • 602
  • 1
  • 7
  • 17
  • 2
    Try `if let dico = result as? [String: AnyObject] { ... }` – mattt Aug 14 '15 at 23:40
  • If that doesn't execute, it's because the result was nil (or not downcastable to a dictionary). You should check to see what's in `error`. – mattt Aug 14 '15 at 23:43
  • Also, worth noting that dictionaries have keys, not indexes. – mattt Aug 14 '15 at 23:43
  • Thank you @mattt for your answer. I find how to do it. I use what you said but it didn't work, and when I do: if let dico = result.value as? [String: AnyObject] {} and just 'replace' result by 'result.value' it work find – Edgar Georgel Aug 15 '15 at 08:25

3 Answers3

56

The accepted answer works great but with the introduction of Alamofire 3.0.0 there are some breaking changes that affects this implementation.
The migration guide has further explanations but i will highlight the ones related to the actual solution.

  • Response
    All response serializers (with the exception of response) return a generic Response struct.

  • Response type
    The Result type has been redesigned to be a double generic type that does not store the NSData? in the .Failure case.

Also take in count that Alamofire treats any completed request to be successful, regardless of the content of the response. So you need to chain a .validate() before .responseJSON() to hit the .Failure case. Read more about it here.

Updated code:

let url = "http://api.myawesomeapp.com"
Alamofire.request(.GET, url).validate().responseJSON { response in
    switch response.result {
    case .Success(let data):
        let json = JSON(data)
        let name = json["name"].stringValue
        print(name)
    case .Failure(let error):
        print("Request failed with error: \(error)")
    }
}

For reference:

  • Xcode 7.3 (Swift 2.2)
  • Alamofire 3.3.1
  • SwiftyJSON 2.3.3
Javier Cadiz
  • 12,326
  • 11
  • 55
  • 76
39

If you don't mind using SwiftyJSON library, here's a working example in Xcode 7 Beta 5 + Alamofire 2.0.0-beta.1 + SwiftyJSON (xcode7 branch)

Alamofire.request(.GET, url, parameters: params, encoding: ParameterEncoding.URL).responseJSON { (_, _, result) in
    switch result {
        case .Success(let data):
            let json = JSON(data)
            let name = json["name"].string
        case .Failure(_, let error):
            print("Request failed with error: \(error)")
    }
}

Edit:

Updated SwiftyJSON git page

swiftBoy
  • 35,607
  • 26
  • 136
  • 135
chemic
  • 800
  • 7
  • 12
0

You can now achieve most of the required behaviour out of the box without the need for SwiftyJSON for example. My OAuthTokenResponse is a simple struct that is Codable. The Alamofire library 5.2.2 lets you respond using the 'responseDecodable'

If you have say a struct that looks like this:

struct OAuthTokenResponse : Codable
{
    var access_token:String?
    var token_type:String?
    var expires_in:Int?
    var scope:String?
}

And then in your network call (using Alamofire)

let request = AF.request(identityUrl, method: .post, parameters: parameters, encoding: URLEncoding.httpBody)
    request
        .validate()
        .responseDecodable { (response:AFDataResponse<OAuthTokenResponse>) in
            
            switch response.result {
            case .success(let data):
                do {
                    let jwt = try decode(jwt: data.access_token!) // example
                    self.connected = true
                    print(jwt)
                } catch {
                    print(error.localizedDescription)
                    self.connected = false
                }
                
            case .failure(let error):
                    self.connected = false
                    print(error.localizedDescription)
            }
        
        }

In the above code, the success case automatically deserialises your JSON using the decodable protocol into your struct. Any errors will result in the error case being hit instead.

The Senator
  • 5,181
  • 2
  • 34
  • 49