0Pricing
Swift Academy · درس

منطق إعادة المحاولة وURLSession في الخلفية

نفّذوا التراجع الأُسّي وواصلوا التنزيلات في الخلفية.

منطق إعادة المحاولة وURLSession في الخلفية درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

لماذا إعادة المحاولة؟

يمكن التعافي من الإخفاقات المؤقتة، مثل انتهاء المهلة أو 503 Service Unavailable. تحسن آلية إعادة المحاولة المرونة دون تدخل المستخدم.

func fetch(retries: Int = 3) async throws -> Data {
  for attempt in 0..<retries {
    do {
      return try await URLSession.shared.data(from: url).0
    } catch {
      if attempt == retries - 1 { throw error }
    }
  }
  fatalError("unreachable")
}

التراجع الأسي

انتظر مدة أطول تدريجيًا بين محاولات إعادة الاتصال لتجنب إرهاق خادم يعاني من مشكلات: 1s و2s و4s.

for attempt in 0..<maxRetries {
  do { return try await fetch() } catch {
    if attempt < maxRetries - 1 {
      try await Task.sleep(nanoseconds: UInt64(pow(2.0, Double(attempt))) * 1_000_000_000)
    } else { throw error }
  }
}

استخدام Jitter لمنع موجة الطلبات

أضف Jitter عشوائيًا إلى فترات التأخير الخاصة بالتراجع حتى لا تصل العملاء الذين يعيدون المحاولة إلى الخادم جميعًا في الوقت نفسه.

let baseDelay = pow(2.0, Double(attempt))
let jitter = Double.random(in: 0..<1)
let delay = (baseDelay + jitter) * 1_000_000_000
try await Task.sleep(nanoseconds: UInt64(delay))

الأخطاء القابلة لإعادة المحاولة وغير القابلة لها

أعد المحاولة مع الأخطاء المؤقتة فقط. يجب عدم إعادة محاولة أخطاء العميل، مثل 401 و400.

func isRetryable(_ error: Error) -> Bool {
  if let urlErr = error as? URLError {
    return urlErr.code == .timedOut || urlErr.code == .networkConnectionLost
  }
  if let netErr = error as? NetworkError, case .httpError(let code) = netErr {
    return code >= 500
  }
  return false
}

URLSession في الخلفية

تواصل جلسة الخلفية تنزيل الملفات حتى عندما يكون تطبيقك معلقًا أو منهيًا.

let config = URLSessionConfiguration.background(withIdentifier: "com.myapp.background")
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

URLSessionDelegate للمهام في الخلفية

طبّق URLSessionDelegate لتلقي استدعاءات الإكمال عندما يُعاد تشغيل التطبيق بعد انتهاء مهمة في الخلفية.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
  let dest = documentsURL.appendingPathComponent("download.pdf")
  try? FileManager.default.moveItem(at: location, to: dest)
}

معالج تحديث التطبيق في الخلفية

في AppDelegate، احفظ معالج إكمال المهمة في الخلفية واستدعِه عند انتهاء جميع المهام.

func application(_ app: UIApplication, handleEventsForBackgroundURLSession id: String, completionHandler: @escaping () -> Void) {
  backgroundCompletionHandler = completionHandler
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
  DispatchQueue.main.async { self.backgroundCompletionHandler?() }
}

مهمة تنزيل باستخدام جلسة الخلفية

استخدم downloadTask(with:) في جلسة خلفية لتنزيل الملفات الكبيرة بموثوقية.

let task = session.downloadTask(with: URL(string: "https://cdn.example.com/large.zip")!)
task.resume()

مهمة رفع في الخلفية

تدعم جلسات الخلفية أيضًا مهام الرفع التي تواصل عملها عندما لا يكون التطبيق قيد التشغيل.

var request = URLRequest(url: uploadURL)
request.httpMethod = "POST"
let task = session.uploadTask(with: request, fromFile: localFileURL)
task.resume()

مراقبة التقدم

راقب URLSessionTaskDelegate لتتبع تقدم الرفع والتنزيل وتحديث واجهة المستخدم.

func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
  let progress = Double(totalBytesSent) / Double(totalBytesExpectedToSend)
  DispatchQueue.main.async { self.uploadProgress = progress }
}

دمج إعادة المحاولة مع الخلفية

استخدم إعادة المحاولة في الواجهة الأمامية لطلبات API، وجلسات الخلفية لعمليات التنزيل والرفع طويلة الأمد.

// API calls: async/await + exponential backoff retry
// Large downloads: URLSessionConfiguration.background + delegate

تحقق سريع

ما التقنية التي تمنع العملاء الذين يعيدون المحاولة من الوصول جميعًا إلى الخادم في اللحظة نفسها؟

مراجعة الدرس

طبّق إعادة المحاولة باستخدام التراجع الأسي مع Jitter لمعالجة الأخطاء المؤقتة. أعد المحاولة فقط مع أخطاء 5xx وأخطاء انتهاء المهلة. استخدم URLSessionConfiguration.background مع delegate لعمليات التنزيل والرفع التي يجب أن تستمر رغم تعليق التطبيق.

الأسئلة الشائعة

هل درس «منطق إعادة المحاولة وURLSession في الخلفية» مجاني؟

نعم — نص درس «منطق إعادة المحاولة وURLSession في الخلفية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «منطق إعادة المحاولة وURLSession في الخلفية»؟

نفّذوا التراجع الأُسّي وواصلوا التنزيلات في الخلفية. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «منطق إعادة المحاولة وURLSession في الخلفية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ‏URLSession data(from:) مع async/await
  2. ‏Codable: ترميز JSON وفك ترميزه
  3. معالجة الأخطاء ورموز حالة HTTP
  4. منطق إعادة المحاولة وURLSession في الخلفية
← العودة إلى Swift Academy