我一直在尝试找到一种在Swift 3 for iOS平台上以编程方式在运行时创建数据库实体/表的方法。 请详细说明这个过程。我已经关注了其他链接,但没有任何对我有用,我无法正确理解该过程,因此请使用工作代码解释整个过程,而不是提供其他现有链接。
还有一个表已从XCode添加,我可以在该表上执行与数据库相关的操作(插入行,删除,更新),但我无法找到对其执行以下操作的方法将在运行时以编程方式创建的表。 需要执行以下操作。
添加实体 - 从界面,用户可以添加实体名称,列数,列名称,然后点击按钮,使用CoreData将实体创建到数据库中。用户可以从界面添加任意数量的表。
插入值 - 然后,用户将拥有将值插入实体的界面。将知道实体的名称,并且用户将输入实体中行的值。在点击按钮时,该行应插入实体/数据库表中。
获取值 - 用户可以选择从实体中获取所有已保存的值。在需要的时候随时使用它们。
更新值用户将能够更新以编程方式创建的表格中的任何值。
删除实体 - 还可以选择删除数据库实体。点击按钮时,实体名称将传递给该函数,该实体/数据库表将从数据库中删除。
我尝试了以下代码 - :
let model = NSManagedObjectModel()
let entityName = "TestEntity"
let entity = NSEntityDescription()
entity.name = entityName
entity.managedObjectClassName = entityName
// Creating a attribute
let remoteURLAttribute = NSAttributeDescription()
remoteURLAttribute.name = "columnOne"
remoteURLAttribute.attributeType = .stringAttributeType
remoteURLAttribute.isOptional = true
remoteURLAttribute.isIndexed = true
var properties = Array<NSAttributeDescription>()
properties.append(remoteURLAttribute)
// Adding the attribute to the entity
entity.properties = properties
// Adding the entity into the model
model.entities = [entity]
do {
try CoreDataManager.managedObjectContext.save()
} catch {
print(error)
}
// Inserting the data into the entity
let testEntity = NSManagedObject(entity: entity, insertInto: CoreDataManager.managedObjectContext)
testEntity.setValue("WHY SO SERIOUS?", forKey: "columnOne")
do {
try CoreDataManager.managedObjectContext.save()
} catch {
print(error)
}
// Fetching the data from the entity
let request = NSFetchRequest<NSFetchRequestResult>()
request.entity = entity
request.propertiesToFetch = ["columnOne"]
request.returnsDistinctResults = false
do {
let results = try CoreDataManager.managedObjectContext.fetch(request)
print(results)
} catch {
}
我在结果 -
中获得以下值▿1个元素 - 0 :(实体:TestEntity; id:0x600000422f80 ; 数据:{ columnOne =&#34;为什么如此严重?&#34 ;; })
但是我没有办法从其他任何地方获取此实体的值,并通过使用 TestEntity 中的实体名称将值插入到其他地方的实体中情况下。
答案 0 :(得分:4)
您描述的某些步骤对于Core Data来说根本不可能。或者至少,不是没有让你的事情变得非常非常复杂和困难。要求完整的工作代码是不合理的,因为您对Core Data有一组非常不寻常和复杂的要求。
NSManagedModel
和所有实体都是可变的,并且可以在代码中进行更改。但是,在使用该模型加载任何数据之前,必须必须进行所有这些更改。致电loadPersistentStores(_:)
后(如果您使用NSPersistentContainer
)或addPersistentStore(ofType:configurationName:at:options:)
(如果您未使用NSPersistentContainer
),则无法进行更改。这样做是一个运行时错误,会导致您的应用崩溃。
因此,提供动态创建和删除核心数据实体的用户界面的想法实际上并不是一种选择。您可以创建和删除实体的实例,但不能创建实体描述。
如果你愿意做很多努力,你可能会得到一些接近的东西。您可以使用Core Data获得的最接近的是在您需要更改时创建一个全新的托管对象模型。然后使用此模型将所有数据复制到新的持久性存储文件(包括处理非轻量级迁移所需的任何自定义代码)。然后删除旧模型和持久性存储文件以及对先前使用它们提取的所有对象的所有引用。
这将很难做到正确,并且可能会遇到我未曾想到的无法预料的困难。我强烈建议不要尝试使用Core Data,因为它不是以这种方式使用的。