【问题标题】:Swift: Handling JSON with Alamofire & SwiftyJSONSwift:使用 Alamofire 和 SwiftyJSON 处理 JSON
【发布时间】:2014-12-27 15:33:18
【问题描述】:

这个肯定被问过好几次了,虽然我一直很努力地找,但我还没有找到正确的答案。

我使用 Alamofire 和 SwiftyJSON,我的 JSON 数据如下所示:

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

...使用此代码:

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

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

        let json = JSON(jsonData!) 

        println(json)

    }

...所以 JSON 应该一切正常

  1. 如何访问这些数据?我的意思是如何获取名称、ID、product_ids 等

  2. 如何将数据(名称)放入我的 TableViewController?

【问题讨论】:

  • 嗯,你有一个包含其他 JSON 对象的 JSON 对象。这意味着包含其他字典的字典。只需访问它们。 (提示:阅读文档。)

标签: ios json swift alamofire


【解决方案1】:

我在我的一个项目中同时使用 SwiftyJSON 和 Alamofire。这是我的使用方法。

  1. 创建一个名为 APIProtocol 的协议。
  2. 使用接受 APIProtocol 类型委托的 GET 方法设置 API 类。
  3. 设置 TableViewController 以实现 APIProtocol。
  4. 从 TableViewController 调用 API.get()

代码

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

【讨论】:

  • 伟大的模式!细微的变化:delegate 应该是 delegate: APIProtocol? 以便回调是可选的。
  • @jlhonora 是的!好决定。我想我实际上已经更改了项目中的代码以反映这一点。
  • 这种模式看起来很棒。但是,上面的代码清单中似乎存在错误。 ActivityViewController 类应该实现 APIProtocol 而不是 APIController。
  • @Shreyas 我很高兴你喜欢它!而且,感谢您指出我的错字。我已经按照你的建议修好了。
【解决方案2】:

访问器(至少对于 SwiftyJSON)的工作方式如下:

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

有关如何使用 SwiftyJSOn 的更多信息可以在其官方文档中找到:https://github.com/SwiftyJSON/SwiftyJSON

关于如何将这些数据放入 UITableView,有很多方法。设置一个 UITableView 单元格,然后将 JSON 数据加载到某种数组中。

【讨论】:

  • 我尝试不使用第一个 [0],然后它对我有用。
【解决方案3】:

查看此 repo 以获取声明如何在代码中使用 Alamofire 以及如何创建具有 swift 和解析 JSON 响应的模型的示例

  1. 在您的项目中安装 Alamofire
  2. 在您的班级中导入 Alamofire
  3. 在你的类中定义这些变量

    typealias complitionBlock = (data: AnyObject) -> Void
    
    let KBASE_URL: String = "http://static.westwing.de/cms/dont-delete/programming_task/data.json"
    
  4. 设置这个函数的实现

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

更多信息: https://github.com/AhmedAskar/WestWing

【讨论】:

    【解决方案4】:

    以下内容应该适合您:-

               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
        }
    

    注意:不需要使用 Swifty JSON,因为 Alamofire 允许 JSON 响应,可以在“.responseJSON”中直接处理。

    【讨论】:

      【解决方案5】:
      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)!)
          }
      }
      }
      
      ================================== 
      

      调用方法

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

      【讨论】:

      • 看起来您一直在为几个问题发布相同的答案(大量代码,没有描述,什么都没有)。为什么?如果它们是同一个问题,则开始标记重复项。通过反复发布如此冗长的代码,不确定您的目标是什么。
      • 但是一个 WebServiceHelper 类用于 get 和 post 方法以及整个应用程序中的图像上传方法
      【解决方案6】:

      // fatch json data swiftjson with alamofire

      // 先在using Alamofire

      //第二个fatch json data in tableView

      //创建json模型类model1

      //model2

      【讨论】:

      • 如果这是一个答案(我真的说不出来),那么它需要重新措辞、解释,如果可能的话,还需要一点可读性。
      猜你喜欢
      • 2019-04-14
      • 2018-11-12
      • 1970-01-01
      • 2018-03-01
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多