> 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/get-started/samples/fdftest.md).

# FDF

Sample code in Swift and Obj-C for using Apryse iOS SDK to programmatically merge forms data with the PDF in order to fill forms, or to extract form field data from the PDF. Apryse SDK has full suppor

Sample code in Swift and Obj-C for using Apryse iOS SDK to programmatically merge forms data with the PDF in order to fill forms, or to extract form field data from the PDF. Apryse SDK has full support for Forms Data Format (FDF).

Learn more about our full [PDF Data Extraction SDK Capabilities](https://apryse.com/capabilities/extraction).

To start your free trial, [get stated with iOS SDK](/ios/get-started/get-started.md).

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

```objc
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

#import <OBJC/PDFNetOBJC.h>
#import <Foundation/Foundation.h>

//---------------------------------------------------------------------------------------
// PDFNet includes a full support for FDF (Forms Data Format) and capability to merge/extract 
// forms data (FDF) with/from PDF. This sample illustrates basic FDF merge/extract functionality 
// available in PDFNet.
//---------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    @autoreleasepool {
        int ret = 0;
        [PTPDFNet Initialize: 0];

        // Example 1)
        // Iterate over all form fields in the document. Display all field names.
        @try  
        {
            PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/form1.pdf"];
            [doc InitSecurityHandler];

            PTFieldIterator * itr;
            for(itr = [doc GetFieldIterator]; [itr HasNext]; [itr Next]) 
            {
                NSLog(@"Field name: %@", [[itr Current] GetName]);
                NSLog(@"Field partial name: %@", [[itr Current] GetPartialName]);

                //NSLog(@"Field type: ");
                int type = [[itr Current] GetType];
                switch(type)
                {
                case e_ptbutton: NSLog(@"Field type: Button"); NSLog(@"------------------------------");break;
                case e_ptcheck: NSLog(@"Field type: Check"); NSLog(@"------------------------------");break;
                case e_ptradio: NSLog(@"Field type: Radio"); NSLog(@"------------------------------");break;
                case e_pttext: NSLog(@"Field type: Text"); NSLog(@"------------------------------");break;
                case e_ptchoice: NSLog(@"Field type: Choice"); NSLog(@"------------------------------");break;
                case e_ptsignature: NSLog(@"Field type: Signature"); NSLog(@"------------------------------");break;
                case e_ptf_null: NSLog(@"Field type: Null"); NSLog(@"------------------------------");break;
                default: NSLog(@"Field type: ------------------------------");
                        
                }

                //NSLog(@"------------------------------");
            }

            NSLog(@"Done.");
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }
        
        // Example 2) Import XFDF into FDF, then merge data from FDF into PDF
        @try  
        {
            // XFDF to FDF
            // form fields
            NSLog(@"Import form field data from XFDF to FDF.");
            
            PTFDFDoc *fdf_doc1 = [PTFDFDoc CreateFromXFDF: @"../../TestFiles/form1_data.xfdf"];
            [fdf_doc1 SaveFDFDocToFile: @"../../TestFiles/Output/form1_data.fdf"];
            
            // annotations
            NSLog(@"Import annotations from XFDF to FDF.");
            
            PTFDFDoc *fdf_doc2 = [PTFDFDoc CreateFromXFDF: @"../../TestFiles/form1_annots.xfdf"];
            [fdf_doc2 SaveFDFDocToFile: @"../../TestFiles/Output/form1_annots.fdf"];
            
            // FDF to PDF
            // form fields
            NSLog(@"Merge form field data from FDF.");
            
            PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/form1.pdf"];
            [doc InitSecurityHandler];
            [doc FDFMerge: fdf_doc1];
            
            // Refreshing missing appearances is not required here, but is recommended to make them 
            // visible in PDF viewers with incomplete annotation viewing support. (such as Chrome)
            [doc RefreshAnnotAppearances: NULL];

            [doc SaveToFile: @"../../TestFiles/Output/form1_filled.pdf" flags: e_ptlinearized];
            
            // annotations
            NSLog(@"Merge annotations from FDF.");
            
            [doc FDFMerge: fdf_doc2];
            // Refreshing missing appearances is not required here, but is recommended to make them 
            // visible in PDF viewers with incomplete annotation viewing support. (such as Chrome)
            [doc RefreshAnnotAppearances: NULL];
            [doc SaveToFile: @"../../TestFiles/Output/form1_filled_with_annots.pdf" flags: e_ptlinearized];
            NSLog(@"Done.");    
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }

        // Example 3) Extract data from PDF to FDF, then export FDF as XFDF
        @try  
        {
            // PDF to FDF
            PTPDFDoc *in_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/form1_filled_with_annots.pdf"];
            [in_doc InitSecurityHandler];
            
            // form fields only
            NSLog(@"Extract form fields data to FDF.");
            
            PTFDFDoc *doc_fields = [in_doc FDFExtract: e_ptforms_only];
            [doc_fields SetPDFFileName: @"../form1_filled_with_annots.pdf"];
            [doc_fields SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_data.fdf"];
            
            // annotations only
            NSLog(@"Extract annotations to FDF.");
            
            PTFDFDoc *doc_annots = [in_doc FDFExtract: e_ptannots_only];
            [doc_annots SetPDFFileName: @"../form1_filled_with_annots.pdf"];
            [doc_annots SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_annot.fdf"];
            
            // both form fields and annotations
            NSLog(@"Extract both form fields and annotations to FDF.");
            
            PTFDFDoc *doc_both = [in_doc FDFExtract: e_ptboth];
            [doc_both SetPDFFileName: @"../form1_filled_with_annots.pdf"];
            [doc_both SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_both.fdf"];
            
            // FDF to XFDF
            // form fields
            NSLog(@"Export form field data from FDF to XFDF.");
            
            [doc_fields SaveAsXFDF: @"../../TestFiles/Output/form1_filled_data.xfdf"];
            
            // annotations
            NSLog(@"Export annotations from FDF to XFDF.");
            
            [doc_annots SaveAsXFDF: @"../../TestFiles/Output/form1_filled_annot.xfdf"];
            
            // both form fields and annotations
            NSLog(@"Export both form fields and annotations from FDF to XFDF.");
            
            [doc_both SaveAsXFDF: @"../../TestFiles/Output/form1_filled_both.xfdf"];
            
            NSLog(@"Done.");
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }
        
        // Example 4) Merge/Extract XFDF into/from PDF
        @try  
        {
            // Merge XFDF from string
            PTPDFDoc *in_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/numbered.pdf"];
            [in_doc InitSecurityHandler];
            
            NSLog(@"Merge XFDF string into PDF.");
            NSString *str = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><xfdf xmlns=\"http://ns.adobe.com/xfdf\" xml:space=\"preserve\"><square subject=\"Rectangle\" page=\"0\" name=\"cf4d2e58-e9c5-2a58-5b4d-9b4b1a330e45\" title=\"user\" creationdate=\"D:20120827112326-07'00'\" date=\"D:20120827112326-07'00'\" rect=\"227.7814207650273,597.6174863387978,437.07103825136608,705.0491803278688\" color=\"#000000\" interior-color=\"#FFFF00\" flags=\"print\" width=\"1\"><popup flags=\"print,nozoom,norotate\" open=\"no\" page=\"0\" rect=\"0,792,0,792\" /></square></xfdf>";
            
            PTFDFDoc *fdoc = [PTFDFDoc CreateFromXFDF: str];
            [in_doc FDFMerge: fdoc];
            [in_doc SaveToFile: @"../../TestFiles/Output/numbered_modified.pdf" flags: e_ptlinearized];
            
            NSLog(@"Merge complete.");
            
            // Extract XFDF as string
            NSLog(@"Extract XFDF as a string.");
            PTFDFDoc *fdoc_new = [in_doc FDFExtract: e_ptboth];
            NSString *XFDF_str = [fdoc_new SaveAsXFDFToString];
            NSLog(@"Extracted XFDF: ");
            NSLog(@"%@", XFDF_str);
            NSLog(@"Extract complete.");
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }
        
        // Example 5) Read FDF files directly
        @try  
        {
            PTFDFDoc *doc = [[PTFDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/form1_filled_data.fdf"];

            PTFDFFieldIterator *itr;
            for(itr = [doc GetFieldIterator]; [itr HasNext]; [itr Next]) 
            {
                NSLog(@"Field name: %@", [[itr Current] GetName]);
                NSLog(@"Field partial name: %@", [[itr Current] GetPartialName]);

                NSLog(@"------------------------------");
            }

            NSLog(@"Done.");
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }
        
        // Example 6) Direct generation of FDF.
        @try  
        {
            PTFDFDoc *doc = [[PTFDFDoc alloc] init];
            // Create new fields (i.e. key/value pairs).
            [doc FieldCreateWithString: @"Company" type: e_pttext field_value: @"PDFTron Systems"];
            [doc FieldCreateWithString: @"First Name" type: e_pttext field_value: @"John"];
            [doc FieldCreateWithString: @"Last Name"  type: e_pttext field_value: @"Doe"];
            // ...        

            // [doc SetPdfFileName: @"mydoc.pdf"];

            [doc SaveFDFDocToFile: @"../../TestFiles/Output/sample_output.fdf"];
            NSLog(@"Done. Results saved in sample_output.fdf");
        }
        @catch(NSException *e)
        {
            NSLog(@"%@", e.reason);
            ret = 1;
        }
        [PTPDFNet Terminate: 0];        
        return ret;
    }
}
```

{% endcode %}
{% endtab %}

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

```swift
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

import PDFNet
import Foundation

//---------------------------------------------------------------------------------------
// PDFNet includes a full support for FDF (Forms Data Format) and capability to merge/extract
// forms data (FDF) with/from PDF. This sample illustrates basic FDF merge/extract functionality
// available in PDFNet.
//---------------------------------------------------------------------------------------
func runFDFTest() -> Int {
    return autoreleasepool{
        var ret: Int = 0
        
        
        // Example 1)
        // Iterate over all form fields in the document. Display all field names
        do {
            try PTPDFNet.catchException {
                let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "form1", ofType: "pdf"))
                doc.initSecurityHandler()
                
                let itr: PTFieldIterator = doc.getFieldIterator()
                while (itr.hasNext()) {
                    print("Field name: \(itr.current().getName()!)")
                    print("Field partial name: \(itr.current().getPartialName()!)")
                    
                    print("Field type: ")
                    let type: PTFieldType = itr.current().getType()
                    switch type {
                    case e_ptbutton:
                        print("Button")
                    case e_pttext:
                        print("Text")
                    case e_ptchoice:
                        print("Choice")
                    case e_ptsignature:
                        print("Signature")
                    default:
                        break
                    }
                    
                    print("------------------------------")
                    itr.next()
                }
                
                print("Done")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        // Example 2)
        // Import XFDF into FDF, then merge data from FDF into PDF
        do {
            try PTPDFNet.catchException {
                // XFDF to FDF
                // form fields
                print("Import form field data from XFDF to FDF.")
                
                let fdf_doc1: PTFDFDoc = PTFDFDoc.create(fromXFDF: Bundle.main.path(forResource: "form1_data", ofType: "xfdf"))
                fdf_doc1.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_data.fdf").path)
                
                // annotations
                print("Import annotations from XFDF to FDF.")
                
                let fdf_doc2: PTFDFDoc = PTFDFDoc.create(fromXFDF: Bundle.main.path(forResource: "form1_annots", ofType: "xfdf"))
                fdf_doc2.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_annots.fdf").path)
                
                // FDF to PDF
                // form fields
                print("Merge form field data from FDF.")
                
                let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "form1", ofType: "pdf"))
                doc.initSecurityHandler()
                doc.fdfMerge(fdf_doc1)
                
                // To use PDFNet form field appearance generation instead of relying on
                // Acrobat, uncomment the following two lines:
                //doc.refreshFieldAppearances()
                //doc.getAcroForm().putBool("NeedAppearances", value: false)
                
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled.pdf").path, flags: e_ptlinearized.rawValue)
                
                print("Merge annotations from FDF.")
                
                doc.fdfMerge(fdf_doc2)
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_with_annots.pdf").path, flags: e_ptlinearized.rawValue)
                print("Done.")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        // Example 3) Extract data from PDF to FDF, then export FDF as XFDF
        do {
            try PTPDFNet.catchException {
                // PDF to FDF
                let in_doc: PTPDFDoc = PTPDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_with_annots.pdf").path)
                in_doc.initSecurityHandler()
                
                // form fields only
                print("Extract form fields data to FDF.")
                
                let doc_fields: PTFDFDoc = in_doc.fdfExtract(e_ptforms_only)
                doc_fields.setPDFFileName("../form1_filled_with_annots.pdf")
                doc_fields.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.fdf").path)
                
                // annotations only
                print("Extract annotations to FDF.")
                
                let doc_annots: PTFDFDoc = in_doc.fdfExtract(e_ptannots_only)
                doc_annots.setPDFFileName("../form1_filled_with_annots.pdf")
                doc_annots.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_annot.fdf").path)
                
                // both form fields and annotations
                print("Extract both form fields and annotations to FDF.")
                
                let doc_both: PTFDFDoc = in_doc.fdfExtract(e_ptboth)
                doc_both.setPDFFileName("../form1_filled_with_annots.pdf")
                doc_both.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_both.fdf").path)
                
                // FDF to XFDF
                // form fields
                print("Export form field data from FDF to XFDF.")
                
                doc_fields.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.xfdf").path)
                
                // annotations
                print("Export annotations from FDF to XFDF.")
                
                doc_annots.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_annot.xfdf").path)
                
                // both form fields and annotations
                print("Export both form fields and annotations from FDF to XFDF.")
                
                doc_both.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_both.xfdf").path)
                
                print("Done.")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        // Example 4) Merge/Extract XFDF into/from PDF
        do {
            try PTPDFNet.catchException {
                // Merge XFDF from string
                let in_doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "numbered", ofType: "pdf"))
                in_doc.initSecurityHandler()
                
                print("Merge XFDF string into PDF.")
                let str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><xfdf xmlns=\"http://ns.adobe.com/xfdf\" xml:space=\"preserve\"><square subject=\"Rectangle\" page=\"0\" name=\"cf4d2e58-e9c5-2a58-5b4d-9b4b1a330e45\" title=\"user\" creationdate=\"D:20120827112326-07'00'\" date=\"D:20120827112326-07'00'\" rect=\"227.7814207650273,597.6174863387978,437.07103825136608,705.0491803278688\" color=\"#000000\" interior-color=\"#FFFF00\" flags=\"print\" width=\"1\"><popup flags=\"print,nozoom,norotate\" open=\"no\" page=\"0\" rect=\"0,792,0,792\" /></square></xfdf>"
                
                let fdoc = PTFDFDoc.create(fromXFDF: str)
                in_doc.fdfMerge(fdoc)
                in_doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("numbered_modified.pdf").path, flags: e_ptlinearized.rawValue)
                
                print("Merge complete.")
                
                // Extract XFDF as string
                print("Extract XFDF as a string.")
                let fdoc_new: PTFDFDoc = in_doc.fdfExtract(e_ptboth)
                let XFDF_str: String = fdoc_new.saveAsXFDFToString()
                print("Extracted XFDF: ")
                print("\(XFDF_str)")
                print("Extract complete.")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        // Example 5) Read FDF files directly
        do {
            try PTPDFNet.catchException {
                let doc: PTFDFDoc = PTFDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.fdf").path)
                
                let itr: PTFDFFieldIterator = doc.getFieldIterator()
                while itr.hasNext() {
                    print("Field name: \(itr.current().getName()!)")
                    print("Field partial name: \(itr.current().getPartialName()!)")
                    
                    print("------------------------------")
                    itr.next()
                }
                
                print("Done.")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        // Example 6) Direct generation of FDF.
        do {
            try PTPDFNet.catchException {
                let doc: PTFDFDoc = PTFDFDoc()
                // Create new fields (i.e. key/value pairs).
                doc.fieldCreate(with: "Company", type: e_pttext, field_value: "PDFTron Systems")
                doc.fieldCreate(with: "First Name", type: e_pttext, field_value: "John")
                doc.fieldCreate(with: "Last Name", type: e_pttext, field_value: "Doe")
                // ...
                
                //doc.setPDFFileName("mydoc.pdf")
                
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("sample_output.fdf").path)
                print("Done.")
            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        return ret
    }
}
```

{% 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/get-started/samples/fdftest.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.
