NSFileCoordinator — چیست، هماهنگی دسترسی به فایل‌های iOS

نویسنده: IT Sectr منتشر شده: 2026-07-11 زمان مطالعه: 7 دقیقه

NSFileCoordinator یک کلاس Foundation در iOS و macOS است که دسترسی امن به فایل‌ها را هنگام کار همزمان چندین رشته، فرآیند یا افزونه فراهم می‌کند. به گفته Apple Developer Documentation, 2024، NSFileCoordinator از شرایط رقابتی (race conditions) هنگام خواندن و نوشتن فایل‌ها جلوگیری می‌کند و تضمین می‌کند که هیچ فرآیندی داده‌ها را در لحظه تغییر آنها توسط دیگری نمی‌خواند. هماهنگ‌کننده در iCloud Drive، File Provider Extension و هرگونه عملیات فایل چندرشته‌ای استفاده می‌شود.

نکات اصلی

  • NSFileCoordinator — کلاسی برای دسترسی امن به فایل‌ها از چندین رشته و فرآیند
  • بلوک‌های هماهنگی (reading/writing intent) نوع عملیات را قبل از اجرا اعلام می‌کنند
  • جلوگیری از race conditions — وظیفه اصلی هماهنگ‌کننده در دسترسی موازی
  • پشتیبانی File Provider — هماهنگ‌کننده هنگام کار با فایل‌های iCloud Drive و افزونه‌ها اجباری است
  • NSFilePresenter — پروتکلی برای دریافت اعلان‌های تغییرات فایل از سایر فرآیندها

NSFileCoordinator چیست؟

NSFileCoordinator — مکانیزم همگام‌سازی دسترسی به فایل‌ها در سطح سیستم‌عامل است که توسط اپل در iOS 5 و macOS 10.7 Lion معرفی شد. برخلاف قفل‌های سنتی (NSLock، pthread_mutex)، هماهنگ‌کننده در سطح سیستم فایل کار می‌کند و می‌تواند دسترسی بین فرآیندهای مختلف را هماهنگ کند، نه فقط بین رشته‌های یک برنامه.

نیاز به NSFileCoordinator از معماری Sandbox در iOS ناشی می‌شود: هر فرآیند (برنامه، افزونه، سرویس سیستمی) در یک محیط ایزوله با دسترسی خاص خود به فایل‌ها کار می‌کند. هنگامی که چندین فرآیند سعی می‌کنند همزمان یک فایل را بخوانند و بنویسند (مثلاً هنگام همگام‌سازی iCloud Drive)، بدون هماهنگ‌کننده شرایط رقابتی ایجاد می‌شود: فرآیند A فایل را در لحظه‌ای می‌خواند که فرآیند B قبلاً بخشی از آن را بازنویسی کرده است.

به گفته WWDC 2023، اپل اکیداً توصیه می‌کند از NSFileCoordinator برای همه عملیات‌های فایل در Ubiquity container (iCloud Drive) و هنگام کار با File Provider Extension استفاده کنید. نادیده گرفتن هماهنگی یکی از دلایل رایج آسیب داده و باگ‌های غیرقابل بازتولید در برنامه‌های iOS است.

انواع اهداف هماهنگی (intents)

هدف هماهنگی (NSFileCoordinator.ReadingIntent / WritingIntent) — شیئی است که نوع عملیاتی را که رشته یا فرآیند قصد اجرای آن را دارد اعلام می‌کند. هماهنگ‌کننده از این اهداف برای تعیین ترتیب دسترسی و حل تعارضات استفاده می‌کند.

نوع هدفتوضیحکی استفاده کنیم
ReadingIntentخواندن فایل بدون تغییرباز کردن سند، بارگذاری داده
WritingIntentنوشتن با تغییر احتمالی محتواذخیره سند، ویرایش
ReadingIntent(URL, options: .withoutChanges)خواندن بدون ردیابی تغییراتپیش‌نمایش سریع محتوا
WritingIntent(URL, options: .contentIndependentMetadataOnly)تغییر فقط فرادادهبه‌روزرسانی تاریخ یا ویژگی‌ها
WritingIntent(URL, options: .forDeleting)حذف فایلحذف سند توسط کاربر

قوانین هماهنگی: چندین خواندن همزمان مجاز است (اگر نوشتن فعالی وجود نداشته باشد)، نوشتن انحصاری است — هیچ خواندن یا نوشتنی در طول عملیات نوشتن مجاز نیست. این مطابق مدل readers-writer lock است، اما با پشتیبانی اضافی از هماهنگی بین‌فرآیندی از طریق launchd و XPC.

نکته مهم: NSFileCoordinator از دسترسی به فایل از طریق NSData یا FileManager معمولی جلوگیری نمی‌کند — فقط عملیاتی را هماهنگ می‌کند که به صراحت در بلوک‌های هماهنگی قرار گرفته‌اند. اگر رشته دیگری مستقیماً و بدون عبور از هماهنگ‌کننده به فایل دسترسی پیدا کند، همان race conditions رخ می‌دهد که هماهنگ‌کننده قرار است از آنها جلوگیری کند.

NSFileCoordinator در عمل: مثال‌های کد

الگوی پایه استفاده از NSFileCoordinator از سه مرحله تشکیل شده است: ایجاد یک نمونه از هماهنگ‌کننده، اعلام هدف (خواندن یا نوشتن) و انجام عملیات در داخل بلوک هماهنگی. هماهنگ‌کننده تضمین می‌کند که هیچ هماهنگ‌کننده دیگری همزمان با همان فایل کار نکند.

swift
import Foundation

let coordinator = NSFileCoordinator()
let fileURL = getDocumentURL()

// خواندن امن
let readIntent = NSFileCoordinator
    .ReadingIntent(url: fileURL)
var content: Data?
var readError: NSError?

coordinator.coordinate(with: readIntent) { error in
    if let error = error {
        readError = error
        return
    }
    content = try? Data(contentsOf: fileURL)
}

// نوشتن امن
let writeIntent = NSFileCoordinator
    .WritingIntent(url: fileURL)

coordinator.coordinate(with: writeIntent) { error in
    guard error == nil else { return }
    do {
        try newData.write(to: fileURL)
    } catch {
        Logger.storage.error(
            "Write failed: \(error)"
        )
    }
}

عملیات دسته‌ای — هماهنگ‌کننده می‌تواند چندین فایل را در یک عملیات با استفاده از آرایه‌ای از اهداف پردازش کند. این برای جابجایی، کپی یا حذف مجموعه‌ای از فایل‌ها به عنوان یک تراکنش واحد مفید است. اگر یکی از اهداف قابل اجرا نباشد، کل عملیات با خطا لغو می‌شود.

swift
let coordinator = NSFileCoordinator()
let readIntent = NSFileCoordinator
    .ReadingIntent(url: sourceURL)
let writeIntent = NSFileCoordinator
    .WritingIntent(url: destURL)

coordinator.coordinate(
    with: [readIntent, writeIntent]
) { error in
    try? FileManager.default
        .copyItem(at: sourceURL, to: destURL)
}

هماهنگی ناهمگام — از iOS 15، NSFileCoordinator از روش‌های ناهمگام با completion handler پشتیبانی می‌کند که امکان انجام هماهنگی بدون مسدود کردن رشته فراخوان را فراهم می‌کند. این برای رشته UI حیاتی است، زیرا انتظار همگام برای هماهنگی می‌تواند باعث قفل شدن رابط کاربری برای ثانیه‌ها شود.

پروتکل NSFilePresenter و اعلان‌ها

NSFilePresenter — پروتکلی است که یک شی برای دریافت اعلان‌های تغییرات فایل‌های هماهنگ شده توسط NSFileCoordinator پیاده‌سازی می‌کند. اگر برنامه شما محتوای فایلی را نمایش می‌دهد که ممکن است توسط فرآیند دیگری تغییر کند (مثلاً iCloud Drive نسخه جدیدی را همگام‌سازی می‌کند)، پیاده‌سازی NSFilePresenter امکان به‌روزرسانی به موقع رابط کاربری را فراهم می‌کند.

swift
class DocumentPresenter: NSFilePresenter {
    let presentedItemURL: URL?
    let presentedItemOperationQueue: OperationQueue

    init(url: URL) {
        presentedItemURL = url
        presentedItemOperationQueue = OperationQueue()
    }

    func presentedItemDidChange() {
        DispatchQueue.main.async {
            NotificationCenter.default
                .post(name: .documentDidChange,
                      object: self)
        }
    }

    func presentedItemDidMove(to newURL: URL) {
        Logger.storage.info(
            "File moved to: \(newURL.lastPathComponent)"
        )
    }

    func accommodatePresentedItemDeletion(
        completionHandler: @escaping (Error?) -> Void
    ) {
        Logger.storage.warn("File deleted externally")
        completionHandler(nil)
    }
}

روش‌های پروتکل: presentedItemDidChange هنگام تغییر محتوای فایل فراخوانی می‌شود، presentedItemDidMove(to:) — پس از جابجایی فایل، accommodatePresentedItemDeletion — قبل از حذف فایل توسط فرآیند دیگر (به برنامه اجازه می‌دهد فایل را به درستی ببندد). علاوه بر این، پروتکل از نسخه‌بندی از طریق presentedItemDidGainVersion: و presentedItemDidLoseVersion: پشتیبانی می‌کند.

مهم: NSFilePresenter باید در سیستم از طریق NSFileCoordinator.addFilePresenter: ثبت شود. بدون ثبت‌نام، اعلان‌ها تحویل داده نمی‌شوند. ثبت‌نام یک بار در هنگام راه‌اندازی برنامه انجام می‌شود و هنگام بازآفرینی ارائه‌دهنده نیاز به ثبت‌نام مجدد ندارد.

بهترین روش‌های هماهنگی فایل‌ها

همیشه از هماهنگ‌کننده استفاده کنید برای فایل‌های موجود در Ubiquity container (iCloud Drive) و دایرکتوری‌های قابل دسترس افزونه‌ها. حتی اگر در حال حاضر برنامه تک‌رشته‌ای باشد، به‌روزرسانی‌های آینده یا تغییرات سیستمی ممکن است دسترسی موازی را اضافه کنند و عدم هماهنگی منجر به باگ‌های دشوار برای یافتن خواهد شد.

زمان را در بلوک هماهنگی به حداقل برسانید. در حالی که بلوک در حال اجراست، سایر فرآیندها نمی‌توانند به فایل دسترسی داشته باشند. عملیات طولانی در داخل بلوک (پردازش پیچیده داده، درخواست‌های شبکه) کل سیستم دسترسی به فایل را مسدود می‌کند. فقط خواندن یا نوشتن داده را در داخل بلوک انجام دهید و پردازش را خارج از آن انجام دهید.

از deadlock جلوگیری کنید: هماهنگ‌کننده را از داخل بلوک هماهنگ‌کننده دیگر برای همان فایل فراخوانی نکنید — این منجر به قفل متقابل می‌شود. از عملیات دسته‌ای (آرایه‌ای از اهداف) به جای فراخوانی‌های تو در تو استفاده کنید. اگر تودرتو ضروری است، از صف‌های مختلف یا URLهای مختلف استفاده کنید.

به گفته objc.io (2024)، خطاهای رایج هنگام کار با NSFileCoordinator شامل: عدم مدیریت خطا در completion handler (منجر به عملیات ناتمام)؛ هماهنگی فقط برای نوشتن اما نه برای خواندن؛ استفاده از API همگام قدیمی در رشته UI؛ نادیده گرفتن پروتکل NSFilePresenter هنگام کار با iCloud Drive. آخرین خطا موذی‌ترین است: برنامه داده‌های قدیمی را نشان می‌دهد بدون اینکه بداند فایل قبلاً تغییر کرده است.

سوالات متداول

NSFileCoordinator چیست؟

NSFileCoordinator — کلاس Foundation برای دسترسی امن به فایل‌ها از چندین رشته یا فرآیند. با هماهنگ کردن عملیات خواندن و نوشتن در سطح سیستم فایل از race conditions جلوگیری می‌کند.

NSFileCoordinator چه تفاوتی با NSLock دارد؟

NSLock فقط در داخل یک فرآیند (بین رشته‌ها) کار می‌کند. NSFileCoordinator دسترسی بین فرآیندهای مختلف و افزونه‌ها را هماهنگ می‌کند، از جمله همگام‌سازی iCloud Drive و File Provider Extension.

آیا استفاده از NSFileCoordinator برای iCloud Drive اجباری است؟

بله، اپل اکیداً توصیه می‌کند از NSFileCoordinator برای همه عملیات‌های فایل Ubiquity container استفاده کنید. بدون هماهنگ‌کننده، آسیب داده هنگام همگام‌سازی بین دستگاه‌ها و تعارضات با File Provider Extension ممکن است رخ دهد.

NSFilePresenter چیست؟

NSFilePresenter — پروتکلی برای دریافت اعلان‌های تغییرات فایل. به برنامه اجازه می‌دهد به تغییرات انجام شده توسط فرآیندهای دیگر واکنش نشان دهد: به‌روزرسانی UI هنگام تغییر، مدیریت جابجایی یا آماده‌سازی برای حذف فایل.

NSFileCoordinator از چه نوع اهدافی پشتیبانی می‌کند؟

پنج نوع: ReadingIntent (خواندن)، WritingIntent (نوشتن)، ReadingIntent با .withoutChanges (خواندن بدون ردیابی)، WritingIntent با .contentIndependentMetadataOnly (فقط فراداده) و WritingIntent با .forDeleting (حذف). هرکدام سطح دسترسی به فایل را تعیین می‌کند.

خلاصه

  • NSFileCoordinator — مکانیزم سیستمی برای دسترسی امن به فایل‌ها از رشته‌ها، فرآیندها و افزونه‌ها
  • اهداف هماهنگی (خواندن/نوشتن) نوع عملیات را قبل از اجرا اعلام می‌کنند
  • خواندن به صورت موازی مجاز است، نوشتن — انحصاری (مدل readers-writer)
  • NSFilePresenter — پروتکل اعلان تغییرات فایل از سایر فرآیندها
  • iCloud Drive و File Provider برای جلوگیری از آسیب داده نیاز به هماهنگی اجباری دارند
  • زمان را در بلوک هماهنگی به حداقل برسانید — عملیات طولانی دسترسی سایر فرآیندها را مسدود می‌کند
  • Deadlock با عملیات دسته‌ای و اجتناب از فراخوانی‌های تو در تو جلوگیری می‌شود

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید