代码之家  ›  专栏  ›  技术社区  ›  spogebob92

CoreData+Codable不保存

  •  1
  • spogebob92  · 技术社区  · 7 年前

    我正试图提取一些数据并将其存储在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数据库。就像它的温度节省。

    更新: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 回复  |  直到 7 年前
        1
  •  2
  •   Fabian    7 年前

    NSPersistentStoreDescription() 创建一个空描述,其中甚至没有设置存储URL。使用 NSPersistentStoreDescription(url:) 相反。

    你可以用 container.persistentStoreDescriptions.first!.url! 以获取默认url,该url正在初始化为 NSPersistentStoreContainer(_)

    您可以使用以下选项显示当前使用的url:

    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
    }()