如何将现有对象保存到核心数据 [英] How to save existing objects to Core Data

查看:53
本文介绍了如何将现有对象保存到核心数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在从事一个项目,并且正在使用一个现有对象。我试图找到一种简单的方法来保存,检索和删除Core Data中的这些对象的列表。



这是我的对象

  import Foundation 

class书籍:可编码{

var coverIndex:Int?
var authorName:[String]?
var title:字符串?
var editionCount:Int?
var firstPublishYear:Int?
var键:字符串?
var publishPlace:[String]吗?
var Publisher:[String]?

公共枚举BookResponseCodingKeys:字符串,CodingKey {
case coverIndex = cover_i
case authorName = author_name
case editionCount = edition_count
case firstPublishYear = first_publish_year
case key =键
case title =标题
case publishPlace = publish_place
case Publisher =发布者
}

公开要求的init(来自解码器:Decoder)抛出{

let container = try encoder.container(keyedBy:BookResponseCodingKeys.self)

self.coverIndex =尝试container.decodeIfPresent(Int.self,forKey:.coverIndex)
self.authorName =试试container.decodeIfPresent([String] .self,forKey:.authorName)
self.editionCount =尝试container.decodeIfPresent(Int.self,forKey:.editionCount)
self.firstPublishYear =尝试container.decodeIfPresent(Int.self,forKey:.firstPublishYear)
self.key =尝试container.decodeIfPresent(String.self,forKey:.key)
self.title =尝试container.decodeIfPresent(String.self,forKey:.title)
self.publishPlace =尝试容器.decodeIfPresent([String] .self,forKey:.publishPlace)
self.publisher =试试container.decodeIfPresent([String,.self,forKey:.publisher)
}
}

最简单的方法是将其保存在Core Data中(或将其映射到Core Data模型)。

解决方案

在您的 xcdatamodeld 中定义一个实体,例如用户





添加具有可转换类型的属性。将其命名为书。





使用以下代码从当前上下文中获取当前数组。这些方法应该放在某种DataManager类中(应该是单例):

  import CoreData 

开放类DataManager:NSObject {

public static let sharedInstance = DataManager()

私有替代init(){}

//帮助器用于获取当前上下文的func。
private func getContext()-> NSManagedObjectContext? {
后卫让appDelegate = UIApplication.shared.delegate为? AppDelegate else {return nil}
return appDelegate.persistentContainer.viewContext
}

func restoreUser()-> NSManagedObject? {
guard letmanagedContext = getContext()else {return nil}
let fetchRequest = NSFetchRequest< NSFetchRequestResult>(实体名称:用户)

做{
let结果=试试managedContext.fetch(fetchRequest)! [NSManagedObject]
,如果result.count> 0 {
//假设应用中将永远只有一个用户。
return result [0]
} else {
return nil
}
} catch let error as NSError {
print( Retrieiving user failed。\ \(error):\(error.userInfo))
return nil
}
}

func saveBook(_ book:Book){
print(NSStringFromClass(type(of:book)))
保护让managedContext = getContext()否则{返回}
保护让用户= resolveUser()否则{返回}

var书籍:[book] = []
如果让pastBooks = user.value(forKey: books)为? [图书] {
本书+ = pastBooks
}
books.append(book)
user.setValue(books,forKey: books)

做{
print( Saving session ...)
trymanagedContext.save()
} catch let error as NSError {
print( Failed to save session data !\(error):\(error.userInfo))
}
}

}

您还需要一种创建用户的方法(并且可能要删除,假设我们要遵循CRUD)。首先,您需要获取对用户实体的引用才能创建一个。此定义应该在DataManager类的顶部。

 扩展DataManager {
private lazy var userEntity:NSEntityDescription = {
让managedContext = getContext()
返回NSEntityDescription.entity(forEntityName: User,位于:managedContext!)!
}()
}

然后实现此功能以创建一个。

 扩展名DataManager {
///用新的起始数据创建一个新用户。
func createUser(){
后卫让managedContext = getContext()否则{返回}
let user = NSManagedObject(entity:userEntity,insertInto:managedContext)

做{
trymanagedContext.save()
}将let错误捕获为NSError {
print(无法保存新用户!\(error):\(error.userInfo))
}
}
}

现在只需致电:



DataManager.sharedInstance.createUser()



创建一个新用户。
然后,将书追加到用户的存储中:



DataManager.sharedInstance.saveBook(book)


I have been working on a project and have an existing object I am using. I am trying to find a simply way to save, retrieve and delete a list of these objects in Core Data.

Here is my object

import Foundation

class Book : Codable {

    var coverIndex:Int?
    var authorName:[String]?
    var title:String?
    var editionCount:Int?
    var firstPublishYear:Int?
    var key: String?
    var publishPlace:[String]?
    var publisher:[String]?

    public enum BookResponseCodingKeys: String, CodingKey {
        case coverIndex = "cover_i"
        case authorName = "author_name"
        case editionCount = "edition_count"
        case firstPublishYear = "first_publish_year"
        case key = "key"
        case title = "title"
        case publishPlace = "publish_place"
        case publisher = "publisher"
    }

    public required init(from decoder: Decoder) throws {

        let container = try decoder.container(keyedBy: BookResponseCodingKeys.self)

        self.coverIndex = try container.decodeIfPresent(Int.self, forKey: .coverIndex)
        self.authorName = try container.decodeIfPresent([String].self, forKey: .authorName)
        self.editionCount = try container.decodeIfPresent(Int.self, forKey: .editionCount)
        self.firstPublishYear = try container.decodeIfPresent(Int.self, forKey: .firstPublishYear)
        self.key = try container.decodeIfPresent(String.self, forKey: .key)
        self.title = try container.decodeIfPresent(String.self, forKey: .title)
        self.publishPlace = try container.decodeIfPresent([String].self, forKey: .publishPlace)
        self.publisher = try container.decodeIfPresent([String].self, forKey: .publisher)
    }
}

What is the most straightforward to save this in Core Data (or to map it to a Core Data model.)

解决方案

In your xcdatamodeld define an entity, such as User:

Add an attribute with a Transformable type. Name it 'books'.

Next, set the Transformable attribute's class to an array of Book. In the Custom Class field below.

Use the following code to get the current array from your current context. These methods should go in some sort of DataManager class (which should be a singleton):

import CoreData

open class DataManager: NSObject {

    public static let sharedInstance = DataManager()

    private override init() {}

    // Helper func for getting the current context.
    private func getContext() -> NSManagedObjectContext? {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return nil }
        return appDelegate.persistentContainer.viewContext
    }

    func retrieveUser() -> NSManagedObject? {
        guard let managedContext = getContext() else { return nil }
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "User")

        do {
            let result = try managedContext.fetch(fetchRequest) as! [NSManagedObject]
            if result.count > 0 {
                // Assuming there will only ever be one User in the app.
                return result[0]
            } else {
                return nil
            }
        } catch let error as NSError {
            print("Retrieiving user failed. \(error): \(error.userInfo)")
           return nil
        }
    }

    func saveBook(_ book: Book) {
        print(NSStringFromClass(type(of: book)))
        guard let managedContext = getContext() else { return }
        guard let user = retrieveUser() else { return }

        var books: [Book] = []
        if let pastBooks = user.value(forKey: "books") as? [Book] {
            books += pastBooks
        }
        books.append(book)
        user.setValue(books, forKey: "books")

        do {
            print("Saving session...")
            try managedContext.save()
        } catch let error as NSError {
            print("Failed to save session data! \(error): \(error.userInfo)")
        }
    }

}

You'll also need a method to create a user (and likely delete, assuming we want to follow CRUD). First, you'll need to grab a reference to the User Entity to create one. This definition should be at the top of your DataManager class.

extension DataManager {
    private lazy var userEntity: NSEntityDescription = {
        let managedContext = getContext()
        return NSEntityDescription.entity(forEntityName: "User", in: managedContext!)!
    }()
}

And then implement this function to create one.

extension DataManager {
    /// Creates a new user with fresh starting data.
    func createUser() {
        guard let managedContext = getContext() else { return }
        let user = NSManagedObject(entity: userEntity, insertInto: managedContext)

        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Failed to save new user! \(error): \(error.userInfo)")
        }
    }
}

Now just call:

DataManager.sharedInstance.createUser()

to create a new user. Then, to append books to the user's storage:

DataManager.sharedInstance.saveBook(book)

这篇关于如何将现有对象保存到核心数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆