【问题标题】:How to create model class for Json response from webservice in Swift 3如何在 Swift 3 中为来自 web 服务的 Json 响应创建模型类
【发布时间】:2017-12-21 07:28:50
【问题描述】:

我是 swift 新手。我正在做 swift 项目。我从服务器响应中得到响应,如下所示

kNetworkManager.executePostRequest(urlString: kAppSocialLoginURL, params:mainDictionary, requestVC: self,completionHandler: {(responseObject) -> () in
         //   print("response object:\(responseObject!)")
            if responseObject != nil {
                let responseDictionary = responseObject as! NSDictionary
                if responseDictionary is NSDictionary{
                    let obj  =  responseDictionary.value(forKey:"user")
                    if obj is NSDictionary{ //success case
                        print("NSDictionary is",obj ?? NSDictionary())
                        UtilityClass.sharedInstance.userDetailsDictionary = responseDictionary as! [String : AnyObject]
                        if let obj = responseDictionary.value(forKey:"user") as? NSDictionary {
                            if let sessionId = obj["token"] as? String {
                                UtilityClass.sharedInstance.kSessionIDString = sessionId
                            }
                            if let userObj = obj["user"] as? NSDictionary {

在上面的代码中,我多次检查它是否是字典,或者分配为字典。我在我所有的课上都在做这种练习。所以,我想为通用逻辑创建一些模态类,并且我想在获取 Web 服务数据后在每个类中使用该逻辑。

我的网络服务响应如下

user =     {
    sessid = "-qadadadad";
    "session_name" =aadadad;
    tokenData = adadadad;
    user =         {
        access = 1513647;
        created = 14822;
        data =             {
            "ckeditor_auto_lang" = t;
            "ckeditor_default" = t;
            "ckeditor_lang" = en;
            "ckeditor_show_toggle" = t;
            "ckeditor_width" = "100%";
            contact = 1;
        };

我正在使用 Alamofire 进行 API 调用。

任何人都可以在这里帮助我实现这一目标吗?谢谢!

【问题讨论】:

  • 您在使用 Alamofire 吗?斯威夫特 4?
  • pod 'Alamofire' 这是我正在使用的
  • 这似乎不是 Alamofire API
  • 这只是 Alamofire
  • @Vyacheslav 似乎他在自定义 kNetworkManager 中使用它。

标签: ios json swift web-services models


【解决方案1】:

由于您在 kNetworkManager 中使用 Alamofire,我建议您也使用 AlamofireObjectMapper 来摆脱解析响应并将其映射到模型的麻烦:

自动转换 JSON 响应的 Alamofire 扩展 使用 ObjectMapper 将数据转换为 swift 对象。

它很容易集成,您可以查看它的文档以熟悉如何做到这一点。

根据您提到的响应,可映射对象应类似于:

import ObjectMapper

class UserResponse: Mappable {
    var sessId: String?
    var sessionName: String?
    var tokenData: String?
    var user: User?

    required init?(map: Map) {

    }

    func mapping(map: Map) {
        sessId <- map["sessid"]
        sessionNamen <- map["session_name"]
        tokenData <- map["tokenData"]
        user <- map["user"]
    }
}

class User: Mappable {
    var access: Int?
    var created: Int?

    required init?(map: Map){

    }

    func mapping(map: Map) {
        access <- map["day"]
        created <- map["access"]
        conditions <- map["created"]
        data <- map["data"]
    }
}

class UserData: Mappable {
    var ckEditorAutoLang: String?
    var ckEditorDefault: String?
    var ckEditorLang: String?
    var ckEditorShowToggle: String?
    var ckEditorWidth: String?
    var contact: Int?


    required init?(map: Map){

    }

    func mapping(map: Map) {
        ckEditorAutoLang <- map["ckeditor_auto_lang"]
        ckEditorDefault <- map["ckeditor_default"]
        ckEditorLang <- map["ckeditor_lang"]
        ckEditorShowToggle <- map["ckeditor_show_toggle"]
        ckEditorWidth <- map["ckeditor_width"]
        contact <- map["contact"]
    }
}

另外,如果你使用的是 Swift 4,你可能想看看Codable,它应该会让你的生活更轻松!

【讨论】:

  • 那么,对于每个类 API 调用,我需要创建模型类吗?
  • 你如何将这个 web 服务响应传递给模型类,我没有看到你的代码
  • 虽然,我这样做是在打印错误 kNetworkManager.executePostRequest(urlString: kAppManualLoginURL, params:paramDict, requestVC: self,completionHandler: {(responseObject: DataResponse ) -> () ("response object:(responseObject!)") let userLoginResponse = responseObject 无法将类型 '(DataResponse) -> ()' 的值转换为预期的参数类型 '(Any?) -> Void!'
【解决方案2】:

如果你使用 Alamofire 那么。使用这个常用方法

//MARK:- Public Method
/**
*  Initiates HTTPS or HTTP request over |kHTTPMethod| method and 
returns call back in success and failure block.
*
*  @param serviceName  name of the service
*  @param method       method type like Get and Post
*  @param postData     parameters
*  @param responeBlock call back in block
*/
func requestApi(serviceName: String, method: kHTTPMethod, postData: Dictionary<String, Any>, withProgressHUD showProgress: Bool, completionClosure:@escaping (_ result: Any?, _ error: Error?, _ errorType: ErrorType, _ statusCode: NSNumber?) -> ()) -> Void
{
if NetworkReachabilityManager()?.isReachable == true
{
  if showProgress
  {
    showProgressHUD()
  }

  let headers = getHeaderWithAPIName(serviceName: serviceName)

  let serviceUrl = getServiceUrl(string: serviceName)

  let params  = getPrintableParamsFromJson(postData: postData)

  print_debug(items: "Connecting to Host with URL \(kBASEURL)\(serviceName) with parameters: \(params)")
  print_debug(items: "###### \(postData) ######")

  //NSAssert Statements
  assert(method != .GET || method != .POST, "kHTTPMethod should be one of kHTTPMethodGET|kHTTPMethodPOST|kHTTPMethodPOSTMultiPart.");

  switch method
  {
  case .GET:
    Alamofire.request(serviceUrl, method: .get, parameters: postData, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler:
      { (DataResponse) in
        SVProgressHUD.dismiss()
        switch DataResponse.result
        {
        case .success(let JSON):
          print_debug_fake(items: "Success with JSON: \(JSON)")
          print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
          let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
          completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        case .failure(let error):
          print_debug(items: "json error: \(error.localizedDescription)")
          if error.localizedDescription == "cancelled"
          {
            completionClosure(nil, error, .requestCancelled, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
          }
          else
          {
            completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
          }
        }
    })
  case .POST:
    Alamofire.request(serviceUrl, method: .post, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
      { (DataResponse) in
        SVProgressHUD.dismiss()
        switch DataResponse.result
        {
        case .success(let JSON):
          print_debug_fake(items: "Success with JSON: \(JSON)")
          print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
          let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
          completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        case .failure(let error):
          print_debug(items: "json error: \(error.localizedDescription)")
          completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        }
    })
  case .PUT:
    Alamofire.request(serviceUrl, method: .put, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
      { (DataResponse) in
        SVProgressHUD.dismiss()
        switch DataResponse.result
        {
        case .success(let JSON):
          print_debug_fake(items: "Success with JSON: \(JSON)")
          print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
          let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
          completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        case .failure(let error):
          print_debug(items: "json error: \(error.localizedDescription)")
          completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        }
    })
  case .PATCH:
    Alamofire.request(serviceUrl, method: .patch, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler:
      { (DataResponse) in
        SVProgressHUD.dismiss()
        switch DataResponse.result
        {
        case .success(let JSON):
          print_debug_fake(items: "Success with JSON: \(JSON)")
          print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
          let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
          completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        case .failure(let error):
          print_debug(items: "json error: \(error.localizedDescription)")
          completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        }
    })
  case .DELETE:
    Alamofire.request(serviceUrl, method: .delete, parameters: postData, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler:
      { (DataResponse) in
        SVProgressHUD.dismiss()
        switch DataResponse.result
        {
        case .success(let JSON):
          print_debug_fake(items: "Success with JSON: \(JSON)")
          print_debug(items: "Success with status Code: \(String(describing: DataResponse.response?.statusCode))")
          let response = self.getResponseDataDictionaryFromData(data: DataResponse.data!)
          completionClosure(response.responseData, response.error, .requestSuccess, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        case .failure(let error):
          print_debug(items: "json error: \(error.localizedDescription)")
          completionClosure(nil, error, .requestFailed, NSNumber.getNSNumber(message: DataResponse.response?.statusCode))
        }
    })
  }
}
else
{
  SVProgressHUD.dismiss()
  completionClosure(nil, nil, .noNetwork, nil)
}
}

请根据你的方法调整这个方法,因为我是直接在我的网络公共类中复制这个方法

【讨论】:

    猜你喜欢
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2013-06-23
    • 1970-01-01
    • 2017-08-29
    • 2012-10-01
    • 2021-04-01
    相关资源
    最近更新 更多