【问题标题】:How to fix invalid json issue in pulling data from API using Alamofire in swift?如何在swift中使用Alamofire从API中提取数据时修复无效的json问题?
【发布时间】:2019-12-07 08:51:47
【问题描述】:

我需要一些关于我的代码的帮助。下面的json 是我从postman 得到的原始回复。

旧格式

{
   "totalCreditedAmount": 2898.3000,
   "periodId": 566,
   "periodDate": "4/26/2019"
}

所以我在下面创建了 API 服务代码。运行流畅。

API服务

 struct DoctorLatestCreditedAmount {
   typealias getLatestCreditedAmountTaskCompletion = (_ latestCreditedAmount: CurrentRemittance?, _ error: NetworkError?) -> Void

  static func getLatestCreditedAmount(doctorNumber: String, completion: @escaping getLatestCreditedAmountTaskCompletion) {

        guard let latestCreditedAmountURL = URL(string: "\(Endpoint.LatestCreditedAmount.latestCreditedAmount)/\(doctorNumber)") else {
            completion(nil, .invalidURL)
            return
        }

        let sessionManager = Alamofire.SessionManager.default
        sessionManager.session.getAllTasks { (tasks) in
            tasks.forEach({ $0.cancel() })
        }

        Alamofire.request(latestCreditedAmountURL, method: .get, encoding: JSONEncoding.default).responseJSON { (response) in
            guard HelperMethods.reachability(responseResult: response.result) else {
                completion(nil, .noNetwork)
                return
            }

            guard let statusCode = response.response?.statusCode else {
                completion(nil, .noStatusCode)
                return
            }

            switch(statusCode) {
            case 200: guard let jsonData = response.data else {
                completion(nil, .invalidJSON)
                return
                }

                let decoder = JSONDecoder()

            do {
                let currentCreditedAmount = try decoder.decode(CurrentRemittance.self, from: jsonData)
                completion(currentCreditedAmount, nil)
            } catch {
                completion(nil, .invalidJSON)
                }

            case 400: completion(nil, .badRequest)
            case 404: completion(nil, .noRecordFound)
            default:
                print("**UNCAPTURED STATUS CODE FROM (getLatestCreditedAmount)\nSTATUS CODE: \(statusCode)")
                completion(nil, .uncapturedStatusCode)
            }

        }

    }

但是当json方面的响应发生了一些变化。 json 格式已更改,现在使用上面的 APIService 我遇到了错误。它说invalidjson,因为新的json 格式在下面。

新格式

 {
   "responseMessage": "Request successful",
    "data": {
         "totalCreditedAmount": 2898.3000,
         "periodId": 566,
         "periodDate": "4/26/2019"
   }
}

已编辑:getTotalCreditedAmount

var currentRemittance: CurrentRemittance!

func getTotalCreditedAmount(doctorNumber: String) {
   windlessSetup()
   APIService.DoctorLatestCreditedAmount.getLatestCreditedAmount(doctorNumber: doctorNumber) { (remittanceDetails, error) in
       guard let creditedAmountDetails = remittanceDetails, error == nil else {
           if let networkError = error {
               switch networkError {
               case .noRecordFound:
                   let alertController = UIAlertController(title: “No Record Found”, message: “You don’t have current payment remittance”, preferredStyle: .alert)
                   alertController.addAction(UIAlertAction(title: “OK”, style: .default))
                    self.present(alertController, animated: true, completion: nil)
               case .noNetwork:
                   let alertController = UIAlertController(title: “No Network”, message: “\(networkError.rawValue)“, preferredStyle: .alert)
                   alertController.addAction(UIAlertAction(title: “OK”, style: .default))
                   self.present(alertController, animated: true, completion: nil)
               default:
                   let alertController = UIAlertController(title: “Error”, message: “There is something went wrong. Please try again”, preferredStyle: .alert)
                   alertController.addAction(UIAlertAction(title: “OK”, style: .default))
                   self.present(alertController, animated: true, completion: nil)
               }
           }
           self.creditedView.windless.end()
           self.remittanceView.windless.end()
           return
       }
       self.currentRemittance = creditedAmountDetails
       self.showLatestTotalCreditedAmount()
       self.creditedView.windless.end()
       self.remittanceView.windless.end()
       return
   }

}

遇到错误

我的问题是,如何更改我的 APIService 代码,使其与我得到的正确的 NEW json 格式匹配。因为我习惯了使用相同的“旧”格式,所以我很难过。我真的是 swift 新手,我真的需要帮助。希望你能给我一些时间。

【问题讨论】:

    标签: ios json swift api alamofire


    【解决方案1】:

    试试下面的代码,它适用于我的数据数组:

    Alamofire.request(url, method: .get).responseJSON {
    
       response in
    
       if response.result.isSuccess {
    
          let dataJSON = JSON(response.result.value!)
    
           if let datas = dataJSON["data"].arrayObject {
    
             print(datas)
    
          }
    
       }
    
    }
    

    【讨论】:

      【解决方案2】:

      你需要

      
      // MARK: - Welcome
      struct Root: Codable {
          let responseMessage: String
          let data: CurrentRemittance
      }
      
      // MARK: - DataClass
      struct CurrentRemittance: Codable {
          let totalCreditedAmount: Double
          let periodId: Int
          let periodDate: String 
      }
      

      解码

       let res = try decoder.decode(Root.self, from: jsonData) 
       print(res.data)
      

      【讨论】:

      • 感谢您的帮助,但我在ViewController 的部分中遇到了错误,我为模型分配了CurrentRemittance,我是否也可以将其更改为Root?,我该怎么做从 viewcontroller 调用 CurrentRemittance? 中的值?
      • 你需要completion(res.data, nil)
      • 在completion(res.data, nil) 中遇到错误Cannot convert value of type 'CurrentRemittance' to expected argument type 'Root'
      • 这部分也需要修改吗? typealias getLatestCreditedAmountTaskCompletion = (_ latestCreditedAmount: CurrentRemittance?, _ error: NetworkError?) -> Void
      • 我听从了你的所有建议我没有更改typealias,但它仍然返回'invalidJSON`
      猜你喜欢
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 2019-10-26
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      相关资源
      最近更新 更多