Как использовать Decodable с данными Generics & Core в Swift - PullRequest
0 голосов
/ 11 июня 2018

Ниже мой JSON.Мне нужно декодировать записи в нем, используя класс модели "Decodable" CoreData.Записи (и соответствующие классы модели в Базовых данных) отличаются, как вы можете видеть по ключу "c"Так что эта переменная "c" должна быть общего типа, я думаю.Таким образом, он может принять все 6 (фиксированных!) Типов моделей, а именно."консультация_время", "ребенок", "встреча", "ребенок_доктор", "клиника", "клиника_пользователь".Не уверен, как это реализовать.Классы моделей, сгенерированные основными данными. (Использовали https://forums.developer.apple.com/thread/96860#295158 эту ссылку для реализации Decodable с Coredata.)

Updates + CoreDataClass.swift

import Foundation
import CoreData


public class Updates: NSManagedObject {

public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(name ?? "" , forKey: .name)
    try container.encode(ids , forKey: .ids)
    try container.encode(c , forKey: .c)
    try container.encode(u , forKey: .u)
    try container.encode(d , forKey: .d)
}

public required convenience init(from decoder: Decoder) throws {

    guard let contextUserInfoKey = CodingUserInfoKey.context,
        let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
        let entity = NSEntityDescription.entity(forEntityName:"Sync", in: managedObjectContext) else {  fatalError()  }

    self.init(entity: entity, insertInto: managedObjectContext)
    let values = try decoder.container(keyedBy: CodingKeys.self)
    name = try values.decode(String.self, forKey: .name)
    ids = try values.decode(Array?.self, forKey: .ids)
    c = try values.decode(Array.self, forKey: .c)
    u = try values.decode(Array.self, forKey: .u)
    d = try values.decode(Array.self, forKey: .d)
}
}

Updates + CoreDataProperties.swift

import Foundation
import CoreData


extension Updates : Codable {

@nonobjc public class func fetchRequest() -> NSFetchRequest<Updates> 
{
    return NSFetchRequest<Updates>(entityName: "Updates")
}

@NSManaged public var name: String?
@NSManaged public var ids: [String]?
@NSManaged public var c: [Parent]?
@NSManaged public var u: [Parent]?
@NSManaged public var d: [Parent]?
//** Here Parent is another Coredata entity model class. And sub entities are created from it. So at runtime c, u & d can have any of values amongst the sub-entities(Child, Clinic, Appointment etc.). So what happens is while decoding c, u and d it tries to decode "Parent" and not the subentities , becoz it doesnt know exact type of subentity(Child, Clinic, Appointment etc.). It just knows it as "Parent".

enum CodingKeys: String, CodingKey {
    case name
    case ids = "sync_token"
    case c
    case u
    case d
}
}

JSON:

"updates": [
   {
     "name": "consultation_time",
     "ids": [ "id" ],
     "c": [
       {
         "id": 1,
         "_id": 1001,
         "is_active_morning": true,
         "morning_start_time": "2016-07-01T09:30:00.000+05:30",
         "morning_end_time": "2016-07-01T12:30:00.000+05:30",
         "is_active_evening": true,
         "evening_start_time": "2016-07-01T18:00:00.000+05:30",
         "evening_end_time": "2016-07-01T19:00:00.000+05:30",
         "day": "Monday",
         "doctor_id": 2,
         "clinic_id": 1
       }
     ],
     "u": [],
     "d": []
   },
   {
     "name": "child",
     "ids": [ "id" ],
     "c": [
       {
         "id": 1,
         "_id": 1022,
         "name": "Sarvesh",
         "gender": "male",
         "dob": "2017-01-01T17:48:20.393+05:30",
         "profile_image": "https://tpn-production.s3.amazonaws.com/710e34ae-49bb-11e7-99dc-      0a6eb743b653.jpg",
         "is_member": true,
         "email": "kiran@joshsoftware.com",
         "birthday_wish_sms": true,
         "program_launch_sms": true,
         "vaccine_reminder_same_day_sms": true,
         "vaccine_reminder_two_days_prior_sms": true,
         "vaccine_reminder_week_prior_sms": true,
         "parent_name": "Kiran"
       }
     ],
     "u": [],
     "d": []
   },
   {
     "name": "appointment",
     "ids": [ "id" ],
     "c": [
       {
         "id": 1,
         "_id": 1076,
         "start_time": "2016-07-01T19:10:00.000+05:30",
         "end_time": "2016-07-01T19:15:00.000+05:30",
         "schedule": "Evening",
         "status": "open",
         "weight": 9.2,
         "height": 45,
         "head_circumference": null,
         "temperature": null,
         "heart_rate": null,
         "blood_pressure": null,
         "respiratory_rate": null,
         "bill_amount": null,
         "child_id": 1,
         "doctor_id": 2,
         "clinic_id": 1,
         "amount_received_for_consultation": null,
         "amount_received_for_indoor_admission": null,
         "amount_received_for_nebulization": null,
         "amount_received_for_injection": null,
         "amount_received_for_vaccination": null,
         "payment_mode": null,
         "total_amount_received": null,
         "pending_amount_till_date": 100
       }
     ],
     "u": [],
     "d": []
   },
   {
     "name": "child_doctor",
     "ids": [ "id" ],
     "c": [
       {
         "id": 129089,
         "_id": null,
         "child_id": 12617,
         "doctor_id": 2,
         "clinic_id": 1
       }
     ],
     "u": [],
     "d": []
   },
   {
     "name": "clinic",
     "ids": [ "id" ],
     "c": [
       {
         "id": 1,
         "_id": 2701,
         "name": "Wellness Clinic",
         "landline": "02027654321",
         "address": {
           "address": "A13/14/15, Sunflower Apartments",
           "area": "Baner",
           "postal_code": "411045",
           "city": "Pune",
           "state": "MH",
           "country": "IN",
           "lat": "18.561338",
           "lng": "73.785545"
         },
         "mobile": null,
         "email": null
       }
     ],
     "u": [],
     "d": []
   },
   {
     "name": "clinics_user",
     "ids": [
       "id"
     ],
     "c": [
       {
         "id": 1,
         "clinic_id": 1,
         "is_active": true,
         "appointment_time_slot": 5,
         "consultation_rate": 400,
         "block_online_appointments_morning": false,
         "block_online_appointments_evening": false,
         "show_generic_name_first": false,
         "show_scheduled_vaccine": true,
         "show_regional_translation_of_number": false,
         "doctor_id": 2
       }
     ],
   "u": [],
   "d": []
 }
 ]
...