iOS PDFKit不会写入

iOS PDFKit不会写入,ios,swift,pdf,Ios,Swift,Pdf,这只是简单的PDFKit代码,应该在pdf的第一页添加一个圆圈,并将其保存到documents目录。除“保存”外,所有操作都有效。当我在之后设置断点时,让数据=…。它显示有数据,但有两个错误: 1) 2018-12-18 05:10:28.887195-0500 PDFWriteTest[21577:1331197] [未知进程名称]加载失败 /System/Library/PrivateFrameworks/CorePDF.framework/Versions/A/CorePDF 无论我是否

这只是简单的
PDFKit
代码,应该在pdf的第一页添加一个圆圈,并将其保存到documents目录。除“保存”外,所有操作都有效。当我在
之后设置断点时,让数据=…
。它显示有数据,但有两个错误:

1) 2018-12-18 05:10:28.887195-0500 PDFWriteTest[21577:1331197] [未知进程名称]加载失败 /System/Library/PrivateFrameworks/CorePDF.framework/Versions/A/CorePDF

  • 无论我是否捕捉到错误并打印,这一个都会显示
2) 无法将文件“Documents”保存到文件夹中 “D3E23B05-92…”

  • 这是从error.localizedDescription打印的内容

这个问题(将PDF数据保存到文件)可以用PDFKit解决吗?

您可以这样调用:

import UIKit
import PDFKit

class ViewController: UIViewController {

    @IBOutlet weak var pdfView: PDFView!

    lazy var pdfDoc:PDFDocument? = {
        guard let path = Bundle.main.path(forResource: "6368", ofType: "pdf") else {return nil}
        let url = URL(fileURLWithPath: path)
        return PDFDocument(url: url)
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupPDFView()
        self.save()
    }

    func setupPDFView() {
        //Setup and put pdf on view
        pdfView.autoScales = true
        pdfView.displayMode = .singlePageContinuous
        pdfView.displayDirection = .horizontal
        pdfView.document = pdfDoc

        self.add(annotation: self.circleAnnotation(), to: 0)
    }

    func add(annotation: PDFAnnotation, to page:Int){
        self.pdfDoc?.page(at: page)?.addAnnotation(annotation)
    }

    func circleAnnotation()->PDFAnnotation {
        let bounds = CGRect(x: 20.0, y: 20.0, width:200.0, height: 200.0)
        let annotation = PDFAnnotation(bounds: bounds, forType: .circle, withProperties: nil)
        annotation.interiorColor = UIColor.black
        return annotation
    }

    func save() {
        //Save to file
        guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {return}
        let data = pdfView.document?.dataRepresentation()
        do {
            if data != nil{try data!.write(to: url)}
        } 
        catch {
            print(error.localizedDescription)
        }
    }
}
如图所示,使用此方法
UIGraphicsBeginPDFContextToData(:::)
保存PDF

创建以指定可变数据对象为目标的基于PDF的图形上下文

宣言 func UIGraphicsBeginPDFContextToData(uData:NSMutableData, _边界:CGRect, _documentInfo:[AnyHashable:Any]?)

参数 资料

用于接收PDF输出数据的数据对象

您还可以使用
UIGraphicsBeginPDFContextToFile(::)

以下是一个例子:

UIGraphicsBeginPDFContextToFile(filePath, .zero, nil)
// do the view rendering
UIGraphicsEndPDFContext()
//处理视图,并调用以将其另存为PDF视图

class ViewController: UIViewController {
//开始渲染

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let v1 = UIScrollView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        v1.contentSize = CGSize(width: 100, height: 100)

        let v2 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
        let v3 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
        v1.backgroundColor = UIColor.red

        v2.backgroundColor = UIColor.green
        v3.backgroundColor = UIColor.blue

        let dst = NSHomeDirectory() + "/dng.pdf"

        UIGraphicsBeginPDFContextToFile(dst, .zero, nil)
        [v1, v2, v3].forEach{ (view : UIView)
            in
            autoreleasepool {
                self.renderPDFPage(view: view)
            }
        }
        UIGraphicsEndPDFContext()
    }
//Util方法,以处理UIScrollView

    func renderPDFPage(view: UIView) {
        func renderScrollView(_ scrollView: UIScrollView) {
            let tmp = scrollView.tempInfo
            scrollView.transformForRender()
            _render(scrollView) { scrollView in
                if let scrollView = scrollView as? UIScrollView{
                    scrollView.restore(tmp)
                }
            }
        }


        if let scrollView = view as? UIScrollView {
            renderScrollView(scrollView)
        } else {
            _render(view)
        }
    }


    func getPageSize(_ view: UIView) -> CGSize {
        switch view {
        case (let scrollView as UIScrollView):
            return scrollView.contentSize
        default:
            return view.frame.size
        }
    }

    func _render(_ view: UIView, completion: (UIView) -> Void = { _ in }) {
        let size: CGSize = getPageSize(view)

        guard size.width > 0 && size.height > 0 else {
            return
        }
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }

        let renderFrame = CGRect(origin: CGPoint(x: 0.0 , y: 0.0),
                                 size: CGSize(width: size.width, height: size.height))
        autoreleasepool {
            let superView = view.superview
            view.removeFromSuperview()
            UIGraphicsBeginPDFPageWithInfo(CGRect(origin: .zero, size: renderFrame.size), nil)
            context.translateBy(x: -renderFrame.origin.x, y: -renderFrame.origin.y)
            view.layer.render(in: context)
            superView?.addSubview(view)
            superView?.layoutIfNeeded()
            completion(view)
        }
    }
}

不能将数据直接写入表示
文档
文件夹的URL,必须指定(并附加)文件名

private extension UIScrollView {
    typealias TempInfo = (frame: CGRect, offset: CGPoint, inset: UIEdgeInsets)

    var tempInfo: TempInfo {
        return (frame, contentOffset, contentInset)
    }

    func transformForRender() {
        contentOffset = .zero
        contentInset = UIEdgeInsets.zero
        frame = CGRect(origin: .zero, size: contentSize)
    }

    func restore(_ info: TempInfo) {
        frame = info.frame
        contentOffset = info.offset
        contentInset = info.inset
    }

}

感谢Rengers的编辑!我很欣赏这种解决方法,但是这是PDFKit中的一个bug还是仅仅是我的硬件?你从哪里知道的,
try(pdfView.document?.dataRepresentation())!。写(到:url)
。我为第一条评论道歉。我把它取下来了。我很沮丧,因为你们似乎在用猎枪来解决手术刀的问题。你似乎比我更了解PDF上下文。希望你能找到一个更合适的问题来回答你的问题。没关系。事实上,当我写评论时,我看到了@vadian的答案。非常好。我忘了处理评论。我没有用谷歌搜索它(pdfView.document?.dataRepresentation())!。写入(到:url)。所以我只想问一个问题。你的问题很好,我投了更高的票。我的答案来自顶级github PDFKIt回购。我是从他那儿摘的。是的!你比我快了30秒。我刚想出来。非常感谢你们两位!我仍然收到无法加载的消息/System/Library/privateframes/CorePDF.framework/Versions/A/CorePDF未来陆家嘴顶尖的投资人 是的,这里也是
private extension UIScrollView {
    typealias TempInfo = (frame: CGRect, offset: CGPoint, inset: UIEdgeInsets)

    var tempInfo: TempInfo {
        return (frame, contentOffset, contentInset)
    }

    func transformForRender() {
        contentOffset = .zero
        contentInset = UIEdgeInsets.zero
        frame = CGRect(origin: .zero, size: contentSize)
    }

    func restore(_ info: TempInfo) {
        frame = info.frame
        contentOffset = info.offset
        contentInset = info.inset
    }

}
func save(filename : String) {
    //Save to file
    guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first,
          let data = pdfView.document?.dataRepresentation() else {return}
    let fileURL = url.appendingPathComponent(filename)
    do {
        try data.write(to: fileURL)
    } catch {
        print(error.localizedDescription)
    }
}