How to Download and Display SVG Image in Swift IOS App by Kingfisher
When working with images in an iOS app, we often have to download and display remote image from the internet. There are many great libraries out there help us do this really simple. I myself choose Kingfisher as the library to go because it is a modern, lightweight and pure-Swift library.
Kingfisher helped me to display and cache almost every typical image format we want. But with SVG image, we need to do a little bit more. We have to manually decode SVG into image data with a Processor.
We do this with a little help from PocketSVG library:
import Kingfisher
import PocketSVG
struct SVGProcessor: ImageProcessor {
// `identifier` should be the same for processors with the same properties/functionality
// It will be used when storing and retrieving the image to/from cache.
let identifier = "svgprocessor"
var size: CGSize!
init(size: CGSize) {
self.size = size
}
// Convert input data/image to target image and return it.
func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> Image? {
switch item {
case .image(let image):
// print("already an image")
return image
case .data(let data):
// print("svg string")
if let svgString = String(data: data, encoding: .utf8){
//let layer = SVGLayer(
let path = SVGBezierPath.paths(fromSVGString: svgString)
let layer = SVGLayer()
layer.paths = path
let frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
layer.frame = frame
let img = self.snapshotImage(for: layer)
return img
}
return nil
}
}
func snapshotImage(for view: CALayer) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
view.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Then we can use this processor like this:
let svgUrl = URL(string: "http://svg_image_url")!
let processor = SVGProcessor(size: CGSize(width: 240, height: 43))
KingfisherManager.shared.retrieveImage(with: svgUrl, options: [.processor(processor), .forceRefresh]) { result in
switch (result){
case .success(let value):
myImageView.image = value.image
case .failure(let error):
print("error", error.localizedDescription)
}
}
Now we can use nice and clean Kingfisher API with our SVG image.