将数据从Webrequest快速存储到结构中

时间:2019-02-18 13:43:23

标签: ios swift alamofire jsondecoder

首先,我真的是Swift的初学者。我为此困了几个小时。

这是问题所在,我正在使用AlamoFire发出请求

func getListFiles(userId: String, page: Int)
{
    let parameters: Parameters = [
        "userId": userId,
        "page": page
    ]

    Alamofire.request(baseUrl + Endpoints.GET_RECORDS.rawValue, method: HTTPMethod.post, parameters: parameters)
        .responseData { response in
            if let result = response.result.value{
                do {
                    let data = try JSONDecoder().decode(ListFilesStruct.self, from: result)
                } catch {
                    print("\(error)")
                }
            }
    }
}

,我想将数据响应存储在我的结构“ ListFilesStruct”中。但它进入“捕获”并失败

Printing description of error:
▿ DecodingError
  ▿ typeMismatch : 2 elements
- .0 : Swift.Dictionary<Swift.String, Any>
▿ .1 : Context
  ▿ codingPath : 3 elements
    - 0 : CodingKeys(stringValue: "data", intValue: nil)
    ▿ 1 : _JSONKey(stringValue: "Index 6", intValue: 6)
      - stringValue : "Index 6"
      ▿ intValue : Optional<Int>
        - some : 6
    - 2 : CodingKeys(stringValue: "expert", intValue: nil)
  - debugDescription : "Expected to decode Dictionary<String, Any> but found a string/data instead."
  - underlyingError : nil

这是主要结构,我想要一个FileDetail数组

struct ListFilesStruct: Codable
{
    var success: Bool?
    var data: [FileDetail]?
}

struct FileDetail: Codable
{
    var id: String?
    var expert: FileElement?
}

由于FileElement结构,它确实失败了,我不知道为什么

struct FileElement: Codable
{
    var id: String?
    var role_id: String?
    var avatar: String?
    var nom: String?
    var prenom: String?  
}

我真的很想存储这样的Web服务数据,谢谢

编辑:期望的JSON:

{
"success": true,
"data": [
    {
        "id": "A19007994",
        "expert": {
            "id": "74EJEEZM",
            "role_id": "EXPERT",
            "avatar": null,
            "nom": "METRTALZ",
            "prenom": "JEREMIE",
        }
     }
 ]
 }

1 个答案:

答案 0 :(得分:2)

将以下struct用于所需的json

class MyCustomJSON: Codable {
    let success: Bool
    let data: [Datum]

    enum CodingKeys: String, CodingKey {
        case success = "success"
        case data = "data"
    }

    init(success: Bool, data: [Datum]) {
        self.success = success
        self.data = data
    }
}

class Datum: Codable {
    let id: String
    let expert: Expert

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case expert = "expert"
    }

    init(id: String, expert: Expert) {
        self.id = id
        self.expert = expert
    }
}

class Expert: Codable {
    let id: String
    let roleID: String
    let nom: String
    let prenom: String

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case roleID = "role_id"
        case nom = "nom"
        case prenom = "prenom"
    }

    init(id: String, roleID: String, nom: String, prenom: String) {
        self.id = id
        self.roleID = roleID
        self.nom = nom
        self.prenom = prenom
    }
}

// MARK: Encode/decode helpers

class JSONNull: Codable, Hashable {

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
        return true
    }

    public var hashValue: Int {
        return 0
    }

    public init() {}

    public required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() {
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    }
}

并像这样初始化

do {
     let myCustomJSON = try JSONDecoder().decode(MyCustomJSON.self, from: jsonData)
} catch {
  print("\(error)")
}

我在操场上尝试了我的代码,一切正常。 enter image description here