Model CoreData dari kode. Atau "Bagaimana Melakukannya Tanpa .XCDataModel" (Bagian 1)

Jika karena alasan tertentu Anda tidak suka proses membuat model coreData menggunakan Xcode GUI, atau Anda adalah seorang programmer yang gila karena saya ingin aplikasi Anda menyingkirkan file .XCDataModel dan berjalan sedikit lebih cepat, selamat datang ke kucing.


Latar Belakang Singkat


Sekitar setengah tahun yang lalu saya telah mengembangkan aplikasi saya sendiri untuk iOS, dan sampai saat ini, proses pengembangan berjalan dengan lancar dan tanpa masalah di bidang penyimpanan data.


Namun baru-baru ini, model coreData telah berkembang ke ukuran yang tidak senonoh dari sudut pandang saya, dan karena saya buta, secara fisik sulit bagi saya untuk bekerja dengan sejumlah besar data semi-visual, saya memutuskan untuk mentransfer semua yang menyangkut coreData ke kode.


Ada sangat sedikit materi tentang pekerjaan "non-visual" dengan coreData, jadi setengah dari kesimpulan dan perkembangan saya didasarkan pada eksperimen gila di Playgrounds dan upaya yang tidak kalah gila untuk google menghilangkan informasi.


Secara umum, ayo pergi!


Mari kita mulai dengan kelas.


Jika dalam pekerjaan standar dengan coreData kami menggambarkan semua entitas dan hubungan di antara mereka dalam file terpisah dengan model, maka dalam kasus kami, kami akan membutuhkan kelas yang menggambarkan entitas tersebut terlebih dahulu (akan lebih mudah untuk memahami apa yang sedang kami kerjakan, dan Xcode akan membantu, meminta nama kelas yang sudah dibuat).


Ngomong-ngomong, di bawah ini kita akan menggunakan catatan tambahan yang aneh di akhir setiap kelas, "MO" - Obyek yang Dikelola. Ini tidak menjadi bingung dengan kelas lain, mungkin mirip, tetapi tidak terkait dengan coreData.


Kami akan menggambarkan situasi berikut:


  • Ada perusahaan (dijelaskan oleh kelas CompanyMO);
  • Ada karyawan (dijelaskan oleh kelas WorkerMO);
  • Setiap karyawan hanya dapat bekerja di satu perusahaan (atau tidak bekerja sama sekali);
  • Setiap perusahaan dapat memiliki sejumlah karyawan (termasuk tidak ada karyawan sama sekali).

@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. Opsional, tetapi Anda masih dapat membaca tentang NSPersistentContainer dan initnya (nama: initializer managedObjectModel :) .

All Articles