لماذا Swift ليس فقط للواجهات، بل للملفات أيضًا
\n\nعندما يبدأ المطورون في تعلم Swift، غالبًا ما يكتبون تطبيقات بواجهات ورسوم متحركة وطلبات شبكة. لكن عاجلاً أم آجلاً تظهر مهمة: حفظ البيانات على الجهاز، قراءة ملف إعدادات، تحليل ملف JSON، أو ببساطة نسخ مستند. وهنا يضيع الكثيرون. وهذا خطأ — العمل مع الملفات في Swift أنيق ومدروس لدرجة أنك لا ترغب في العودة إلى لغات أخرى بعده.
\n\nفي هذه المقالة، سنستعرض التفاعل مع نظام الملفات في Swift من البسيط إلى المعقد. ستتعلم كيفية إنشاء الملفات وقراءتها وكتابتها وحذفها، والعمل مع الدلائل، ومعالجة الأخطاء، وحتى تشفير البيانات. هيا بنا!
\n\nالأساسيات: FileManager و FileHandle
\n\nقلب نظام الملفات في Swift هو الفئة FileManager. إنه "المدير" الذي يعرف كل شيء عن المجلدات والملفات على الجهاز. يسمح بالتحقق من الوجود، والنقل، والنسخ، والحذف. للعمل مع محتوى الملفات (القراءة والكتابة)، يُستخدم FileHandle أو الطرق عالية المستوى مثل Data و String و Codable.
أين تخزن الملفات؟ المسارات والدلائل
\n\nقبل كتابة الكود، يجب أن تفهم أين يُسمح لك بحفظ البيانات. في iOS و macOS، هناك قواعد صارمة: يمكن للتطبيق الكتابة فقط داخل صندوق الحماية الخاص به (sandbox). أشهر الدلائل:
\n\n- \n
- Documents — للبيانات الخاصة بالمستخدم التي يجب الاحتفاظ بها أثناء النسخ الاحتياطي. \n
- Library/Caches — للملفات المؤقتة التي يمكن للنظام حذفها. \n
- tmp — للملفات لمرة واحدة، تُحذف عند إعادة التشغيل. \n
الحصول على المسار إلى المجلد المطلوب سهل للغاية:
\n\nimport Foundation\n\nlet fileManager = FileManager.default\nlet documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!\nprint("Documents: \\(documentsURL.path)")\n\nlet cachesURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!\nprint("Caches: \\(cachesURL.path)")\n\nإنشاء وحذف الملفات في Swift
\n\nلنبدأ بالأساسي — إنشاء ملف فارغ في دليل Documents:
\n\nlet fileURL = documentsURL.appendingPathComponent("myFile.txt")\n\n// إنشاء الملف إذا لم يكن موجودًا\nif !fileManager.fileExists(atPath: fileURL.path) {\n fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil)\n print("تم إنشاء الملف!")\n}\n\nلاحظ: createFile(atPath:contents:attributes:) يُرجع Bool يخبرك ما إذا تم إنشاء الملف بنجاح. تحقق دائمًا من النتيجة — فهذا سينقذك من الأخطاء غير المتوقعة.
حذف الملف يتم بسطر واحد:
\n\ndo {\n try fileManager.removeItem(at: fileURL)\n print("تم حذف الملف")\n} catch {\n print("خطأ في الحذف: \\(error.localizedDescription)")\n}\n\nهنا نستخدم try وكتلة do-catch — الطريقة القياسية لمعالجة الأخطاء في Swift. لا تستدعِ removeItem أبدًا دون تحقق، وإلا سيتعطل التطبيق.
قراءة وكتابة الملفات النصية
\n\nالسيناريو الأكثر شيوعًا هو العمل مع البيانات النصية. يوفر Swift طرقًا مريحة لـ قراءة ملف Swift والكتابة عبر السلاسل النصية:
\n\n// كتابة النص\nlet text = "مرحبًا بالعالم! Hello, Swift!"\ndo {\n try text.write(to: fileURL, atomically: true, encoding: .utf8)\n print("تم كتابة النص")\n} catch {\n print("خطأ في الكتابة: \\(error)")\n}\n\n// قراءة النص\ndo {\n let savedText = try String(contentsOf: fileURL, encoding: .utf8)\n print("تمت القراءة: \\(savedText)")\n} catch {\n print("خطأ في القراءة: \\(error)")\n}\n\nالعلم atomically: true يضمن أن الكتابة ستكون ذرية — أولاً تُكتب البيانات