نموذج CoreData من التعليمات البرمجية. أو "كيفية الاستغناء عن .XCDataModel" (الجزء الأول)

إذا كنت لسبب ما لا ترغب في عملية إنشاء نموذج CoreData باستخدام واجهة المستخدم الرسومية Xcode ، أو أنك مبرمج مجنون كما أريد أن يتخلص تطبيقك من ملفات .XCDataModel وتشغيل أسرع قليلاً ، ثم مرحبًا بك.


خلفية موجزة


منذ حوالي نصف عام ، كنت أقوم بتطوير تطبيقي الخاص لـ iOS ، وحتى وقت قريب ، كانت عملية التطوير تتم بسلاسة ودون أي مشاكل في مجال تخزين البيانات.


ولكن في الآونة الأخيرة ، نما نموذج CoreData إلى أحجام غير لائقة من وجهة نظري ، وبما أنني عمياء ، فمن الصعب جسديًا العمل مع كمية كبيرة من البيانات شبه المرئية ، قررت نقل كل ما يتعلق ببيانات Core إلى التعليمات البرمجية.


هناك القليل جدًا من المواد حول العمل "غير المرئي" مع coreData ، لذا فإن نصف استنتاجاتي وتطوريات تستند إلى تجارب مجنونة في Playgrounds ومحاولات أقل جنونًا لمعلومات Google المفقودة.


بشكل عام ، دعنا نذهب!


لنبدأ بالفصول.


إذا قمنا أثناء العمل القياسي مع coreData بوصف جميع الكيانات والعلاقات بينها في ملف منفصل مع النموذج ، فسنحتاج في حالتنا إلى فئات تصف تلك الكيانات أولاً (سيكون من الأسهل فهم ما نعمل معه ، وسيساعد Xcode ، المطالبة بأسماء الفئات التي تم إنشاؤها بالفعل).


بالمناسبة ، سنستخدم لاحقًا ملحقًا غريبًا في نهاية كل فئة ، "MO" - كائن مُدار. هذا لا يجب الخلط بينه وبين الفئات الأخرى ، ربما مشابهة ، ولكن لا يتعلق بالبيانات الأساسية.


سنصف الحالة التالية:


  • هناك شركة (موصوفة في فئة CompanyMO) ؛
  • هناك موظفين (تم وصفهم بواسطة فئة WorkerMO) ؛
  • يمكن لكل موظف العمل في شركة واحدة فقط (أو لا يعمل على الإطلاق) ؛
  • يمكن لكل شركة أن يكون لديها أي عدد من الموظفين (بما في ذلك عدم وجود موظفين على الإطلاق).

@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. اختياري، ولكن لا يزال بإمكانك قراءة حول NSPersistentContainer وفي الحرف الأول (اسم: managedObjectModel :) مهيئ.

All Articles