العمل مع CSV في Swift (iOS/macOS): من البسيط إلى المعقد
CSV (قيم مفصولة بفواصل) هو أحد أكثر التنسيقات شيوعًا لتبادل البيانات الجدولية. يُستخدم للتصدير من Excel وGoogle Sheets وقواعد البيانات والسجلات البسيطة. في نظام Swift البيئي (iOS وmacOS وwatchOS وtvOS) لا توجد وحدة مدمجة للعمل مع CSV، ولكن هناك العديد من المكتبات الموثوقة التي تبسط هذه العملية بشكل كبير. في هذه المقالة، سنستعرض أفضل الأدوات ونكتب عدة أمثلة على الكود.
لماذا لا يجب كتابة محلل CSV يدويًا؟
للوهلة الأولى، يبدو CSV بسيطًا: قم بتقسيم السطر بفواصل - وانتهى الأمر. ولكن في الواقع، تظهر تعقيدات:
- قد تحتوي الحقول على فواصل بداخلها (مثل
"Smith, John"). - قد تكون الحقول محاطة بعلامات اقتباس، وداخل علامات الاقتباس توجد علامات اقتباس مُهربة (
""). - تستخدم الأنظمة المختلفة فواصل مختلفة (فاصلة، فاصلة منقوطة، علامة تبويب).
- مشاكل الترميز (UTF-8، UTF-16، Windows-1251).
لذلك، يُوصى بشدة باستخدام مكتبة جاهزة لكود الإنتاج.
أفضل مكتبات CSV في Swift
1. SwiftCSV (من Naoto Kaneko)
واحدة من أشهر وأخف المكتبات. تدعم القراءة والكتابة، وتتعامل تلقائيًا مع علامات الاقتباس والتهريب. تعمل عبر Swift Package Manager (SPM) وCocoaPods.
// الاتصال عبر SPM: .package(url: "https://github.com/naoty/SwiftCSV.git", from: "0.9.0")2. CodableCSV (من Dehesa)
مكتبة حديثة تتكامل مع بروتوكول Codable. تسمح بتحليل CSV مباشرة إلى هياكل Swift. مثالية للمشاريع التي تحتوي فيها البيانات على كتابة صارمة.
// الاتصال: .package(url: "https://github.com/dehesa/CodableCSV.git", from: "0.6.0")3. CSwift
مكتبة بسيطة وسريعة مع واجهة برمجة تطبيقات (API) بسيطة. مناسبة تمامًا للمشاريع الصغيرة أو النماذج الأولية السريعة.
مثال 1: قراءة CSV باستخدام SwiftCSV
لنفترض أن لدينا ملف users.csv:
id,name,email1,إيفان إيفانوف,ivan@example.com2,ماريا بيتروفا,maria@example.com3,جون دو,"john.doe@example.com"كود القراءة:
import SwiftCSV
guard let csvURL = Bundle.main.url(forResource: "users", withExtension: "csv") else { print("الملف غير موجود") return}
do { let csv = try CSV(url: csvURL) // الوصول إلى الصفوف كمصفوفة من القواميس for row in csv.rows { if let id = row["id"], let name = row["name"], let email = row["email"] { print("ID: \\(id), الاسم: \\(name), البريد الإلكتروني: \\(email)") } } // أو الوصول حسب الأعمدة print("جميع الأسماء: \\(csv.columns["name"] ?? [])")} catch { print("خطأ في التحليل: \\(error)")}مثال 2: كتابة CSV باستخدام SwiftCSV
import SwiftCSV
let headers = ["الاسم", "العمر", "المدينة"]let rows = [ ["آنا", "28", "موسكو"], ["بوريس", "35", "سانت بطرسبرغ"], ["فيكتور", "22", "نوفوسيبيرسك"]]
do { let csv = try CSV(string: "", headers: headers, rows: rows) let csvString = csv.output // الحصول على سلسلة CSV print(csvString) // حفظ في ملف let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsPath.appendingPathComponent("output.csv") try csvString.write(to: fileURL, atomically: true, encoding: .utf8) print("تم حفظ الملف: \\(fileURL)")} catch { print("خطأ في الكتابة: \\(error)")}مثال 3: CodableCSV — تحليل إلى هياكل
يوضح هذا المثال كيفية دمج CSV بسهولة مع نماذج البيانات:
import CodableCSV
struct User: Decodable { let id: Int let name: String let email: String}\