একটি বিকল্প হ'ল একটি মোড়কের ধরণ ব্যবহার করা যা প্রদত্ত মানকে ডিকোড করার চেষ্টা করে; nil
ব্যর্থ হলে সংরক্ষণ করা :
struct FailableDecodable<Base : Decodable> : Decodable {
let base: Base?
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.base = try? container.decode(Base.self)
}
}
এর পরে আমরা স্থানধারকটি GroceryProduct
পূরণ করে এর একটি অ্যারে ডিকোড করতে পারি Base
:
import Foundation
let json = """
[
{
"name": "Banana",
"points": 200,
"description": "A banana grown in Ecuador."
},
{
"name": "Orange"
}
]
""".data(using: .utf8)!
struct GroceryProduct : Codable {
var name: String
var points: Int
var description: String?
}
let products = try JSONDecoder()
.decode([FailableDecodable<GroceryProduct>].self, from: json)
.compactMap { $0.base } // .flatMap in Swift 4.0
print(products)
// [
// GroceryProduct(
// name: "Banana", points: 200,
// description: Optional("A banana grown in Ecuador.")
// )
// ]
আমরা তখন .compactMap { $0.base }
ফিল্টার আউট ব্যবহার করছিnil
উপাদানগুলি (ডিকোডিংয়ের ক্ষেত্রে ত্রুটি ফেলেছিল)
এটি মধ্যবর্তী অ্যারে তৈরি করবে [FailableDecodable<GroceryProduct>]
, যা কোনও সমস্যা হওয়া উচিত নয়; তবে আপনি যদি এটিকে এড়াতে চান তবে আপনি সর্বদা আর একটি মোড়কের ধরণ তৈরি করতে পারেন যা প্রতিটি উপাদানকে বিনা রঙের ধারক থেকে ডিকোড করে এবং মোড়কজাত করে:
struct FailableCodableArray<Element : Codable> : Codable {
var elements: [Element]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var elements = [Element]()
if let count = container.count {
elements.reserveCapacity(count)
}
while !container.isAtEnd {
if let element = try container
.decode(FailableDecodable<Element>.self).base {
elements.append(element)
}
}
self.elements = elements
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(elements)
}
}
তারপরে আপনি এই হিসাবে ডিকোড করবেন:
let products = try JSONDecoder()
.decode(FailableCodableArray<GroceryProduct>.self, from: json)
.elements
print(products)
// [
// GroceryProduct(
// name: "Banana", points: 200,
// description: Optional("A banana grown in Ecuador.")
// )
// ]