Kingfisher: PDF Support

Created on 10 Jan 2017  路  6Comments  路  Source: onevcat/Kingfisher

Is it possible to download pdf files?
example http://ipattaya.net/fanta-logo.pdf

Most helpful comment

@ivampir you can use my code:

struct PDFProcessor: ImageProcessor {
    // `identifier` should be the same for processors with same properties/functionality
    // It will be used when storing and retrieving the image to/from cache.
    let identifier = "au.com.makemeapp.testus"

    // Convert input data/image to target image and return it.
    func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
        switch item {
        case .image(let image):
            return image
        case .data(let data):
            let pdfData = data as CFData
            guard let provider:CGDataProvider = CGDataProvider(data: pdfData) else {return nil}
            guard let pdfDoc:CGPDFDocument = CGPDFDocument(provider) else {return nil}
            guard let pdfPage:CGPDFPage = pdfDoc.page(at: 1) else {return nil}
            var pageRect:CGRect = pdfPage.getBoxRect(.mediaBox)
            pageRect.size = CGSize(width:pageRect.size.width, height:pageRect.size.height)
            UIGraphicsBeginImageContextWithOptions(pageRect.size, false, UIScreen.main.scale)
            guard let context:CGContext = UIGraphicsGetCurrentContext()  else {return nil}
            context.saveGState()
            context.translateBy(x: 0.0, y: pageRect.size.height)
            context.scaleBy(x: 1, y: -1)
            context.concatenate(pdfPage.getDrawingTransform(.mediaBox, rect:  pageRect, rotate: 0, preserveAspectRatio: true))
            context.drawPDFPage(pdfPage)
            context.restoreGState()
            let pdfImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return pdfImage
        }
    }
}

so you could:

        let processor = PDFProcessor()
        yourImageView.kf.setImage(with: url, placeholder: #imageLiteral(resourceName: "tile1"), options: [.processor(processor)])

All 6 comments

@ivampir it is possible to download PDF files from an iOS or macOS application, but I don't think Kingfisher would best serve you for this. Kingfisher is great for getting images and getting them to your UIImageViews and other views where you display images.

If you need to download a PDF file over HTTP, I would use Alamofire. If you need to display the PDF, you could use a webview or another Swift open source library like UXMPDFKit :)

@ivampir Sorry for the late reply! But as @sahandnayebaziz mentioned, Kingfisher does not support PDF files. You might be able to download and cache them by implementing some specified ImageProcessor and CacheSerializer, but it would be much easier to use some other ways in the comment above.

@ivampir you can use my code:

struct PDFProcessor: ImageProcessor {
    // `identifier` should be the same for processors with same properties/functionality
    // It will be used when storing and retrieving the image to/from cache.
    let identifier = "au.com.makemeapp.testus"

    // Convert input data/image to target image and return it.
    func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> Image? {
        switch item {
        case .image(let image):
            return image
        case .data(let data):
            let pdfData = data as CFData
            guard let provider:CGDataProvider = CGDataProvider(data: pdfData) else {return nil}
            guard let pdfDoc:CGPDFDocument = CGPDFDocument(provider) else {return nil}
            guard let pdfPage:CGPDFPage = pdfDoc.page(at: 1) else {return nil}
            var pageRect:CGRect = pdfPage.getBoxRect(.mediaBox)
            pageRect.size = CGSize(width:pageRect.size.width, height:pageRect.size.height)
            UIGraphicsBeginImageContextWithOptions(pageRect.size, false, UIScreen.main.scale)
            guard let context:CGContext = UIGraphicsGetCurrentContext()  else {return nil}
            context.saveGState()
            context.translateBy(x: 0.0, y: pageRect.size.height)
            context.scaleBy(x: 1, y: -1)
            context.concatenate(pdfPage.getDrawingTransform(.mediaBox, rect:  pageRect, rotate: 0, preserveAspectRatio: true))
            context.drawPDFPage(pdfPage)
            context.restoreGState()
            let pdfImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return pdfImage
        }
    }
}

so you could:

        let processor = PDFProcessor()
        yourImageView.kf.setImage(with: url, placeholder: #imageLiteral(resourceName: "tile1"), options: [.processor(processor)])

@ADevelopStudio Great work. Thanks for the code snippet.

@ADevelopStudio thank you very much for the processor!

@ADevelopStudio - this is LIT, 2020 and still saving people from suicide. 馃ぃ馃ぃ馃ぃThanks, man!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

freak4pc picture freak4pc  路  3Comments

litt1e-p picture litt1e-p  路  4Comments

vCrespoP picture vCrespoP  路  3Comments

wudijimao picture wudijimao  路  3Comments

kbpontius picture kbpontius  路  3Comments