如何使用可编码协议使用Alamofire和解析数据

问题描述 投票:0回答:2

使用Codable协议花费了很多时间,尚不清楚。在经历了几篇教程之后,我们开始使用Codable来解析数据。下面是代码:

struct MyTasks : Codable {
var strDateDay : String = ""
var strReminder : String = ""
var strRepetitions : String = ""
var name : String = ""
var strNotes : String = ""
var strUserId : String = ""

private enum CodingKeys: String, CodingKey {
    case strDateDay = "duedate"
    case strReminder = "reminder"
    case strRepetitions = "recurring"
    case name = "name"
    case strNotes = "notes"
    case strUserId = "userId"

}
}

let networkManager = DataManager()
    networkManager.postLogin(urlString: kGetMyTasks, header: header, jsonString: parameters as [String : AnyObject]) { (getMyTasks) in

        print(getMyTasks?.name as Any) // -> for log
        Common_Methods.hideHUD(view: self.view)
    }

//网络管理员:

func postLogin(urlString: String, header: HTTPHeaders, jsonString:[String: AnyObject], completion: @escaping (MyTasks?) -> Void) {

           let apiString = KbaseURl + (kGetMyTasks as String)
           print(apiString)

                Alamofire.request(apiString, method: .post, parameters: jsonString , encoding: URLEncoding.default, headers:header).responseJSON
                { response in

                let topVC = UIApplication.shared.keyWindow?.rootViewController

                DispatchQueue.main.async {
                    //Common_Methods.showHUD(view: (topVC?.view)!)
                }

                guard let data = response.data else { return }
                do {
                    let decoder = JSONDecoder()
                    let loginRequest = try decoder.decode(MyTasks.self, from: data)
                    completion(loginRequest)
                } catch let error {
                    print(error)
                    completion(nil)
                }
            }
    }

现在,这是响应:

keyNotFound(CodingKeys(stringValue: "strDateDay", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"strDateDay\", intValue: nil) (\"strDateDay\").", underlyingError: nil))

下面是我要解析的json响应:

{
"data": [
    {
        "userId": 126,
        "name": "My task from postman ",
        "notes": null,
        "totalSteps": 0,
        "completedSteps": 0,
        "files": 0
    },
    {
        "userId": 126,
        "name": "My task from postman 1",
        "notes": null,
        "totalSteps": 0,
        "completedSteps": 0,
        "files": 0
    }
]   
} 

我知道我缺少了一些东西,但是即使花费了超过半天的时间,我仍然无法正确理解出什么问题和问题所在。请指导。

ios swift5 xcode11 codable decodable
2个回答
0
投票

问题与您的结构有关,该结构中属性的名称应与json数据匹配,或者如果您要使用自定义名称,则应使用enum CodingKeys将其转换为您喜欢的名称

struct MyTasks: Codable {
    let data: [Datum]
}

struct Datum: Codable {
    let userID: Int
    let name: String
    let notes: String?
    let totalSteps, completedSteps, files: Int

    enum CodingKeys: String, CodingKey {
        case userID = "userId"
        case name, notes, totalSteps, completedSteps, files
    }
 }

    func postLogin(urlString: String, header: HTTPHeaders, jsonString:[String: AnyObject], completion: @escaping (MyTasks?) -> Void) {

       let apiString = KbaseURl + (kGetMyTasks as String)
       print(apiString)

        Alamofire.request(apiString, method: .post, parameters: jsonString , encoding: URLEncoding.default, headers:header).responseJSON
        { response in

            let topVC = UIApplication.shared.keyWindow?.rootViewController

            DispatchQueue.main.async {
                //Common_Methods.showHUD(view: (topVC?.view)!)
            }

            guard let data = response.data else { return }
            do {
                let decoder = JSONDecoder()
                let loginRequest = try decoder.decode(MyTasks.self, from: data)
                completion(loginRequest)
            } catch let error {
                print(error)
                completion(nil)
            }
        }
}

希望这会有所帮助。


0
投票

问题是,在您的顶级JSON中,您只有一个“数据”数组属性。

您正在要求JSONDecoder将仅包含“数据”属性的对象解码为具有定义的存储属性(包括strDateDay)的名为“ MyTasks”的对象。

您必须成为反序列化的首要对象。像:

struct MyResponse: Codable {
   var data: [MyTasks]
}

然后就像已经将它交给您的JSONDecoder一样:

let loginRequest = try decoder.decode(MyResponse.self, from: data)
© www.soinside.com 2019 - 2024. All rights reserved.