在iOS上使用Swift从Gmail API响应创建对象时出现“ keyNotFound”错误

问题描述

我正在使用Alamofire通过邮件ID从Gmail API获取电子邮件

     AF.request("https://www.googleapis.com/gmail/v1/users/me/messages/\(id)?format=full",headers: headers)
            .responseJSON { [self] response in
                do {
                    let json = try JSON(data: response.data!)

                    if let rawString = json.rawString() {
                        let email = try Email(rawString)
                    } else {
                        print("json.rawString is nil")
                    }
                    emailFetchGroup.leave()
                }
                catch {
                    print(error)
                    emailFetchGroup.leave()
                }
            }

我要尝试通过JSON响应创建以下类Email

// This file was generated from JSON Schema using quicktype,do not modify it directly.
// To parse the JSON,add this file to your project and do:
//
//   let email = try Email(json)

import Foundation

// MARK: - Email
class Email: Codable {
    let sizeEstimate: Int
    let historyID,threadID: String
    let payload: Payload
    let internalDate,snippet,id: String
    let labelIDS: [String]

    enum CodingKeys: String,CodingKey {
        case sizeEstimate
        case historyID = "historyId"
        case threadID = "threadId"
        case payload,internalDate,id
        case labelIDS = "labelIds"
    }

    init(sizeEstimate: Int,historyID: String,threadID: String,payload: Payload,internalDate: String,snippet: String,id: String,labelIDS: [String]) {
        self.sizeEstimate = sizeEstimate
        self.historyID = historyID
        self.threadID = threadID
        self.payload = payload
        self.internalDate = internalDate
        self.snippet = snippet
        self.id = id
        self.labelIDS = labelIDS
    }
}

// MARK: Email convenience initializers and mutators

extension Email {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(Email.self,from: data)
        self.init(sizeEstimate: me.sizeEstimate,historyID: me.historyID,threadID: me.threadID,payload: me.payload,internalDate: me.internalDate,snippet: me.snippet,id: me.id,labelIDS: me.labelIDS)
    }

    convenience init(_ json: String,using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding",code: 0,userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        sizeEstimate: Int? = nil,historyID: String? = nil,threadID: String? = nil,payload: Payload? = nil,internalDate: String? = nil,snippet: String? = nil,id: String? = nil,labelIDS: [String]? = nil
    ) -> Email {
        return Email(
            sizeEstimate: sizeEstimate ?? self.sizeEstimate,historyID: historyID ?? self.historyID,threadID: threadID ?? self.threadID,payload: payload ?? self.payload,internalDate: internalDate ?? self.internalDate,snippet: snippet ?? self.snippet,id: id ?? self.id,labelIDS: labelIDS ?? self.labelIDS
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(),encoding: encoding)
    }
}

// MARK: - Payload
class Payload: Codable {
    let mimeType: String
    let headers: [Header]
    let body: Body
    let partID,filename: String

    enum CodingKeys: String,CodingKey {
        case mimeType,headers,body
        case partID = "partId"
        case filename
    }

    init(mimeType: String,headers: [Header],body: Body,partID: String,filename: String) {
        self.mimeType = mimeType
        self.headers = headers
        self.body = body
        self.partID = partID
        self.filename = filename
    }
}

// MARK: Payload convenience initializers and mutators

extension Payload {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(Payload.self,from: data)
        self.init(mimeType: me.mimeType,headers: me.headers,body: me.body,partID: me.partID,filename: me.filename)
    }

    convenience init(_ json: String,userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        mimeType: String? = nil,headers: [Header]? = nil,body: Body? = nil,partID: String? = nil,filename: String? = nil
    ) -> Payload {
        return Payload(
            mimeType: mimeType ?? self.mimeType,headers: headers ?? self.headers,body: body ?? self.body,partID: partID ?? self.partID,filename: filename ?? self.filename
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(),encoding: encoding)
    }
}

// MARK: - Body
class Body: Codable {
    let size: Int
    let attachmentID: String

    enum CodingKeys: String,CodingKey {
        case size
        case attachmentID = "attachmentId"
    }

    init(size: Int,attachmentID: String) {
        self.size = size
        self.attachmentID = attachmentID
    }
}

// MARK: Body convenience initializers and mutators

extension Body {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(Body.self,from: data)
        self.init(size: me.size,attachmentID: me.attachmentID)
    }

    convenience init(_ json: String,userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        size: Int? = nil,attachmentID: String? = nil
    ) -> Body {
        return Body(
            size: size ?? self.size,attachmentID: attachmentID ?? self.attachmentID
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(),encoding: encoding)
    }
}

// MARK: - Header
class Header: Codable {
    let name,value: String

    init(name: String,value: String) {
        self.name = name
        self.value = value
    }
}

// MARK: Header convenience initializers and mutators

extension Header {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(Header.self,from: data)
        self.init(name: me.name,value: me.value)
    }

    convenience init(_ json: String,userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        name: String? = nil,value: String? = nil
    ) -> Header {
        return Header(
            name: name ?? self.name,value: value ?? self.value
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(),encoding: encoding)
    }
}

// MARK: - Helper functions for creating encoders and decoders

func newJSONDecoder() -> JSONDecoder {
    let decoder = JSONDecoder()
    if #available(iOS 10.0,OSX 10.12,tvOS 10.0,watchOS 3.0,*) {
        decoder.dateDecodingStrategy = .iso8601
    }
    return decoder
}

func newJSONEncoder() -> JSONEncoder {
    let encoder = JSONEncoder()
    if #available(iOS 10.0,*) {
        encoder.dateEncodingStrategy = .iso8601
    }
    return encoder
}

这几乎完美; attachmentID参数除外-尝试创建电子邮件时,出现以下错误

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

对此我一无所知;因此,感谢您提供任何帮助-我需要做什么以确保将分配此属性

EDIT 我忘了包含JSON响应;如下:

{
  "snippet" : "","id" : "1758550e1d57a61e","internalDate" : "1604259323000","sizeEstimate" : 1811162,"threadId" : "1758549a183c08f0","payload" : {
    "partId" : "","mimeType" : "video\/mp4","filename" : "nicholasarner@gmail.com-2020_11_01_11_35_23-WDYT?.mp4","body" : {
      "size" : 1322930,"attachmentId" : "ANGjdJ_nEZvNaV972a1H9osO7Ze3WH-F5hlf8cSEQjgM9NmI8XzsKsfhAF_zV7addIHsIEgm8nmlPGID8pICD5ew8399hocuXwvfGVx_Pl3Z7f1jwgmrm1_UD6k1daGkaXFFy7kbfiiRRidy42IoKT9r3FoS4tb7mVmv7ctrQE9KvCjV2Op3MCkzvrjM494iG06yJtQhM5Zt697BG-kythaCjacFJ5cTh4c-qdCN60JIUL3sR95AWnoEvSBMVr_i6iPKIP67gpddw27MkMmqICA8jkJXXSGhGaZek2hJu886ik_3VCvqlQ4c2uypWVYNOfWMPvjVuNmlW-_MH41cSo_mqd2DaxBVkXut70bu24y2-aY50ljhVZRqhV6CSoUlbBiPEe_VxToATBy_vFLF8TZRlOGg5Jq0kleymZvRgg"
    },"headers" : [
      {
        "name" : "Return-Path","value" : "<nicholasarner@gmail.com>"
      },{
        "name" : "Received","value" : "from iPhone ([2601:645:4200:3950:441:1411:7e85:db6d])        by smtp.gmail.com with ESMTPSA id u124sm12113464pfc.21.2020.11.01.11.35.24        for <nicholasarner@gmail.com>        (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128\/128);        Sun,01 Nov 2020 11:37:51 -0800 (PST)"
      },{
        "name" : "Date","value" : "Sun,1 Nov 2020 11:35:23 -0800"
      },{
        "name" : "From","value" : "nicholasarner@gmail.com"
      },{
        "name" : "To","value" : "Nick Arner <nicholasarner@gmail.com>"
      },{
        "name" : "Message-ID","value" : "<d5ff6514-1c55-4d98-a4d3-43a776d7b05d@iPhone>"
      },{
        "name" : "In-Reply-To","value" : "<CAD1H43XCrKQD3omFV2ggf_e2kLm_v4234p2oHvvKGd-bJ4PZeQ@mail.gmail.com>"
      },{
        "name" : "Subject","value" : "Re: tett"
      },{
        "name" : "MIME-Version","value" : "1.0"
      },{
        "name" : "Content-Type","value" : "video\/mp4"
      },{
        "name" : "Content-transfer-encoding","value" : "base64"
      },{
        "name" : "Content-disposition","value" : "attachment; filename=\"nicholasarner@gmail.com-2020_11_01_11_35_23-WDYT?.mp4\""
      }
    ]
  },"historyId" : "11441245","labelIds" : [
    "IMPORTANT","SENT","INBox"
  ]
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)