简体   繁体   中英

Swift: Handling JSON with Alamofire & SwiftyJSON

This is sure to be asked several times, but I have not yet found the right answer, although I have been looking very hard.

I use Alamofire and SwiftyJSON and my JSON data looks like that:

{
  "528" : {
    "name" : "Name 1",
    "id" : "528",
    "product_id" : null,
    "visible" : "0",
    "level" : "2"
  },
  "29" : {
    "name" : "Name 2",
    "id" : "29",
    "product_id" : null,
    "visible" : "1",
    "level" : "1"
  },
  "173" : {
    "name" : "Name 3",
    "id" : "173",
    "product_id" : null,
    "visible" : "0",
    "level" : "2"
  },
  "143" : {
    "name" : "Name 4",
    "id" : "143",
    "product_id" : null,
    "visible" : "1",
    "level" : "2"
  },

...with this code:

Alamofire.request(.GET, dataURL, parameters: nil, encoding: .JSON)

    .responseJSON { (request, response, jsonData, error) in

        let json = JSON(jsonData!) 

        println(json)

    }

...so everything should be fine with JSON

  1. How can i access to that data? I mean how can i get names, ids, product_ids etc

  2. How can i put that data (name) to my TableViewController?

I am using both SwiftyJSON and Alamofire in one of my projects. Here is how I am using it.

  1. Create a protocol called APIProtocol.
  2. Setup an API class with a GET method that accepts a delegate of type APIProtocol.
  3. Setup TableViewController to implement the APIProtocol.
  4. Call API.get() from TableViewController

Code

// Step 1
protocol APIProtocol {
  func didReceiveResult(results: JSON)
}

// Step 2
func get(path: String, parameters: [String: AnyObject]? = nil, delegate: APIProtocol? = nil){
  let url = "\(self.hostname)\(path)"
  NSLog("Preparing for GET request to: \(url)")

  Alamofire.request(.GET, url, parameters: parameters)
    .responseJSON { (req, res, json, error) in
      if(error != nil) {
        NSLog("GET Error: \(error)")
        println(res)
      }
      else {
        var json = JSON(json!)
        NSLog("GET Result: \(json)")

        // Call delegate if it was passed into the call
        if(delegate != nil) {
            delegate!.didReceiveResult(json)
        }
      }
    }
}

// Step 3
class ActivityViewController: UITableViewController, APIProtocol {
  var activityModelList: NSMutableArray = [] // This is the array that my tableView is using.

  ... 

  func didReceiveResult(result: JSON) {
    var activities: NSMutableArray = []

    NSLog("Activity.didReceiveResult: \(result)")

    for (index: String, activity: JSON) in result {

      var activityModel = ActivityModel(
        id: activity["id"].intValue,
        message: activity["message"].stringValue
      )

      activities.addObject(activityModel)
    }

    // Set our array of new models
    activityModelList = activities

    // Make sure we are on the main thread, and update the UI.
    dispatch_sync(dispatch_get_main_queue(), {
      self.refreshControl!.endRefreshing()
      self.tableView.reloadData()
    })
  }
}

// Step 4
override func viewDidLoad() {
  MyAPI.get("/activities", delegate: self)
}

The accessors (for SwiftyJSON at least) work like:

if let userName = json[0]["528"]["name"].string{
    println(userName) // "Name 1"
}

More information on how to use SwiftyJSOn can be found here in its official documentation: https://github.com/SwiftyJSON/SwiftyJSON

Regarding how to put that data into a UITableView, there are many methods. Set up a UITableView cell and then load in the JSON data in some sort of array for instance.

Check this repo for an example that declare how to use Alamofire in your code and how to create models with swift and parsing JSON response

  1. Install Alamofire in your project
  2. Import Alamofire in your class
  3. Define these variables in you class

    typealias complitionBlock = (data: AnyObject) -> Void let KBASE_URL: String = "http://static.westwing.de/cms/dont-delete/programming_task/data.json"
  4. Set the implementation for this function

    func getMainItems(complition block: complitionBlock) { Alamofire.request(.GET, KBASE_URL, parameters:nil).responseJSON { response in do { let items = try NSJSONSerialization.JSONObjectWithData(response.data!, options: NSJSONReadingOptions()) as! NSArray let mutableArray: NSMutableArray = [] items.enumerateObjectsUsingBlock({ object, index, stop in let str = object as! NSDictionary //Replace WESItem with your model //let item = WESItem(dictionary: str as NSDictionary) mutableArray.addObject(item) }) block(data: mutableArray) } catch { print(error) } } }

For more information: https://github.com/AhmedAskar/WestWing

Following should work for you :-

           var nameArr = [String]() 

            Alamofire.request(.GET,"your url", parameters: nil)
                      .validate().responseJSON { response in
                         if let responseJson = response.result.value {
                           let name = responseJson["name"] as! String
                           nameArr.append(name)
                          }

                            dispatch_async(dispatch_get_main_queue(), {
                            self.tableView.reloadData()
                            })
                     }// Alamofire Close




 Use tableview as you normally use it i.e.

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier("cell")

        if cell == nil {
            cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
        }

        cell!.textLabel?.text = nameArr[indexPath.row]
        return cell!
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return nameArr.count
    }

Note: No need to use Swifty JSON as Alamofire allows JSON response which can be directly handled within ".responseJSON".

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] = ["DeviceIDString", "DeviceType" : "iOS", ]

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

// fatch json data swiftjson with alamofire

// First in using Alamofire

// second in fatch json data in tableView

// create json model class model1

// model2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM