Kingfisher este o bibliotecă pentru încărcarea și stocarea în cache a imaginilor pe iOS, macOS și watchOS, scrisă în Swift pur. Conform repository-ului oficial, biblioteca oferă suport complet pentru Swift Concurrency, Combine și SwiftUI, precum și stocare automată în cache pe două niveluri. Kingfisher este cunoscută pentru API-ul sigur din punct de vedere al tipurilor și integrarea ușoară cu proiectele Swift.
Principalele puncte
Kingfisher — o bibliotecă pentru încărcarea asincronă și stocarea în cache a imaginilor pe platformele Apple, scrisă integral în Swift. Autorul bibliotecii este Wei Wang (onevcat). Kingfisher oferă un set de instrumente pentru încărcarea imaginilor din rețea cu stocare automată în cache, transformări și suport pentru tehnologiile moderne Swift: async/await, Combine, Sendable.
Biblioteca are peste 23 000 de stele pe GitHub și este utilizată în aplicații precum Telegram, Snapchat și Dropbox. Kingfisher suportă GIF, APNG, HEIF și toate formatele standard de imagini. Fiecare solicitare returnează un Result
Arhitectura Kingfisher este construită pe trei componente principale: Manager (manager de încărcare), Cache (cache pe două niveluri) și Processor (transformări). Aceste componente sunt conectate prin protocoale, ceea ce permite înlocuirea oricărei părți fără a modifica dependențele.
KingfisherManager — clasa centrală care coordonează încărcarea, stocarea în cache și procesarea imaginilor. Conține referințe la ImageCache și ImageDownloader și oferă o metodă unică retrieveImage care returnează imaginea gata după parcurgerea tuturor etapelor.
La apelarea retrieveImage, Manager verifică mai întâi Memory Cache — NSCache cu UIImage, unde cheia este formată din URL-ul sursei și CacheSerializer. Dacă imaginea este găsită — este returnată imediat. În caz de lipsă, se verifică Disk Cache — citire din sistemul de fișiere cu decriptare prin serializer. Dacă cache-ul pe disc este gol, se execută o solicitare de rețea prin ImageDownloader, rezultatul este decodat, transformat și salvat în ambele niveluri de cache.
Începând cu versiunea 7.0, Kingfisher suportă complet async/await. Metoda retrieveImage este disponibilă ca funcție asincronă, returnând Result direct fără blocuri de completare. Acest lucru permite utilizarea bibliotecii în arhitecturi moderne Swift cu Structured Concurrency.
Kingfisher este împărțită în mai multe module, fiecare rezolvând propria sarcină. Această divizare simplifică testarea și înlocuirea componentelor.
KingfisherManager — o fațadă care combină încărcarea, cache-ul și procesoarele. În mod implicit, se utilizează singleton-ul KingfisherManager.shared, dar se poate crea o instanță separată cu setări personalizate pentru scenarii izolate (de exemplu, pentru teste unitare).
ImageCache — cache pe două niveluri cu setări separate pentru memorie și disc. Memory Cache nu are limită de număr de obiecte, dar este curățată de sistem la lipsa de memorie. Disk Cache stochează fișierele într-un director cu setări TTL (implicit 7 zile), limită de dimensiune (implicit 0 — fără limită) și curățare automată.
ImageProcessor — protocol cu o singură metodă process(item:options:) care returnează imaginea procesată. Implementări încorporate: ResizingImageProcessor (redimensionare), RoundCornerImageProcessor (rotunjire), BlurImageProcessor (estompare gaussiană), OverlayImageProcessor (aplicare culoare). Procesoarele pot fi combinate prin operatorul |>.
Arhitectura cache-ului Kingfisher se bazează pe principiul write-through: datele sunt scrise simultan în ambele niveluri, iar citirea începe de la nivelul cel mai rapid — memoria. Cheia cache-ului este URL-ul absolut al imaginii după eliminarea parametrilor de interogare.
| Parametru | Memory Cache | Disk Cache |
|---|---|---|
| Stocare | NSCache (RAM) | Sistem de fișiere (SSD) |
| Format | UIImage (decodat) | Data (comprimat, prin serializer) |
| Curățare | UIApplication.didReceiveMemoryWarningNotification | TTL + depășire limită |
| Serializare | Nu este necesară | CacheSerializer (implicit PNG/JPEG) |
| Siguranță fire | Da (acces sincronizat) | Da (coadă IO + bariere) |
Pentru gestionarea dimensiunii Disk Cache se utilizează calcularea dimensiunii totale a fișierelor cu sortare după data ultimei accesări. La depășirea limitei, fișierele cu cea mai veche dată de acces sunt șterse până când dimensiunea scade sub 50% din limită. Curățarea TTL are loc la inițializarea cache-ului și la fiecare apel cleanExpired.
Kingfisher oferă mai multe interfețe pentru încărcarea imaginilor: extensie pe UIImageView, manager separat și SwiftUI View.
kf — proprietatea namespace pe UIImageView care oferă metodele setImage, cancelDownload și indicatoare de încărcare. Metoda setImage acceptă URLSource și parametrii opționali Options și completionHandler.
import Kingfisher
imageView.kf.setImage(
with: URL(string: "https://example.com/image.jpg"),
placeholder: UIImage(named: "placeholder"),
options: [
.processor(RoundCornerImageProcessor(radius: .point(12))),
.transition(.fade(0.3)),
.cacheMemoryOnly
],
progressBlock: { receivedSize, totalSize in
print("Încărcat \(receivedSize) / \(totalSize)")
}
)
Metoda returnează DownloadTask, care suportă anularea prin cancel și urmărirea progresului. Intern, setImage apelează KingfisherManager.shared.retrieveImage cu determinarea automată a ImageView ca Target.
Începând cu Kingfisher 7.0, metoda setImage este disponibilă în versiunea asincronă. Acest lucru permite integrarea încărcării imaginilor în Swift Structured Concurrency fără callback-uri.
func loadAvatar() async {
do {
let result = try await imageView.kf.setImage(
with: url,
options: [.processor(ResizingImageProcessor(
targetSize: CGSize(width: 100, height: 100)
))]
)
// result.image conține UIImage
} catch {
print("Eșuat: \(error)")
}
}
KFImage — SwiftUI View, similară cu AsyncImage din iOS 15, dar cu suport complet pentru cache-ul Kingfisher. View utilizează automat KingfisherManager.shared, dar suportă un manager personalizat prin modificatorul .configure.
struct AvatarView: View {
let url: URL
var body: some View {
KFImage(url)
.placeholder { ProgressView() }
.resizable()
.fade(duration: 0.25)
.forceTransition()
.frame(width: 80, height: 80)
.cornerRadius(40)
}
}
Kingfisher oferă un sistem încorporat de indicatoare pentru afișarea progresului încărcării imaginii. IndicatorType — o enumerare cu trei variante: .activity (UIActivityIndicatorView), .progress (UIProgressView) și .custom (implementare personalizată a protocolului Indicator). Indicatorul este afișat automat pe ImageView în timpul încărcării și ascuns după finalizare.
Pentru un indicator personalizat, trebuie implementat protocolul Indicator cu metodele startAnimatingView() și stopAnimatingView(). Acest lucru permite utilizarea soluțiilor hibride: schelet cu animație shimmer, imagine de substituție cu apariție treptată sau logo cu animație de transparență. Kingfisher suportă și setarea globală a indicatorului prin KingfisherManager.shared.defaultOptions.
Pe platforma iOS, Kingfisher și SDWebImage sunt cele două biblioteci dominante pentru încărcarea imaginilor. Alegerea între ele depinde de limbajul proiectului, cerințele de performanță și ecosistem.
| Criteriu | Kingfisher | SDWebImage |
|---|---|---|
| Limbaj | Swift (100%) | Objective-C + Swift |
| Async/Await | Suport nativ | Prin wrapper |
| Combine | Publisher încorporat | Nu |
| Sendable | Suportă | Limitat |
| Siguranță tipuri | Completă (tip Result) | Prin Any? |
| ImageProcessor | Composite prin |> | Transformer prin && |
| Dimensiune | ~900 KB | ~1.2 MB |
| Stele GitHub | 23 000+ | 25 000+ |
Avantajul cheie al Kingfisher este arhitectura Swift-first: suport complet pentru async/await, Combine Publishers, Sendable și tipuri Result. SDWebImage își păstrează liderul datorită ecosistemului mai larg de pluginuri (WebP, SVG, MapKit) și suportului pentru Objective-C.
Kingfisher se instalează prin Swift Package Manager, CocoaPods sau Carthage. După instalare, este suficient să importați modulul și să apelați orice metodă de încărcare — biblioteca este gata de funcționare fără configurație suplimentară.
// Swift Package Manager (Package.swift)
dependencies: [
.package(
url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"
)
]
// CocoaPods (Podfile)
pod 'Kingfisher', '~> 7.12'
Pentru personalizarea setărilor globale se utilizează KingfisherManager.shared. Se poate modifica timeout-ul încărcătorului, strategia de cache și procesoarele implicite. Mai jos este un exemplu de configurare a cache-ului de 500 MB cu TTL de 14 zile.
let cache = ImageCache(name: "custom")
cache.memoryStorage.config.totalCostLimit = 100 * 1024 * 1024
cache.diskStorage.config.sizeLimit = 500 * 1024 * 1024
cache.diskStorage.config.expiration = .days(14)
KingfisherManager.shared.cache = cache
ImageDownloader se configurează și prin manager: se poate seta o URLSessionConfiguration personalizată cu timeout-uri, antete și politici de cache. Pentru monitorizarea progresului, este disponibil modulul KFIndicator cu suport pentru ActivityIndicator, ProgressView și indicatoare personalizate.
Întrebări frecvente
Kingfisher — o bibliotecă pentru încărcarea imaginilor pe iOS, scrisă în Swift pur. Este utilizată pentru încărcarea asincronă, stocarea în cache și transformarea imaginilor din rețea cu integrare completă în SwiftUI, UIKit și tehnologiile moderne Swift.
Adăugați pachetul https://github.com/onevcat/Kingfisher.git cu versiunea de la 7.12.0 în Xcode prin File → Add Packages. Sau specificați dependența în Package.swift cu parametrul from: „7.12.0”. După instalare, importați modulul Kingfisher.
Kingfisher suportă JPEG, PNG, GIF, APNG, HEIF și WebP. Toate formatele sunt decodate prin framework-urile sistemului (ImageIO, CoreGraphics). GIF este suportat prin CGImageSource cu încărcare progresivă și animație.
Kingfisher este scris în Swift pur și suportă complet async/await, Combine și Sendable. Oferă un API sigur din punct de vedere al tipurilor Result și o arhitectură modulară prin protocoale, simplificând înlocuirea componentelor și testarea.
Pentru a curăța Memory Cache, apelați KingfisherManager.shared.cache.clearMemoryCache(). Pentru Disk Cache utilizați clearDiskCache(). Pentru a șterge doar fișierele expirate — cleanExpiredDiskCache(). Dimensiunea cache-ului se verifică prin cache.calculateDiskStorageSize().
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și