Làm cách nào để phân tích phản hồi JSON từ API của Alamofire trong Swift?


125

Theo mã tôi đã viết và tôi cũng nhận được phản hồi trong JSON nhưng loại JSON là "AnyObject" và tôi không thể chuyển đổi nó thành Array để tôi có thể sử dụng nó.

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

    println(JSON?)
}

Tôi đã không đánh giá thấp câu hỏi của bạn nhưng tôi cho rằng vì phân tích JSON là chủ đề quá rộng để đưa ra câu trả lời rõ ràng, thẳng thắn. Hãy thử thư viện này được gọi là SwiftyJSON .
Isuru

@Isuru Không sao đâu! Tôi đã thấy Thư viện đó nhưng tôi đang sử dụng Alamofire! Nhưng bạn có thể gửi cho tôi mã mẫu mà bạn đã sử dụng SwiftyJson không? Có mã không làm việc cho tôi!
Nhà phát triển

Tôi cũng sử dụng SwiftyJSON cùng với Alamofire. Tôi chỉ cần vượt qua các phản ứng như thế này let data = JSONValue(JSON!). Sau đó tôi có thể trích xuất các giá trị như thế này data["Id"]. Tài liệu SwiftyJSON cung cấp các ví dụ về cách truy xuất các giá trị đó trong các loại mong muốn. Chính xác thì bạn đang gặp lỗi gì?
Isuru

Câu trả lời:


160

Câu trả lời cho Swift 2.0 Alamofire 3.0 thực sự sẽ giống như thế này:

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

CẬP NHẬT cho Alamofire 4.0 và Swift 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)
            }

        }

13
Làm thế nào để bạn có được nội dung thực tế của JSON? Đây là loại đối tượng gì? Thiết kế và tài liệu rất mơ hồ Tôi không thể tìm ra nó và không thể tìm thấy bất kỳ ví dụ nào trên internet ...
Alex Worden

Tôi đã thêm một vài dòng trong câu trả lời của tôi sẽ giúp.
Joseph Geraghty

@JosephGeraghty có kết quả tham số mã hóa trong trình biên dịch cho tôi biết có một cuộc gọi đối số phụ ... Có ý kiến ​​gì không?
amariduran

@ jch-duran không tích cực, nhưng tôi mơ hồ nhớ mình đã chạy vào một cái gì đó tương tự một lúc trước. Tôi nghĩ rằng nó có một cái gì đó để làm với các thư viện không được cập nhật hoặc có thể không hiện tại với phiên bản nhanh chóng. Đảm bảo rằng bạn đang sử dụng các phiên bản mới nhất có thể giúp đỡ
Joseph Geraghty

1
@AlexWorden đã đồng ý, trang này đã giúp tôi trả lời những câu hỏi đó và cung cấp một giải pháp hay: github.com/SwiftyJSON/SwiftyJSON
iljn

31

như đã đề cập ở trên, bạn có thể sử dụng thư viện SwiftyJSON và nhận các giá trị của bạn như tôi đã làm dưới đây

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

}

danh sách sản phẩm json của tôi trở về từ kịch bản

{ "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"}    
  ]
}

đầu ra:

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

Tôi đang cố gắng sử dụng điều SwiftyJson sau khi cài đặt nhưng đưa ra một số lỗi 300 trong tệp SwiftyJson, có ai gặp phải vấn đề này không? i ', sử dụng Xcode phiên bản 6.2, ios phiên bản 8.1, cacaoPods 36 như được đề cập trong tài liệu [github] ( github.com/SwiftyJSON/SwiftyJSON ).
Sashi

2
Anh bạn Các lỗi là gì? Đặt một câu hỏi riêng biệt và cung cấp một số chi tiết. SwiftyJSON đẹp như ma thuật. Sử dụng nó nếu có thể.
Zia

Thực sự nên chuyển đổi chuỗi json thành một đối tượng nhanh chóng cụ thể để bạn có thể sử dụng nó một cách sạch sẽ một cách tự nhiên. Truy cập các trường bằng tên chuỗi của chúng là vô lý và dễ bị lỗi.
Người đàn ông Muffin

26

Swift 3, Alamofire 4.4 và 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!)
        }
      }
  }

Điều đó sẽ phân tích cú pháp JSON này:

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

Ngoài ra còn có một Alamofire Swifty-JSON-cụ plugin mà loại bỏ sự cần thiết cho rõ ràng JSON()chuyển đổi: github.com/SwiftyJSON/Alamofire-SwiftyJSON
Robin Macharg

Điều này giúp tôi, nhưng tôi đã gặp một số vấn đề với phương thức JSON vì ném Ngoại lệ
iGhost

24

Tôi đã tìm thấy câu trả lời trên GitHub cho 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
Đây là phiên bản chính xác cho phân tích cú pháp JSON của Swift 2.0 + Alamofire.
Saqib Omer

5
hmm tôi vẫn không nhận được thông báo lỗi: '(_, _, _) -> Void' không thể chuyển đổi thành 'Phản hồi <AnyObject, NSError> -> Void'
alex

@alex Xem câu trả lời này cho những gì tôi đã sử dụng để giải quyết nó.
Giuse

Cảm ơn bạn rất nhiều ! Bạn không biết có bao nhiêu thứ tôi đã cố gắng hiển thị đúng thông điệp phản hồi từ máy chủ, vị cứu tinh!
thibaut noah 4/2/2016

17

Tôi không phải là chuyên gia JSON cũng không phải chuyên gia Swift, nhưng những điều sau đây đang làm việc cho tôi. :) Tôi đã trích xuất mã từ ứng dụng hiện tại của mình và chỉ thay đổi "MyLog thành println" và thụt vào các khoảng trắng để hiển thị dưới dạng khối mã (hy vọng tôi không phá vỡ mã này).

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

          }
      }
}

Hi vọng điêu nay co ich.

Biên tập:

Để tham khảo, đây là những gì PHP Script của tôi trả về:

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

Đây phải là câu trả lời được chọn mặc dù bạn có thể muốn cập nhật nó vì Alamofire đã cập nhật phương thức của họ một chút
Snymax

10

nhanh 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"])")
            }
        }
    }

2

Tôi đã tìm thấy một cách để chuyển đổi answer.result.value (bên trong một bao đóng phản hồi của Jacksonofire) thành định dạng JSON mà tôi sử dụng trong ứng dụng của mình.

Tôi đang sử dụng Alamofire 3 và Swift 2.2.

Đây là mã tôi đã sử dụng:

    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
        }

2

Tôi thường sử dụng thư viện Gloss để tuần tự hóa hoặc giải tuần tự JSON trong iOS. Ví dụ: tôi có JSON trông như thế này:

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

Đầu tiên, tôi mô hình hóa mảng JSON trong Gloss struct:

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

Và sau đó, trong câu trả lời của Alamofire, tôi làm điều này như sau:

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

Đầu ra từ mã trên:

qwerty
uiop
1234
asdf

2

Swift 5

class User: Decodable {

    var name: String
    var email: String
    var token: String

    enum CodingKeys: String, CodingKey {
        case name
        case email
        case token
    }

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try container.decode(String.self, forKey: .name)
        self.email = try container.decode(String.self, forKey: .email)
        self.token = try container.decode(String.self, forKey: .token)
    }
}

API củaofofire

    Alamofire.request("url.endpoint/path", method: .get, parameters: params, encoding: URLEncoding.queryString, headers: nil)
     .validate()
     .responseJSON { response in

        switch (response.result) {

            case .success( _):

            do {
                let users = try JSONDecoder().decode([User].self, from: response.data!)
                print(users)

            } catch let error as NSError {
                print("Failed to load: \(error.localizedDescription)")
            }

             case .failure(let error):
                print("Request error: \(error.localizedDescription)")
         }

1

Điều này đã được xây dựng với Xcode 10.1 và Swift 4

Sự kết hợp hoàn hảo "Alamofire" (4.8.1) và "SwiftyJSON" (4.2.0). Trước tiên, bạn nên cài đặt cả hai nhóm

pod 'Alamofire'pod 'SwiftyJSON'

Phản hồi của máy chủ ở định dạng JSON:

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip;q=1.0, compress;q=0.5", 
    "Accept-Language": "en;q=1.0", 
    "Host": "httpbin.org", 
    "User-Agent": "AlamoFire TEST/1.0 (com.ighost.AlamoFire-TEST; build:1; iOS 12.1.0) Alamofire/4.8.1"
  }, 
  "origin": "200.55.140.181, 200.55.140.181", 
  "url": "https://httpbin.org/get"
}

Trong trường hợp này tôi muốn in thông tin "Máy chủ": "Máy chủ": "httpbin.org"

Alamofire.request("https://httpbin.org/get").validate().responseJSON { response in
        switch response.result {
        case .success:
            print("Validation Successful)")

            if let json = response.data {
                do{
                    let data = try JSON(data: json)
                    let str = data["headers"]["Host"]
                    print("DATA PARSED: \(str)")
                }
                catch{
                print("JSON Error")
                }

            }
        case .failure(let error):
            print(error)
        }
    }

Giữ bình tĩnh và hạnh phúc Mã 😎


0

trong swift 5 chúng tôi thích, Sử dụng typealias để hoàn thành. Typlealias không có gì chỉ sử dụng để làm sạch mã.

typealias response = (Bool,Any?)->()


static func postCall(_ url : String, param : [String : Any],completion : @escaping response){
    Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response) in

        switch response.result {
           case .success(let JSON):
               print("\n\n Success value and JSON: \(JSON)")

           case .failure(let error):
               print("\n\n Request failed with error: \(error)")

           }
    }
}

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

6
Một lời giải thích về những gì tất cả các mã này sẽ hữu ích.
peter.swallow
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.