简体   繁体   中英

Implementing Codable and NSManagedObject simultaneously in Swift

I have an order processing application I'm working on for my employers that was originally designed to get all data about orders, products, and clients dynamically from the API. So all of the objects and and all of the functions dealing with those objects are interacting in the app with a "pass by value" expectation, utilizing structs conforming to Codable.

I now have to cache pretty much all of these objects. Enter CoreData.

I have no desire to create two files for one object(one as a Codable struct and the other as an NSManagedObject class) and then trying to figure out how to convert one to another. So I want to implement both in the same file...while still somehow being able to use my "pass by value" code.

Perhaps this is impossible.

edit

I'm looking for something a bit simpler than rebuilding all my data structures from the ground up. I understand I'll have to do some alterations to make a Codable struct compatible with a NSManagedObject class. I'd like to avoid making a custom initializer that requires me to enter in every property by hand, because there's hundreds of them.

In the end, it sounds like there is no "good" solution when migrating from an API dynamic app without caching to a cached app.

I decided to just bite the bullet and try the method in this Question: How to use swift 4 Codable in Core Data?

EDIT:

I couldn't figure out how to make that work so I used the following solution:

import Foundation
import CoreData

/*
 SomeItemData vs SomeItem:
 The object with 'Data' appended to the name will always be the codable struct. The other will be the NSManagedObject class.
 */

struct OrderData: Codable, CodingKeyed, PropertyLoopable
{
    typealias CodingKeys = CodableKeys.OrderData

    let writer: String,
    userID: String,
    orderType: String,
    shipping: ShippingAddressData
    var items: [OrderedProductData]
    let totals: PaymentTotalData,
    discount: Float

    init(json:[String:Any])
    {
        writer = json[CodingKeys.writer.rawValue] as! String
        userID = json[CodingKeys.userID.rawValue] as! String
        orderType = json[CodingKeys.orderType.rawValue] as! String
        shipping = json[CodingKeys.shipping.rawValue] as! ShippingAddressData
        items = json[CodingKeys.items.rawValue] as! [OrderedProductData]
        totals = json[CodingKeys.totals.rawValue] as! PaymentTotalData
        discount = json[CodingKeys.discount.rawValue] as! Float
    }
}

extension Order: PropertyLoopable //this is the NSManagedObject. PropertyLoopable has a default implementation that uses Mirror to convert all the properties into a dictionary I can iterate through, which I can then pass directly to the JSON constructor above
{
    convenience init(from codableObject: OrderData)
    {
        self.init(context: PersistenceManager.shared.context)

        writer = codableObject.writer
        userID = codableObject.userID
        orderType = codableObject.orderType
        shipping = ShippingAddress(from: codableObject.shipping)
        items = []
        for item in codableObject.items
        {
            self.addToItems(OrderedProduct(from: item))
        }
        totals = PaymentTotal(from: codableObject.totals)
        discount = codableObject.discount
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM