ios - CoreData + Codable 不保存

标签 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)")
        }
    }
}

}

最佳答案

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

您可以使用container.persistentStoreDescriptions.first!.url!获取默认 url,该 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
}()

关于ios - CoreData + Codable 不保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52082117/

相关文章:

ios - 快速 bool 值

objective-c - [图像计数] : unrecognized selector sent to instance

ios - iTunesConnect 截图顺序困惑

ios - UIView 动画 - 展开时意外发现 nil

iOS为图片创建唯一标识符

swift - 如何在 Realm 中建模 3 个模型之间的关系?

ios - 如何处理核心数据保存错误?

ios - Xcode UI 不显示我创建的核心数据实体

ios - 表格 View 单元格不需要多余的分隔线

iphone - 在构建和提交到应用程序商店时使用代码签名有什么区别?