معالجة الأخطاء في Swift: try/catch والتقنيات المتقدمة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

معالجة الأخطاء في Swift: try/catch وما بعدها — المستوى المتقدم



معالجة الأخطاء جزء لا يتجزأ من أي تطوير جاد لنظامي iOS/macOS. يوفر Swift نظامًا قويًا ومعبرًا لإدارة الأخطاء يتجاوز بكثير مجرد try/catch. في هذه المقالة، سنستعرض التقنيات المتقدمة: العمل مع بروتوكول Error، تعدادات الأخطاء، الكلمات المفتاحية throws و rethrows، بالإضافة إلى نوع Result والمناهج الوظيفية. المادة موجهة للمطورين الملمين بالفعل بأساسيات Swift.



1. بروتوكول Error وأنواع الأخطاء المخصصة



في أساس معالجة الأخطاء في Swift يكمن بروتوكول Error. أي نوع يتوافق مع هذا البروتوكول يمكن طرحه كخطأ. غالبًا ما تُستخدم التعدادات (enum) لهذا الغرض.



import Foundation

// تعريف نوع خطأ مخصص لطلب الشبكةenum NetworkError: Error { case invalidURL case noData case decodingFailed(description: String) case serverError(statusCode: Int)}

// دالة يمكنها طرح خطأfunc fetchUserData(from urlString: String) throws -> Data { guard let url = URL(string: urlString) else { throw NetworkError.invalidURL }

// محاكاة طلب الشبكة let success = Bool.random() if !success { throw NetworkError.serverError(statusCode: 500) }

return Data()}


يسمح استخدام التعدادات بتجميع الأخطاء ذات الصلة ونقل معلومات إضافية (associated values)، مما يجعل الكود أكثر قابلية للقراءة والتوثيق الذاتي.



2. الاستخدام المتقدم لـ do-catch



كتلة do-catch هي الأداة الرئيسية لالتقاط الأخطاء. على المستوى المتقدم، من المهم معرفة كيفية معالجة أنواع مختلفة من الأخطاء بطرق مختلفة.



func processUserData() {    do {        let data = try fetchUserData(from: "https://api.example.com/user")        // العمل مع البيانات        print("تم استلام البيانات: \\(data.count) بايت")    } catch NetworkError.invalidURL {        print("خطأ: رابط URL غير صالح")    } catch NetworkError.serverError(let code) where code >= 500 {        print("خطأ خادم برمز \\(code). حاول مرة أخرى لاحقًا.")    } catch let error as NetworkError {        print("خطأ شبكة: \\(error)")    } catch {        // معالجة جميع الأخطاء الأخرى        print("خطأ غير معروف: \\(error.localizedDescription)")    }}


النقاط الرئيسية:

  • مطابقة الأنماط مع where: يسمح بتصفية الأخطاء وفقًا لشروط إضافية (مثل نطاق رموز الاستجابة).
  • تحويل النوع (as): إذا كنت تتوقع عدة أنواع من الأخطاء، يمكنك استخدام catch let error as MyErrorType.
  • كتلة catch العامة: يجب أن تكون دائمًا الأخيرة، لأنها تلتقط أي خطأ غير معالج.


3. الكلمات المفتاحية throws و rethrows ونشر الأخطاء



تشير الكلمة المفتاحية throws إلى أن الدالة يمكنها طرح خطأ. rethrows هي آلية أكثر دقة: فهي تشير إلى أن الدالة يمكنها طرح خطأ فقط إذا قام أحد معاملات الإغلاق (closure) الخاصة بها بطرح خطأ.



// دالة مع throws — يمكنها طرح خطأ بنفسهاfunc loadConfig() throws -> [String: String] {    // ...    throw NetworkError.noData}

// دالة مع rethrows — تنقل الخطأ من الإغلاقfunc performWithRetry(times: Int, operation: () throws -> Void) rethrows { for _ in 0..<times { try operation() }}

// الاستخدامdo { try performWithRetry(times: 3) { try loadConfig() }} catch { print("فشلت العملية بعد 3 محاولات: \\(erro")

المدونات

توصيات الكتب