> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/ios/digital-signature/certify-pdf.md).

# Adding a certified signature field to a PDF on iOS

Learn how to add a certification signature field to a PDF document and digitally sign it with a full code sample. Understand the process of certifying a PDF/A document for compliance. The Apryse iOS S

To add a certification signature field to a PDF document and sign it:

{% tabs %}
{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTPDFDoc* doc = [[PTPDFDoc alloc] initWithFilepath: docpath];
PTPage* page1 = [doc GetPage: 1];

// Create a text field that we can lock using the field permissions feature.
PTTextWidget* annot1 = [PTTextWidget Create: doc pos: [[PTPDFRect alloc] initWithX1: 50 y1: 550 x2: 350 y2: 600] field_name: @"asdf_test_field"];
[page1 AnnotPushBack: annot1];

/* Create a new signature form field in the PDFDoc. The name argument is optional;
leaving it empty causes it to be auto-generated. However, you may need the name for later.
Acrobat doesn't show digsigfield in side panel if it's without a widget. Using a
Rect with 0 width and 0 height, or setting the NoPrint/Invisible flags makes it invisible. */
PTDigitalSignatureField* certification_sig_field = [doc CreateDigitalSignatureField: cert_field_name];
PTSignatureWidget* widgetAnnot = [PTSignatureWidget CreateWithDigitalSignatureField: doc pos: [[PTPDFRect alloc] initWithX1: 0 y1: 100 x2: 200 y2: 150] field: certification_sig_field];
[page1 AnnotPushBack: widgetAnnot];

// (OPTIONAL) Add an appearance to the signature field.
PTImage* img = [PTImage CreateWithFile: [doc GetSDFDoc] filename: appearance_image_path encoder_hints: [[PTObj alloc]init]];
[widgetAnnot CreateSignatureAppearance: img];

// Prepare the document locking permission level to be applied upon document certification.
[certification_sig_field SetDocumentPermissions: e_ptannotating_formfilling_signing_allowed];

// Prepare to lock the text field that we created earlier.
NSMutableArray<NSString *> * fields_to_lock = [[NSMutableArray<NSString *> alloc] init];
[fields_to_lock addObject:@"asdf_test_field"];
[certification_sig_field SetFieldPermissions: e_ptdigsig_permission_include in_field_names: [fields_to_lock copy]];

[certification_sig_field CertifyOnNextSave: private_key_file_path in_password: keyfile_password];

// (OPTIONAL) Add more information to the signature dictionary.
[certification_sig_field SetLocation: @"Vancouver, BC"];
[certification_sig_field SetReason: @"Document certification."];
[certification_sig_field SetContactInfo: @"www.apryse.com"];

// Save the PDFDoc. Once the method below is called, PDFNet will also sign the document using the information provided.
[doc SaveToFile: outpath flags: 0];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
let doc: PTPDFDoc = PTPDFDoc(filepath: in_docpath)
let page1: PTPage = doc.getPage(1)

// Create a text field that we can lock using the field permissions feature.
let annot1 = PTTextWidget.create(doc, pos: PTPDFRect(x1: 50, y1: 550, x2: 350, y2: 600), field_name: "asdf_test_field")
page1.annotPushBack(annot1)

/* Create a new signature form field in the PDFDoc. The name argument is optional;
leaving it empty causes it to be auto-generated. However, you may need the name for later.
Acrobat doesn't show digsigfield in side panel if it's without a widget. Using a
Rect with 0 width and 0 height, or setting the NoPrint/Invisible flags makes it invisible. */
let certification_sig_field: PTDigitalSignatureField = doc.createDigitalSignatureField(in_cert_field_name)
let widgetAnnot: PTSignatureWidget = PTSignatureWidget.create(withDigitalSignatureField: doc, pos: PTPDFRect(x1: 0, y1: 100, x2: 200, y2: 150), field: certification_sig_field)
page1.annotPushBack(widgetAnnot)

// (OPTIONAL) Add an appearance to the signature field.
let img = PTImage.create(withFile: doc.getSDFDoc(), filename: in_appearance_image_path, encoder_hints: PTObj())
widgetAnnot.createSignatureAppearance(img)

// Prepare the document locking permission level. It will be applied upon document certification.
certification_sig_field.setDocumentPermissions(e_ptannotating_formfilling_signing_allowed)

// Prepare to lock the text field that we created earlier.
var fields_to_lock: [String] = []
fields_to_lock.append("asdf_test_field")
certification_sig_field.setFieldPermissions(e_ptdigsig_permission_include, in_field_names: fields_to_lock)

certification_sig_field.certify(onNextSave: in_private_key_file_path, in_password: in_keyfile_password)

// (OPTIONAL) Add more information to the signature dictionary.
certification_sig_field.setLocation("Vancouver, BC")
certification_sig_field.setReason("Document certification.")
certification_sig_field.setContactInfo("www.apryse.com")

// Save the PDFDoc. Once the method below is called, PDFNet will also sign the document using the information provided.
doc.save(toFile: in_outpath, flags: 0)
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Digitally sign PDF files](/ios/get-started/samples.md#digitalsignatures) Full code sample which demonstrates using the digital signature API to digitally sign and/or certify PDF documents.

## About certifying a PDF document

Unlike, approval signatures, there can be only one certification per PDF document. Only the first signature in the PDF document can be used as the certification signature. Certifying a document is like notarizing a document. The process of certifying a document is almost exactly the same as adding approval signatures with the exception of certification signatures requires an entry in the "Perms" dictionary.

## About certifying a PDF/A document

If you want to certify a PDF/A document, it is best to convert to PDF/A first, then certify. This is because PDF/A changes the contents of the document, while digital signatures, including certifications, rely on the document's bytes remaining the same so that they can be digested and compared with the embedded cryptographic digital signature.

A `DigitalSignatureField` can be added before or after PDF/A conversion, since there aren't any requirements in PDF/A upon it.

The `PDF/A-2` specification allows `adbe.pkcs7.detached` and `adbe.pkcs7.sha1 certification-type` or `UR3-type` cryptographic digital signatures, with or without secure timestamps, with or without embedded revocation information, which must be signed if present. A single `SignerInfo` must be present. Attribute certificates must not be used. The PDFNet SDK's signing support is sufficient to meet the requirements of `PDF/A-2` compliance if used properly.

There shouldn't be any problem with retaining PDF/A compliance after digitally signing a document, so long as there is no annotation appearance for the digital signature field, or there is an appearance and that appearance conforms to PDF/A, i.e. e.g. sections 6.3.2 and 6.3.3 of the PDF/A-2 specification (ISO-19005-2).

An additional limitation of PDF/A for digital signing is the implementation limit that says that a conforming file shall not contain any string longer than 32767 bytes. Sometimes, signatures with a large amount of data will cause the Contents byte string in the digital signature dictionary to exceed this limit.

The PDF/A-2 specification also mentions the following:

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
A Widget annotation dictionary or Field dictionary shall not
contain the A or AA keys. The NeedAppearances flag of the
interactive form dictionary shall either not be present
or shall be false.
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here is what 6.3.2 and 6.3.3 say about the annotation:

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
6.3.2 Annotation dictionaries

Except for annotation dictionaries whose Subtype value
is Popup, all annotation dictionaries shall contain
the F key. If present, the F key’s Print flag bit shall
be set to 1 and its Hidden, Invisible, ToggleNoView, and
NoView flag bits shall be set to 0.

Text annotations should set the NoZoom and NoRotate
flag bits of the F key to 1.

NOTE The restrictions on annotation flags prevent the
use of annotations that are hidden or that are viewable
but not printable. The NoZoom and NoRotate flags are
permitted, which allows the use of annotation types that
have the same behaviour as the commonly-used text
annotation type. By definition, text annotations exhibit
the NoZoom and NoRotate behaviour even if the flags are
not set, as described in ISO 32000-1:2008, 12.5.3;
explicitly setting these flags removes any potential
ambiguity between the annotation dictionary settings and
reader behaviour.

6.3.3 Annotation Appearances

Every annotation (including those whose Subtype value
is Widget, as used for form fields), except for the two
cases listed below, shall have at least one appearance
dictionary.

-- Annotations where the value of the Rect key consists
of an array where value 1 is equal to value 3 and value
2 is equal to value 4.

-- Annotations whose Subtype value is Popup or Link.

A conforming reader shall render the appearance dictionary
without regard to any other keys and values in the
annotation dictionary and shall ignore the values of
the C, IC, Border, BS, BE, CA, H, DA, Q, DS, LE, LL,
LLE, and Sy keys.

NOTE 1 Requiring an appearance dictionary for each
annotation ensures the reliable rendering of the
annotations.

For all annotation dictionaries containing an AP key,
the appearance dictionary that it defines as its value
shall contain only the N key. If an annotation
dictionary’s Subtype key has a value of Widget and
its FT key has a value of Btn, the value of the N
key shall be an appearance subdictionary otherwise
the value of the N key shall be an appearance stream.

NOTE 2 In accordance with the requirements of 12.7.4.2.3
and 12.7.4.2.4 of ISO 32000-1:2008, a Button form field
needs to have multiple appearance states, each one
associated with the specific values that the button can take.
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/ios/digital-signature/certify-pdf.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
