CoreData + Codable无法保存

时间:2018-08-29 16:24:59

标签: ios swift core-data codable

我正在尝试提取一些数据并将其存储在CoreData中。下拉数据可以正常工作,但不会持久保存数据。

这是我用来尝试保存CoreData的代码:

guard let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.context else {
                        fatalError("Failed to retrieve managed object context")
                    }
                    let context = CoreDataHelper.sharedInstance.persistentContainer.viewContext
                    let decoder = JSONDecoder()
                    decoder.userInfo[codingUserInfoKeyManagedObjectContext] = context
                    _ = try decoder.decode(DeltaModel.self, from: actualData) //we'll get the value from another context using a fetch request later...
                    try context.save()
                    let oilArray : [Oil] = self.fetchFromStorage()!
                    print(oilArray)

这将打印数组的内容,但是在重新加载应用程序时再次获取时,它将返回一个空数组。这是机油NSManagedObject的模型:

public class Oil: NSManagedObject, Codable {

enum CodingKeys: String, CodingKey {
    case resourceType = "resource_type"
    case id, name
    case imageURL = "image_url"
    case color
    case latinName = "latin_name"
    case emotions
    case safetyInformation = "safety_information"
    case fact, research
    case viewsCount = "views_count"
    case commentsCount = "comments_count"
    case blendsWith = "blends_with"
    case foundInBlends = "found_in_blends"
    case properties
    case sourcingMethods = "sourcing_methods"
    case usages
}

required convenience public init(from decoder: Decoder) throws {
    guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError() }
    guard let entity = NSEntityDescription.entity(forEntityName: "Oil", in: context) else { fatalError() }

    self.init(entity: entity, insertInto: context)

    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.resourceType = try! container.decodeIfPresent(String.self, forKey: .resourceType)!
    self.id = try! container.decodeIfPresent(Int64.self, forKey: .id)!
    self.name = try! container.decodeIfPresent(String.self, forKey: .name)!
    self.imageURL = try! container.decodeIfPresent(String.self, forKey: .imageURL)!
    self.color = try! container.decodeIfPresent(String.self, forKey: .color)!
    self.viewsCount = try! container.decodeIfPresent(Int64.self, forKey: .viewsCount)!
    self.viewsCount = try! container.decodeIfPresent(Int64.self, forKey: .viewsCount)!
    self.commentsCount = try! container.decodeIfPresent(Int64.self, forKey: .commentsCount)!
    self.latinName = try! container.decodeIfPresent(String.self, forKey: .latinName)!
}

public func encode(to encoder: Encoder) throws {

}

}

在模拟器或实际设备上似乎都看不到SQLLite DB。这就像它的临时保存。

更新:CoreDataHelper类的内容:

class CoreDataHelper {

static let sharedInstance: CoreDataHelper = CoreDataHelper()

func getItems<T : NSManagedObject>(predicate : NSPredicate? = nil) -> [T]{
    do {
        let reqest = T.fetchRequest()
        reqest.predicate = predicate
        if let items = try persistentContainer.viewContext.fetch(reqest) as? [T] {
            return items
        } else {
            return [T]()
        }
    } catch let error as NSError {
        print("Could not fetch. \(error), \(error.userInfo)")
        return [T]()
    }
}

func getObjectBy<T : NSManagedObject>(id : NSManagedObjectID) -> T? {
    if let object = try? persistentContainer.viewContext.existingObject(with: id) as? T {
        return object
    }
    else {
        return nil
    }
}

var persistentContainer: NSPersistentContainer = {
    let description = NSPersistentStoreDescription()

    let container = NSPersistentContainer(name: "ELModel")

    container.persistentStoreDescriptions = [description]
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            print("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            let nserror = error as NSError
            print("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

}

1 个答案:

答案 0 :(得分:2)

NSPersistentStoreDescription()创建一个空的描述,甚至没有设置商店URL。请改用NSPersistentStoreDescription(url:)

您可以使用container.persistentStoreDescriptions.first!.url!来获取默认网址,该网址已用NSPersistentStoreContainer(_)初始化,因此可以在加载前使用。

您可以通过以下方式显示当前使用的网址:

print(container.persistentStoreCoordinator.persistentStores.first!.url!)

更新的NSPersistentContainer创建代码

var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "ELModel")

    let storeURL = container.persistentStoreDescriptions.first!.url!
    let description = NSPersistentStoreDescription(url: storeURL)

    container.persistentStoreDescriptions = [description]
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            print("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()