SDWebImage คือไลบรารีสำหรับการโหลดภาพแบบไม่ซังโครนัสบน iOS และ macOS ที่ให้ API แบบเดียวสำหรับการทำงานกับเครือข่าย แคช และแอนิเมชั่น ตามข้อมูลจาก คลังอย่างเป็นทางการ ไลบรารีนี้ถูกใช้ในมากกว่า 100,000 โปรเจกต์ และรองรับ GIF, WebP, SVG และการโหลดแบบค่อยเป็นลำดับ SDWebImage มีแคชอัตโนมัติบนดิสก์และหน่วยความจำ รวมถึงการผนวกานกับ UIKit และ SwiftUI
หัวข้อสำคัญ
SDWebImage คือไลบรารีสำหรับการโหลดภาพแบบไม่ซังโครนัสบนแพลตฟอร์ม Apple (iOS, macOS, tvOS, watchOS) โดยมีเพนาการสำหรับ UIImageView กับเมธอด sd_setImage ที่สามารถโหลด แคช และแสดงภาพจากแหล่งใดๆ ได้ในเดียวเดียวกับโค้ดเดียวเท่านั้น
ไลบรารีรองรับ การโหลดแบบค่อยเป็นลำดับ (ภาพจะปรากฏขึ้นเมื่อไบต์ถูกรับมา) ภาพแอนิเมชั่น (GIF, APNG) การแปลงรูป (การทำให้เป็นมุมกลม การตัดเฉเฉื่อน การใส่ลายน้ำ) และตัวถอดรหัสที่กำหนดเอง ตาม สถิติ GitHub SDWebImage มีมากกว่า 25,000 ดาว และถูกใช้ในแอปพลิเคชั่นหลัก รวมถึง Twitter, Pinterest และ Instagram
สถาปัตยกรรมสร้างขึ้นจากโซ่ส่วนประกอบ: Coder (การถอดรหัส), Cache (การจัดเก็บ), Loader (เครือข่าย) และ Transformer (การประมวลผล) แต่ละส่วนประกอบสามารถแทนที่ได้ ทำให้สามารถปรับไลบรารีให้เหมาะกับความต้องการเฉพาะของโปรเจกต์
SDWebImageManager คือส่วนกลางที่ประสานงานการโหลด โดยรับ URL ตรวจสอบแคช โหลดข้อมูล ถอดรหัสเป็น UIImage และส่งต่อไปยง ImageView หรือ Completion Handler ตัวจัดการทำงานผ่านซิงเกิลทอนที่ใช้ร่วมกัน สามารถเข้าถึงได้จากทุกส่วนของแอพพลิเคชั่น
ตัวจัดการจะตรวจสอบแคชหน่วยความจำ (NSDictionary กับ UIImage) ก่อน จากนั้นจึงตรวจสอบแคชบนดิสก์ (ระบบไฟล์) เมื่อไม่เจอ จะมีการร้องขอเครือข่ายผ่าน NSURLSession หลังจากการโหลด ข้อมูลจะถูกถอดรหัส ผ่านการแปลงรูป และถูกจัดเก็บไว้ในแคชทั้งสอง กระบวนการทั้งหมดทำงานในคัวบางหลัง และผลลัพธ์จะถูกส่งไปยังคัวหลัก
UIImageView+WebCache คือเพนาการ Objective-C (สามารถเข้าถึงได้จาก Swift) ที่เพิ่มเมธอด sd_setImage เมธอดนี้รับ URL, placeholder, ตัวเลือก (SDWebImageOptions) และบล็อกสำเร็จสิ้น เพนาการจะยกเลีกคำขอก่อนหน้าโดยอัตโนมัติเมื่อเซลล์ตารางถูกนำกลับมาใช้อีกผ่านกลไก sd_cancelCurrentImageLoad
สถาปัตยกรรม SDWebImage แบ่งออกเป็นหลายโมดูลที่มีขอบเขตความรับผิดชอบที่ชัดเจน แต่ละคลาสแก้ปัญหาหนึ่งอย่าง ตั้งแต่การโหลดไปจนถึงการแสดงผล
SDWebImageManager คือส่วนติดต่อสำหรับการดำเนินการกับภาพทั้งหมด โดยมีการอ้างอิงไปยัง ImageCache (SDImageCache) และ ImageLoader (SDWebImageDownloader) ผ่านตัวแทน SDWebImageManagerDelegate คุณสามารถสกัดการโหลดและเปลี่ยนแปลง URL หรือพฤติกรรมได้
SDImageCache คือแคชสองระดับ (หน่วยความจำ + ดิสก์) ที่เริ่มต้นด้วยชื่อพื้นที่เฉพาะ แคชหน่วยความจำจัดเก็บ UIImage โดยมีขอจำกัดที่กำหนดได้ (โดยค่าเริ่มต้น — จนกระทั่งเตือนหน่วยความจำของระบบ) แคชบนดิสก์จัดเก็บข้อมูลในไดเรกตอรี่ Library/Caches โดยมีระยะเวลาการจัดเก็บที่กำหนดได้ (ค่าเริ่มต้น 7 วัน)
SDWebImageDownloader คือตัวแทน HTTP ที่อิงอยู่บน NSURLSession ที่รองรับส่วนหัว กำหนดเวลาหมด และการลองใหม่ ตัวดาวน์โหลดจะรวมคำขอที่เหมือนกันเป็นการเรียกเครือข่ายเดียว และแจจ่ายผลลัพธ์ไปยังผู้สมัครทุกราย
SDWebImage ใช้แคชสองระดับโดยมีลำดับการตรวจสอบแน่นอน: หน่วยความจำก่อน จากนั้นดิสก์ แคย์ของแคชคือ URL สมบูรณ์ของภาพที่ไม่มีพารามิเตอร์คำสั่งหรือ MD5 แฮชของมัน
| ระดับ | ชนิดการจัดเก็บ | เนื้อหา | ขอจำกัด |
|---|---|---|---|
| แคชหน่วยความจำ | NSCache (NSDictionary) | UIImage (บิตแมปที่ถอดรหัสแล้ว) | จนกระทั่งหน่วยความจำ |
| แคชบนดิสก์ | ระบบไฟล์ | NSData (JPEG/PNG/WebP) | 7 วัน TTL (กำหนดได้) |
| แคชลบองอัตโนมัติ | หน่วยความจำ + ดิสก์ | แคชรวมของเฟรมเวิร์ค | ขนาดไฟล์ที่กำหนดได้ |
เมื่อได้รับการเตือนหน่วยความจำ iOS จะแจ้ง SDImageCache ผ่าน UIApplicationDidReceiveMemoryWarningNotification หลังจากนั้นแคชหน่วยความจำจะถูกล้างออกอย่างสมบูรณ์ แคชบนดิสก์จะถูกล้างตาม TTL หรือเมื่อเกินขอจำกัด โดยเรียงลำดับไฟล์ตามวันที่เข้าถึงล่าสุด
สำหรับการจัดการแคชด้วยตนเอง มีเมธอดดังต่อไปนี้: clearMemory, clearDisk, calculateSize การแคชสามารถปิดการใช้งานสำหรับคำขอเฉพาะได้โดยใช้ตัวเลือก SDWebImageCacheMemoryOnly หรือ SDWebImageAvoidAutoSetImage
SDWebImage มีหลายอินเตอร์เฟสสำหรับการโหลดภาพ: ตั้งแต่เพนาการ UIImageView ที่เรียบง่าย ไปจนถึงตัวจัดการขั้นสูงที่มีการประมวลผลแบบกำหนดเอง
sd_setImage คือเมธอดหลักสำหรับการโหลดภาพใน UIImageView โดยรับ URL, placeholder และพารามิเตอร์ที่เลือกได้ผ่าน Options และ Context โดยทุก Completion Handler จะทำงานในเธรดหลัก
let imageView = UIImageView()
imageView.sd_setImage(
with: URL(string: "https://example.com/photo.jpg"),
placeholderImage: UIImage(named: "placeholder"),
options: [.progressiveLoad, .retryFailed],
context: [.imageThumbnailPixelSize : CGSize(width: 300, height: 300)]
)
เมธอดจะส่งคืน SDWebImageToken (การดำเนินการ) ที่สามารถยกเลิกได้หากจำเป็น ภายใน sd_setImage จะเรียก SDWebImageManager.load โดยส่ง ImageView เป็น Target สำหรับการตั้งค่าภาพอัตโนมัติ
SDWebImage รองรับ Transformer — โปรโตคอลที่มีเมธอดเดียว transformedImage การแปลงรูปในตัวรวมถึง: วงกลม มุมมน การวางตัวกรองสี และการเปลี่ยนขนาด การแปลงรูปสามารถรวมกันได้โดยใช้อุปกรณ์ &&
let transformer = SDImageResizingTransformer(
size: CGSize(width: 200, height: 200),
scaleMode: .aspectFill
)
let roundedTransformer = SDImageRoundCornerTransformer(
radius: 16,
corners: .allCorners,
borderWidth: 0
)
imageView.sd_setImage(
with: url,
placeholderImage: placeholder,
context: [.imageTransformer : transformer && roundedTransformer]
)
ไลบรารีให้ WebImage — คอมโพนนต์ View สำหรับ SwiftUI ที่รองรับ placeholder ตัวบ่งบอกความคืบหน้า และการจัดการข้อผิดพลาด คอมโพนนต์จะติดตามวงจรของ View โดยอัตโนมัติ และยกเลิกการโหลดเมื่อหายไป
struct CachedImageView: View {
let url: URL
var body: some View {
WebImage(url: url) { phase in
if let image = phase.image {
image.resizable()
} else if phase.error {
Color.red
} else {
ProgressView()
}
}
}
}
SDWebImage มีระบบการแปลงรูปที่ยืดหยุ่นผ่านโปรโตคอล SDImageTransformer การแปลงรูปจะถูกนำไปใช้หลังจากการถอดรหัสแต่ก่อนการแคช — ผลลัพธ์ของการแปลงรูปจะถูกจัดเก็บไว้บนดิสก์ภายใต้แคย์ใหม่ ซึ่งป้องกันการนำไปใช้ซ้ำในคำขอที่ต่อไป
การแปลงรูปในตัวรวมถึง: SDImageResizingTransformer (การเปลี่ยนขนาดด้วย mode), SDImageRoundCornerTransformer (มุมมนแบบมีขอบเลือกได้), SDImageFlipTransformer (การพลิกภาพกระจก) และ SDImageFilterTransformer (ตัวกรอง CoreImage) การรวมกันทำได้โดยใช้อุปกรณ์ && สร้างโซ่กระบวนการประมวลผล
สำหรับการแปลงรูปที่กำหนดเอง เพียงแค่นำไปใช้โปรโตคอล SDImageTransformer กับเมธอด transformedImageWithImage:forKey: แคย์ของการแปลงรูปจะถูกเพิ่มไปยังแคย์ของแคชโดยอัตโนมัติ เพื่อป้องกันการซ้ำกันระหว่างรุ่นที่แตกต่างกันของภาพเดียวกัน
บนแพลตฟอร์ม iOS คู่แข่งหลักของ SDWebImage คือ Kingfisher (Swift บริสุทธิ์) และ Nuke การเลือกระหว่าง SDWebImage และ Kingfisher มักจะถูกกำหนดโดยภาษาของโปรเจกต์และฟังก์ชันที่ต้องการ
| คุณลักษณะ | SDWebImage | Kingfisher |
|---|---|---|
| ภาษา | Objective-C + Swift API | Swift (100%) |
| SwiftUI | WebImage View | KFImage View |
| GIF | ใช่ (ในตัว) | ใช่ (ในตัว) |
| WebP | ใช่ (ปลั๊กอิน) | ใช่ (ในตัว) |
| การโหลดแบบค่อยเป็นลำดับ | ใช่ (กับปลั๊กอิน) | ใช่ |
| ขนาดเฟรมเวิร์ค | ~1.2 MB | ~900 KB |
| แคช | หน่วยความจำ + ดิสก์ | หน่วยความจำ + ดิสก์ |
| การสนับสนุน CocoaPods | ใช่ | ใช่ |
SDWebImage ยังคงเป็นทางเลือกสำหรับโปรเจกต์ที่ใช้ Objective-C หรือโปรเจกต์แบบลูกผสม Kingfisher เหมาะกับโปรเจกต์ Swift บริสุทธิ์มากกว่า โดยเฉพาะเรื่องความปลอดภัยของชนิดและไวยากรณ์เฉพาะของ Swift ไลบรารีทั้งสองมีสถาปัตยกรรมแคชและประสิทธิภาพที่คล้ายกัน
การเชื่อมต่อ SDWebImage สามารถทำได้ผ่าน Swift Package Manager, CocoaPods หรือ Carthage ไลบรารีแบ่งออกเป็นโมดูล: หลัก (SDWebImage), Coder (รูปแบบเพิ่มเติม) และ MapKit (สำหรับ MKAnnotationView)
// Swift Package Manager (Package.swift)
dependencies: [
.package(
url: "https://github.com/SDWebImage/SDWebImage.git",
from: "5.19.0"
)
]
// CocoaPods (Podfile)
pod 'SDWebImage', '~> 5.19.0'
// ปลั๊กอินสำหรับ WebP และ SVG:
pod 'SDWebImageWebPCoder'
pod 'SDWebImageSVGCoder'
หลังจากติดตั้ง ไลบรารีพร้อมใช้งานโดยไม่ต้องการตั้งค่าเพิ่มเติม สำหรับการปรับแต่งแคช ให้สร้างอินสแตนซ์ของ SDImageCache ที่มีชื่อพื้นที่เฉพาะ และส่งต่อไปยัง SDWebImageManager ในระหว่างการเริ่มต้น การตั้งค่าทั่วไปทำได้ผ่าน SDWebImageManager.shared
// การปรับแต่งแคช
let config = SDImageCacheConfig()
config.maxDiskAge = 14 * 86400 // 14 วันแทน 7
config.maxDiskSize = 500 * 1024 * 1024 // 500 MB
config.shouldCacheImagesInMemory = .true
let cache = SDImageCache(
namespace: "custom",
diskCacheDirectory: FileManager.default.urls(
for: .cachesDirectory,
in: .userDomainMask
).first?.appendingPathComponent("custom_cache"),
config: config
)
SDWebImageManager.sharedImageCache = cache
คำถามที่พบบ่อย
SDWebImage คือไลบรารีสำหรับการโหลดภาพแบบไม่ซังโครนัสบน iOS และ macOS โดยจะแก้ปัญหาเรื่องแคช การถอดรหัส การแปลงรูป และการแสดงภาพจากเครือข่าย ซึ่งช่วยให้นักพัฒนาไม่ต้องจัดการเธรดและหน่วยความจำด้วยตนเอง
ในเมธอด cellForRowAt ให้ใช้ sd_setImage กับ URL และ placeholder ไลบรารีจะยกเลิกคำขอก่อนหน้าโดยอัตโนมัติเมื่อนำเซลล์กลับมาใช้อีก สำหรับการเลื่อนไผลชนิดราบรื่น ให้ระบุตัวเลือก .progressiveLoad และกำหนดขนาดรูปย่อผ่านคอนเทกซ์ต์
SDWebImage เขียนด้วย Objective-C และมี Swift wrapper ส่วน Kingfisher เขียนด้วย Swift บริสุทธิ์ SDWebImage มีระบบนิเวศของปลั๊กอินที่กว้างกว่า (WebP, SVG, MapKit) Kingfisher ให้ความปลอดภัยของชนิดที่ดีกว่าและการผนวกานกับ Swift Concurrency
ติดตั้งปลั๊กอิน SDWebImageWebPCoder ผ่าน CocoaPods หรือ SPM จากนั้นลงทะเบียนตัวถอดรหัสโดยการเรียก SDImageWebPCoder.shared ใน AppDelegate หลังจากการลงทะเบียน ไลบรารีจะตรวจจับรูปแบบโดยอัตโนมัติและถอดรหัส WebP
เรียก SDImageCache.shared.clearMemory() สำหรับหน่วยความจำ และ SDImageCache.shared.clearDisk() สำหรับดิสก์ หากต้องการล้างเฉพาะไฟล์ที่ล้าสมัย ให้ใช้ clearDisk(completion:) พร้อมการตรวจสอบ TTL เมธอด calculateSizeWithCompletionBlock จะคืนขนาดแคชปัจจุบัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ