enum PostType: Decodable {
init(from decoder: Decoder) throws {
// What do i put here?
}
case Image
enum CodingKeys: String, CodingKey {
case image
}
}
Apa yang saya masukkan untuk menyelesaikan ini? Juga, katakanlah saya mengubah case
ini:
case image(value: Int)
Bagaimana cara membuat ini sesuai dengan Decodable?
Sunting Di Sini adalah kode lengkap saya (yang tidak berfungsi)
let jsonData = """
{
"count": 4
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
let response = try decoder.decode(PostType.self, from: jsonData)
print(response)
} catch {
print(error)
}
}
}
enum PostType: Int, Codable {
case count = 4
}
Edit Final Juga, bagaimana ia menangani enum seperti ini?
enum PostType: Decodable {
case count(number: Int)
}
iOS 13.3
. Saya mengujiiOS 13.3
daniOS 12.4.3
, mereka berperilaku berbeda. Di bawahiOS 13.3
, enum dapat en- / diterjemahkan hanya.Cara membuat enum dengan tipe terkait sesuai dengan
Codable
Jawaban ini mirip dengan @Howard Lovatt tetapi menghindari membuat
PostTypeCodableForm
struct dan sebaliknya menggunakanKeyedEncodingContainer
jenis yang disediakan oleh Apple sebagai propertiEncoder
danDecoder
, yang mengurangi boilerplate.Kode ini berfungsi untuk saya di Xcode 9b3.
sumber
Either
codableSwift akan melempar
.dataCorrupted
kesalahan jika menemui nilai enum yang tidak diketahui. Jika data Anda berasal dari server, ia dapat mengirimi Anda nilai enum yang tidak diketahui kapan saja (sisi server bug, jenis baru ditambahkan dalam versi API dan Anda ingin versi aplikasi Anda sebelumnya menangani kasus ini dengan anggun, dll), Anda sebaiknya siap, dan kode "gaya defensif" untuk mendekodekan enum Anda dengan aman.Berikut adalah contoh cara melakukannya, dengan atau tanpa nilai terkait
Dan cara menggunakannya dalam struct tertutup:
sumber
Untuk memperluas jawaban @ Toka, Anda juga dapat menambahkan nilai representatif mentah ke enum, dan menggunakan konstruktor opsional default untuk membangun enum tanpa
switch
:Itu dapat diperluas menggunakan protokol khusus yang memungkinkan untuk refactor konstruktor:
Itu juga dapat dengan mudah diperpanjang untuk melempar kesalahan jika nilai enum yang tidak valid ditentukan, daripada default pada nilai. Inti dari perubahan ini tersedia di sini: https://gist.github.com/stephanecopin/4283175fabf6f0cdaf87fef2a00c8128 .
Kode ini dikompilasi dan diuji menggunakan Swift 4.1 / Xcode 9.3.
sumber
Varian dari respon @ proxpero yang terser adalah merumuskan decoder sebagai:
Ini memungkinkan kompiler untuk memverifikasi kasus secara mendalam, dan juga tidak menekan pesan kesalahan untuk kasus di mana nilai yang dikodekan tidak cocok dengan nilai yang diharapkan kunci.
sumber
Sebenarnya jawaban di atas benar-benar hebat, tetapi mereka kehilangan beberapa perincian untuk apa yang dibutuhkan banyak orang dalam proyek klien / server yang terus dikembangkan. Kami mengembangkan aplikasi sementara backend kami terus berkembang dari waktu ke waktu, yang berarti beberapa kasus enum akan mengubah evolusi itu. Jadi kita memerlukan strategi decoding enum yang dapat men-decode array enum yang berisi kasus yang tidak diketahui. Kalau tidak, decoding objek yang berisi array hanya gagal.
Apa yang saya lakukan cukup sederhana:
Bonus: Sembunyikan implementasi> Jadikan Koleksi
Menyembunyikan detail implementasi selalu merupakan ide yang bagus. Untuk ini, Anda akan memerlukan sedikit lebih banyak kode. Caranya adalah dengan menyesuaikan
DirectionsList
untukCollection
dan membuat internal Andalist
array yang pribadi:Anda dapat membaca lebih lanjut tentang menyesuaikan dengan koleksi khusus dalam posting blog ini oleh John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb00
sumber
Anda dapat melakukan apa yang Anda inginkan, tetapi ini sedikit melibatkan :(
sumber