Swift'de Alamofire API'den JSON yanıtı nasıl ayrıştırılır?


125

Aşağıdaki kod yazdım ve JSON'da da yanıt alıyorum ancak JSON türü "AnyObject" ve bunu kullanabilmek için bunu Array'e dönüştüremiyorum.

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

    println(JSON?)
}

Sorunuza olumsuz oy vermedim, ancak bunun JSON'u ayrıştırmanın net ve doğru bir cevap veremeyecek kadar geniş bir konu olduğunu varsayıyorum. SwiftyJSON adlı bu kitaplığı deneyin .
Isuru

@Isuru Tamam! O Kütüphaneyi gördüm ama Alamofire kullanıyorum! Ama bana SwiftyJson'ı kullandığınız örnek kodu gönderebilir misiniz? Orada kod benim için işe yaramadı!
Geliştirici

Ben de SwiftyJSON'u Alamofire ile birlikte kullanıyorum. Yanıtı böyle iletiyorum let data = JSONValue(JSON!). Sonra bunun gibi değerleri çıkarabilirim data["Id"]. SwiftyJSON belgeleri, bu değerlerin istenen türlerde nasıl alınacağına dair örnekler sağlar. Tam olarak ne hata alıyorsun?
Isuru

Yanıtlar:


160

Swift 2.0 Alamofire 3.0'ın cevabı aslında daha çok şöyle görünmeli:

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 ve Swift 3.0 için GÜNCELLEME:

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'un gerçek içeriğine nasıl ulaşırsınız? Bu ne tür bir nesne? Tasarım ve dokümantasyon o kadar belirsiz ki, bunu çözemiyorum ve internette hiçbir örnek bulamıyorum ...
Alex Worden

Cevabıma yardımcı olması gereken birkaç satır ekledim.
Joseph Geraghty

@JosephGeraghty kodlama parametresine sahip olması derleyicinin bana fazladan bir argüman çağrısı olduğunu söylemesi ile sonuçlanır ... Herhangi bir fikriniz var mı?
amariduran

@ jch-duran olumlu değil, ancak bir süre önce benzer bir şeyle karşılaştığımı belli belirsiz hatırlıyorum. Bence kütüphanelerin güncellenmemesi veya belki de hızlı sürümle güncel olmaması ile bir ilgisi var. En son sürümleri kullandığınızdan emin olmak yardımcı olabilir
Joseph Geraghty

1
@AlexWorden kabul etti, bu sayfa bu soruları yanıtlamama yardımcı oldu ve güzel bir çözüm sağladı
iljn

31

yukarıda bahsettiğim gibi SwiftyJSON kütüphanesini kullanabilir ve aşağıda yaptığım gibi değerlerinizi alabilirsiniz.

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 ürün listemin komut dosyasından dönmesi

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

çıktı :

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

Yükledikten sonra SwiftyJson şeyini kullanmaya çalışıyorum ancak SwiftyJson dosyasında 300 hata veriyor, sorunla karşılaşan var mı? i ', [github] ( github.com/SwiftyJSON/SwiftyJSON ) belgelerinde belirtildiği gibi Xcode sürüm 6.2, ios sürüm 8.1, cocoaPods 36 kullanarak .
Sashi

2
Kanka. Hatalar nelerdir? Ayrı bir soru sorun ve bazı ayrıntılar sağlayın. SwiftyJSON, sihir kadar güzel. Mümkünse kullanın.
Zia

Gerçekten json dizesini somut bir hızlı nesneye dönüştürmelisiniz, böylece doğal bir şekilde temiz bir şekilde kullanabilirsiniz. Alanlara dize adlarıyla erişmek saçma ve hataya meyillidir.
Kek Adam

26

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

Bu JSON girdisini ayrıştıracak:

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

Ayrıca, açık JSON()dönüştürme ihtiyacını ortadan kaldıran Alamofire Swifty-JSON'a özgü bir eklenti de var : github.com/SwiftyJSON/Alamofire-SwiftyJSON
Robin Macharg

Bu bana yardımcı oldu, ancak JSON yöntemiyle ilgili bazı sorunlar
yaşadım

24

Cevabı Swift2 için GitHub'da buldum

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
Bu, Swift 2.0 + Alamofire JSON ayrıştırması için doğru sürümdür.
Saqib Omer

5
hmm hala başarısız oluyorum bir hata mesajı oluşturdum: '(_, _, _) -> Void', 'Response <AnyObject, NSError> -> Void' olarak dönüştürülemiyor
alex

@alex Çözmek için kullandığım şey için bu yanıta bakın .
Joseph

Çok teşekkür ederim ! Sunucudan gelen yanıt mesajını ne kadar düzgün görüntülemeye çalıştığım hakkında hiçbir fikriniz yok, hayat kurtarıcı!
thibaut noah

17

Ne JSON uzmanıyım ne de Swift uzmanıyım, ancak aşağıdakiler benim için çalışıyor. :) Mevcut uygulamamdan kodu çıkardım ve yalnızca "MyLog'u println" olarak değiştirdim ve bir kod bloğu olarak gösterilmesi için boşluklarla girintili yaptım (umarım onu ​​kırmadım).

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

          }
      }
}

Bu yardımcı olur umarım.

Düzenle:

Başvuru için, PHP Komut Dosyamın döndürdüğü şey:

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

Alamofire yöntemlerini biraz güncellediği için güncellemek isteyebilirsiniz, ancak bu seçili cevap olmalıdır
Snymax

10

hızlı 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 değerini (bir Alamofire responseJSON kapanışı içinde) uygulamamda kullandığım JSON formatına dönüştürmenin bir yolunu buldum.

Alamofire 3 ve Swift 2.2 kullanıyorum.

İşte kullandığım kod:

    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

İOS'ta JSON'u serileştirmek veya seriyi kaldırmak için genellikle Gloss kitaplığını kullanıyorum . Örneğin, aşağıdaki gibi görünen JSON'm var:

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

İlk olarak, JSON dizisini Gloss yapısında modelliyorum:

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

Ve sonra Alamofire yanıtında JSON, şu şeyi yapıyorum:

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

Yukarıdaki kodun çıktısı:

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

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

Bu, Xcode 10.1 ve Swift 4 ile oluşturuldu

"Alamofire" (4.8.1) ve "SwiftyJSON" (4.2.0) mükemmel kombinasyon. İlk önce her iki bölmeyi de yüklemelisiniz

pod 'Alamofire' ve pod 'SwiftyJSON'

JSON biçiminde sunucu yanıtı:

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

Bu durumda "Host" bilgisini yazdırmak istiyorum: "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)
        }
    }

Sakin ve Mutlu Olun Kod 😎


0

swift 5'te seviyoruz, Tamamlamak için tür takma adlar kullanın. Typlealias hiçbir şey kodu temizlemek için kullanmaz.

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
Tüm bu kodun ne olduğuna dair bir açıklama yardımcı olacaktır.
peter.swallow
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.