Kingfisher é uma biblioteca para carregar e armazenar em cache imagens no iOS, macOS e watchOS, escrita em Swift puro. De acordo com o repositório oficial, a biblioteca oferece suporte completo a Swift Concurrency, Combine e SwiftUI, além de cache automático em dois níveis. Kingfisher é conhecida por sua API type-safe e fácil integração com projetos em Swift.
Pontos principais
Kingfisher é uma biblioteca para carregamento assíncrono e cache de imagens em plataformas Apple, escrita inteiramente em Swift. O autor da biblioteca é Wei Wang (onevcat). Kingfisher fornece um conjunto de ferramentas para carregar imagens da rede com cache automático, transformações e suporte a tecnologias modernas do Swift: async/await, Combine, Sendable.
A biblioteca tem mais de 23.000 estrelas no GitHub e é usada em aplicativos como Telegram, Snapchat e Dropbox. Kingfisher suporta GIF, APNG, HEIF e todos os formatos de imagem padrão. Cada requisição retorna um Result
A arquitetura do Kingfisher é construída em três componentes principais: Manager (gerenciador de downloads), Cache (cache de dois níveis) e Processor (transformações). Esses componentes são conectados através de protocolos, permitindo substituir qualquer parte sem alterar as dependências.
KingfisherManager é a classe central que coordena o carregamento, cache e processamento de imagens. Ela contém referências a ImageCache e ImageDownloader e fornece um único método retrieveImage que retorna a imagem pronta após passar por todas as etapas.
Ao chamar retrieveImage, o Manager primeiro verifica o Memory Cache — um NSCache com UIImage, onde a chave é formada a partir da URL de origem e do CacheSerializer. Se a imagem for encontrada, ela é retornada imediatamente. Em caso de falha, verifica-se o Disk Cache — leitura do sistema de arquivos com descriptografia através do serializador. Se o cache em disco estiver vazio, uma requisição de rede é feita através do ImageDownloader, o resultado é decodificado, transformado e salvo em ambos os níveis de cache.
A partir da versão 7.0, o Kingfisher suporta totalmente async/await. O método retrieveImage está disponível como uma função assíncrona, retornando Result diretamente sem blocos de conclusão. Isso permite usar a biblioteca em arquiteturas Swift modernas com Structured Concurrency.
O Kingfisher é dividido em vários módulos, cada um resolvendo sua própria tarefa. Essa separação simplifica os testes e a substituição de componentes.
KingfisherManager é uma fachada que combina carregamento, cache e processadores. Por padrão, usa-se o singleton KingfisherManager.shared, mas uma instância separada com configurações personalizadas pode ser criada para cenários isolados (por exemplo, para testes unitários).
ImageCache é um cache de dois níveis com configurações separadas para memória e disco. O Memory Cache não tem limite no número de objetos, mas o sistema o limpa quando a memória está baixa. O Disk Cache armazena arquivos em um diretório com TTL configurável (padrão 7 dias), limite de tamanho (padrão 0 — sem limite) e limpeza automática.
ImageProcessor é um protocolo com um único método process(item:options:) que retorna a imagem processada. Implementações integradas: ResizingImageProcessor (redimensionamento), RoundCornerImageProcessor (arredondamento), BlurImageProcessor (desfoque gaussiano), OverlayImageProcessor (sobreposição de cor). Os processadores podem ser combinados usando o operador |>.
A arquitetura de cache do Kingfisher é baseada no princípio write-through: os dados são gravados em ambos os níveis simultaneamente e a leitura começa no nível mais rápido — a memória. A chave do cache é a URL absoluta da imagem após remover os parâmetros de consulta.
| Parâmetro | Memory Cache | Disk Cache |
|---|---|---|
| Armazenamento | NSCache (RAM) | Sistema de arquivos (SSD) |
| Formato | UIImage (decodificado) | Data (comprimido, via serializador) |
| Limpeza | UIApplication.didReceiveMemoryWarningNotification | TTL + excedeu o limite |
| Serialização | Não necessária | CacheSerializer (padrão PNG/JPEG) |
| Segurança de threads | Sim (acesso sincronizado) | Sim (fila IO + barreiras) |
Para gerenciar o tamanho do Disk Cache, calcula-se o tamanho total dos arquivos ordenados pela data do último acesso. Quando o limite é excedido, os arquivos com a data de acesso mais antiga são removidos até que o tamanho fique abaixo de 50% do limite. A limpeza TTL ocorre durante a inicialização do cache e em cada chamada a cleanExpired.
O Kingfisher fornece várias interfaces para carregar imagens: uma extensão no UIImageView, um gerenciador separado e uma View do SwiftUI.
kf é uma propriedade namespace no UIImageView que fornece os métodos setImage, cancelDownload e indicadores de carregamento. O método setImage aceita URLSource e os parâmetros opcionais Options e 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("Carregado \(receivedSize) / \(totalSize)")
}
)
O método retorna um DownloadTask que suporta cancelamento via cancel e rastreamento de progresso. Internamente, setImage chama KingfisherManager.shared.retrieveImage com detecção automática do ImageView como Target.
A partir do Kingfisher 7.0, o método setImage está disponível em uma versão assíncrona. Isso permite integrar o carregamento de imagens no Swift Structured Concurrency sem callbacks.
func loadAvatar() async {
do {
let result = try await imageView.kf.setImage(
with: url,
options: [.processor(ResizingImageProcessor(
targetSize: CGSize(width: 100, height: 100)
))]
)
// result.image contém UIImage
} catch {
print("Falhou: \(error)")
}
}
KFImage é uma View do SwiftUI, similar à AsyncImage do iOS 15, mas com suporte completo ao cache do Kingfisher. A View usa automaticamente o KingfisherManager.shared, mas suporta um gerenciador personalizado através do modificador .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)
}
}
O Kingfisher fornece um sistema de indicadores integrado para exibir o progresso do carregamento de imagens. IndicatorType é uma enumeração com três opções: .activity (UIActivityIndicatorView), .progress (UIProgressView) e .custom (implementação personalizada do protocolo Indicator). O indicador aparece automaticamente sobre o ImageView durante o carregamento e é ocultado após a conclusão.
Para um indicador personalizado, é necessário implementar o protocolo Indicator com os métodos startAnimatingView() e stopAnimatingView(). Isso permite soluções híbridas: um esqueleto com animação shimmer, uma imagem placeholder com revelação gradual ou um logotipo com animação de opacidade. O Kingfisher também suporta a configuração global do indicador através de KingfisherManager.shared.defaultOptions.
Na plataforma iOS, Kingfisher e SDWebImage são as duas bibliotecas dominantes para carregamento de imagens. A escolha entre elas depende da linguagem do projeto, requisitos de desempenho e ecossistema.
| Critério | Kingfisher | SDWebImage |
|---|---|---|
| Linguagem | Swift (100%) | Objective-C + Swift |
| Async/Await | Suporte nativo | Via wrapper |
| Combine | Publisher integrado | Não |
| Sendable | Suporta | Limitado |
| Type Safety | Completo (tipo Result) | Via Any? |
| ImageProcessor | Composto via |> | Transformer via && |
| Tamanho | ~900 KB | ~1.2 MB |
| Estrelas GitHub | 23.000+ | 25.000+ |
A principal vantagem do Kingfisher é sua arquitetura Swift-first: suporte completo a async/await, Combine Publishers, Sendable e tipos Result. O SDWebImage mantém a liderança devido ao seu ecossistema mais amplo de plugins (WebP, SVG, MapKit) e suporte a Objective-C.
O Kingfisher é instalado via Swift Package Manager, CocoaPods ou Carthage. Após a instalação, basta importar o módulo e chamar qualquer método de carregamento — a biblioteca está pronta para uso sem configuração adicional.
// Swift Package Manager (Package.swift)
dependencies: [
.package(
url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"
)
]
// CocoaPods (Podfile)
pod 'Kingfisher', '~> 7.12'
Para personalizar as configurações globais, usa-se KingfisherManager.shared. É possível alterar o tempo limite do downloader, a estratégia de cache e os processadores padrão. Abaixo está um exemplo de configuração de um cache de 500 MB com TTL de 14 dias.
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 também é configurado através do gerenciador: é possível definir uma URLSessionConfiguration personalizada com timeouts, cabeçalhos e políticas de cache. Para monitoramento de progresso, o módulo KFIndicator está disponível com suporte a ActivityIndicator, ProgressView e indicadores personalizados.
Perguntas frequentes
Kingfisher é uma biblioteca para carregar imagens no iOS, escrita em Swift puro. É usada para carregamento assíncrono, cache e transformação de imagens da rede com integração completa ao SwiftUI, UIKit e tecnologias modernas do Swift.
Adicione o pacote https://github.com/onevcat/Kingfisher.git com versão a partir de 7.12.0 no Xcode através de File → Add Packages. Ou especifique a dependência no Package.swift com o parâmetro from: "7.12.0". Após a instalação, importe o módulo Kingfisher.
Kingfisher suporta JPEG, PNG, GIF, APNG, HEIF e WebP. Todos os formatos são decodificados através dos frameworks do sistema (ImageIO, CoreGraphics). O GIF é suportado via CGImageSource com carregamento progressivo e animação.
Kingfisher é escrito em Swift puro e suporta totalmente async/await, Combine e Sendable. Ele fornece uma API Result type-safe e uma arquitetura modular através de protocolos, simplificando a substituição de componentes e os testes.
Para limpar o Memory Cache, chame KingfisherManager.shared.cache.clearMemoryCache(). Para o Disk Cache, use clearDiskCache(). Para remover apenas arquivos expirados — cleanExpiredDiskCache(). O tamanho do cache pode ser verificado através de cache.calculateDiskStorageSize().
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também