CoreData-Modell aus dem Code. Oder „Wie man auf .XCDataModel verzichtet“ (Teil 1)

Wenn Ihnen das Erstellen eines CoreData-Modells mithilfe der Xcode-Benutzeroberfläche aus irgendeinem Grund nicht gefällt oder Sie ein ebenso verrückter Programmierer sind, wie ich möchte, dass Ihre Anwendung .XCDataModel-Dateien entfernt und etwas schneller ausgeführt wird, können Sie sich bei cat.


Kurzer Hintergrund


Vor ungefähr einem halben Jahr habe ich meine eigene Anwendung für iOS entwickelt. Bis vor kurzem verlief der Entwicklungsprozess reibungslos und ohne Probleme im Bereich der Datenspeicherung.


In letzter Zeit ist das coreData-Modell auf Größen angewachsen, die aus meiner Sicht unanständig sind. Da ich blind bin und es physisch schwierig ist, mit einer großen Menge halbvisueller Daten zu arbeiten, habe ich beschlossen, alles, was coreData betrifft, in Code zu übertragen.


Es gibt sehr wenig Material zur "nicht-visuellen" Arbeit mit coreData, daher basiert die Hälfte meiner Schlussfolgerungen und Entwicklungen auf wahnsinnigen Experimenten auf Spielplätzen und nicht weniger wahnsinnigen Versuchen, fehlende Informationen zu googeln.


Im Allgemeinen lass uns gehen!


Beginnen wir mit dem Unterricht.


Wenn wir in der Standardarbeit mit coreData alle Entitäten und die Beziehungen zwischen ihnen in einer separaten Datei mit dem Modell beschreiben, benötigen wir in unserem Fall Klassen, die diese Entitäten zuerst beschreiben (es ist einfacher zu verstehen, mit was wir arbeiten, und Xcode hilft). Aufforderung zur Eingabe der Namen bereits erstellter Klassen).


Übrigens werden wir unten am Ende jeder Klasse ein seltsames Nachskript verwenden, "MO" - Managed Object. Dies ist nicht mit anderen, möglicherweise ähnlichen Klassen zu verwechseln, bezieht sich jedoch nicht auf coreData.


Wir werden die folgende Situation beschreiben:


  • Es gibt eine Firma (beschrieben von der Klasse CompanyMO);
  • Es gibt Mitarbeiter (beschrieben von der WorkerMO-Klasse);
  • Jeder Mitarbeiter kann nur in einem Unternehmen arbeiten (oder überhaupt nicht).
  • Jedes Unternehmen kann eine beliebige Anzahl von Mitarbeitern haben (einschließlich überhaupt keiner Mitarbeiter).

@objc(CompanyMO)
public class CompanyMO: NSManagedObject {
@NSManaged public var companyName: String
@NSManaged public var workers: NSSet
}

@objc(WorkerMO)
public class WorkerMO: NSManagedObject {
@NSManaged public var firstname: String
@NSManaged public var lastname: String
@NSManaged public var company: CompanyMO?
}

.


objc() — , , .


objc(CompanyMO) CompanyMO , CompanyMO Objective-C CompanyMO. objc(NameOfClass) Objective-C.


— @NSManaged .


@NSManaged , , . , ( Apple, ), @NSManaged coreData.



— , .


, , extension .


extension NSEntityDescription {
convenience init(from classType: AnyClass) {
self.init()
self.name = NSStringFromClass(classType)
self.managedObjectClassName = NSStringFromClass(classType)
}

func addProperty(_ property: NSPropertyDescription) {
self.properties.append(property)
}
}

extension NSAttributeDescription {
convenience init(name: String, ofType: NSAttributeType, isOptional: Bool = false) {
self.init()
self.name = name
self.attributeType = ofType
self.isOptional = isOptional
}
}

.


NSEntityDescription — coreData, (, ). ( , ) (managedObjectClassName), , (, — CompanyMO, WorkerMO ).


, :


let company = NSEntityDescription()
company.name = "CompanyMO"
company.managedObjectClassName = "CompanyMO"

, , NSEntityDescription. , :


let company = NSEntityDescription(from: CompanyMO.self)
let worker = NSEntityDescription(from: WorkerMO.self)

, , .



( , ), .


var model: NSManagedObjectModel {
let _model = NSManagedObjectModel()

let companyEntity = NSEntityDescription(from: CompanyMO.self)
companyEntity.addProperty(NSAttributeDescription(name: "companyName", ofType: .stringAttributeType))
//      CompanyMO.workers,         
let workerEntity = NSEntityDescription(from: WorkerMO.self)
workerEntity.addProperty(NSAttributeDescription(name: "firstname", ofType: .stringAttributeType))
workerEntity.addPropertyNSAttributeDescription((name: "lastname", ofType: .stringAttributeType))

_model.entities = [companyEntity, workerEntity]
return _model
}

.


NSManagedObjectModel entities, NSEntityDescription.


NSManagedObjectModel.entities: [NSEntityDescription]

NSEntityDescription . , , - . , , .


NSEntityDescription , companyEntity workerEntity companyEntity.properties workerEntity.properties, NSPropertyDescription.


NSPropertyDescription NSAttributeDescription ( , , ) NSRelationshipDescription ( ).


NSRelationshipDescription .


, :


  1. CompanyMO WorkerMO;
  2. , . companyEntity companyName ( workers ), workerEntity firstname lastname.
  3. entities "" .

.


.



NSPersistentStore NSPersistentStoreCoordinator NSPersistentContainer (, . ).


coreData .


, ( ) .


persistentContainer .


lazy var persistentContainer: NSPersistentContainer {
let _container = NSPersistentContainer(name: "CyrmaxModel", managedObjectModel: model)
_container.loadPersistentStores {
(description, error) in
//  ,  -
}
return _container
}

, ( ) , .


persistentContainer coreData , .



  1. , ;
  2. (- - , );
  3. ( , "?", ).


, , , , , .


, .


, .


WorkerMO, .


@objc(WorkerMO)
public class WorkerMO: NSManagedObject {
@NSManaged public var firstname: String
@NSManaged public var lastname: String

static private var _entityDescription: NSEntityDescription?
static func entityDescription() -> NSEntityDescription {
guard self._entityDescription == nil else {
return _entityDescription!
}
let des = NSEntityDescription(from: self)
des.addProperty(NSAttributeDescription(name: "firstname", ofType: .stringAttributeType))
des.addProperty(NSAttributeDescription(name: "lastname", ofType: .stringAttributeType))
self._entityDescription = des
return self._entityDescription!
}
}

CompanyMO ( ).


.


_entityDescription , ?


, NSRelationshipDescription .


, , CompanyMO.entityDescription() NSEntityDescription, .



coreData- — . , . ( , StoryBoard, ), .


- , , StoryBoard, XCDataModel.



  1. NSManagedObjectModel;
  2. NSEntityDescription;
  3. NSPropertyDescription NSAttributeDescription;
  4. Optional, aber Sie können immer noch Informationen zu NSPersistentContainer und seinem Initialisierer (Name: manageObjectModel :) lesen .

All Articles