ฉันจะใช้คีย์แบบกำหนดเองกับโปรโตคอลถอดรหัสได้ของ Swift 4 ได้อย่างไร


105

Swift 4 เปิดตัวรองรับการเข้ารหัสและถอดรหัส JSON แบบเนทีฟผ่านDecodableโปรโตคอล ฉันจะใช้คีย์ที่กำหนดเองสำหรับสิ่งนี้ได้อย่างไร

เช่นบอกว่าฉันมีโครงสร้าง

struct Address:Codable {
    var street:String
    var zip:String
    var city:String
    var state:String
}

ฉันสามารถเข้ารหัสสิ่งนี้เป็น JSON

let address = Address(street: "Apple Bay Street", zip: "94608", city: "Emeryville", state: "California")

if let encoded = try? encoder.encode(address) {
    if let json = String(data: encoded, encoding: .utf8) {
        // Print JSON String
        print(json)

        // JSON string is 
           { "state":"California", 
             "street":"Apple Bay Street", 
             "zip":"94608", 
             "city":"Emeryville" 
           }
    }
}

ฉันสามารถเข้ารหัสกลับเป็นวัตถุได้

    let newAddress: Address = try decoder.decode(Address.self, from: encoded)

แต่ถ้าฉันมีวัตถุ json ที่เป็น

{ 
   "state":"California", 
   "street":"Apple Bay Street", 
   "zip_code":"94608", 
   "city":"Emeryville" 
}

ฉันจะบอกตัวถอดรหัสบนแผนที่Addressนั้นได้อย่างไร ฉันเชื่อว่าคุณใช้โปรโตคอลใหม่แต่ฉันคิดไม่ออกว่าจะใช้อย่างไรzip_codezipCodingKey

คำตอบ:


265

ปรับแต่งคีย์การเข้ารหัสด้วยตนเอง

ในตัวอย่างของคุณคุณจะได้รับความสอดคล้องที่สร้างขึ้นโดยอัตโนมัติCodableเนื่องจากคุณสมบัติทั้งหมดของคุณเป็นไปตามCodableด้วย ความสอดคล้องนี้จะสร้างประเภทคีย์โดยอัตโนมัติซึ่งสอดคล้องกับชื่อคุณสมบัติซึ่งจะถูกใช้เพื่อเข้ารหัส / ถอดรหัสจากคอนเทนเนอร์ที่มีคีย์เดียว

อย่างไรก็ตามหนึ่งจริงๆคุณลักษณะเรียบร้อยของนี้สอดคล้องสร้างขึ้นโดยอัตโนมัติคือว่าถ้าคุณกำหนดซ้อนกันenumในรูปแบบของคุณเรียกว่า " CodingKeys" (หรือใช้typealiasชื่อนี้) ที่สอดคล้องกับCodingKeyโพรโทคอ - สวิฟท์โดยอัตโนมัติจะใช้นี้เป็นชนิดที่สำคัญ ดังนั้นจึงช่วยให้คุณปรับแต่งคีย์ที่คุณสมบัติของคุณเข้ารหัส / ถอดรหัสด้วย

สิ่งนี้หมายความว่าคุณสามารถพูดได้ว่า:

struct Address : Codable {

    var street: String
    var zip: String
    var city: String
    var state: String

    private enum CodingKeys : String, CodingKey {
        case street, zip = "zip_code", city, state
    }
}

ชื่อเคส enum ต้องตรงกับชื่อคุณสมบัติและค่าดิบของเคสเหล่านี้ต้องตรงกับคีย์ที่คุณกำลังเข้ารหัส / ถอดรหัสจาก (เว้นแต่จะระบุไว้เป็นอย่างอื่นค่าดิบของการStringแจงนับจะเหมือนกับชื่อเคส ). ดังนั้นzipสถานที่ให้บริการในขณะนี้จะมีการเข้ารหัส / "zip_code"ถอดรหัสโดยใช้กุญแจ

กฎที่แน่นอนสำหรับการสร้างEncodable/ ความDecodableสอดคล้องโดยอัตโนมัติมีรายละเอียดตามข้อเสนอวิวัฒนาการ (เน้นของฉัน):

นอกจากอัตโนมัติCodingKeyสังเคราะห์ต้องการสำหรับ enums, EncodableและDecodableข้อกำหนดสามารถสังเคราะห์โดยอัตโนมัติบางประเภทเช่นกัน:

  1. ประเภทที่สอดคล้องกับEncodableที่มีคุณสมบัติทั้งหมดที่Encodableได้รับการสร้างขึ้นโดยอัตโนมัติString-backed CodingKeyคุณสมบัติการทำแผนที่ enum ชื่อกรณี ในทำนองเดียวกันสำหรับDecodableประเภทที่มีคุณสมบัติทั้งหมดDecodable

  2. ประเภทที่อยู่ใน (1) - และประเภทที่ระบุCodingKey enum(ตั้งชื่อCodingKeysโดยตรงหรือผ่าน a typealias) ด้วยตนเองซึ่งกรณีที่แมป 1-to-1 ถึงEncodable/ Decodableคุณสมบัติตามชื่อ - รับการสังเคราะห์อัตโนมัติinit(from:)และencode(to:)ตามความเหมาะสมโดยใช้คุณสมบัติและคีย์เหล่านั้น

  3. ประเภทที่ไม่อยู่ใน (1) หรือ (2) จะต้องระบุประเภทคีย์ที่กำหนดเองหากจำเป็นและระบุของตนเองinit(from:)และ encode(to:)ตามความเหมาะสม

ตัวอย่างการเข้ารหัส:

import Foundation

let address = Address(street: "Apple Bay Street", zip: "94608",
                      city: "Emeryville", state: "California")

do {
    let encoded = try JSONEncoder().encode(address)
    print(String(decoding: encoded, as: UTF8.self))
} catch {
    print(error)
}
//{"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}

ตัวอย่างการถอดรหัส:

// using the """ multi-line string literal here, as introduced in SE-0168,
// to avoid escaping the quotation marks
let jsonString = """
{"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}
"""

do {
    let decoded = try JSONDecoder().decode(Address.self, from: Data(jsonString.utf8))
    print(decoded)
} catch {
    print(error)
}

// Address(street: "Apple Bay Street", zip: "94608",
// city: "Emeryville", state: "California")

snake_caseคีย์ JSON อัตโนมัติสำหรับcamelCaseชื่อคุณสมบัติ

ในสวิฟท์ 4.1 ถ้าคุณเปลี่ยนชื่อของคุณzipคุณสมบัติเพื่อzipCodeคุณสามารถใช้ประโยชน์จากการเข้ารหัสคีย์ / ถอดรหัสกลยุทธ์ในJSONEncoderและJSONDecoderเพื่อที่จะแปลงโดยอัตโนมัติเข้ารหัสคีย์ระหว่างและcamelCasesnake_case

ตัวอย่างการเข้ารหัส:

import Foundation

struct Address : Codable {
  var street: String
  var zipCode: String
  var city: String
  var state: String
}

let address = Address(street: "Apple Bay Street", zipCode: "94608",
                      city: "Emeryville", state: "California")

do {
  let encoder = JSONEncoder()
  encoder.keyEncodingStrategy = .convertToSnakeCase
  let encoded = try encoder.encode(address)
  print(String(decoding: encoded, as: UTF8.self))
} catch {
  print(error)
}
//{"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}

ตัวอย่างการถอดรหัส:

let jsonString = """
{"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}
"""

do {
  let decoder = JSONDecoder()
  decoder.keyDecodingStrategy = .convertFromSnakeCase
  let decoded = try decoder.decode(Address.self, from: Data(jsonString.utf8))
  print(decoded)
} catch {
  print(error)
}

// Address(street: "Apple Bay Street", zipCode: "94608",
// city: "Emeryville", state: "California")

สิ่งสำคัญอย่างหนึ่งที่ควรทราบเกี่ยวกับกลยุทธ์นี้ก็คือจะไม่สามารถไป - กลับชื่อคุณสมบัติบางอย่างที่มีตัวย่อหรือการเริ่มต้นซึ่งตามแนวทางการออกแบบ Swift APIควรเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กเหมือนกัน (ขึ้นอยู่กับตำแหน่ง ).

ยกตัวอย่างเช่นชื่อคุณสมบัติsomeURLจะได้รับการเข้ารหัสด้วยกุญแจแต่ในการถอดรหัสนี้จะถูกเปลี่ยนเป็นsome_urlsomeUrl

ในการแก้ไขปัญหานี้คุณจะต้องระบุรหัสการเข้ารหัสด้วยตนเองเพื่อให้คุณสมบัตินั้นเป็นสตริงที่ตัวถอดรหัสคาดหวังเช่นsomeUrlในกรณีนี้ (ซึ่งsome_urlตัวเข้ารหัสจะยังคงถูกแปลงเป็น):

struct S : Codable {

  private enum CodingKeys : String, CodingKey {
    case someURL = "someUrl", someOtherProperty
  }

  var someURL: String
  var someOtherProperty: String
}

(นี่ไม่ได้ตอบคำถามเฉพาะของคุณอย่างเคร่งครัด แต่ด้วยลักษณะที่ยอมรับได้ของคำถาม & คำตอบนี้ฉันคิดว่ามันคุ้มค่าที่จะรวมไว้ด้วย)

การแมปคีย์ JSON อัตโนมัติที่กำหนดเอง

ใน Swift 4.1 คุณสามารถใช้ประโยชน์จากกลยุทธ์การเข้ารหัส / ถอดรหัสคีย์ที่กำหนดเองJSONEncoderและJSONDecoderช่วยให้คุณสามารถจัดเตรียมฟังก์ชันที่กำหนดเองเพื่อแมปคีย์การเข้ารหัส

ฟังก์ชันที่คุณระบุจะใช้ a [CodingKey]ซึ่งแสดงถึงเส้นทางการเข้ารหัสสำหรับจุดปัจจุบันในการเข้ารหัส / ถอดรหัส (ในกรณีส่วนใหญ่คุณจะต้องพิจารณาเฉพาะองค์ประกอบสุดท้ายนั่นคือคีย์ปัจจุบัน) ฟังก์ชันจะส่งคืน a CodingKeyที่จะแทนที่คีย์สุดท้ายในอาร์เรย์นี้

ตัวอย่างเช่นUpperCamelCaseคีย์ JSON สำหรับlowerCamelCaseชื่อคุณสมบัติ:

import Foundation

// wrapper to allow us to substitute our mapped string keys.
struct AnyCodingKey : CodingKey {

  var stringValue: String
  var intValue: Int?

  init(_ base: CodingKey) {
    self.init(stringValue: base.stringValue, intValue: base.intValue)
  }

  init(stringValue: String) {
    self.stringValue = stringValue
  }

  init(intValue: Int) {
    self.stringValue = "\(intValue)"
    self.intValue = intValue
  }

  init(stringValue: String, intValue: Int?) {
    self.stringValue = stringValue
    self.intValue = intValue
  }
}

extension JSONEncoder.KeyEncodingStrategy {

  static var convertToUpperCamelCase: JSONEncoder.KeyEncodingStrategy {
    return .custom { codingKeys in

      var key = AnyCodingKey(codingKeys.last!)

      // uppercase first letter
      if let firstChar = key.stringValue.first {
        let i = key.stringValue.startIndex
        key.stringValue.replaceSubrange(
          i ... i, with: String(firstChar).uppercased()
        )
      }
      return key
    }
  }
}

extension JSONDecoder.KeyDecodingStrategy {

  static var convertFromUpperCamelCase: JSONDecoder.KeyDecodingStrategy {
    return .custom { codingKeys in

      var key = AnyCodingKey(codingKeys.last!)

      // lowercase first letter
      if let firstChar = key.stringValue.first {
        let i = key.stringValue.startIndex
        key.stringValue.replaceSubrange(
          i ... i, with: String(firstChar).lowercased()
        )
      }
      return key
    }
  }
}

ตอนนี้คุณสามารถเข้ารหัสด้วย.convertToUpperCamelCaseกลยุทธ์หลัก:

let address = Address(street: "Apple Bay Street", zipCode: "94608",
                      city: "Emeryville", state: "California")

do {
  let encoder = JSONEncoder()
  encoder.keyEncodingStrategy = .convertToUpperCamelCase
  let encoded = try encoder.encode(address)
  print(String(decoding: encoded, as: UTF8.self))
} catch {
  print(error)
}
//{"Street":"Apple Bay Street","City":"Emeryville","State":"California","ZipCode":"94608"}

และถอดรหัสด้วย.convertFromUpperCamelCaseกลยุทธ์หลัก:

let jsonString = """
{"Street":"Apple Bay Street","City":"Emeryville","State":"California","ZipCode":"94608"}
"""

do {
  let decoder = JSONDecoder()
  decoder.keyDecodingStrategy = .convertFromUpperCamelCase
  let decoded = try decoder.decode(Address.self, from: Data(jsonString.utf8))
  print(decoded)
} catch {
  print(error)
}

// Address(street: "Apple Bay Street", zipCode: "94608",
// city: "Emeryville", state: "California")

เพิ่งสะดุดกับตัวเอง! ฉันสงสัยว่ามีวิธีแทนที่เฉพาะคีย์เดียวที่ฉันต้องการเปลี่ยนและปล่อยให้ส่วนที่เหลืออยู่คนเดียวหรือไม่? เช่นในคำสั่งกรณีภายใต้CodingKeysenum; ฉันสามารถระบุคีย์เดียวที่ฉันกำลังเปลี่ยนแปลงได้ไหม
chrismanderson

2
"""is for a multi-line literal :)
Martin R

6
@MartinR หรือแม้แต่ลิเทอรัลบรรทัดเดียวโดยไม่ต้องหนี"s: D
Hamish

1
@chrismanderson แน่นอน - โดยเฉพาะอย่างยิ่งเมื่อคอมไพเลอร์บังคับว่าชื่อเคสจะถูกซิงค์กับชื่อคุณสมบัติ (มันจะทำให้คุณมีข้อผิดพลาดว่าคุณไม่เป็นไปตามนั้นCodable)
Hamish

1
@ClayEllis ใช่แล้วแม้ว่าแน่นอนว่าจะใช้คอนเทนเนอร์ที่ซ้อนกันเช่นในตัวเริ่มต้นของการAddressเชื่อมโยงตัวเองโดยไม่จำเป็นกับการถอดรหัสออบเจ็กต์ JSON ที่เริ่มต้นที่ตำแหน่งเฉพาะในกราฟออบเจ็กต์ระดับบนสุด มันจะดีกว่ามากที่จะเป็นนามธรรมเส้นทางสำคัญที่เริ่มต้นขึ้นในการถอดรหัสของตัวเอง - นี่คือการดำเนินงาน hackey-ish หยาบ
Hamish

17

ด้วย Swift 4.2 ตามความต้องการของคุณคุณสามารถใช้หนึ่งใน 3 กลยุทธ์ต่อไปนี้เพื่อตั้งชื่อคุณสมบัติที่กำหนดเองของออบเจ็กต์โมเดลให้ตรงกับคีย์ JSON ของคุณ


# 1. ใช้คีย์การเข้ารหัสแบบกำหนดเอง

เมื่อคุณประกาศโครงสร้างที่สอดคล้องกับCodable( DecodableและEncodableโปรโตคอล) ด้วยการใช้งานต่อไปนี้ ...

struct Address: Codable {
    var street: String
    var zip: String
    var city: String
    var state: String        
}

... คอมไพเลอร์จะสร้าง enum ที่ซ้อนกันโดยอัตโนมัติซึ่งเป็นไปตามCodingKeyโปรโตคอลสำหรับคุณ

struct Address: Codable {
    var street: String
    var zip: String
    var city: String
    var state: String

    // compiler generated
    private enum CodingKeys: String, CodingKey {
        case street
        case zip
        case city
        case state
    }
}

ดังนั้นหากคีย์ที่ใช้ในรูปแบบข้อมูลซีเรียลของคุณไม่ตรงกับชื่อคุณสมบัติจากประเภทข้อมูลของคุณคุณสามารถใช้ enum นี้ด้วยตนเองและตั้งค่าที่เหมาะสมrawValueสำหรับกรณีที่ต้องการ

ตัวอย่างต่อไปนี้แสดงวิธีการทำ:

import Foundation

struct Address: Codable {
    var street: String
    var zip: String
    var city: String
    var state: String

    private enum CodingKeys: String, CodingKey {
        case street
        case zip = "zip_code"
        case city
        case state
    }
}

เข้ารหัส (แทนที่zipคุณสมบัติด้วยคีย์ JSON "zip_code"):

let address = Address(street: "Apple Bay Street", zip: "94608", city: "Emeryville", state: "California")

let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(address), let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

/*
 prints:
 {"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}
 */

ถอดรหัส (แทนที่คีย์ JSON "zip_code" ด้วยzipคุณสมบัติ):

let jsonString = """
{"state":"California","street":"Apple Bay Street","zip_code":"94608","city":"Emeryville"}
"""

let decoder = JSONDecoder()
if let jsonData = jsonString.data(using: .utf8), let address = try? decoder.decode(Address.self, from: jsonData) {
    print(address)
}

/*
 prints:
 Address(street: "Apple Bay Street", zip: "94608", city: "Emeryville", state: "California")
 */

# 2. การใช้เคสงูกับอูฐเคสกลยุทธ์การเข้ารหัสที่สำคัญ

หาก JSON ของคุณมีปุ่มงูใส่ซองและคุณต้องการที่จะแปลงให้เป็นคุณสมบัติอูฐดาดสำหรับวัตถุรูปแบบของคุณคุณสามารถตั้งค่าของคุณJSONEncoder's keyEncodingStrategyและJSONDecoder' s คุณสมบัติkeyDecodingStrategy.convertToSnakeCase

ตัวอย่างต่อไปนี้แสดงวิธีการทำ:

import Foundation

struct Address: Codable {
    var street: String
    var zipCode: String
    var cityName: String
    var state: String
}

เข้ารหัส (การแปลงคุณสมบัติที่ใส่อูฐเป็นคีย์ JSON แบบงู):

let address = Address(street: "Apple Bay Street", zipCode: "94608", cityName: "Emeryville", state: "California")

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
if let jsonData = try? encoder.encode(address), let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

/*
 prints:
 {"state":"California","street":"Apple Bay Street","zip_code":"94608","city_name":"Emeryville"}
 */

ถอดรหัส (การแปลงคีย์ JSON ที่ใส่งูเป็นคุณสมบัติของอูฐ):

let jsonString = """
{"state":"California","street":"Apple Bay Street","zip_code":"94608","city_name":"Emeryville"}
"""

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
if let jsonData = jsonString.data(using: .utf8), let address = try? decoder.decode(Address.self, from: jsonData) {
    print(address)
}

/*
 prints:
 Address(street: "Apple Bay Street", zipCode: "94608", cityName: "Emeryville", state: "California")
 */

# 3. ใช้กลยุทธ์การเข้ารหัสคีย์แบบกำหนดเอง

ถ้าจำเป็นJSONEncoderและJSONDecoderช่วยให้คุณสามารถกำหนดกลยุทธ์ที่กำหนดเองเพื่อ map เข้ารหัสคีย์การใช้และJSONEncoder.KeyEncodingStrategy.custom(_:)JSONDecoder.KeyDecodingStrategy.custom(_:)

ตัวอย่างต่อไปนี้แสดงวิธีการนำไปใช้:

import Foundation

struct Address: Codable {
    var street: String
    var zip: String
    var city: String
    var state: String
}

struct AnyKey: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) {
        self.stringValue = stringValue
    }

    init?(intValue: Int) {
        self.stringValue = String(intValue)
        self.intValue = intValue
    }
}

เข้ารหัส (การแปลงคุณสมบัติอักษรตัวแรกที่ลดขนาดเป็นคีย์ JSON ตัวพิมพ์ใหญ่ตัวแรก):

let address = Address(street: "Apple Bay Street", zip: "94608", city: "Emeryville", state: "California")

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .custom({ (keys) -> CodingKey in
    let lastKey = keys.last!
    guard lastKey.intValue == nil else { return lastKey }
    let stringValue = lastKey.stringValue.prefix(1).uppercased() + lastKey.stringValue.dropFirst()
    return AnyKey(stringValue: stringValue)!
})

if let jsonData = try? encoder.encode(address), let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

/*
 prints:
 {"Zip":"94608","Street":"Apple Bay Street","City":"Emeryville","State":"California"}
 */

ถอดรหัส (การแปลงคีย์ JSON ตัวพิมพ์ใหญ่ตัวแรกเป็นคุณสมบัติอักษรตัวแรกตัวพิมพ์เล็ก):

let jsonString = """
{"State":"California","Street":"Apple Bay Street","Zip":"94608","City":"Emeryville"}
"""

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .custom({ (keys) -> CodingKey in
    let lastKey = keys.last!
    guard lastKey.intValue == nil else { return lastKey }
    let stringValue = lastKey.stringValue.prefix(1).lowercased() + lastKey.stringValue.dropFirst()
    return AnyKey(stringValue: stringValue)!
})

if let jsonData = jsonString.data(using: .utf8), let address = try? decoder.decode(Address.self, from: jsonData) {
    print(address)
}

/*
 prints:
 Address(street: "Apple Bay Street", zip: "94608", city: "Emeryville", state: "California")
 */

แหล่งที่มา:


3

สิ่งที่ฉันทำคือสร้างโครงสร้างของตัวเองเช่นเดียวกับสิ่งที่คุณได้รับจาก JSON เกี่ยวกับประเภทข้อมูล

เช่นนี้:

struct Track {
let id : Int
let contributingArtistNames:String
let name : String
let albumName :String
let copyrightP:String
let copyrightC:String
let playlistCount:Int
let trackPopularity:Int
let playlistFollowerCount:Int
let artistFollowerCount : Int
let label : String
}

หลังจากนี้คุณจะต้องสร้างส่วนขยายของเดียวกันstructการขยายdecodableและenumโครงสร้างเดียวกันกับCodingKeyและแล้วคุณจะต้องเริ่มต้นถอดรหัสโดยใช้ enum นี้กับคีย์และประเภทข้อมูลของตน (Keys จะมาจาก enum และประเภทข้อมูลจะมาหรือพูด อ้างอิงจากโครงสร้างนั่นเอง)

extension Track: Decodable {

    enum TrackCodingKeys: String, CodingKey {
        case id = "id"
        case contributingArtistNames = "primaryArtistsNames"
        case spotifyId = "spotifyId"
        case name = "name"
        case albumName = "albumName"
        case albumImageUrl = "albumImageUrl"
        case copyrightP = "copyrightP"
        case copyrightC = "copyrightC"
        case playlistCount = "playlistCount"
        case trackPopularity = "trackPopularity"
        case playlistFollowerCount = "playlistFollowerCount"
        case artistFollowerCount = "artistFollowers"
        case label = "label"
    }
    init(from decoder: Decoder) throws {
        let trackContainer = try decoder.container(keyedBy: TrackCodingKeys.self)
        if trackContainer.contains(.id){
            id = try trackContainer.decode(Int.self, forKey: .id)
        }else{
            id = 0
        }
        if trackContainer.contains(.contributingArtistNames){
            contributingArtistNames = try trackContainer.decode(String.self, forKey: .contributingArtistNames)
        }else{
            contributingArtistNames = ""
        }
        if trackContainer.contains(.spotifyId){
            spotifyId = try trackContainer.decode(String.self, forKey: .spotifyId)
        }else{
            spotifyId = ""
        }
        if trackContainer.contains(.name){
            name = try trackContainer.decode(String.self, forKey: .name)
        }else{
            name = ""
        }
        if trackContainer.contains(.albumName){
            albumName = try trackContainer.decode(String.self, forKey: .albumName)
        }else{
            albumName = ""
        }
        if trackContainer.contains(.albumImageUrl){
            albumImageUrl = try trackContainer.decode(String.self, forKey: .albumImageUrl)
        }else{
            albumImageUrl = ""
        }
        if trackContainer.contains(.copyrightP){
            copyrightP = try trackContainer.decode(String.self, forKey: .copyrightP)
        }else{
            copyrightP = ""
        }
        if trackContainer.contains(.copyrightC){
                copyrightC = try trackContainer.decode(String.self, forKey: .copyrightC)
        }else{
            copyrightC = ""
        }
        if trackContainer.contains(.playlistCount){
            playlistCount = try trackContainer.decode(Int.self, forKey: .playlistCount)
        }else{
            playlistCount = 0
        }

        if trackContainer.contains(.trackPopularity){
            trackPopularity = try trackContainer.decode(Int.self, forKey: .trackPopularity)
        }else{
            trackPopularity = 0
        }
        if trackContainer.contains(.playlistFollowerCount){
            playlistFollowerCount = try trackContainer.decode(Int.self, forKey: .playlistFollowerCount)
        }else{
            playlistFollowerCount = 0
        }

        if trackContainer.contains(.artistFollowerCount){
            artistFollowerCount = try trackContainer.decode(Int.self, forKey: .artistFollowerCount)
        }else{
            artistFollowerCount = 0
        }
        if trackContainer.contains(.label){
            label = try trackContainer.decode(String.self, forKey: .label)
        }else{
            label = ""
        }
    }
}

คุณต้องเปลี่ยนที่นี่ทุกคีย์และประเภทข้อมูลตามความต้องการของคุณและใช้กับตัวถอดรหัส


-1

ด้วยการใช้CodingKeyคุณสามารถใช้คีย์แบบกำหนดเองในโปรโตคอลที่เข้ารหัสหรือถอดรหัสได้

struct person: Codable {
    var name: String
    var age: Int
    var street: String
    var state: String

    private enum CodingKeys: String, CodingKey {
        case name
        case age
        case street = "Street_name"
        case state
    } }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.