कोडेबल: गलत एनम वैल्यू को हैंडल करना
अपने कोडबेस की सुरक्षा करना: अप्रत्याशित एनम मूल्यों से निपटना
कभी ऐसी स्थिति का सामना करना पड़ा जहां आपका ऐप कहीं से भी दुर्घटनाग्रस्त होना शुरू हो गया, जिसकी जांच से पता चलता है कि बैकएंड ने कुछ एनुम आधारित फ़ील्ड के लिए एक मूल्य प्रदान किया है जो कोड में एनम के अंदर मौजूद नहीं है?
निम्नलिखित उदाहरण पर विचार करें:
import Foundation
struct Person: Codable {
let name: String
let favouriteBeverage: Beverage
}
enum Beverage: String, Codable {
case Tea
case Coffee
}
let jsonString = """
{
"name": "Shubham Bakshi",
"favouriteBeverage": "Tea"
}
""".data(using: .utf8)!
let decodedJSON = try! JSONDecoder().decode(Person.self, from: jsonString)
switch decodedJSON.favouriteBeverage {
case .Tea:
print("Ohhh I love some Tea")
case .Coffee:
print("Coffee is no Tea but meh, I'll take it")
}
ओह्ह मुझे कुछ चाय बहुत पसंद है
लेकिन क्या होगा अगर हम favouriteBeverage
JSON डेटा को चाय से जूस में बदल दें (एक मान जो एनम, बेवरेज के अंदर मौजूद नहीं है )?
let jsonString = """
{
"name": "Shubham Bakshi",
"favouriteBeverage": "Juice"
}
""".data(using: .utf8)!
संदेश के भाग पर फ़ोकस करें: "अमान्य स्ट्रिंग मान रस से पेय प्रारंभ नहीं कर सकता"
यदि यह खेल के मैदान के कोड के बजाय एक वास्तविक ऐप होता, तो ऐप क्रैश हो जाता। तो, हम इस तथ्य का कैसे ध्यान रखते हैं कि भले ही बैकएंड प्रतिक्रिया में एक अमान्य मान भेजता है, हमारा ऐप एकमुश्त दुर्घटनाग्रस्त होने के बजाय इसे संभालने में सक्षम होना चाहिए ?
तरीकों में से एक, और मेरा व्यक्तिगत पसंदीदा: गलत एनम फॉलबैक तंत्र।
यह तंत्र कहता है लेकिन कमोबेश एक प्रोटोकॉल है जो हर चीज का ख्याल रखता है। तो अब हम शुरू करें …।
/// This is useful in case the backend specifies some value that does not
/// exist inside the enum as in such cases the app crashes since it fails to
/// parse the enum.
///
/// This ensures that in case an invalid value is specified, the app will
/// not crash but rather resort to a value specified for
/// `fallbackForIncorrectEnumValue`
///
protocol IncorrectEnumFallbackMechanism: RawRepresentable, Codable {
/// Fallback value in case the backend returns an incorrect value for
/// the enum
static var fallbackForIncorrectEnumValue: Self { get }
}
extension IncorrectEnumFallbackMechanism where RawValue: Codable {
init(from decoder: Decoder) throws {
// Fetching the value specified inside the JSON
let value = try decoder.singleValueContainer().decode(RawValue.self)
// Creating the instance based on the provided value or falling back
// to a default value in case the provided value for creating is
// invalid
self = Self(rawValue: value) ?? Self.fallbackForIncorrectEnumValue
}
/// Since `RawRepresentable` declares a `encode(coder:)` by default so we
/// don't need to implement that explicitly
}
enum Beverage: String, IncorrectEnumFallbackMechanism {
static var fallbackForIncorrectEnumValue: Beverage = .SomeWeirdBeverage
case Tea
case Coffee
case SomeWeirdBeverage
}
इंतज़ार! वह क्या है?
कोई फर्क नहीं पड़ता कि बैकएंड हमें किस रूप में भेजता है favouriteBeverage
, हम इसे संभाल सकेंगे, या इसे पी सकेंगे, जो भी हो!
तो हमारा पूरा कोड अब इस तरह दिखेगा:
import Foundation
/// This is useful in case the backend specifies some value that does not
/// exist inside the enum as in such cases the app crashes since it fails to
/// parse the enum.
///
/// This ensures that in case an invalid value is specified, the app will
/// not crash but rather resort to a value specified for
/// `fallbackForIncorrectEnumValue`
///
protocol IncorrectEnumFallbackMechanism: RawRepresentable, Codable {
/// Fallback value in case the backend returns an incorrect value for
/// the enum
static var fallbackForIncorrectEnumValue: Self { get }
}
extension IncorrectEnumFallbackMechanism where RawValue: Codable {
init(from decoder: Decoder) throws {
// Fetching the value specified inside the JSON
let value = try decoder.singleValueContainer().decode(RawValue.self)
// Creating the instance based on the provided value or falling back
// to a default value in case the provided value for creating is
// invalid
self = Self(rawValue: value) ?? Self.fallbackForIncorrectEnumValue
}
/// Since `RawRepresentable` declares a `encode(coder:)` by default so we
/// don't need to implement that explicitly
}
struct Person: Codable {
let name: String
let favouriteBeverage: Beverage
}
enum Beverage: String, IncorrectEnumFallbackMechanism {
static var fallbackForIncorrectEnumValue: Beverage = .SomeWeirdBeverage
case Tea
case Coffee
case SomeWeirdBeverage
}
let jsonString = """
{
"name": "Shubham Bakshi",
"favouriteBeverage": "Juice"
}
""".data(using: .utf8)!
let decodedJSON = try! JSONDecoder().decode(Person.self, from: jsonString)
switch decodedJSON.favouriteBeverage {
case .Tea:
print("Ohhh I love some Tea")
case .Coffee:
print("Coffee is no Tea but meh, I'll take it")
case .SomeWeirdBeverage:
print("Wait! What is that?")
}
बस इतना ही, लोग! हैप्पी कोडिंग!
आप मेरे साथ LinkedIn पर जुड़ सकते हैं या अन्य चैनलों के माध्यम से मुझसे संपर्क कर सकते हैं