ตรรกะการลองใหม่และ URLSession เบื้องหลัง
ใช้งานการหน่วงเวลาแบบทวีคูณ และทำให้การดาวน์โหลดดำเนินต่อในเบื้องหลัง
ตรรกะการลองใหม่และ URLSession เบื้องหลัง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องลองใหม่
ความล้มเหลวชั่วคราว เช่น หมดเวลาและ 503 บริการไม่พร้อมใช้งาน สามารถกู้คืนได้ ตรรกะการลองใหม่ช่วยเพิ่มความทนทานโดยไม่ต้องให้ผู้ใช้ดำเนินการเอง
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")
}การหน่วงเวลาเพิ่มแบบทวีคูณ
รอให้นานขึ้นเรื่อย ๆ ระหว่างการลองใหม่ เพื่อไม่ให้เซิร์ฟเวอร์ที่กำลังมีปัญหารับภาระมากเกินไป เช่น 1 วินาที, 2 วินาที และ 4 วินาที
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 }
}
}การสุ่มหน่วงเวลาเพื่อป้องกันการแห่เข้าพร้อมกัน
เพิ่มการหน่วงเวลาแบบสุ่มให้กับช่วงรอ เพื่อไม่ให้ไคลเอ็นต์ที่กำลังลองใหม่ทั้งหมดเข้าถึงเซิร์ฟเวอร์พร้อมกัน
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ตรวจสอบอย่างรวดเร็ว
เทคนิคใดช่วยป้องกันไม่ให้ไคลเอ็นต์ที่กำลังลองใหม่ทั้งหมดเข้าถึงเซิร์ฟเวอร์ในเวลาเดียวกัน
สรุปบทเรียน
ใช้การลองใหม่ร่วมกับการหน่วงเวลาเพิ่มแบบทวีคูณและการสุ่มหน่วงเวลาสำหรับข้อผิดพลาดชั่วคราว ให้ลองใหม่เฉพาะข้อผิดพลาด 5xx และข้อผิดพลาดหมดเวลา ใช้ URLSessionConfiguration.background ร่วมกับ delegate สำหรับการดาวน์โหลดและอัปโหลดที่ต้องทำงานต่อได้แม้แอปถูกพักการทำงาน
คำถามที่พบบ่อย
บทเรียน “ตรรกะการลองใหม่และ URLSession เบื้องหลัง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตรรกะการลองใหม่และ URLSession เบื้องหลัง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตรรกะการลองใหม่และ URLSession เบื้องหลัง”
ใช้งานการหน่วงเวลาแบบทวีคูณ และทำให้การดาวน์โหลดดำเนินต่อในเบื้องหลัง คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ตรรกะการลองใหม่และ URLSession เบื้องหลัง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- URLSession data(from:) พร้อม async/await
- Codable: การเข้ารหัสและถอดรหัส JSON
- การจัดการข้อผิดพลาดและรหัสสถานะ HTTP
- ตรรกะการลองใหม่และ URLSession เบื้องหลัง