簡體   English   中英

Swift 可重用 model 類/結構

[英]Swift reusable model class/struct

我有一個服務,其響應根據 orderNumer(我傳遞給服務的輸入參數)而有所不同。 幾乎所有 object 都是相同的,但只有一個對象(例如元 object 是字典)根據訂單號而有所不同。 But I would like to reuse the same model class everywhere but due to different meta object can't be able to create that meta object in model class.I can achieve it by creating individual model class but not a right solution.

struct BookingInfo: Codable {
        let created_time: Int
        // Some other 20 key value pairs
        let oms_meta: Meta  /* oms_meta": {
            "package": {
                "description": "gzhdjjdjd"
            }*/

    }
    // Meta for Order1
    struct Meta: Codable {
        let package: Description
        enum CodingKeys : String, CodingKey {
            case package = "package"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            package = try values.decode(Description.self, forKey: .package)
        }
    }

    // Meta for Order 2
    struct Meta: Codable {
        let customer_payment_details: Int
        let items: Int // this can be anything dictinary or some time array of dictionary

        enum CodingKeys : String, CodingKey {
            case package = "customer_payment_details"
            case items = "items"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            customer_payment_details = try values.decode(Int.self, forKey: .package)
            items = try values.decode(Int.self, forKey: .package)

        }
    }
Only meta parameters are varying from service to service.

Thanks in advance

如果您只想使用 1 個 model,您應該為字典中所有可能的鍵提供一個變量並將它們設置為可選。

假設所有訂單都有一個 orderNumber,但只有一些訂單有一個 orderImage,你可以這樣做:

struct Order: Codable { var orderNumber: Int var orderImage: Data? var orderName: String? var orderDescription: String? }

這樣,返回的數據只需包含一個 orderNumber 即可對其進行解碼。

編輯:您必須為每種類型的“元數據”制作單獨的 model,因為它們似乎彼此非常不同。 請注意,創建大量 model 類沒有任何問題,只要它們代表特定的數據 object。

[
  {
    "created_time": 1,
    "oms_meta": {
    "name": "1"
    }
  },
  {
   "created_time": 1,
   "oms_meta": [
   1
]
}
]

假設我們有一個類似這樣的響應,其中可以有多個oms_meta對象。 所以我們在這里可以做的是指定一個enum ,它既包含array又包含dictionary ,如果您需要指定該枚舉中提到的其他data types ,服務是否向您發送arraydictionary並不重要。 所以它會像,

struct BookingInfoElement: Codable {
    let createdTime: Int?
    let omsMeta: OmsMetaUnion?

    enum CodingKeys: String, CodingKey {
        case createdTime = "created_time"
        case omsMeta = "oms_meta"
    }
}

enum OmsMetaUnion: Codable {
    case integerArray([Int])
    case omsMetaClass(OmsMetaClass)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode([Int].self) {
            self = .integerArray(x)
            return
        }
        if let x = try? container.decode(OmsMetaClass.self) {
            self = .omsMetaClass(x)
            return
        }
        throw DecodingError.typeMismatch(OmsMetaUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for OmsMetaUnion"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integerArray(let x):
            try container.encode(x)
        case .omsMetaClass(let x):
            try container.encode(x)
        }
    }
}

struct OmsMetaClass: Codable {
    let name: String?

    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
}

typealias BookingInfo = [BookingInfoElement]

因此,如果您特別希望單個變量具有多種類型,您可以創建具有該多種類型的另一個枚舉並相應地分配。 您可以使用switch like 訪問該變量,並檢查arraydictionary類型。

在做了一些分析后,我找到了滿足我要求的解決方案。 因為我想重用 Model class 和 OMS_Meta 字典因產品而異,所以我將 omsMeta 添加到 JSONDecoder().userInfo 屬性

   struct BookingInfo: Codable {
          let created_time: Int
          let oms_meta: [String: Any]
        }
        public static let metaUserInfo = CodingUserInfoKey(rawValue: "oms_meta")!
        decoder.userInfo[BookingInfo.metaUserInfo] = jsonDecode

通過這樣做,我可以重新使用我的 model class。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM