我一直在从事一个项目,并且正在使用一个现有的对象。我试图找到一种简单的方法来保存,检索和删除Core Data中的这些对象的列表。
这是我的对象
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)
}
}
将其保存到Core Data(或将其映射到Core Data模型)最直接的方法是
答案 0 :(得分:2)
在您的xcdatamodeld
中定义一个实体,例如User
:
添加具有可转换类型的属性。将其命名为“书”。
接下来,将Transformable属性的类设置为Book数组。在下面的Custom Class
字段中。
使用以下代码从当前上下文中获取当前数组。这些方法应该放在某种DataManager类中(应该是单例):
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)")
}
}
}
您还需要一种创建用户的方法(假设我们要遵循CRUD,则有可能删除)。首先,您需要获取对用户实体的引用才能创建一个。此定义应位于DataManager类的顶部。
extension DataManager {
private lazy var userEntity: NSEntityDescription = {
let managedContext = getContext()
return NSEntityDescription.entity(forEntityName: "User", in: managedContext!)!
}()
}
然后实现此功能以创建一个。
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)")
}
}
}
现在只需致电:
DataManager.sharedInstance.createUser()
创建一个新用户。 然后,将书籍添加到用户的存储中:
DataManager.sharedInstance.saveBook(book)
答案 1 :(得分:0)
这取决于您要如何使用对象。您可以从NSManagedObject继承对象,也可以从包含对象数据到类的NSManagedObject建立映射。
如果您不会从NSManagedObject继承对象,则可以使用如下代码:
func save(bookObject: Book, in container: NSPersistentContainer) -> NSManagedObject {
container?.performBackgroundTask { context in
do {
// Create NSManagedObject backed object
let bookEntity = BookEntity(context: context)
bookEntity.coverIndex = bookObject.coverIndex
// And all the rest properties
try context.save()
} catch (let error) {
print(error)
return
}
}
}