Skip to content

Instantly share code, notes, and snippets.

@saish98
Created June 24, 2022 07:39
Show Gist options
  • Save saish98/b848fc279ee0a1f87fb6afc20bcc0f33 to your computer and use it in GitHub Desktop.
Save saish98/b848fc279ee0a1f87fb6afc20bcc0f33 to your computer and use it in GitHub Desktop.
Svg image download from url
//
// Kingfisher+Svg.swift
// Created by Saish Chachad on 23/06/22.
//
import UIKit
import Kingfisher
import PocketSVG
// Convert SVG images from Server to UIImage
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) -> UIImage? {
switch item {
case .image(let image):
return image
case .data(let data):
if let svgString = String(data: data, encoding: .utf8) {
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
}
}
// Get actual image
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
}
}
// For SVG rendering only
extension UIImageView {
/// Use this function for downloading SVG image from URL
/// - Parameters:
/// - url: SVG image url
/// - processor: SVG Image Processor
func svgImage(from url: URL?, processor: SVGProcessor) {
guard let url = url else {
self.image = nil
return
}
KingfisherManager.shared.retrieveImage(with: url, options: [.processor(processor), .forceRefresh]) { result in
switch result {
case .success(let value):
DispatchQueue.main.async {
self.image = value.image
}
case .failure(let error):
print("Image download fail:\(error.localizedDescription)")
}
}
}
}
//
// TableViewCell.swift
// Created by Saish Chachad on 10/06/22.
//
import UIKit
final class TableViewCell: UITableViewCell {
// MARK: Outlets
@IBOutlet private weak var imgView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
/// Set Data
func setData(_ data: urlString) {
// Send image size here
let processor = SVGProcessor(size: CGSize(width: 17, height: 17))
imgView.svgImage(from: URL(string: urlString), processor: processor)
}
}
@crazypoo
Copy link

2023-04-13 10:51:26.829605+0800 FootballInfomation[32055:1334276] *** Assertion failure in hexTriplet::hexTriplet(NSString *__strong)(), SVGEngine.mm:904
2023-04-13 10:51:26.830488+0800 FootballInfomation[32055:1334276] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: [str hasPrefix:@"#"]'
*** First throw call stack:
(0x1816dbc80 0x198f00ee4 0x182e81de0 0x1044d6bac 0x1044d3d68 0x1044d2fe4 0x1044d5608 0x1044d1f74 0x1043de174 0x104457bc8 0x104457878 0x104479504 0x1043ebf74 0x1061ac700 0x1061adfc8 0x1061b5150 0x1061b5ddc 0x1061c163c 0x1dca40e10 0x1dca4093c)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: [str hasPrefix:@"#"]'
terminating with uncaught exception of type NSException

@solinder
Copy link

solinder commented May 17, 2023

Thanks a lot! It is really very helpfull!

This code works excellent with svgs, that have viewBox parameter starting with "0 0 ... ", for example viewBox="0 0 80 80".
But it displays not correctly svgs with viewBox like this: viewBox="-40 -40 80 80".
Link example of such svg: https://upload.wikimedia.org/wikipedia/commons/1/17/Yin_yang.svg

Perhaps you could help me to remake this code for working well with any variation of viewBox?

@yessenali
Copy link

Thanks a lot! You saved my day:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment