بدءًا من البيانات الأساسية! صعب بكلمات بسيطة [الجزء 2]

في هذه المقالة ، أود أن أكشف المزيد من قدرات البيانات الأساسية. هذه المقالة هي استمرار . آمل حقًا أن أحصل على فكرة أن Core Data ليست واحدة من العديد من قواعد البيانات العلائقية ، ولكنها أداة قوية جدًا يمكن أن تصبح سلاحًا متكاملاً في ترسانة أي مطور IOS يحترم نفسه.

حسنًا ، لنبدأ!

ننظر اليوم في العمل مع اثنين من NSManageObjectContext و NSFetchedResultsController.

اثنان NSManageObjectContext ولماذا هذا مطلوب؟


إذا كان تطبيقك يستخدم بنشاط أي واجهة برمجة تطبيقات يتلقى من خلالها البيانات ، وتريد حفظ هذه البيانات في مكان ما ، فإن البيانات الأساسية هي خيار ممتاز. ما المشاكل التي قد تواجهها في هذا؟ الأول والأكثر وضوحًا - ستكون كمية البيانات كبيرة جدًا لدرجة أنه عندما تحاول حفظها ، سيتجمد تطبيقنا لبعض الوقت ، مما سيؤثر على تجربة المستخدم. لا يمكن الاستغناء عن GCD العادي هنا ، حيث تعمل مجموعة البيانات الأساسية الخاصة بنا ، والتي تم ذكرها هنا بشكل متزامن وبشكل مستقل ومن أجل أي وصول إلى NSManageObjectContext ، سيتعين علينا الانتظار حتى نهاية الحلقة.

ولكن هنا يأتي NSManageObjectContext الخاص الذي يعمل في موضوع الخلفية إلى الإنقاذ. للاتصال به ، يجب عليك أولاً الاتصال بـ NSPersistentContainer.

ستبدو التهيئة بالشكل التالي:

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "Preset")
    container.loadPersistentStores { (persistent, error) in
        if let error = error {
            fatalError("Error: " + error.localizedDescription)
        }
    }
    container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
    container.viewContext.shouldDeleteInaccessibleFaults = true
    container.viewContext.automaticallyMergesChangesFromParent = true
    return container
}()

Mergepolicy


هنا يمكنك تحديد سياسة الدمج الخاصة بنا NSManageObjectContext. نوضح هنا صراحة كيف يجب أن تتصرف البيانات الأساسية في حالة وجود تعارض في البيانات.

خيارات MergePolicy:

  1. NSRollbackMergePolicy - في حالة وجود تعارض ، يتجاهل كل التغييرات حتى يحدث
  2. NSOverwriteMergePolicy - يحفظ القيم الجديدة بغض النظر عن البيانات
  3. NSMergeByPropertyStoreTrumpMergePolicy - يحفظ خاصية الكائنات المتغيرة حسب الخاصية ، في هذه الحالة ، ستسود البيانات المحفوظة
  4. NSMergeByPropertyObjectTrumpMergePolicy - يحفظ خاصية الكائنات المتغيرة حسب الملكية ، وفي هذه الحالة ستسود البيانات الجديدة

AutomaticallyMergesChangesFromParent - يوضح ما إذا كان سياقنا سيدمج البيانات تلقائيًا.
ثم قم بإنشاء سياق جديد:

let context = persistentContainer.viewContext
let context = persistentContainer.newBackgroundContext()

الآن لدينا NSManageObjectContext. الأول للعمل مع واجهة المستخدم ويعمل على مؤشر الترابط الرئيسي ، والثاني لديه privateQueueConcurrencyType للعمل في الخلفية.

سنستخدمه لتنزيل البيانات.

let object = NSEntityDescription.insertNewObject(forEntityName: "Name", into: context)
saveChanges(with: context)

هنا ننشئ كياننا وبعد ذلك يمكننا تعيين الخصائص اللازمة له ، وبعد ذلك نسمي طريقة الحفظ ، يبدو كما يلي:

func saveChanges(with context: NSManagedObjectContext) {
        context.performAndWait {
            if context.hasChanges {
                do {
                    try context.save()
                } catch {
                    context.rollback()
                }
            }
            context.reset()
        }
    }

هناك طريقتان للاختيار من بينهما:

  • PerformAndWait - يقوم بتنفيذ الإجراءات على مؤشر ترابط السياق بشكل متزامن
  • تنفيذ - تنفيذ إجراءات على دفق السياق بشكل غير متزامن


NSFetchedResultsController


NSFetchedResultsController - وحدة تحكم تقوم بتنفيذ طلبات معينة وتعرض البيانات الضرورية للمستخدم.

lazy var fetchedResultsController: NSFetchedResultsController<Pack> = {
        let fetchRequest = NSFetchRequest<Pack>(entityName:"Pack")
        fetchRequest.fetchBatchSize = 20
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending:true)]
        let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

        controller.delegate = self
        do {
            try controller.performFetch()
        } catch {
            print(error.localizedDescription)
        }
        return controller
    }()

يحتوي NSFetchedResultsController على عدد كبير جدًا من التكوينات ، وسنقوم بتحليل اثنين منها:

الجلب
FetchLimit —

Sketchoffset
FetchOffset — . 2, .

حجم الجلب
FetchBatchSize — . Table/CollectionView 5 , 7 , .

حجم الجلب
FetchBatchSize — .

SortDescriptor
SortDescriptor — , .

ReturnsObjectsAsFaults
ReturnsObjectsAsFaults — , , , PersistentStore RawCache

في الوقت الحالي ، لدينا NSFetchedResultsController الذي يجب أن يعرض بياناتنا في جدول. لتحديث البيانات ، تحتاج إلى استدعاء طريقة التفويض:

extension ViewController: NSFetchedResultsControllerDelegate {
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
       collectionView.reloadData()
    }
}

يعمل أسلوب التفويض هذا عندما يكون لدينا أي تغييرات في سياقنا. في هذا التطبيق ، يحدث هذا بعد حفظ البيانات في نص خاص. في هذه اللحظة ، يتم تشغيل طريقة التفويض ويتم تحديث البيانات.

مجرد اثنين من الإجراءات والبيانات الأساسية من قاعدة بيانات منتظمة تتحول إلى سلاح قوي من أي مطور iOS.

الترميز سعيدة!

All Articles