العمل مع CSV في Swift (iOS/macOS): مكتبة SwiftCSV وأساسيات التحليل
CSV (Comma-Separated Values) هو أحد أكثر التنسيقات شيوعًا لتخزين البيانات الجدولية. في بيئة Apple (iOS، macOS)، غالبًا ما تكون هناك حاجة للعمل مع ملفات CSV لاستيراد البيانات من مصادر خارجية، أو تصدير التقارير، أو تحميل الإعدادات. في هذه المقالة، سنستعرض مكتبة SwiftCSV - وهي حل خفيف ومريح لتحليل CSV في Swift، بالإضافة إلى أمثلة أساسية للعمل مع هذا التنسيق دون تبعيات خارجية.
ما هي SwiftCSV؟
SwiftCSV هي مكتبة مفتوحة المصدر للغة Swift تتيح قراءة ومعالجة ملفات CSV بسهولة. تدعم التحليل النصي والعمل مع الملفات، وتحدد تلقائيًا الفواصل (فاصلة، علامة تبويب، فاصلة منقوطة)، وتوفر واجهة برمجة تطبيقات مريحة للوصول إلى الصفوف والأعمدة والخلايا الفردية.
الميزات الرئيسية:
- تحليل CSV من نص، Data، أو URL (محلي أو عن بعد).
- دعم رؤوس الأعمدة (الصف الأول كمفاتيح).
- التعامل مع علامات الاقتباس المتداخلة والأحرف المهربة.
- إمكانية اختيار الفاصل (فاصلة، علامة تبويب، مخصص).
- الحد الأدنى من التبعيات (Swift نقي).
تثبيت SwiftCSV
أضف المكتبة عبر Swift Package Manager (SPM):
- في Xcode، اختر
File → Add Packages.... - ألصق رابط المستودع:
https://github.com/swiftcsv/SwiftCSV.git. - اختر الإصدار (يوصى بأحدث إصدار مستقر).
- أضف الحزمة إلى هدفك.
أو أضف في Package.swift:
dependencies: [ .package(url: "https://github.com/swiftcsv/SwiftCSV.git", from: "0.9.0")]مثال أساسي: قراءة CSV من نص
لنفترض أن لدينا نص CSV يحتوي على بيانات المستخدمين:
let csvString = """name,age,cityAlice,30,New YorkBob,25,Los AngelesCharlie,35,Chicago"""نقوم بتحليله باستخدام SwiftCSV:
import SwiftCSV
do { let csv = try CSV(string: csvString) // الوصول إلى الصفوف كقواميس (المفاتيح هي الرؤوس) for row in csv.rows { if let name = row["name"], let age = row["age"], let city = row["city"] { print("\\(name) (\\(age) سنة) يعيش في \\(city)") } }} catch { print("خطأ في التحليل: \\(error)")}المخرجات:
Alice (30 سنة) يعيش في New YorkBob (25 سنة) يعيش في Los AngelesCharlie (35 سنة) يعيش في Chicagoقراءة CSV من ملف (iOS/macOS)
لتحميل CSV من ملف محلي (مثل مجلد Documents أو من الحزمة):
import SwiftCSV
// المسار إلى الملف (مثل في Documents)let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("data.csv")
do { let csv = try CSV(url: fileURL) // الوصول إلى الأعمدة let names = csv.columns["name"] ?? [] print("جميع الأسماء: \\(names)")} catch { print("خطأ: \\(error)")}لملف من الحزمة:
if let path = Bundle.main.path(forResource: "data", ofType: "csv") { let url = URL(fileURLWithPath: path) let csv = try CSV(url: url) // العمل مع البيانات}الفواصل المخصصة والإعدادات
إذا كان ملف CSV الخاص بك يستخدم علامة تبويب أو فاصلة منقوطة، حدد الفاصل بشكل صريح:
// TSV (Tab-Separated Values)let tsv = try CSV(string: "name\\tageAlice\\t30", delimiter: .tab)
// الفاصل هو فاصلة منقوطةlet csvSemicolon = try CSV(string: "name;ageAlice;30", delimiter: Character(";"))يمكنك أيضًا تعطيل تحليل الرؤوس (سيتم التعامل مع الصف الأول كصف عادي):
let csvNoHead