NSFilePresenter — این یک پروتکل Foundation است که به یک شی اجازه میدهد اعلانهایی درباره تغییرات فایلها و دایرکتوریها در سیستم فایل iOS و macOS دریافت کند. کلاس متدهای پروتکل را پیادهسازی میکند و از طریق NSFileCoordinator ثبت میشود، پس از آن سیستم به طور خودکار این متدها را در هر عملیات با فایل ردیابیشده فراخوانی میکند. طبق Apple Developer Documentation (2025)، NSFilePresenter در برنامههای با دسترسی چندنخی به اسناد برای جلوگیری از تداخل نوشتن استفاده میشود. پروتکل الزاماً در ترکیب با NSFileCoordinator استفاده میشود — فقط بدین ترتیب هماهنگی امن دسترسی تضمین میشود.
نکات اصلی
NSFilePresenter — یک پروتکل Foundation است که برای ردیابی تغییرات فایلها و دایرکتوریها در سیستمهای عامل Apple طراحی شده است. پروتکل مجموعهای از متدها را تعریف میکند که شی ناظر برای دریافت اعلانهایی درباره رویدادهای سیستم فایل پیادهسازی میکند.
وظیفه اصلی پروتکل تضمین دسترسی امن به فایلها در سناریوهای چندنخی است. در iOS و macOS، چندین فرآیند و نخ میتوانند همزمان از طریق NSFileCoordinator به یک فایل دسترسی داشته باشند و NSFilePresenter تضمین میکند که هر شرکتکننده وضعیت بهروز دادهها را دریافت میکند.
پروتکل از iOS 5.0 و macOS 10.7 در Foundation گنجانده شده است. این پروتکل در برنامههایی که با اسناد، پایگاههای داده و هر فایلی که ممکن است همزمان از منابع مختلف تغییر کند — مثلاً هنگام همگامسازی از طریق iCloud یا ویرایش مشترک — استفاده میشود.
برنامههای سندمحور — حوزه اصلی استفاده از NSFilePresenter. برنامههایی که با UIDocument یا NSDocument کار میکنند به طور خودکار خود را از طریق NSFileCoordinator به عنوان ارائهدهنده ثبت میکنند. این امکان را میدهد که هنگام ویرایش یک فایل از چندین پنجره یا دستگاه، تداخلها به درستی پردازش شوند.
همگامسازی iCloud — دومین سناریوی کلیدی. وقتی فایل در یک دستگاه تغییر میکند، iCloud آن را در همه دستگاههای متصل همگامسازی میکند. NSFilePresenter برنامه را از این تغییرات مطلع میکند و امکان بهروزرسانی بهموقع رابط را فراهم میکند.
ویرایشگرهای چندنخی — سومین سناریو. در برنامههایی که صفهای پسزمینه همزمان با کار کاربر دادهها را بارگیری و ذخیره میکنند، NSFilePresenter از شرایط مسابقه در نوشتن و خواندن فایلها جلوگیری میکند.
مکانیزم کار NSFilePresenter بر اساس مدل نمایندگی است: شی متدهای پروتکل را پیادهسازی میکند، از طریق NSFileCoordinator ثبت میشود و با هر تغییر فایل ردیابیشده فراخوانی دریافت میکند. سیستم خود تعیین میکند چه زمانی تغییر رخ داده و کدام متدها باید فراخوانی شوند.
فرآیند با ایجاد یک نمونه از NSFileCoordinator توسط شی و فراخوانی متد هماهنگکننده با ارسال URL فایل آغاز میشود. هماهنگکننده بررسی میکند که آیا برای این URL ارائهدهندهای ثبت شده است یا خیر. اگر بله، دسترسی خواندن یا نوشتن را مسدود میکند و از طریق متدهای پروتکل به ارائهدهندگان درباره تغییر قریبالوقوع اطلاع میدهد.
پس از اتمام عملیات، هماهنگکننده قفل را برمیدارد و اعلانهای نهایی را فراخوانی میکند. مهم است که ارائهدهنده جریان اجرا را مدیریت نمیکند — او فقط به رویدادها واکنش نشان میدهد. هماهنگی کامل بر عهده NSFileCoordinator است.
فاز آمادهسازی — قبل از اجرای عملیات، هماهنگکننده متد accommodatePresentedItemDeletion یا accommodatePresentedSubitemDeletion را فراخوانی میکند. ارائهدهنده میتواند وضعیت را پردازش کند یا با بازگرداندن خطا، عملیات را لغو کند. این فاز به برنامه اجازه میدهد قبل از تغییر فایل، کار با آن را به درستی به پایان برساند.
فاز اعلان — پس از اتمام عملیات، هماهنگکننده presentedItemDidChange یا presentedSubitemDidChange را فراخوانی میکند. ارائهدهنده سیگنالی دریافت میکند که فایل تغییر کرده است و میتواند محتوای آن را دوباره بخواند. برای جابهجایی فایل، presentedItemDidMoveToURL با مکان جدید فراخوانی میشود.
فاز پایان — هماهنگکننده همه قفلها را برمیدارد و منابع را آزاد میکند. ارائهدهنده میتواند با دادههای بهروز شده به کار ادامه دهد. هر سه فاز به صورت همزمان در یک نخ اجرا میشوند، بنابراین متدهای پروتکل باید سریع و بدون عملیات طولانی ورودی-خروجی کار کنند.
پروتکل NSFilePresenter شامل چندین متد اجباری و اختیاری است. تنها ویژگی اجباری presentedItemURL است که URL فایل یا دایرکتوری ردیابیشده را برمیگرداند. بدون این ویژگی، شی نمیتواند به عنوان ارائهدهنده ثبت شود.
presentedItemURL — ویژگی از نوع URL? که باید مسیر فایل ردیابیشده را برگرداند. اگر شی چندین فایل را ردیابی میکند، ویژگی URL عنصر اصلی را برمیگرداند. برای دایرکتوریها، URL خود دایرکتوری برگردانده میشود.
presentedItemDidChange — پس از تغییر محتوای فایل ردیابیشده فراخوانی میشود. در این متد، ارائهدهنده وضعیت داخلی خود را بهروز میکند و دادهها را دوباره بارگذاری میکند. این متد اطلاعاتی درباره اینکه دقیقاً چه چیزی تغییر کرده دریافت نمیکند — فقط واقعیت تغییر را اعلام میکند.
accommodatePresentedItemDeletion — قبل از حذف فایل فراخوانی میشود. ارائهدهنده میتواند وضعیت فعلی را ذخیره کند، توصیفکنندههای فایل را ببندد یا با بازگرداندن NSError عملیات را لغو کند. اگر متد خطا برگرداند، عملیات حذف انجام نمیشود.
presentedItemDidMoveToURL — پس از جابهجایی یا تغییر نام فایل فراخوانی میشود. متد URL جدید را دریافت میکند و ارائهدهنده باید ارجاع به فایل را بهروز کند. بدون پیادهسازی این متد، ارائهدهنده همچنان به مسیر قدیمی و ناموجود اشاره خواهد کرد.
NSFileCoordinator و NSFilePresenter — یک جفت جدانشدنی. NSFileCoordinator دسترسی به فایلها را مدیریت میکند و متدهای ارائهدهنده را فراخوانی میکند. ارائهدهنده مستقیماً با سیستم فایل کار نمیکند — همه عملیات از طریق هماهنگکننده انجام میشود که اتمی بودن تغییرات را تضمین میکند.
هماهنگکننده ارائهدهنده را از طریق متد addFilePresenter کلاس NSFileCoordinator ثبت میکند. پس از اضافه شدن، ارائهدهنده شروع به دریافت اعلانها میکند. حذف از طریق removeFilePresenter انجام میشود. سیستم یک ارجاع ضعیف به ارائهدهنده نگه میدارد، بنابراین شی باید در طول کل دوره ردیابی زنده بماند.
طبق Apple WWDC 2022، NSFileCoordinator از مکانیزم هماهنگی در سطح هسته استفاده میکند که حداقل تأخیر را در قفلها تضمین میکند. در جدیدترین نسخههای iOS، هماهنگکننده برای کار با Sandbox و افزونههای برنامه بهینه شده است.
Intention — هر عملیات خواندن یا نوشتن باید در یک بلوک هماهنگی پیچیده شود: خواندن از طریق coordinateReadingItemAtURL، نوشتن از طریق coordinateWritingItemAtURL. هماهنگکننده به طور خودکار فایل را برای سایر شرکتکنندگان در طول اجرای بلوک قفل میکند.
هماهنگی دستهای — برای عملیات با چندین فایل از هماهنگی دستهای استفاده میشود. هماهنگکننده همه فایلهای مشخصشده را به صورت اتمی قفل میکند، عملیات را اجرا میکند و قفلها را برمیدارد. این در جابهجایی یا کپی کردن مجموعههای اسناد حیاتی است.
کلاس DocumentPresenter را ایجاد میکنیم که پروتکل NSFilePresenter را پیادهسازی کرده و تغییرات فایل سند را ردیابی میکند. کلاس شامل ارجاع به فایل، دادههای داخلی و پرچم بهروزرسانی است.
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 رخ میدهد. قبل از شروع هماهنگی در داخل handler، پرچم isCoordinatedOperation را بررسی کنید.
| خطا | نتیجه | راهحل |
|---|---|---|
| عدم صف عملیات | رقابت داده در چندنخی | تعیین OperationQueue |
| مسدود کردن در متدها | قفل شدن هماهنگکننده | انتقال به نخ پسزمینه |
| نادیده گرفتن deletion | از دست دادن داده هنگام حذف | پیادهسازی ذخیرهسازی |
| هماهنگی چرخهای | Deadlock برنامه | پرچم isCoordinatedOperation |
سوالات متداول
NSFileHandle — یک رابط سطح پایین برای خواندن و نوشتن دادهها است که مکانیزمهای اعلان تغییرات از سایر فرآیندها را فراهم نمیکند. NSFilePresenter در سطح هماهنگی کار میکند: رویدادها را از سیستم با هر تغییر فایل دریافت میکند، صرفنظر از منبع — نخ دیگر، فرآیند یا iCloud.
بله. NSFilePresenter بدون NSFileCoordinator بیمعنی است. ارائهدهنده فقط متدهای پردازش را تعریف میکند، در حالی که هماهنگکننده قفلها را مدیریت کرده و این متدها را فراخوانی میکند. اگر از NSFilePresenter بدون هماهنگکننده استفاده کنید، اعلانها تحویل داده نخواهند شد.
میتواند، اما با محدودیتهایی. ویژگی presentedItemURL فقط یک URL برمیگرداند، بنابراین برای ردیابی چندین فایل از پروتکل NSFilePresenter با متدهای اضافی برای زیرعناصر استفاده میشود. جایگزین — ایجاد یک نمونه جداگانه از ارائهدهنده برای هر فایل است.
NSFilePresenter کاملاً با Sandbox iOS سازگار است. برنامه فقط میتواند فایلهای داخل کانتینر خود را ردیابی کند. برای دسترسی به فایلهای سایر برنامهها از App Groups یا Security-Scoped Bookmark استفاده میشود. هماهنگکننده در چارچوب مجوزهای Sandbox کار میکند.
در داخل متد presentedItemDidChange از debounce یا throttle استفاده کنید. یک تایمر با تأخیر ۰.۳-۰.۵ ثانیه ایجاد کنید و آن را با هر فراخوانی جدید بازنشانی کنید. پس از پایدار شدن، بارگذاری مجدد دادهها را انجام دهید. این کار از پردازش مکرر یک بسته تغییرات جلوگیری میکند.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید