如何在Swift中解析来自Alamofire API的JSON响应?

问题描述:

下面的代码我写了,我也得到了JSON的响应,但JSON的类型是“AnyObject”,我不能将它转换为数组,以便我可以使用它。如何在Swift中解析来自Alamofire API的JSON响应?

Alamofire.request(.POST, "MY URL", parameters:parameters, encoding: .JSON) .responseJSON 
{ 
    (request, response, JSON, error) in 

    println(JSON?) 
} 
+0

我没有downvote你的问题但我认为它是因为解析JSON过于宽泛的话题而给出了明确而直接的答案。试试这个名为[SwiftyJSON]的库(https://github.com/SwiftyJSON/SwiftyJSON)。 – Isuru 2014-09-30 10:21:15

+0

@Isuru它确定!我看过那个图书馆,但我正在使用Alamofire! 但是,你能给我发送你使用过SwiftyJson的示例代码吗?有代码不适合我! – Developer 2014-09-30 10:49:50

+0

我也使用SwiftyJSON和Alamofire。我只是在这个'let data = JSONValue(JSON!)'中传递响应。然后我可以提取像这样的数据[“Id”]'。 SwiftyJSON文档提供了如何检索所需类型的值的示例。你究竟发生了什么错误? – Isuru 2014-09-30 12:09:36

我既不是JSON专家,也不是Swift专家,但以下是我的工作。 :)我已经从我当前的应用程序中提取了代码,并且只将“MyLog更改为println”,并用空格缩进以使其显示为代码块(希望我没有破坏它)。

func getServerCourseVersion(){ 

    Alamofire.request(.GET,"\(PUBLIC_URL)/vtcver.php") 
     .responseJSON { (_,_, JSON, _) in 
      if let jsonResult = JSON as? Array<Dictionary<String,String>> { 
      let courseName = jsonResult[0]["courseName"] 
      let courseVersion = jsonResult[0]["courseVersion"] 
      let courseZipFile = jsonResult[0]["courseZipFile"] 

      println("JSON: courseName: \(courseName)") 
      println("JSON: courseVersion: \(courseVersion)") 
      println("JSON: courseZipFile: \(courseZipFile)") 

      } 
     } 
} 

希望这会有所帮助。

编辑:

仅供参考,这里是我的PHP脚本返回:

[{"courseName": "Training Title","courseVersion": "1.01","courseZipFile": "101/files.zip"}] 

像上面提到你可以使用SwiftyJSON库,让你的价值观像我有以下

Alamofire.request(.POST, "MY URL", parameters:parameters, encoding: .JSON) .responseJSON 
{ 
    (request, response, data, error) in 

var json = JSON(data: data!) 

     println(json) 
     println(json["productList"][1])     

} 
完成

我的json产品列表返回脚本

{ "productList" :[ 

{"productName" : "PIZZA","id" : "1","productRate" : "120.00","productDescription" : "PIZZA AT 120Rs","productImage" : "uploads\/pizza.jpeg"}, 

{"productName" : "BURGER","id" : "2","productRate" : "100.00","productDescription" : "BURGER AT Rs 100","productImage" : "uploads/Burgers.jpg"}  
    ] 
} 

输出:

{ 
    "productName" : "BURGER", 
    "id" : "2", 
    "productRate" : "100.00", 
    "productDescription" : "BURGER AT Rs 100", 
    "productImage" : "uploads/Burgers.jpg" 
} 
+0

我试图在安装后使用SwiftyJson的东西,但在SwiftyJson文件中给出了一些300错误,是否有人面临这个问题?我',使用Xcode版本6.2,ios版本8.1,在[github](https://github.com/SwiftyJSON/SwiftyJSON)文档中提到的cocoaPods 36。 – Sashi 2015-04-17 19:33:16

+1

伙计。什么是错误?询问一个单独的问题并提供一些细节。 SwiftyJSON和魔术一样美丽。如果可能,请使用它。 – 2015-08-10 17:17:17

+0

真的应该将json字符串转换为具体的swift对象,以便以自然的方式干净地使用它。按字符串名称访问字段很荒谬,容易出错。 – 2017-09-02 21:55:29

我发现在GitHub上的答案Swift2

https://github.com/Alamofire/Alamofire/issues/641

Alamofire.request(.GET, URLString, parameters: ["foo": "bar"]) 
    .responseJSON { request, response, result in 
     switch result { 
     case .Success(let JSON): 
      print("Success with JSON: \(JSON)") 

     case .Failure(let data, let error): 
      print("Request failed with error: \(error)") 

      if let data = data { 
       print("Response data: \(NSString(data: data, encoding: NSUTF8StringEncoding)!)") 
      } 
     } 
    } 
+3

这是Swift 2.0 + Alamofire JSON解析的正确版本。 – 2015-09-21 13:49:44

+5

嗯我仍然越来越失败建立了一个错误消息:'(_,_,_) - > Void'不能转换为'Response - >无效' – alex 2015-10-02 18:33:28

+0

@alex请参见[本答案](http: //*.com/a/32960847/596239)我用来解决它。 – Joseph 2015-10-29 16:27:51

的雨燕2.0的答案Alamofire 3.0实际上应该看起来更像是这样的:

Alamofire.request(.POST, url, parameters: parameters, encoding:.JSON).responseJSON 
{ response in switch response.result { 
       case .Success(let JSON): 
        print("Success with JSON: \(JSON)") 

        let response = JSON as! NSDictionary 

        //example if there is an id 
        let userId = response.objectForKey("id")! 

       case .Failure(let error): 
        print("Request failed with error: \(error)") 
       } 
    } 

https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md

更新Alamofire 4.0和3.0雨燕:

Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default) 
      .responseJSON { response in 
       print(response) 
//to get status code 
       if let status = response.response?.statusCode { 
        switch(status){ 
        case 201: 
         print("example success") 
        default: 
         print("error with response status: \(status)") 
        } 
       } 
//to get JSON return value 
      if let result = response.result.value { 
       let JSON = result as! NSDictionary 
       print(JSON) 
      } 

     } 
+9

你如何得到JSON的实际内容?这是什么类型的对象?设计和文档是如此晦涩难懂,我无法弄清楚,在互联网上找不到任何例子...... – 2016-01-18 21:22:08

+0

我在我的答案中添加了几行应该有所帮助。 – 2016-01-19 22:29:27

+0

@JosephGeraghty具有编码参数导致编译器告诉我有一个额外的参数调用...任何想法? – damiancesar 2016-11-19 23:17:19

我找到了一种方法的response.result.value转换(一Alamofire responseJSON闭包)成JSON格式,我在我的应用程序使用。

我正在使用Alamofire 3和Swift 2.2。

这是我使用的代码:

Alamofire.request(.POST, requestString, 
         parameters: parameters, 
         encoding: .JSON, 
         headers: headers).validate(statusCode: 200..<303) 
             .validate(contentType: ["application/json"]) 
             .responseJSON { (response) in 
     NSLog("response = \(response)") 

     switch response.result { 
     case .Success: 
      guard let resultValue = response.result.value else { 
       NSLog("Result value in response is nil") 
       completionHandler(response: nil) 
       return 
      } 

      let responseJSON = JSON(resultValue) 

      // I do any processing this function needs to do with the JSON here 

      // Here I call a completionHandler I wrote for the success case 
     break 
     case .Failure(let error): 
      NSLog("Error result: \(error)") 
      // Here I call a completionHandler I wrote for the failure case 
      return 
     } 

我通常使用Gloss库序列化或反序列化的iOS JSON。例如,我有JSON,看起来像这样:

Struct Struct_Name: Decodable { 
    let IJ: String? 
    let KL: String? 
    init?(json: JSON){ 
     self.IJ = "AB" <~~ json 
     self.KL = "CD" <~~ json 
    } 
} 

然后在Alamofire responseJSON,我这样做以下事情:

{"ABDC":[{"AB":"qwerty","CD":"uiop"}],[{"AB":"12334","CD":"asdf"}]} 

首先,我在光泽结构中的JSON阵列模式

Alamofire.request(url, method: .get, paramters: parametersURL).validate(contentType: ["application/json"]).responseJSON{ response in 
switch response.result{ 
    case .success (let data): 
    guard let value = data as? JSON, 
     let eventsArrayJSON = value["ABDC"] as? [JSON] 
    else { fatalError() } 
    let struct_name = [Struct_Name].from(jsonArray: eventsArrayJSON)//the JSON deserialization is done here, after this line you can do anything with your JSON 
    for i in 0 ..< Int((struct_name?.count)!) { 
     print((struct_name?[i].IJ!)!) 
     print((struct_name?[i].KL!)!) 
    } 
    break 

    case .failure(let error): 
    print("Error: \(error)") 
    break 
} 
} 

从上面的代码的输出:

qwerty 
uiop 
1234 
asdf 

pod 'Alamofire' 
pod 'SwiftyJSON' 
pod 'ReachabilitySwift' 



import UIKit 
import Alamofire 
import SwiftyJSON 
import SystemConfiguration 

class WebServiceHelper: NSObject { 

    typealias SuccessHandler = (JSON) -> Void 
    typealias FailureHandler = (Error) -> Void 

    // MARK: - Internet Connectivity 

    class func isConnectedToNetwork() -> Bool { 

     var zeroAddress = sockaddr_in() 
     zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size) 
     zeroAddress.sin_family = sa_family_t(AF_INET) 

     guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, { 
      $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { 
       SCNetworkReachabilityCreateWithAddress(nil, $0) 
      } 
     }) else { 
      return false 
     } 

     var flags: SCNetworkReachabilityFlags = [] 
     if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { 
      return false 
     } 

     let isReachable = flags.contains(.reachable) 
     let needsConnection = flags.contains(.connectionRequired) 

     return (isReachable && !needsConnection) 
    } 

    // MARK: - Helper Methods 

    class func getWebServiceCall(_ strURL : String, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler) 
    { 
     if isConnectedToNetwork() { 

      print(strURL) 

      if isShowLoader == true { 

       AppDelegate.getDelegate().showLoader() 
      } 

      Alamofire.request(strURL).responseJSON { (resObj) -> Void in 

       print(resObj) 

       if resObj.result.isSuccess { 
        let resJson = JSON(resObj.result.value!) 

        if isShowLoader == true { 
         AppDelegate.getDelegate().dismissLoader() 
        } 

        debugPrint(resJson) 
        success(resJson) 
       } 
       if resObj.result.isFailure { 
        let error : Error = resObj.result.error! 

        if isShowLoader == true { 
         AppDelegate.getDelegate().dismissLoader() 
        } 
        debugPrint(error) 
        failure(error) 
       } 
      } 
     }else { 


      CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) 
     } 
    } 

    class func getWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure :@escaping FailureHandler){ 
     if isConnectedToNetwork() { 

      if isShowLoader == true { 
       AppDelegate.getDelegate().showLoader() 
      } 


      Alamofire.request(strURL, method: .get, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in 

       print(resObj) 

       if resObj.result.isSuccess { 
        let resJson = JSON(resObj.result.value!) 

        if isShowLoader == true { 
         AppDelegate.getDelegate().dismissLoader() 
        } 

        success(resJson) 
       } 
       if resObj.result.isFailure { 
        let error : Error = resObj.result.error! 

        if isShowLoader == true { 
         AppDelegate.getDelegate().dismissLoader() 
        } 

        failure(error) 
       } 

      }) 
     } 
    else { 

      CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) 
    } 

    } 



    class func postWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure :@escaping FailureHandler) 
    { 
     if isConnectedToNetwork() 
     { 

      if isShowLoader == true 
      { 
       AppDelegate.getDelegate().showLoader() 
      } 

      Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in 

       print(resObj) 

       if resObj.result.isSuccess 
       { 
        let resJson = JSON(resObj.result.value!) 

        if isShowLoader == true 
        { 
         AppDelegate.getDelegate().dismissLoader() 
        } 

        success(resJson) 
       } 

       if resObj.result.isFailure 
       { 
        let error : Error = resObj.result.error! 

        if isShowLoader == true 
        { 
         AppDelegate.getDelegate().dismissLoader() 
        } 

        failure(error) 
       } 
      }) 
     }else { 
      CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) 
     } 
    } 


    class func postWebServiceCallWithImage(_ strURL : String, image : UIImage!, strImageParam : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler) 
    { 
     if isConnectedToNetwork() { 
      if isShowLoader == true 
      { 
       AppDelegate.getDelegate().showLoader() 
      } 

      Alamofire.upload(
       multipartFormData: { multipartFormData in 
        if let imageData = UIImageJPEGRepresentation(image, 0.5) { 
         multipartFormData.append(imageData, withName: "Image.jpg") 
        } 

        for (key, value) in params! { 

         let data = value as! String 

         multipartFormData.append(data.data(using: String.Encoding.utf8)!, withName: key) 
         print(multipartFormData) 
        } 
       }, 
       to: strURL, 
       encodingCompletion: { encodingResult in 
        switch encodingResult { 
        case .success(let upload, _, _): 
         upload.responseJSON { response in 
          debugPrint(response) 
          //let datastring = String(data: response, encoding: String.Encoding.utf8) 
          // print(datastring) 
         } 
        case .failure(let encodingError): 
         print(encodingError) 
         if isShowLoader == true 
         { 
          AppDelegate.getDelegate().dismissLoader() 
         } 

         let error : NSError = encodingError as NSError 
         failure(error) 
        } 

        switch encodingResult { 
        case .success(let upload, _, _): 
         upload.responseJSON { (response) -> Void in 

          if response.result.isSuccess 
          { 
           let resJson = JSON(response.result.value!) 

           if isShowLoader == true 
           { 
            AppDelegate.getDelegate().dismissLoader() 
           } 

           success(resJson) 
          } 

          if response.result.isFailure 
          { 
           let error : Error = response.result.error! as Error 

           if isShowLoader == true 
           { 
            AppDelegate.getDelegate().dismissLoader() 
           } 

           failure(error) 
          } 

         } 
        case .failure(let encodingError): 
         if isShowLoader == true 
         { 
          AppDelegate.getDelegate().dismissLoader() 
         } 

         let error : NSError = encodingError as NSError 
         failure(error) 
        } 
       } 
      ) 
     } 
     else 
     { 
      CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) 
     } 
    } 

} 


================================== 


Call Method 


let aParams : [String : String] = [ 
       "ReqCode" : Constants.kRequestCodeLogin, 
       ] 

      WebServiceHelper.postWebServiceCall(Constants.BaseURL, params: aParams as [String : AnyObject]?, isShowLoader: true, success: { (responceObj) in 


       if "\(responceObj["RespCode"])" != "1" 
       { 
        let alert = UIAlertController(title: Constants.kAppName, message: "\(responceObj["RespMsg"])", preferredStyle: UIAlertControllerStyle.alert) 
        let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in 
        } 
        alert.addAction(OKAction) 
        self.present(alert, animated: true, completion: nil) 
       } 
       else 
       { 
        let aParams : [String : String] = [ 
         "Password" : self.dictAddLogin[AddLoginConstants.kPassword]!, 
         ] 
        CommonMethods.saveCustomObject(aParams as AnyObject?, key: Constants.kLoginData) 

       } 
       }, failure: 
       { (error) in 

        CommonMethods.showAlertWithError(Constants.kALERT_TITLE_Error, strMessage: error.localizedDescription,withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) 
      }) 
     } 
+2

所有这些代码的解释是有帮助的。 – 2017-01-28 19:33:13

SWIFT 3

pod 'Alamofire', '~> 4.4' 
pod 'SwiftyJSON' 

File json format: 
{ 
    "codeAd": { 
     "dateExpire": "2017/12/11", 
     "codeRemoveAd":"1231243134" 
     } 
} 

import Alamofire 
import SwiftyJSON 
    private func downloadJson() { 
     Alamofire.request("https://yourlinkdownloadjson/abc").responseJSON { response in 
      debugPrint(response) 

      if let json = response.data { 
       let data = JSON(data: json) 
       print("data\(data["codeAd"]["dateExpire"])") 
       print("data\(data["codeAd"]["codeRemoveAd"])") 
      } 
     } 
    } 

斯威夫特3,Alamofire 4.4和SwiftyJSON:

Alamofire.request(url, method: .get) 
    .responseJSON { response in 
     if response.data != nil { 
     let json = JSON(data: response.data!) 
     let name = json["people"][0]["name"].string 
     if name != nil { 
      print(name!) 
     } 
     } 
    } 

,它将分析这个JSON输入:

{ 
    people: [ 
    { name: 'John' }, 
    { name: 'Dave' } 
    ] 
}