NSFilePresenter: ما هو، بروتوكول NSFileCoordinator وطرق التتبع

المؤلف: IT Sectr نُشر: 2026-07-12 وقت القراءة: 7 دق

NSFilePresenter هو بروتوكول Foundation يسمح للكائن بتلقي إشعارات حول تغييرات الملفات والدلائل في نظام ملفات iOS وmacOS. يقوم الفصل بتنفيذ طرق البروتوكول والتسجيل عبر NSFileCoordinator، وبعد ذلك يستدعي النظام تلقائياً هذه الطرق أثناء أي عمليات مع الملف المتتبع. وفقاً لوثائق مطوري Apple (2025)، يُستخدم NSFilePresenter في التطبيقات ذات الوصول متعدد الخيوط إلى المستندات لمنع تعارضات الكتابة. يجب استخدام البروتوكول بالتزامن مع NSFileCoordinator — فقط بهذه الطريقة يتم ضمان تنسيق وصول آمن.

النقاط الرئيسية

  • NSFilePresenter — بروتوكول Foundation لتتبع تغييرات الملفات والدلائل في iOS وmacOS.
  • NSFileCoordinator — فئة مكملة إلزامية تدير الوصول وتستدعي طرق المفوض.
  • accommodatePresentedItemDeletion — طريقة لمعالجة حذف الملف المتتبع مع إمكانية الإلغاء.
  • presentedItemDidChange — تُستدعى عندما يتغير محتوى ملف أو دليل.
  • presentedItemURL — خاصية إلزامية تُرجع عنوان URL للملف المتتبع.

ما هو NSFilePresenter؟

NSFilePresenter هو بروتوكول Foundation مصمم لتتبع تغييرات الملفات والدلائل في أنظمة تشغيل Apple. يحدد البروتوكول مجموعة من الطرق التي ينفذها كائن المراقب لتلقي إشعارات أحداث نظام الملفات.

الغرض الرئيسي من البروتوكول هو توفير وصول آمن إلى الملفات في السيناريوهات متعددة الخيوط. في iOS وmacOS، يمكن لعمليات وخيوط متعددة الوصول في وقت واحد إلى نفس الملف عبر NSFileCoordinator، ويضمن NSFilePresenter حصول كل مشارك على أحدث حالة بيانات.

تم تضمين البروتوكول في Foundation منذ iOS 5.0 وmacOS 10.7. يُستخدم في التطبيقات التي تعمل مع المستندات وقواعد البيانات وأي ملفات قد يتم تعديلها في وقت واحد من مصادر مختلفة — على سبيل المثال، أثناء مزامنة iCloud أو التحرير التعاوني.

أين يُستخدم NSFilePresenter

التطبيقات المستندة إلى المستندات — المجال الرئيسي لاستخدام NSFilePresenter. التطبيقات التي تعمل مع UIDocument أو NSDocument تسجل نفسها تلقائياً كمقدمين عبر NSFileCoordinator. يتيح ذلك معالجة التعارضات بشكل صحيح عند تحرير نفس الملف من نوافذ أو أجهزة متعددة.

مزامنة iCloud — السيناريو الرئيسي الثاني. عندما يتم تعديل ملف على جهاز واحد، يقوم iCloud بمزامنته عبر جميع الأجهزة المتصلة. يُعلم NSFilePresenter التطبيق بهذه التغييرات، مما يسمح بتحديث الواجهة في الوقت المناسب.

المحررات متعددة الخيوط — السيناريو الثالث. في التطبيقات حيث تقوم قوائم الخلفية بتحميل وحفظ البيانات بالتزامن مع عمل المستخدم، يمنع NSFilePresenter حالات التسابق أثناء كتابة وقراءة الملفات.

كيف يعمل NSFilePresenter؟

آلية العمل لـ NSFilePresenter تعتمد على نموذج التفويض: يقوم الكائن بتنفيذ طرق البروتوكول، والتسجيل عبر NSFileCoordinator، ويتلقى استدعاءات كلما تغير الملف المتتبع. يحدد النظام نفسه متى يحدث التغيير وأي الطرق يجب استدعاؤها.

تبدأ العملية عندما يقوم الكائن بإنشاء مثيل لـ NSFileCoordinator واستدعاء طريقة المنسق، وتمرير عنوان URL للملف. يتحقق المنسق مما إذا كان هناك أي مقدمين مسجلين لهذا العنوان. إذا كان الأمر كذلك، فإنه يحظر الوصول للقراءة أو الكتابة ويُعلم المقدمين بالتغيير القادم عبر طرق البروتوكول.

بعد اكتمال العملية، يحرر المنسق القفل ويستدعي الإشعارات النهائية. من المهم ملاحظة أن المقدم لا يتحكم في تدفق التنفيذ — بل يتفاعل فقط مع الأحداث. NSFileCoordinator مسؤول بالكامل عن التنسيق.

دورة حياة الإشعار

مرحلة التحضير — قبل تنفيذ العملية، يستدعي المنسق accommodatePresentedItemDeletion أو accommodatePresentedSubitemDeletion. يمكن للمقدم معالجة الموقف أو إلغاء العملية بإرجاع خطأ. تسمح هذه المرحلة للتطبيق بإنهاء العمل مع الملف بشكل صحيح قبل تعديله.

مرحلة الإشعار — بعد اكتمال العملية، يستدعي المنسق presentedItemDidChange أو presentedSubitemDidChange. يتلقى المقدم إشارة بأن الملف قد تغير ويمكنه إعادة قراءة محتوياته. لنقل الملف، يُستدعى presentedItemDidMoveToURL مع الموقع الجديد.

مرحلة الإكمال — يحرر المنسق جميع الأقفال والموارد. يمكن للمقدم مواصلة العمل مع البيانات المحدثة. جميع المراحل الثلاث تُنفذ بشكل متزامن في خيط واحد، لذلك يجب أن تنفذ طرق البروتوكول بسرعة دون عمليات إدخال/إخراج طويلة.

الطرق الرئيسية للبروتوكول

يحتوي بروتوكول NSFilePresenter على عدة طرق إلزامية واختيارية. الخاصية الإلزامية الوحيدة هي presentedItemURL، التي تُرجع عنوان URL للملف أو الدليل المتتبع. بدون هذه الخاصية، لا يمكن تسجيل الكائن كمقدم.

الطرق الإلزامية

presentedItemURL — خاصية من نوع URL? يجب أن تُرجع المسار إلى الملف المتتبع. إذا كان الكائن يتتبع ملفات متعددة، تُرجع الخاصية عنوان URL للعنصر الرئيسي. للدلائل، تُرجع عنوان URL للدليل.

presentedItemDidChange — تُستدعى بعد تغيير محتويات الملف المتتبع. في هذه الطريقة، يقوم المقدم بتحديث حالته الداخلية وإعادة تحميل البيانات. لا تتلقى هذه الطريقة معلومات حول ما تغير بالضبط — فقط حقيقة التغيير.

الطرق الاختيارية

accommodatePresentedItemDeletion — تُستدعى قبل حذف الملف. يمكن للمقدم حفظ الحالة الحالية، إغلاق واصفات الملفات، أو إلغاء العملية بإرجاع NSError. إذا أعادت الطريقة خطأ، لا يتم تنفيذ عملية الحذف.

presentedItemDidMoveToURL — تُستدعى بعد نقل أو إعادة تسمية الملف. تتلقى الطريقة عنوان URL الجديد، ويجب على المقدم تحديث مرجع الملف. بدون تنفيذ هذه الطريقة، سيستمر المقدم في الإشارة إلى المسار القديم غير الموجود.

NSFilePresenter وNSFileCoordinator

NSFileCoordinator وNSFilePresenter زوج لا ينفصل. يدير NSFileCoordinator الوصول إلى الملفات ويستدعي طرق المقدم. لا يعمل المقدم مباشرة مع نظام الملفات — جميع العمليات تمر عبر المنسق الذي يضمن ذرية التغييرات.

يسجل المنسق المقدم عبر طريقة addFilePresenter من فئة NSFileCoordinator. بعد التسجيل، يبدأ المقدم في تلقي الإشعارات. يتم الإزالة عبر removeFilePresenter. يحتفظ النظام بمرجع ضعيف للمقدم، لذلك يجب أن يبقى الكائن حياً طوال فترة التتبع.

وفقاً لـ Apple WWDC 2022، يستخدم NSFileCoordinator آلية تنسيق على مستوى النواة، مما يضمن أقل زمن استجابة أثناء الأقفال. في أحدث إصدارات iOS، تم تحسين المنسق للعمل مع Sandbox وإضافات التطبيقات.

قواعد التنسيق

النوايا — يجب تغليف كل عملية قراءة أو كتابة في كتلة تنسيق: القراءة عبر coordinateReadingItemAtURL، الكتابة عبر coordinateWritingItemAtURL. يقوم المنسق تلقائياً بقفل الملف للمشاركين الآخرين أثناء تنفيذ الكتلة.

التنسيق الدفعي — للعمليات التي تتضمن ملفات متعددة، يُستخدم التنسيق الدفعي. يقوم المنسق بقفل جميع الملفات المحددة بشكل ذري، وينفذ العملية، ويحرر الأقفال. هذا مهم بشكل حاسم عند نقل أو نسخ مجموعات المستندات.

مثال تنفيذ

لننشئ فئة DocumentPresenter تنفذ بروتوكول NSFilePresenter وتتتبع تغييرات ملف المستند. تحتوي الفئة على مرجع للملف وبيانات داخلية وعلامة صلاحية.

swift
import Foundation

class DocumentPresenter: NSObject, NSFilePresenter {
    var presentedItemURL: URL? {
        return self.fileURL
    }

    var presentedItemOperationQueue: OperationQueue {
        return self.queue
    }

    private let fileURL: URL
    private let queue = OperationQueue()

    func presentedItemDidChange() {
        self.reloadData()
    }

    func accommodatePresentedItemDeletion() throws {
        try self.saveCurrentState()
    }

    private func reloadData() {
        let coordinator = NSFileCoordinator(filePresenter: self)
        var error: NSError?
        coordinator.coordinate(readingItemAt: self.fileURL,
                               options: [],
                               error: &error)
        { readURL in
            guard let data = try? Data(contentsOf: readURL)
            else { return }
            self.processData(data)
        }
    }

    private func processData(_: Data) {
        // معالجة بيانات المستند
    }
}

تنفذ الفئة presentedItemDidChange لإعادة تحميل البيانات عندما يتغير الملف وaccommodatePresentedItemDeletion لحفظ الحالة قبل الحذف. تضمن قائمة العمليات معالجة جميع الإشعارات بشكل تسلسلي.

يتم تسجيل المقدم عبر NSFileCoordinator.addFilePresenter عند فتح مستند. من المهم تمرير خيارات القراءة الصحيحة إلى المنسق — withoutChanges للعمليات غير المعدلة أو immediatelyAvailable للسيناريوهات التي تتطلب وصولاً فورياً.

الأخطاء الشائعة

الخطأ الشائع الأول هو عدم تنفيذ presentedItemOperationQueue. إذا لم تحدد قائمة انتظار، قد تصل الإشعارات في خيط عشوائي، مما يسبب تسابق البيانات. استخدم دائماً OperationQueue تسلسلية لمعالجة الإشعارات.

الخطأ الثاني هو الحظر في طرق المقدم. تُستدعى طرق البروتوكول بشكل متزامن من المنسق. إذا قام المقدم بعملية طويلة (كتابة في قاعدة البيانات، طلب شبكة)، فإنه يحظر المنسق لجميع المشاركين الآخرين. انقل العمليات الثقيلة إلى قوائم الخلفية.

الخطأ الثالث هو تجاهل accommodatePresentedItemDeletion. إذا لم ينفذ المقدم هذه الطريقة ولم يُرجع خطأ، قد يتم حذف الملف دون حفظ الحالة الحالية. احفظ البيانات دائماً في هذه الطريقة إذا لم تكن قد كُتبت على القرص بعد.

الخطأ الرابع هو التنسيق الدائري. عندما يستدعي المقدم داخل طريقة إشعار المنسق مرة أخرى لنفس الملف، يحدث deadlock. تحقق من علامة isCoordinatedOperation قبل بدء التنسيق داخل المعالج.

الخطأالنتيجةالحل
لا توجد قائمة انتظار عملياتتسابق البيانات في تعدد الخيوطتحديد OperationQueue
حظر في الطرقتجميد المنسقنقل إلى خلفية
تجاهل الحذففقدان البيانات عند الحذفتنفيذ الحفظ
تنسيق دائريتوقف التطبيقعلامة isCoordinatedOperation

الأسئلة الشائعة

لماذا نحتاج NSFilePresenter إذا كان NSFileHandle موجوداً؟

NSFileHandle هو واجهة منخفضة المستوى لقراءة وكتابة البيانات لا توفر آليات إشعار بالتغييرات من العمليات الأخرى. يعمل NSFilePresenter على مستوى التنسيق: يتلقى أحداثاً من النظام كلما تغير ملف، بغض النظر عن المصدر — خيط آخر، عملية أو iCloud.

هل من الإلزامي استخدام NSFileCoordinator مع NSFilePresenter؟

نعم. NSFilePresenter لا معنى له بدون NSFileCoordinator. المقدم يحدد فقط طرق المعالجة، بينما يدير المنسق الأقفال ويستدعي هذه الطرق. إذا استخدمت NSFilePresenter بدون منسق، لن يتم تسليم الإشعارات.

هل يمكن لكائن واحد أن يكون مقدماً لعدة ملفات؟

يمكن، ولكن مع قيود. الخاصية presentedItemURL تُرجع عنوان URL واحد فقط، لذلك لتتبع ملفات متعددة يُستخدم بروتوكول NSFilePresenter مع طرق إضافية للعناصر الفرعية. البديل هو إنشاء مثيل منفصل من المقدم لكل ملف.

كيف يعمل NSFilePresenter مع Sandbox في iOS؟

NSFilePresenter متوافق تماماً مع بيئة الحماية في iOS. يمكن للتطبيق تتبع الملفات فقط داخل حاويته الخاصة. للوصول إلى ملفات التطبيقات الأخرى، تُستخدم App Groups أو Security-Scoped Bookmarks. يعمل المنسق ضمن صلاحيات بيئة الحماية.

ماذا تفعل إذا تم استدعاء presentedItemDidChange بشكل متكرر جداً؟

استخدم debounce أو throttle داخل طريقة presentedItemDidChange. أنشئ مؤقتاً بتأخير 0.3–0.5 ثانية وأعد تعيينه عند كل استدعاء جديد. بعد الاستقرار، قم بإعادة تحميل البيانات. هذا يمنع معالجة متعددة لنفس الدفعة من التغييرات.

الملخص

  • NSFilePresenter — بروتوكول Foundation لتلقي إشعارات تغييرات الملفات في iOS وmacOS، يعمل حصراً بالتزامن مع NSFileCoordinator.
  • خاصية إلزامية presentedItemURL — بدونها، لا يمكن تسجيل الكائن كمقدم ولن يتلقى إشعارات.
  • الطريقة الرئيسية presentedItemDidChange تُستدعى بعد أي تغيير في محتوى الملف — استخدمها لإعادة تحميل البيانات.
  • accommodatePresentedItemDeletion تسمح بمعالجة حذف الملف بشكل صحيح وحفظ حالة التطبيق الحالية.
  • NSFileCoordinator يدير الأقفال ويضمن ذرية العمليات — بدون منسق، المقدم عديم الفائدة.
  • الأخطاء الشائعة تشمل عدم وجود قائمة انتظار عمليات، الحظر في الطرق، والتنسيق الدائري — يجب تجنبها من خلال التصميم السليم.
  • Debounce في presentedItemDidChange عند الاستدعاءات المتكررة — استخدم مؤقتاً لتجميع التغييرات قبل إعادة التحميل.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا