Customizing Digital Signatures on iOS
PSPDFKit offers various options for customizing the digital signing experience, primarily via DigitalSignatureCoordinator
subclassing hooks.
File Path for Digitally Signed Documents
A document that is digitally signed will be copied, signed, and saved to a new path to keep the (unsigned) original document intact. You can customize the path where the digitally signed document should be saved by subclassing DigitalSignatureCoordinator
and overriding pathForDigitallySignedDocument(fromOriginalDocument:suggestedFileName:)
to return a custom path. The suggested file name parameter is based on the title of the original document, if available, or the file name as a fallback. It can be used as the last path component in the path where the digitally signed document should be stored. The returned path will be sanitized, and we will append the .pdf
path extension.
Presentation for Digitally Signed Documents
You can also customize how the signed document should be presented. By default, this is done by pushing a new PDFViewController
instance on the navigation controller with the digitally signed document shown. This can be customized by overriding presentSignedDocument(_:showingPageIndex:with:)
in your DigitalSignatureCoordinator
subclass. By overriding this method, you are responsible for presenting/pushing the document that should be part of your digital signing experience. The pageIndex
parameter is the page index of the signature form field of the document, which you have the option of scrolling to.
Biometric Data
By default, all available properties on PDFSignatureBiometricProperties
are populated and stored. These properties can be customized to restrict storing specific properties via PDFConfiguration.signatureBiometricPropertiesOptions
. When signing a document, only the specified values are stored in the digital signature.
For example, to only store the touch radius and the input method biometric properties of the ink signature, you can use the following code:
let controller = PDFViewController(document: document) { $0.signatureBiometricPropertiesOptions = [.touchRadius, .inputMethod] }
PSPDFViewController *controller = [[PSPDFViewController alloc] initWithDocument:document configuration:[PSPDFConfiguration configurationWithBuilder:^(PSPDFConfigurationBuilder *builder) { builder.signatureBiometricPropertiesOptions = PSPDFSignatureBiometricPropertiesOptionTouchRadius | PSPDFSignatureBiometricPropertiesOptionInputMethod; }]];
You can customize the properties that are stored by overriding SignatureContainer(annotation:signer:biometricProperties:)
and modifying the biometricProperties
object to fit your needs.
Signature Appearances
During the signing process, you can customize how the final signature will be shown in the document.
PDFSignatureAppearance
has some Boolean properties to decide whether the signer’s name, date of signing, signature location, or signature reason should be shown after the document is signed.
The appearanceMode
property enables further configuration of the visual appearance, with three supported modes: .signatureAndDescription
, .signatureOnly
, and .descriptionOnly
. If your signature field has some appearance you want to keep after it’s signed (for example, a border or watermark logo), set the reuseExistingAppearance
property.
You can provide your own artwork (for example, a handwritten signature) that will be displayed on the left part of a signature field when its appearance mode is .signatureAndDescription
. Set the signatureGraphic
property to type Annotation.AppearanceStream
to accomplish this. You can create an Annotation.AppearanceStream
with either a JPEG image or a PDF document. The signature watermark that will be drawn in the center of the signature can also be configured. Set the signatureWatermark
property to accomplish this. If you don’t configure this property, the PSPDFKit logo will be shown. If you don’t want to show a signature watermark at all, set the showWatermark
property to false
.
If you are signing a document programmatically, you can pass the PDFSignatureAppearance
class by configuring the dataSource
property of the PDFSigner
instance, like this:
// A custom document signer data source that will provide the custom signature appearance. class MyCustomDataSource: NSObject, PDFDocumentSignerDataSource { func documentSigner(_ signer: PDFSigner, signatureAppearance formFieldFqn: String) -> PDFSignatureAppearance { let image = ... let signatureAppearance = PDFSignatureAppearance { builder in builder.appearanceMode = .signatureAndDescription builder.reuseExistingAppearance = true builder.signatureGraphic = Annotation.AppearanceStream(image: image!) } return signatureAppearance } } // Set the custom signer's data source. let customDataSource = MyCustomDataSource() signer.dataSource = customDataSource // Sign the document. var signedDocument: Document? signer.sign(signatureFormElement, usingPassword: "test", writeTo: path) {(_ success: Bool, _ document: Document, _ err: Error?) -> Void in signedDocument = document }
// A custom document signer data source that will provide the custom signature appearance. @interface MyCustomDataSource: NSObject<PSPDFDocumentSignerDataSource> @end @implementation MyCustomDataSource - (PSPDFSignatureAppearance *)documentSigner:(PSPDFSigner *)signer signatureAppearance:(NSString *)formFieldFqn { PSPDFSignatureAppearance *signatureAppearance = [PSPDFSignatureAppearance configurationWithBuilder:^(PSPDFSignatureAppearanceBuilder *builder) { builder.appearanceMode = PSPDFSignatureAppearanceModeSignatureAndDescription; builder.reuseExistingAppearance = YES; builder.signatureGraphic = [PSPDFAnnotationAppearanceStream appearanceStreamWithImage:image]; }]; return signatureAppearance; } @end // Set the custom signer's data source. let customDataSource = [[MyCustomDataSource alloc] init]; signer.dataSource = customDataSource; // Sign the document. __block PSPDFDocument *signedDocument; [signer signFormElement:signatureFormElement usingPassword:@"test" writeTo:path completion:^(BOOL success, PSPDFDocument *document, NSError *err) { signedDocument = document; }];
When providing an ink signature, the default signature appearance looks like the following image.
