gpt4 book ai didi

ios - 将数组保存到 CoreData Swift

转载 作者:搜寻专家 更新时间:2023-10-31 08:14:34 25 4
gpt4 key购买 nike

我想用 Core Data 保存这种数组:

let crypto1 = Cryptos(name: "Bitcoin", code: "bitcoin", symbol: "BTC", placeholder: "BTC Amount", amount: "0.0")
let crypto2 = Cryptos(name: "Bitcoin Cash", code: "bitcoinCash", symbol: "BCH", placeholder: "BCH Amount", amount: "0.0")

这可能吗?

我知道我可以创建一个数组来保存...

let name = "Bitcoin"
let code = "bitcoin"
let symbol = "BTC"
let placeholder = "BTC Amount"
let amount = "0.0"
let cryptos = CryptoArray(context: PersistenceService.context)
cryptos.name = name
cryptos.code = code
cryptos.symbol = symbol
cryptos.placeholder = placeholder
cryptos.amount = amount
crypto.append(cryptos)
PersistenceService.saveContext()

...但是当用户创建理论上无限数量的数组时,这似乎很不方便。

保存数据、加载数据、编辑数据和删除数据的最佳方式是什么?

最佳答案

这是一个针对教程的问题,而不是一个直接的答案。我建议您花一些时间阅读有关 CoreData 的内容。话虽如此,您的问题听起来很笼统,“在 Swift 中将数组保存到 CoreData”,所以我想逐步解释一个简单的实现并没有什么坏处:

第 1 步:创建模型文件 (.xcdatamodeld)

在Xcode中,file - new - file - iOS 然后选择Data Model

第 2 步:添加实体

在 Xcode 中选择文件,找到并点击 Add Entity,为你的实体命名(CryptosMO 跟随),点击 Add Attribute 并添加您要存储的字段。 (在本例中,name、code、symbol... 都是 String 类型)。为了方便起见,我将忽略除 name 之外的所有其他内容。

第 3 步生成这些实体的对象表示 (NSManagedObject)

在 Xcode 中,Editor - Create NSManagedObject subclass 并按照步骤操作。

第 4 步让我们创建这个子类的克隆

NSManagedObject 不是线程安全的,所以让我们创建一个可以安全传递的结构:

struct Cryptos {
var reference: NSManagedObjectID! // ID on the other-hand is thread safe.

var name: String // and the rest of your properties
}

第 5 步:CoreDataStore

让我们创建一个商店,使我们能够访问 NSManagedObjectContext:

class Store {
private init() {}
private static let shared: Store = Store()

lazy var container: NSPersistentContainer = {

// The name of your .xcdatamodeld file.
guard let url = Bundle().url(forResource: "ModelFile", withExtension: "momd") else {
fatalError("Create the .xcdatamodeld file with the correct name !!!")
// If you're setting up this container in a different bundle than the app,
// Use Bundle(for: Store.self) assuming `CoreDataStore` is in that bundle.
}
let container = NSPersistentContainer(name: "ModelFile")
container.loadPersistentStores { _, _ in }
container.viewContext.automaticallyMergesChangesFromParent = true

return container
}()

// MARK: APIs

/// For main queue use only, simple rule is don't access it from any queue other than main!!!
static var viewContext: NSManagedObjectContext { return shared.container.viewContext }

/// Context for use in background.
static var newContext: NSManagedObjectContext { return shared.container.newBackgroundContext() }
}

Store 使用您的 .xcdatamodeld 文件设置持久容器。

第 6 步:获取这些实体的数据源

Core Data 带有 NSFetchedResultsController 以从允许广泛配置的上下文中获取实体,这里是使用此 Controller 支持数据源的简单实现。

class CryptosDataSource {

let controller: NSFetchedResultsController<NSFetchRequestResult>
let request: NSFetchRequest<NSFetchRequestResult> = CryptosMO.fetchRequest()

let defaultSort: NSSortDescriptor = NSSortDescriptor(key: #keyPath(CryptosMO.name), ascending: false)

init(context: NSManagedObjectContext, sortDescriptors: [NSSortDescriptor] = []) {
var sort: [NSSortDescriptor] = sortDescriptors
if sort.isEmpty { sort = [defaultSort] }

request.sortDescriptors = sort

controller = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
}

// MARK: DataSource APIs

func fetch(completion: ((Result) -> ())?) {
do {
try controller.performFetch()
completion?(.success)
} catch let error {
completion?(.fail(error))
}
}

var count: Int { return controller.fetchedObjects?.count ?? 0 }

func anyCryptos(at indexPath: IndexPath) -> Cryptos {
let c: CryptosMO = controller.object(at: indexPath) as! CryptosMO
return Cryptos(reference: c.objectID, name: c.name)
}
}

我们只需要从此类的一个实例中获取对象的数量、count 和给定 indexPath 中的项目。请注意,数据源返回结构 Cryptos 而不是 NSManagedObject 的实例。

第 7 步:用于添加、编辑和删除的 API

让我们将此 api 添加为 NSManagedObjectContext 的扩展:但在此之前,这些操作可能会成功或失败,所以让我们创建一个枚举来反射(reflect)这一点:

enum Result {
case success, fail(Error)
}

API:

extension NSManagedObjectContext {

// MARK: Load data

var dataSource: CryptosDataSource { return CryptosDataSource(context: self) }

// MARK: Data manupulation

func add(cryptos: Cryptos, completion: ((Result) -> ())?) {
perform {
let entity: CryptosMO = CryptosMO(context: self)
entity.name = cryptos.name
self.save(completion: completion)
}
}

func edit(cryptos: Cryptos, completion: ((Result) -> ())?) {
guard cryptos.reference != nil else {
print("No reference")
return
}
perform {
let entity: CryptosMO? = self.object(with: cryptos.reference) as? CryptosMO
entity?.name = cryptos.name
self.save(completion: completion)
}
}

func delete(cryptos: Cryptos, completion: ((Result) -> ())?) {
guard cryptos.reference != nil else {
print("No reference")
return
}
perform {
let entity: CryptosMO? = self.object(with: cryptos.reference) as? CryptosMO
self.delete(entity!)
self.save(completion: completion)
}
}

func save(completion: ((Result) -> ())?) {
do {
try self.save()
completion?(.success)
} catch let error {
self.rollback()
completion?(.fail(error))
}
}
}

第 8 步:最后一步,用例

要获取主队列中存储的数据,请使用 Store.viewContext.dataSource。要添加、编辑或删除项目,请决定是否要使用 viewContext 在主队列中执行,或者使用 newContext 或从任意队列(甚至是主队列)执行Store 容器使用 Store.container.performInBackground... 提供的临时背景上下文,这将公开一个上下文。例如添加一个密码:

let cryptos: Cryptos = Cryptos(reference: nil, name: "SomeName")
Store.viewContext.add(cryptos: cryptos) { result in
switch result {
case .fail(let error): print("Error: ", error)
case .success: print("Saved successfully")
}
}

使用加密数据源的简单 UITableViewController:

class ViewController: UITableViewController {

let dataSource: CryptosDataSource = Store.viewContext.dataSource

// MARK: UITableViewDataSource

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableView.dequeueReusableCell(withIdentifier: "YourCellId", for: indexPath)
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cryptos: Cryptos = dataSource.anyCryptos(at: indexPath)
// TODO: Configure your cell with cryptos values.
}
}

关于ios - 将数组保存到 CoreData Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49076904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com