使用 CoreData 以编程方式创建实体/表并在 Swift 3 for iOS 中将值插入该实体

mac*_*mac 4 entity core-data ios swift

我一直在寻找一种方法,可以在运行时在 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 {

    }
Run Code Online (Sandbox Code Playgroud)

我在结果中得到以下值-:

? 1 个元素 - 0 :(实体:TestEntity;id:0x600000422f80;数据:{columnOne =“为什么这么严重?”;})

但是我没有任何方法可以从其他任何地方的实体中获取值,也无法通过使用实体名称(在本例中为TestEntity)将值从其他地方插入到实体中。

Tom*_*ton 5

您描述的某些步骤在 Core Data 中根本无法实现。或者至少,这会让事情变得极其复杂和困难。要求完整的工作代码是不合理的,因为您对 Core Data 有一组极其不寻常和复杂的要求。

确实,NSManagedModel实体和所有实体都是可变的,可以在代码中更改。但是,在使用该模型加载任何数据之前,必须进行所有这些更改。在您调用loadPersistentStores(_:)(如果您使用NSPersistentContainer)或addPersistentStore(ofType:configurationName:at:options:)(如果您不使用NSPersistentContainer)之后,您将无法进行更改。这样做会导致应用程序崩溃的运行时错误。

因此,提供用户界面来动态创建和删除 Core Data 实体的想法并不是一个真正的选择。您可以创建和删除实体的实例,但不能创建和删除实体描述。

如果你愿意做很多艰苦的工作,你可能会接近一些。使用 Core Data 最接近的方法是在任何需要更改时创建一个全新的托管对象模型。然后使用此模型将所有数据复制到新的持久存储文件(包括处理非轻量级迁移所需的任何自定义代码)。然后删除旧模型和持久存储文件以及对您之前使用它们获取的所有对象的所有引用。

这将很难做到正确,并且可能会有我没有想到的不可预见的困难。我强烈建议不要尝试使用 Core Data 来执行此操作,因为它不是设计为以这种方式使用的。