John Doe
John Doe

Reputation: 49

How properly to add a password to programmatically created PDF in Swift?

Currently I'm creating my PDF in the next way:

func drawPDFUsingPrintPageRenderer(printPageRenderer: UIPrintPageRenderer) -> NSData! {
    let data = NSMutableData()

    UIGraphicsBeginPDFContextToData(data, CGRect(x: 0, y: 0, width: A4PageHeight, height: A4PageWidth), nil)
    UIGraphicsBeginPDFPage()

    printPageRenderer.drawPage(at: 0, in: UIGraphicsGetPDFContextBounds())

    UIGraphicsEndPDFContext()

    return data
}

by using Page Renderer:

let printPageRenderer = CustomPrintPageRenderer()
let printFormatter = UIMarkupTextPrintFormatter(markupText: self.getHTML())
printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)

and try to create the PDF from data as:

let pdfData = printPageRenderer.drawPDFUsingPrintPageRenderer(printPageRenderer: printPageRenderer)
mailComposer.addAttachmentData(pdfData as Data, mimeType: "application/pdf", fileName: "My PDF")

When I'm creating a new instance for my Page Renderer:

class CustomPrintPageRenderer: UIPrintPageRenderer {
let A4PageWidth: CGFloat = 595.2
let A4PageHeight: CGFloat = 841.8

var html: String?

override init() {
    super.init()

    // Specify the frame of the A4 page.
    let pageFrame = CGRect(x: 0.0, y: 0.0, width: A4PageHeight, height: A4PageWidth)

    // Set the page frame.
    self.setValue(NSValue(cgRect: pageFrame), forKey: "paperRect")

    // Set the horizontal and vertical insets (that's optional).
    self.setValue(NSValue(cgRect: pageFrame), forKey: "printableRect")
    self.setValue(1234, forKey: kCGPDFContextUserPassword as String)
    self.setValue(1234, forKey: kCGPDFContextOwnerPassword as String)
}

I'm trying to set password to it via:

self.setValue(1234, forKey: kCGPDFContextUserPassword as String)
self.setValue(1234, forKey: kCGPDFContextOwnerPassword as String)

but when I run my code it crashes with the error:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason:  
setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key kCGPDFContextUserPassword.'

What do I do wrong and how can I fix it? I was googling but could not find anything useful

Upvotes: 1

Views: 476

Answers (1)

rmaddy
rmaddy

Reputation: 318814

According to the documentation for UIGraphicsBeginPDFContextToData, the last parameter is a dictionary that takes the same auxiliary keys as used by CGPDFContext.

kCGPDFContextUserPassword and kCGPDFContextOwnerPassword are among those auxiliary keys.

So it would seem you need to set the password in your call to UIGraphicsBeginPDFContextToData.

let info: [AnyHashable: Any] = [kCGPDFContextUserPassword as String : "1234", kCGPDFContextOwnerPassword as String : "1234"]
UIGraphicsBeginPDFContextToData(data, CGRect(x: 0, y: 0, width: A4PageHeight, height: A4PageWidth), info)

Upvotes: 3

Related Questions