Swift에서 Alamofire API의 JSON 응답을 구문 분석하는 방법은 무엇입니까?


125

다음 코드를 작성하고 JSON으로 응답을 받고 있지만 JSON 유형은 "AnyObject"이며이를 사용할 수 있도록 배열로 변환 할 수 없습니다.

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

    println(JSON?)
}

나는 귀하의 질문에 반대 투표를하지 않았지만 JSON 구문 분석이 명확하고 직접적인 답변을 제공하기에는 너무 광범위한 주제이기 때문에 추측합니다. SwiftyJSON 이라는 라이브러리를 사용해보십시오 .
Isuru 2014-09-30

@Isuru 괜찮아! 나는 그 라이브러리를 보았지만 Alamofire를 사용하고 있습니다! 하지만 SwiftyJson을 사용한 샘플 코드를 보내 주시겠습니까? 저에게 코드가 작동하지 않습니다!
개발자

나도 Alamofire와 함께 SwiftyJSON을 사용합니다. 나는 단지 이와 같이 응답을 전달합니다 let data = JSONValue(JSON!). 그런 다음 이와 같은 값을 추출 할 수 있습니다 data["Id"]. SwiftyJSON 문서는 원하는 유형의 값을 검색하는 방법에 대한 예제를 제공합니다. 정확히 어떤 오류가 발생합니까?
Isuru 2014-09-30

답변:


160

Swift 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 및 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
JSON의 실제 내용을 어떻게 얻습니까? 이것은 어떤 유형의 물건입니까? 디자인과 문서는 ... 그래서 그것을 알아낼 수 없습니다 모호하고 인터넷에 예제를 찾을 수 없습니다
알렉스 워든에게

내 대답에 도움이 될 몇 줄을 추가했습니다.
Joseph Geraghty

@JosephGeraghty에 인코딩 매개 변수가 있으면 컴파일러가 추가 인수 호출이 있다고 알려줍니다.
amariduran

@ jch-duran은 긍정적이지 않지만, 얼마 전에 비슷한 일을 겪었던 기억이 막연합니다. 나는 그것이 업데이트되지 않은 라이브러리와 관련이 있거나 빠른 버전과 관련이 있다고 생각합니다. 당신이 최신 버전의 힘 도움말에있는 만들기
조셉 라그 티

1
@AlexWorden은 동의했습니다.이 페이지는 제가 이러한 질문에 답하는 데 도움이되었고 좋은 솔루션을 제공합니다. github.com/SwiftyJSON/SwiftyJSON
iljn

31

위에서 언급했듯이 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"
}

설치 후 SwiftyJson을 사용하려고하는데 SwiftyJson 파일에 약 300 개의 오류가 발생합니다. 누구든지이 문제에 직면 했습니까? 저는 [github] ( github.com/SwiftyJSON/SwiftyJSON ) 문서에 언급 된대로 Xcode 버전 6.2, ios 버전 8.1, cocoaPods 36을 사용 합니다.
Sashi

2
친구. 오류는 무엇입니까? 별도의 질문을하고 몇 가지 세부 사항을 제공하십시오. SwiftyJSON은 마법만큼이나 아름답습니다. 가능하면 사용하십시오.
Zia

자연스럽고 깔끔하게 사용할 수 있도록 json 문자열을 구체적인 신속한 객체로 변환해야합니다. 문자열 이름으로 필드에 액세스하는 것은 우스꽝스럽고 오류가 발생하기 쉽습니다.
The Muffin Man

26

Swift 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' }
  ]
}

명시의 필요성 제거하는 Alamofire 스위프 티 - JSON 특정 플러그인도 있습니다 JSON()변환 : github.com/SwiftyJSON/Alamofire-SwiftyJSON
로빈 Macharg

이것은 나를 도와 주지만 예외가 발생하기 때문에 JSON 메소드에 몇 가지 문제가
있었습니다

24

Swift2 에 대한 GitHub에서 답변을 찾았 습니다.

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 구문 분석을위한 올바른 버전입니다.
Saqib Omer

5
흠 나는 여전히 실패 빌드 오류 메시지를 받고 있습니다 : '(_, _, _)-> Void'는 'Response <AnyObject, NSError>-> Void'로 변환 할 수 없습니다.
alex

@alex 내가 그것을 해결하는 데 사용한 것에 대해서는 이 답변 을 참조하십시오 .
Joseph

정말 고맙습니다 ! 당신은 내가 서버, 생명의 구세주에서 응답 메시지를 제대로 표시하려고 얼마나 많은 것을 알지 못합니다!
thibaut noah

17

저는 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"}]

Alamofire가 메서드를 약간 업데이트했기 때문에 업데이트하고 싶을 수도 있지만 이것은 선택된 답변이어야합니다
Snymax

10

스위프트 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

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
        }

2

저는 일반적으로 Gloss 라이브러리를 사용 하여 iOS에서 JSON을 직렬화하거나 역 직렬화합니다. 예를 들어 다음과 같은 JSON이 있습니다.

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

먼저 Gloss 구조체에서 JSON 배열을 모델링합니다.

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

그리고 Alamofire responseJSON에서 다음 작업을 수행합니다.

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

2

스위프트 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)
    }
}

Alamofire API

    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

이것은 Xcode 10.1 및 Swift 4로 빌드되었습니다.

"Alamofire"(4.8.1)와 "SwiftyJSON"(4.2.0)의 완벽한 조합입니다. 먼저 두 포드를 모두 설치해야합니다.

pod 'Alamofire'pod 'SwiftyJSON'

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

이 경우 "Host"정보를 인쇄하고 싶습니다. "Host": "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)
        }
    }

조용하고 행복한 코드 유지 😎


0

신속한 5에서는 완성을 위해 typealias를 사용합니다. Typlealias는 코드를 정리하는 데 사용하지 않습니다.

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
이 모든 코드가 무엇인지에 대한 설명이 도움이 될 것입니다.
peter.swallow
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.