1. Home
  2. Foxit PDF SDK for iOS
  3. Developer Guide for Foxit PDF SDK for iOS

Developer Guide for Foxit PDF SDK for iOS

Introduction to Foxit PDF SDK

Foxit PDF SDK provides high-performance libraries to help any software developer add robust PDF functionality to their enterprise, mobile and cloud applications across all platforms (includes Windows, Mac, Linux, Web, Android, iOS, and UWP), using the most popular development languages and environments.

Application developers who use Foxit PDF SDK can leverage Foxit’s powerful, standard compliant PDF technology to securely display, create, edit, annotate, format, organize, print, share, secure, search documents as well as to fill PDF forms. Additionally, Foxit PDF SDK includes a built-in, embeddable PDF Viewer, making the development process easier and faster. For more detailed information, please visit the website https://developers.foxitsoftware.com/pdfsdk/. In this guide, we focus on the introduction of Foxit PDF SDK for Android platform.

Foxit PDF SDK for iOS

Have you ever worried about the complexity of the PDF specification? Or have you ever felt lost when asked to build a full-featured PDF app within a limited time-frame? If your answer is “Yes”, then congratulations! You have just found the best solution in the industry for rapidly integrating PDF functionality into your apps.

Foxit PDF SDK for iOS focuses on helping developers easily integrate powerful Foxit PDF technology into their own mobile apps. With this SDK, even developers with a limited knowledge of PDF can quickly build a professional PDF viewer with just a few lines of code on iOS platform.

Why Foxit PDF SDK for iOS is your choice

Foxit is an Amazon-invested leading software provider of solutions for reading, editing, creating, organizing, and securing PDF documents. Foxit PDF SDK libraries have been used in many of today’s leading apps, and they are proven, robust, and battle-tested to provide the quality, performance, and features that the industry’s largest apps demand.

Foxit PDF SDK for iOS provides quick PDF viewing and manipulation support for iOS Devices. Customers choose it for the following reasons:

  • Easy to integrate
    Developers can seamlessly integrate Foxit PDF SDK for iOS into their own apps with just a few lines of code.
  • Perfectly designed
    Foxit PDF SDK for iOS is designed with a simple, clean, and friendly style, which provides the best user experience.
  • Flexible customization
    Foxit PDF SDK for iOS provides the source code for the user interface which lets the developers have full control of the functionality and appearance of their apps.
  • Robust performance on mobile platforms
    Foxit PDF SDK for iOS provides an OOM (out-of-memory) recovery mechanism to ensure the app has high robust performance when running the app on a mobile device which offers limited memory.
  • Powered by Foxit’s high fidelity rendering PDF engine
    The core technology of Foxit PDF SDK for iOS is based on Foxit’s PDF engine, which is trusted by a large number of the world’s largest and well-known companies. Foxit’s powerful engine makes the app fast on parsing, rendering, and makes document viewing consistent on a variety of devices.
  • Premium World-side Support
    Foxit offers premium support for its developer products because when you are developing mission critical products you need the best support. Foxit has one of the PDF industry’s largest team of support engineers. Updates are released on a regular basis to improve user experience by adding new features and enhancements.

Foxit PDF SDK for iOS

Foxit PDF SDK for iOS is a Rapid Development Kit for mobile platforms which focuses on helping developers easily integrate powerful Foxit PDF technology into their own apps. With Foxit PDF SDK for iOS, even developers with a limited knowledge of PDF can quickly build a professional PDF viewer with just a few lines of code on the iOS platform.

Foxit PDF SDK for iOS consists of three elements as shown in the following picture.

The three elements for Foxit PDF SDK for iOS

  • PDF Core API
    The PDF Core API is the heart of this SDK and is built on Foxit’s powerful underlying technology. It provides the functionality for basic PDF operation features, and is utilized by the PDF View Control 0.and UI Extensions Component, which ensures the apps can achieve high performance and efficiency. The Core API can be used independently for document rendering, analysis, text extraction, text search, form filling, digital signatures, Pressure Sensitive Ink, certificate and password security,
    annotation creation and manipulation and much more.
  • PDF View Control
    The PDF View Control is a utility class that provides the functionality for developers to interact with rendering PDF documents per their requirements. With Foxit’s renowned and widely used PDF rendering technology at its core, the View Control provides fast and high quality rendering, zooming, scrolling and page navigation features. The View Control derives from platform related viewer classes (e.g. UIView on iOS) and allows for extension to accommodate specific user needs.
  • UI Extensions Component
    The UI Extensions Component is an open source library that provides a customizable user interface with built-in support for text selection, markup annotation, outline navigation, reading bookmarks, full-text searching, form filling, text reflow, attachment, digital/handwritten signature, reflow, document editing and password encryption. These features in the UI Extensions Component are implemented using the PDF Core API and PDF View Control. Developers can utilize these ready-to-use UI implementations to build a PDF viewer quickly with the added benefit of complete flexibility and control to customize the UI design as desired.

From version 4.0, Foxit PDF SDK for iOS makes a big change and optimization for the UI Extensions Component. It wraps the basic UI implementations to FSPDFReader class, such as panel controller, toolbar settings, and alter view, etc. Building a full-featured PDF Reader is getting simpler and easier. Furthermore, users can flexibily customize the features they want through a configuration file.

From version 5.0, Foxit PDF SDK for iOS removes the FSPDFReader class, and move the wrapped APIs in FSPDFReader class to UI Extensions Component. In version 5.0, every element in the built-in UI can be configurable. More advanced APIs and more powerful configuration file are provided for developers to further customize the UI elements, such as showing or hiding a specific panel, top/bottom bar, the items in the top bar, and the items in the View setting bar and More Menu view.

UI Extensions Component Overview

The UI Extensions Component uses “module” mechanism which refines each feature into a module. All of the modules except LocalModule (used for file management) will be loaded by default if you add UIExtension. Users can customize module through implementing Module interface class, and then call UIExtensionsManager#registerModule to register the custom module to current UIExtensions manager. When not in use, you can call UIExtensionsManager#unregisterModule to unregister it from current UIExtensions manager.

UIExtensionsManager contains the main-frame UI, such as top/bottom bar, and other UI components which are shared between each module. Meanwhile, through UIExtensionsManager, each feature module can also be loaded separately. And when loaded, the feature module will adapt and adjust the main-frame UI, as well as establish the connection of message event response. Each feature module may contain its module-specific UI components, and have its self-contained message event handling logic. UIExtensionsManager will also be responsible for distributing messages and events received from View Control component to each feature module. The following figure shows the detailed relationship between UIExtensionsManager and modules.

The relationship between UIExtensionsManager and modules

Tool handler and annotation handler will process the events from touch screen or gestures of PDFViewCtrl. When the touch screen and gestures occur, PDFViewCtrl will send the corresponding events to UIExtensionsManager:

  1. If a tool handler exists currently, UIExtensionsManager will send the corresponding events to the current tool handler, and then event-handing process ends.
  2. If an annotation is selected currently, UIExtensionsManager will send the corresponding events to the annotation handler corresponding to the currently selected annotation, and then event-handing process ends.
  3. If currently no tool handler exists and no annotation is selected, UIExtensionsManager will send the corresponding events to selection tool handler. Text Selection tool is used for processing the related events for text selection. For example, select a piece of text, and add Highlight annotation. Blank Selection tool is used for processing the related events for blank space. For example, add a Note annotation on the blank space.
  4. Note: Tool Handler and Annotation Handler will not respond the events at the same time. Tool Handler is primarily used for annotation creation (currently, the creation of link annotation is not supported), signature creation and text selection. Annotation Handler is mainly used for annotation editing and form filling. The following figure shows the event response flow chart between Tool Handler and Annotation Handler.

    The event response flow chart between Tool Handler and Annotation Handler

    Key Features of Foxit PDF SDK for iOS

    Foxit PDF SDK for iOS has several main features which help app developers quickly implement the functions that they really need and reduce the development cost.

    Features

    PDF Document: Open and close files, set and get metadata.

    PDF Page: Parse, render, read, and edit PDF pages.

    Render: Graphics engine created on a bitmap for platform graphics device.

    Reflow: Rearrange page content.

    Crop: Crop PDF pages for better reading.

    Text Select: Select text in a PDF document.

    Text Search: Search text in a PDF document.

    Outline: Directly locate and link to point of interest within a document.

    Reading Bookmark: Mark progress and interesting passages as users read.

    Annotation: Create, edit and remove annotations.

    Layers: Add, edit and remove optional content groups.

    Attachments: Add, edit and remove document level attachments.

    Form: Fill form with JavaScript support, export and import form data by XFDF/FDF/XML file.

    Signature: Sign a PDF document, verify a signature, add or delete a signature field. Add and verify third-party digital signature.

    Security: Protect PDFs with password or certificate.

    Pan and Zoom: Adjust the magnification and position of the view area to match the area in an adjustable rectangle in the Pan & Zoom window’s thumbnail view of the page.

    Print: Print PDF document.

    Out of Memory: Recover from an OOM condition.

    Note: Outline is the technical term used in the PDF specification for what is commonly known as bookmarks in traditional desktop PDF viewers. Reading bookmarks are commonly used on mobile and tablet PDF viewers to mark progress and interesting passages as users read but are not technically outline and are stored at app level rather than within the PDF itself.

    Support robust PDF applications with Foxit PDF SDK for iOS

    Development of robust PDF applications is challenging on mobile platforms which has limited memory. When memory allocation fails, applications may crash or exit unexpectedly. To deal with this issue, Foxit PDF SDK for iOS provides an out-of-memory (OOM) mechanism to support applications.

    OOM is an evolved feature in Foxit PDF SDK for iOS because of its complexity. The key of OOM mechanism is that Foxit PDF SDK for iOS will monitor the usage of memory and take recovery operations automatically once OOM is detected. During the recovery process, Foxit PDF SDK for iOS reloads the document and page automatically and restores the status to the original before OOM. It means the current reading page and location, as well as page view mode (single or continuous page) can be recovered. However, the data generated from editing will be lost.

    Foxit PDF SDK for iOS provides the property “shouldRecover” in FSPDFViewCtrl class. By default, the value of “shouldRecover”” is “YES”. If you do not want to enable the auto-recovery when OOM is detected, you can set “shouldRecover” to “false” as follows:

    self.pdfViewCtrl = [[FSPDFViewCtrl alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.pdfViewerCtrl.shouldRecover = NO;

    At that time, the application will throw an exception, and may crash or exit unexpectedly.

    Evaluation

    Foxit PDF SDK for iOS allows users to download trial version to evaluate SDK. The trial version has no difference from the standard licensed version except for the free 21-day trial limitation and the trial watermarks in the generated pages. After the evaluation period expires, customers should contact the Foxit sales team and purchase licenses to continue using Foxit PDF SDK for iOS.

    License

    Developers should purchase licenses to use Foxit PDF SDK for iOS in their solutions. Licenses grant developers permission to release their apps which utilize Foxit PDF SDK for iOS. However, users are prohibited to distribute any documents, sample code, or source code in the released package of Foxit PDF SDK for iOS to any third party without written permission from Foxit Software Incorporated.

    About this Guide

    Foxit PDF SDK for iOS is currently available on iOS and Android platforms. This guide is intended for the developers who need to integrate Foxit PDF SDK for iOS into their own apps. It aims at introducing the following sections:

    • Introduction to Foxit PDF SDK for iOS: gives an introduction of Foxit PDF SDK for iOS.
    • Getting Started: illustrates the package structure, running demo, and adding PDF SDK into app.
    • Rapidly Building a PDF Reader: describes how to quickly create a full-featured PDF Reader.
    • Customizing the UI Implementation: introduces how to customize the UI implementation.
    • Creating a custom tool: shows how to create a custom tool.
    • Technical Support: provides support information.

    Getting Started

    It is very easy to setup Foxit PDF SDK for iOS and see it in action! It takes just a few minutes and we will show you how to use it on the iOS platform. The following sections introduce the structure of the installation package, how to run a demo, and how to create your own project in Xcode.

    Requirements

    • iOS 9 or higher
    • Xcode 9.0 or newer for Objective-C; Xcode 9.0 or newer for Swift

    What’s in the package

    Download the “foxitpdfsdk_6_1_ios.zip” package, and extract it to a new directory like “foxitpdfsdk_6_1_ios” as shown in Figure 2-1. The package contains:

    • docs: A folder containing API references, developer guide.
    • libs: A folder containing license files, SDK framework, and UI Extensions Component and source code.
    • samples: A folder containing iOS sample projects.
    • getting_started_ios.pdf: A quick guide for Foxit PDF SDK for iOS.
    • legal.txt: Legal and copyright information.
    • release_notes.txt: Release information.

     

    Figure 2-1

    In the “libs” folder as shown in Figure 2-2, there are items that make up the core components of Foxit PDF SDK for iOS.

    Figure 2-2

    • FoxitRDK.framework – The framework that includes the Foxit PDF SDK for iOS dynamic library and associated header files.
    • uiextensionsDynamic.framewor – The framework that includes UIExtensions dynamic library, associated header files, and the resource files that are needed for the default built-in UI implementations.
    • uiextensions project- found in the “libs/uiextensions_src” folder. It is an open source library that contains some ready-to-use UI module implementations, which can help developers rapidly embed a fully functional PDF reader into their iOS app. Of course, developers are not forced to use the default UI, they can freely customize and design the UI for their specific apps through the “uiextensions” project.

    How to run a demo

    Download and install Xcode IDE (https://developer.apple.com/download/).

    Note: In this guide, we do not cover the installation of Xcode. You can refer to Apple’s developer site if you haven’t installed it already.

    Foxit PDF SDK for iOS provides three useful demos (Function demo, Viewer Control demo, and Complete PDF viewer demo) in both Objective-C and Swift programming languages for developers to learn how to call the SDK. The Swift demos are located in the “swift” folder. (See Figure 2-3)

    Note: The complete PDF viewer demo in Swift provides tabs reading mode to support viewing multiple PDF documents.

    Figure 2-3

    Function demo

    The function demo is provided with Objective-C and Swift programming languages, which is used to show how to use Foxit PDF SDK for iOS to realize some specific features related with PDF. This demo includes the following features:

    • pdf2txt: extract all the text from a PDF document, and then save them to a text file.
    • outline: edit outline (aka bookmark) appearances and titles.
    • annotation: add some annotations to one page of a PDF page.
    • docinfo: export basic information of a PDF to a TXT file.
    • render: render a specified page of a PDF to a Bitmap, and save the bitmap.
    • signature: add a signature to PDF, sign PDF and verify the signature.

    To run it in XCode, follow the steps below:

    • Double-click function_demo.xcodeproj found in the “samples/function_demo” folder to open the demo in Xcode. (For Swift, double-click function_demo_swift.xcodeproj found in the “samples/swift/function_demo_swift” folder)Note: There is another way to open the demo in Xocde: double-click samples_xcworkspace found in the “samples” folder. It is a workspace including the three demos.
      Note: There is another way to open the demo in Xcode: double-click samples_xcworkspace found in the “samples” folder. It is a workspace including the three demos.
    • Click on “Product -> Run” to run the demo on an iOS device or simulator. In this guide, an iPhone 7 Simulator will be used as an example. After building the demo successfully, the features are listed like the Figure 2-4.

 

Figure 2-4

    • Click the feature buttons in the above picture to perform the corresponding actions. For example, click “pdf2txt”, and then a message box will be popped up as shown in Figure 2-5. It shows where the text file was saved to. Just run the demo and try the features.

 


Figure 2-5

Viewer control demo

The viewer control demo is provided with Objective-C and Swift programming languages, which is used to demonstrate how to implement the features related to the View Control feature level, such as performing annotations (note, typewriter, highlight, underline, strikeout, squiggly, etc.), outline, reading bookmarks and text search. The logical structure of the code is quite clear and simple so that developers can quickly find the detailed implementation of features which are used widely in PDF apps, such as a PDF viewer. With this demo, developers can take a closer look at the APIs provided in Foxit PDF SDK for iOS.

To run the demo in Xcode, please refer to the setup steps outlined in the Function demo.

Figure 2-6 shows what the demo looks like after it was built successfully. Here, an iPhone 8 Simulator will be used as an example to run the demo.

Figure 2-6

This demo provides the features like text search and listing reading bookmarks, outline and annotations.
For example, click on the button below:

Then, select the second tab (outline). The outline of this document will be displayed as shown in Figure 2-7.

Note: Outline is the technical term used in the PDF specification for what is commonly known as bookmarks in traditional desktop PDF viewers. Reading bookmarks are commonly used on mobile and tablet PDF viewers to mark progress and interesting passages as users read but are not technically outlines and are stored at app level rather than within the PDF itself.

Figure 2-7

Complete PDF viewer demo

The complete PDF viewer demo demonstrates how to use Foxit PDF SDK for iOS to realize a completely full-featured PDF viewer which is almost ready-to-use as a real world mobile PDF reader. This demo utilizes all of the features and built-in UI implementations which are provided in Foxit PDF SDK for iOS.

Note: The complete PDF viewer demo in Swift provides tabs reading mode to support viewing multiple PDF documents.

To run the demo in Xcode, please refer to the setup steps outlined in the Function demo.

Here, an iPhone 8 Simulator will also be used as an example to run the demo. After building the demo successfully, on the start screen, it lists the “Sample.pdf” and “complete_pdf_viewer_guide_ios.pdf” documents. If you want to view multiple PDF documents, click the top-right button to switch to the tabs reading mode (see Figure 2-8).

Note: If you want to use some other PDF files to test this demo, you need to put them onto the “Document” folder of the device.

Figure 2-8

Click YES to switch to the tabs reading mode. Select the “complete_pdf_viewer_guide_ios.pdf” document, and then click the top-left Back button , and select the “Sample.pdf”, then it will be displayed as shown in Figure 2 9. Now, you can browse the two PDF documents by switching the tabs.

Figure 2-9

This demo realizes a completely full-featured PDF viewer, please feel free to run it and try it.

For example, it provides the page thumbnail feature. You can click the View menu, choose the Thumbnail as shown in Figure 2-10, and then the thumbnail of the document will be displayed as shown in Figure 2-131.

Figure 2-12

Figure 2-13

 

Foxit PDF SDK for iOS wrapped all of the UI implementations including the basic UI for app and ready-to- use UI feature modules to UI Extensions Component, so that developers can easily and rapidly build a full-featured PDF Reader with just a few lines of code. This section will help you to quickly get started with using Foxit PDF SDK for iOS to make a full-featured PDF Reader app in Objective-C and Swift with step-by-step instructions provided.

Make an iOS app in Objective-C with Foxit PDF SDK for iOS

This section will help you to quickly make an iOS app in Objective-C using Foxit PDF SDK for iOS. It includes the following steps:

  1. Create a new iOS project in Objective-C
  2. Integrate Foxit PDF SDK for iOS into your apps
  3. Initialize Foxit PDF SDK for iOS
  4. Display a PDF document using PDFViewCtrl
  5. Add UI Extensions Component to build a full-featured PDF Reader

Create a new iOS project in Objective-C

In this guide, we use Xcode 9.1 to create a new iOS project.

Fire up Xcode, choose File -> New -> Project…, and then select iOS -> Single View Application as shown in Figure 3-1. Click Next.

Figure 3-1

Choose the options for your new project as shown in Figure 3-2. Please make sure to choose Objective-C as the programming language. For simplicity, we don’t check the Unit Tests and UI Tests which are used for automated testing. Then, Click Next.

Figure 3-2

Place the project to the location as desired. The option “version control” is not actually important for building your first PDF app, so let’s use the default setting. Here, we place the project to the desktop as shown in Figure 3-3. Then, click Create.

Figure 3-3

Integrate Foxit PDF SDK for iOS into your apps

Note: In this section, we will use the default built-in UI implementations to develop the app, for simplicity and convenience (use the UI Extensions Component directly, and don’t need to build the source code project), we need to add the following files to the pdfreader project.

  • FoxitRDK.framework – The framework that includes the Foxit PDF SDK for iOS dynamic library and associated header files.
  • • uiextensionsDynamic.framework – The framework that includes UIExtensions dynamic library, associated header files, and the resource files that are needed for the default built-in UI implementations.

    Tip: The UI Extensions Component (uiextensionsDynamic.framework) are not required for the following two sections “Initialize Foxit PDF SDK for iOS” and “Display a PDF document using PDFViewCtrl”, so you can just add FoxitRDK.framework to the project at first. Then, add uiextensionsDynamic.framework when you need to use the UI Extensions Component, such like the project described in the section “Add UI Extensions Component to build a full-featured PDF Reader”,

  • To add the above two dynamic framework files into the pdfreader project, please follows the steps below:

    a) Right-click the “pdfreader” project, select Add Files to “pdfreader”… as shown in Figure 3-4.

    Figure 3-4

    b) Find and choose “FoxitRDK.framework” in the “libs” folder of the download package, and then click Add as shown in Figure 3-5.

    Note: Make sure to check the “Copy items if needed” option.

    Figure 3-5

    c) Repeat the steps like a) and b) to add “uiextensionsDynamic.framework”. Then, the pdfreader project will look like the Figure 3 6.

    Figure 3-6

    d) Add the dynamic framework “FoxitRDK.framework” to the Xcode’s Embedded Binaries. Left- click the project, find Embedded Binaries in the General tab, and press on the + button as shown in Figure 3-7.

    Figure 3-7

    Then, choose the “FoxitRDK.framework” and “uiextensionsDynamic.framework” to add, and the Embedded Binaries will be like the Figure 3-8.

    Note: Remove the repeated frameworks from Xcode’s Linked Frameworks and Libraries.

    Figure 3-8

    Now, we have added “FoxitRDK.framework” and “uiextensionsDynamic.framework” to the pdfreader project successfully.

    Initialize Foxit PDF SDK for iOS

    It is necessary for apps to initialize and unlock Foxit PDF SDK for iOS using a license before calling any APIs. The function [FSLibrary init:sn key:key] is provided to initialize Foxit PDF SDK for iOS. The trial license files can be found in the “libs” folder of the download package. After the evaluation period expires, you should purchase an official license to continue using it. Finish the initialization in the didFinishLaunchingWithOptions method within the AppDelegate.m file.

    #import "AppDelegate.h"
    #import "FoxitRDK/FSPDFObjC.h"
     
    @interface AppDelegate ()
     
    @end
     
    @implementation AppDelegate
     
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     
        // The value of "sn" can be found in the "rdk_sn.txt".
        // The value of "key" can be found in the "rdk_key.txt".
        NSString* sn = @" ";
        NSString* key = @" ";
     
      FS_ERRORCODE eRet = [FSLibrary init:sn key:key];
        if (e_errSuccess != eRet) {
            return NO;
        }
        return YES;
    }
     
    @end

    Note: The parameter “sn” can be found in the “rdk_sn.txt” (the string after “SN=”) and the “key” can be found in the “rdk_key.txt” (the string after “Sign=”).

    Display a PDF document using PDFViewCtrl

    So far, we have added “FoxitRDK.framework” to the pdfreader project, and finished the initialization of the Foxit PDF SDK for iOS. Now, let’s start building a simple PDF viewer with just a few lines of code

    Note: The UI Extensions Component is not required if you only want to display a PDF document.

    First of all, add a PDF file to the project which will be used as the test file. For example, we use “Sample.pdf” found in the “samples/test_files” folder of the download package. Right-click the pdfreader project, and select Add Files to “pdfreader”… to add this file. After adding, you can see the PDF in the Xcode’s Copy Bundle Resources as shown in Figure 3-9.

    Note: You can add the PDF to Copy Bundle Resources directly. Just left-click the pdfreader project, find Copy Bundle Resources in the Build Phases tab, press on the + button, and choose the file to add. You can refer to any PDF file, just add it to the Xcode’s Copy Bundle Resources.

    Figure 3-9

    Then, add the following code to ViewController.m to display a PDF document. It’s really easy to present a PDF on screen. All you need is to get a PDF file and call [FSPDFViewCtrl openDoc:filePath password:password completion:completion] function to open and display the PDF.

    Update ViewController.m as follows:

    #import "ViewController.h"
    #import "FoxitRDK/FSPDFViewControl.h"
     
    @interface ViewController ()
     
    @end
     
    @implementation ViewController
     
    - (void)viewDidLoad {
        [super viewDidLoad];
     
         // Get the path of a PDF
         NSString* pdfPath = [[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"pdf"];
     
         // Initialize a PDFDoc object with the path to the PDF file
         FSPDFDoc* pdfdoc = [FSPDFDoc createFromFilePath:pdfPath];
         if(e_errSuccess != [pdfdoc load:nil]) {
             return;
         }
     
        // Initialize a FSPDFViewCtrl object with the size of the entire screen
        FSPDFViewCtrl* pdfViewCtrl;
        pdfViewCtrl = [[FSPDFViewCtrl alloc] initWithFrame: [self.view bounds]];
     
        // Set the document to display
        [pdfViewCtrl setDoc:pdfdoc];
     
        // Add the pdfViewCtrl to the root view
        [self.view addSubview:pdfViewCtrl];
     
    }
     
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
     
    @end

    Fantastic! We have now finished building a simple iOS app which uses Foxit PDF SDK for iOS to display a PDF document with just a few lines of code. The next step is to run the project on a device or simulator.

    In this guide, we build and run the project on an iPhone 8 Simulator, and you will see that the “Sample.pdf” document is displayed as shown in Figure 3-10. Now, this sample app has some basic PDF features, such as zooming in/out and page turning. Just have a try!

    Figure 3-10

    Build a full-featured PDF Reader

    Foxit PDF SDK for iOS comes with built-in UI design including the basic UI for app and the feature modules UI, which are implemented using Foxit PDF SDK for iOS and are shipped in the UI Extensions Component. Hence, building a full-featured PDF Reader is getting simpler and easier. All you need to do is to add UI Extensions Component, and then instantiate a UIExtensionsManager object and set it to PDFViewCtrl.

    Instantiate a UIExtensionsManager object and set it to PDFViewCtrl

    In the “ViewController.m” file, you only need to add the following code:

    #import "../uiextensions/UIExtensionsManager.h"
     
    UIExtensionsManager* extensionsManager;
    ...
    extensionsManager = [[UIExtensionsManager alloc] initWithPDFViewControl:pdfViewCtrl];
    pdfViewCtrl.extensionsManager = extensionsManager;

    The whole update of ViewController.m is as follows:

    #import "ViewController.h"
    #import "FoxitRDK/FSPDFViewControl.h"
    #import "../uiextensions/UIExtensionsManager.h"
     
    @interface ViewController ()
     
     
    @end
     
    @implementation ViewController
    {
        UIExtensionsManager* extensionsManager;
    }
     
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        // Get the path of a PDF
        NSString* pdfPath = [[NSBundle mainBundle] pathForResource:@"FoxitForm" ofType:@"pdf"];
     
        // Initialize a PDFDoc object with the path to the PDF file
        FSPDFDoc* pdfdoc = [FSPDFDoc createFromFilePath:pdfPath];
        if(e_errSuccess != [pdfdoc load:nil]) {
            return;
        }
     
        // Initialize a FSPDFViewCtrl object with the size of the entire screen
        FSPDFViewCtrl* pdfViewCtrl;
        pdfViewCtrl = [[FSPDFViewCtrl alloc] initWithFrame: [self.view bounds]];
     
        // Set the document to display
        [pdfViewCtrl setDoc:pdfdoc];
     
        // Add the pdfViewCtrl to the root view
        [self.view addSubview:pdfViewCtrl];
     
     
        // Initialize a UIExtensionsManager object and set it to pdfViewCtrl
        extensionsManager = [[UIExtensionsManager alloc] initWithPDFViewControl:pdfViewCtrl];
        pdfViewCtrl.extensionsManager = extensionsManager;
    }
     
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
     
    }
     
    @end

    Let’s run it on an iPhone 8 Simulator. Now, it is a full-featured PDF Reader as shown in Figure 3-11, which includes all of the features in Complete PDF Viewer Demo. Feel free to try it.

    Figure 3-11

    Make an iOS app in Swift with Foxit PDF SDK for iOS

    Nowadays, Swift is more and more popular for iOS developers because its syntax is much cleaner and easier to read. To better support Swift developers, this section will help you to quickly get started with using Foxit PDF SDK for iOS to make an iOS app in Swift with step-by-step instructions provided. From now, you can get familiar with Foxit PDF SDK for iOS and use Swift to create your first PDF iOS app in Xcode. This section includes the following steps:

    1. Create a new iOS project in Swift
    2. Integrate Foxit PDF SDK for iOS into your apps
    3. Initialize Foxit PDF SDK for iOS
    4. Display a PDF document using PDFViewCtrl
    5. Build a full-featured PDF Reader

    Create a new iOS project in Swift

    In this guide, we use Xcode 9.1 to create a new iOS project.

    To create a new iOS project in Swift, you can refer to section 3.1.1 Create a new iOS project in Objective-C”. The only difference is that you should choose Swift as the programming language (See Figure 3-12).

    Figure 3-12

    Integrate Foxit PDF SDK for iOS into your apps (Swift)

     

    To integrate Foxit PDF SDK for iOS into your apps, please first refer to the previous “Integrate Foxit PDF SDK for iOS into your apps” section to add the dynamic framework “FoxitRDK.framework” and “uiextensionsDynamic.framework” into the pdfreader project.

    Initialize Foxit PDF SDK for iOS

    It is necessary for apps to initialize and unlock Foxit PDF SDK for iOS using a license before calling any APIs. The function FSLibrary init:(sn key:key) is provided to initialize Foxit PDF SDK for iOS. The trial license files can be found in the “libs” folder of the download package. After the evaluation period expires, you should purchase an official license to continue using it. Finish the initialization in the application method within the AppDelegate.swift file.

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     
            let sn = ""
            let key = ""
            let eRet = FSLibrary.init(sn, key:key)
            if FS_ERRORCODE.e_errSuccess != eRet {
                return false
            }
            return true
    }
    }

    Note: The parameter “sn” can be found in the “rdk_sn.txt” (the string after “SN=”) and the “key” can be found in the “rdk_key.txt” (the string after “Sign=”).

    Display a PDF document using PDFViewCtrl

    So far, we have added “FoxitRDK.framework” to the pdfreader project, and finished the initialization of the Foxit PDF SDK for iOS. Now, let’s start displaying a PDF document using PDFViewCtrl with just a few lines of code.

    Note: The UI Extensions Component is not required if you only want to display a PDF document.

    First of all, add a PDF file to the project which will be used as the test file. For example, we use “Sample.pdf” found in the “samples\test_files” folder of the download package. Right-click the pdfreader project, and select Add Files to “pdfreader“… to add this file. After adding, you can see the PDF in the Xcode’s Copy Bundle Resources as shown in Figure 3-13.

    Note: You can add the PDF to Copy Bundle Resources directly. Just left-click the pdfreader project, find Copy Bundle Resources in the Build Phases tab, press on the + button, and choose the file to add. You can refer to any PDF file, just add it to the Xcode’s Copy Bundle Resources.

    Figure 3-24

    Then, add the following code to ViewController.m to display a PDF document. It’s really easy to present a PDF on screen. All you need is to get a PDF file and call [FSPDFViewCtrl openDoc:filePath password:password completion:completion] function to open and display the PDF.

    Update ViewController.swift as follows:

    import UIKit
    import FoxitRDK
     
    class ViewController: UIViewController {
     
        override func viewDidLoad() {
            super.viewDidLoad()
     
            // Get the path of a PDF.
            let pdfPath = Bundle.main.path(forResource: "Sample", ofType: "pdf")!
     
            // Initialize a FSPDFViewCtrl object with the size of the entire screen.
            var pdfViewCtrl: FSPDFViewCtrl!
            pdfViewCtrl = FSPDFViewCtrl.init(frame:self.view.bounds)
     
            // Set the document to display.
            pdfViewCtrl.openDoc(pdfPath, password: nil, completion: nil)
     
            // Add the pdfViewCtrl to the root view.
            self.view.insertSubview(pdfViewCtrl, at: 0)
        }
     
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

    Fantastic! We have now finished building a simple iOS app in Swift which uses Foxit PDF SDK for iOS to display a PDF document with just a few lines of code. The next step is to run the project on a device or simulator.

    In this guide, we build and run the project on an iPhone 8 Simulator, and you will see that the “Sample.pdf” document is displayed as shown in Figure 3-14. Now, this sample app has some basic PDF features, such as zooming in/out and page turning. Just have a try!

    Figure 3-25

    Build a full-featured PDF Reader with UIExtensions Component

    Foxit PDF SDK for iOS comes with built-in UI design including the basic UI for app and the feature modules UI, which are implemented using Foxit PDF SDK and are shipped in the UI Extensions Component. Hence, building a full-featured PDF Reader is getting simpler and easier. All you need to do is to instantiate a UIExtensionsManager object and set it to PDFViewCtrl.

    Add code to instantiate a UIExtensionsManager object and set it to PDFViewCtrl

    In the “ViewController.swift” file, you only need to add the following code:

    import uiextensionsDynamic
    ...
     
    var extensionsManager: UIExtensionsManager!
    ...
    extensionsManager = UIExtensionsManager(pdfViewControl: pdfViewCtrl)
    pdfViewCtrl.extensionsManager = extensionsManager;

    The whole update of “ViewController.swift” is as follows:

    var extensionsManager: UIExtensionsManager !
    ...
    extensionsManager = UIExtensionsManager(pdfViewControl: pdfViewCtrl)
    pdfViewCtrl.extensionsManager = extensionsManager;

    The whole update of “ViewController.swift” is as follows:

    import UIKit
    import FoxitRDK
    import uiextensionsDynamic
     
    class ViewController: UIViewController {
     
        var extensionsManager: UIExtensionsManager!
     
        override func viewDidLoad() {
            super.viewDidLoad()
     
            // Get the path of a PDF.
            let pdfPath = Bundle.main.path(forResource: "Sample", ofType: "pdf")!
     
            // Initialize a FSPDFViewCtrl object with the size of the entire screen.
            var pdfViewCtrl: FSPDFViewCtrl!
            pdfViewCtrl = FSPDFViewCtrl.init(frame:self.view.bounds)
     
            // Set the document to display.
            pdfViewCtrl.openDoc(pdfPath, password: nil, completion: nil)
     
            // Add the pdfViewCtrl to the root view.
            self.view.insertSubview(pdfViewCtrl, at: 0)
     
            // Initialize a UIExtensionsManager object and set it to pdfViewCtrl.
            extensionsManager = UIExtensionsManager(pdfViewControl: pdfViewCtrl)
            pdfViewCtrl.extensionsManager = extensionsManager;
        }
     
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

    Let’s run it on an iPhone 8 Simulator. Now, it is a full-featured PDF Reader as shown in Figure 3-15, which includes all of the features in Complete PDF Viewer demo. Feel free to try it.

    Figure 3-15

    Customizing User Interface

    Foxit PDF SDK for iOS provides a simple, clean and friendly user interface for developers to quickly build a full-featured PDF app without needing to take much time on the design. Furthermore, customizing the user interface is straightforward. Foxit PDF SDK for iOS provides the source code of the UI Extensions Component that contains ready-to-use UI module implementations, which lets the developers have full control of styling the appearance as desired.

    From version 4.0, developers can flexibly customize the features they want through a configuration file.

    From version 5.0, every element in the built-in UI can be configurable. More advanced APIs and more powerful configuration file are provided for developers to further customize the UI elements, such as showing or hiding a specific panel, top/bottom bar, the items in the top bar, and the items in the View setting bar and More Menu view.

    The following section will introduce how to customize the feature modules in your project and how to customize the UI elements and implementations through a configuration file or APIs.

    About configuration file

    From version 4.0, Foxit PDF SDK for iOS provides a more convenient way to flexibly control and customize the features through a configuration file. Developers can easily choose the features that they want without needing to write any additional code or redesign the app’s UI.

    Two formats of the configuration file

    The configuration file can be provided as a JSON file or implemented directly in code. It controls which feature modules are enabled. Now, we will introduce the two formats of the configuration file respectively.

    The first format, use a JSON file (e.g name “uiextensions_config.json”) which should look like as follows:

    {
     
        "modules": {
     
            "thumbnail": true,
     
            "readingBookmark": true,
     
            "outline": true,
     
            "tools": true,
     
            "attachment": true,
     
            "signature": true,
     
            "search": true,
     
            "pageNavigation": true,
     
            "form": true,
     
            "encryption": true
     
        }
     
    }

    Note: For a full-featured PDF Reader, all of the items in “modules” should be set to “true”, which ensures that all of the features are enabled.

    Then, use the following code to get the configuration file:

    Objective-C:

    NSString* configPath = [[NSBundle mainBundle] pathForResource:@"uiextensions_config" ofType:@"json"];

    Swfit:

    let configPath = Bundle.main.path(forResource: "uiextensions_config", ofType: "json")
    var data: Data?
    if nil != configPath {
        data = NSData(contentsOfFile: configPath!) as Data?
    }

    The second format, implement it in the code instead of a JSON file as follows:

    Objective-C:

    NSDictionary* configContent =
                 @{@"modules":@{@"readingbookmark": @true,
                                @"outline": @true,
                                @"annotations": @true,
                                @"thumbnail": @true,
                                @"attachment": @true,
                                @"signature": @true,
                                @"search": @true,
                                @"pageNavigation": @false,
                                @"form": @true,
                                @"selection": @true,
                                @"encryption": @true}
                      };
    NSData* configData = [NSJSONSerialization dataWithJSONObject:configContent options:NSJSONWritingPrettyPrinted error: nil];

    Swift:

    let configContent: String = "{\"modules\": {\n"
                                   + "\"readingbookmark\": true,\n"
                                   + "\"outline\": true,\n"
                                   + "\"annotations\": true,\n"
                                   + "\"thumbnail\" : true,\n"
                                   + "\"attachment\": true,\n"
                                   + "\"signature\": true,\n"
                                   + "\"search\": true,\n"
                                   + "\"pageNavigation\": false,\n"
                                   + "\"form\": true,\n"
                                   + "\"selection\": true,\n"
                                   + "\"encryption\" : true}}"
    let configData: Data? = configContent.data(using: String.Encoding.utf8)

    In this guide, we will use the first format (JSON file) to present the configuraton file.

    Notice items of configuration file

    The JSON configuration file can be written by yourself. There are some situations needed to notice you are writing the configuration file. Following lists some typical examples:

  • All of the items in “modules” are set to “true”, in this case, all of the feature modules will be enabled.
{
    "modules": {
        "thumbnail": true,
        "readingBookmark": true,
        "outline": true,
        "tools": true,
        "annotations": true,
        "attachment": true,
        "signature": true,
        "search": true,
        "pageNavigation": true,
        "form": true,
        "encryption": true
    }
}
  • Some items in “modules” are set to “false”. For example, “search” and “thumbnail” modules are set to “false”, in this case, only the “search” and “thumbnail” feature modules are disabled, the others are all enabled.
{
    "modules": {
        "thumbnail": false,
        "readingBookmark": true,
        "outline": true,
        "tools": true,
        "attachment": true,
        "signature": true,
        "search": false,
        "pageNavigation": true,
        "form": true,
        "selection": true,
        "encryption": true
    }
}
  • Some items in “modules” are not set. For example, “search” and “thumbnail” modules are not set in the configuration file, in this case, the “search” and “thumbnail” feature modules are enabled, because the default settings are “true”. It means if some features modules are not in the configuration file, they will also be available.
{
    "modules": {
        "readingBookmark": true,
        "outline": true,
        "tools": true,
        "attachment": true,
        "signature": true,
        "pageNavigation": true,
        "form": true,
        "encryption": true
    }
}
}

Note:The “tools” item includes the Selection tool and the Annotation tools (except Attachment tool) in the built-in Annotation setting bar.

From version 5.0, Foxit PDF SDK for iOS supports customizing the annotations in the built-in Annotation setting bar through a configuration file, so that developers can choose the annotations that they want without needing to write any additional code. Rewrite the JSON file as follows:

{
    "modules": {
        "thumbnail": true,
        "readingBookmark": true,
        "outline": true,
        "tools":{
            "Insert": true,
            "Eraser": true,
            "Line": true,
            "Arrow": true,
            "Selection": true, 
            "Underline": true, 
            "Replace": true, 
            "StrikeOut": true, 
            "Note": true, 
            "Highlight": true, 
            "Squiggly": true, 
            "Oval": true,  
            "Freetext": true, 
            "Stamp": true, 
            "Rectangle": true, 
            "Pencil": true
            "Textbox": true, 
            "Polygon": true, 
            "Cloud": true, 
            "Image": true, 
            "Distance": true, 
        }
        "attachment": true,
        "signature": true,
        "search": true,
        "pageNavigation": true,
        "form": true,
        "encryption": true
    }
}

Set the types of annotations that you want to “true”. If you want to remove a specific type of the annotations, just set it to “false”.

Note: If some types of annotations are not in the configuration file, they are also enabled, because the default setting is “true”. For example, if you delete “”highlight“: true,”, it is still available.

Instantiate a UIExtensionsManager object with the configuration file

In section Add UI Extensions Component to build a full-featured PDF Reader (Objective-C) and Add UI Extensions Component to build a full-featured PDF Reader (Swift), we have already introduced how to initialize UIExtensionsManager, and in this way all the built-in UI framework would be loaded by default. In this section, we will provide another method to initialize UIExtensionsManager that uses the configuration file, so that developers can easily customize the feature modules or tools as desired.

Please refer to the following code to instantiate a UIExtensionsManager object with the configuration file.

Note: You should prepare the JSON configuration file, and then add it to your project. Here, we assume that you have already added a JSON file named “uiextensions_config.json”.

In ViewController.swift: (Objective-C)

UIExtensionsManager* extensionsManager;
...
// Instantiate a FSPDFViewCtrl object with the size of the entire screen.
FSPDFViewCtrl* pdfViewCtrl;
pdfViewCtrl = [[FSPDFViewCtrl alloc] initWithFrame: [self.view bounds]];
 
// Get the path of the JSON configuration file.
NSString* configPath = [[NSBundle mainBundle] pathForResource:@"uiextensions_config" ofType:@"json"];
 
// Initialize a UIExtensionsManager object and set it to pdfViewCtrl.
extensionsManager = [[UIExtensionsManager alloc] initWithPDFViewControl:pdfViewCtrl configuration:[NSData dataWithContentsOfFile:configPath]];
if (nil == extensionsManager) {
        return;
}
pdfViewCtrl.extensionsManager = extensionsManager;

In ViewController.swift: (Swift)

var extensionsManager: UIExtensionsManager!
...
// Initialize a FSPDFViewCtrl object with the size of the entire screen
var pdfViewCtrl: FSPDFViewCtrl!
pdfViewCtrl = FSPDFViewCtrl.init(frame:self.view.bounds)
 
// Get the path of the JSON configuration file.
let configPath = Bundle.main.path(forResource: "uiextensions_config", ofType: "json")
var data: Data?
if nil != configPath {
     data = NSData(contentsOfFile: configPath!) as Data?
}
 
// Initialize a UIExtensionsManager object and set it to pdfViewCtrl.
extensionsManager = UIExtensionsManager.init(pdfViewControl: pdfViewCtrl, configuration: data)
if nil == extensionsMgr  {
   return
}
pdfViewCtrl.extensionsManager = extensionsManager;

Note: Here, we uses a JSON file to configure the UIExtensions. If you do not want to use configuration file, please refer to the “Build a full-featured PDF Reader with UIExtensions Component” section for your respective language (Objective-C or Swift). ). If you want to implement the configuration file in code directly instead of a JSON file, please see Two formats of the configuration file.

Customize feature modules and tools through a configuration file

From version 4.0, Foxit PDF SDK for iOS provides a more convenient way to flexibly control and customize the features through a configuration file. Developers can easily choose the features that they want without needing to write any additional code or redesign the app’s UI.

From version 5.0, Foxit PDF SDK for iOS supports customizing the tools which include the Selection tool and the Annotation tools (except Attachment tool) in the built-in Annotation setting bar (See Figure 4-1)through a configuration file. For more details about the configuration file, you can see section “About configuration file”.

Note: To find the Annotation setting bar, just click Comment at the bottom bar, and then click the button below:

Figure 4-1

The above picture does not display all of the annotation tools. You can swipe left on the setting bar to see the other annotation tools.

The configuration file looks like as follows:

{
    "modules": {
        "thumbnail": true,
        "readingBookmark": true,
        "outline": true,
        "tools":{
            "Insert": true,
            "Eraser": true,
            "Line": true,
            "Arrow": true,
            "Selection": true, 
            "Underline": true, 
            "Replace": true, 
            "StrikeOut": true, 
            "Note": true, 
            "Highlight": true, 
            "Squiggly": true, 
            "Oval": true,  
            "Freetext": true, 
            "Stamp": true, 
            "Rectangle": true, 
            "Pencil": true
            "Textbox": true, 
            "Polygon": true, 
            "Cloud": true, 
            "Image": true, 
            "Distance": true, 
        }
        "attachment": true,
        "signature": true,
        "search": true,
        "pageNavigation": true,
        "form": true,
        "encryption": true
    }
}

Please note that only the attachment annotation in the Annotation setting bar is not controlled by the subitems in “tools”. “attachment”: true, ” controls the attachments panel and attachment annotation. If you set it to “false”, both of them will be disabled. If you want to hide “Comment” in the bottom bar, you should set both “annotations” and “attachment” to “false”.

Set the types of tools that you want to “true”, and if you want to remove a specific type of the tools, just set it to “false”.

Note: If all types of the tools in the configuration file are set to “false”, it is equal to ““tools”: false,”. If some types of tools are not in the configuration file, they are also enabled, because the default setting is “true”. For example, if you comment out ““Highlight”: true,”, it is still available.

In this section, we will show you how to customize feature modules and tools in your project. You will find it is extremely easy! You only need to modify the configuration file. Below you can see an example of how to do it.

Note: For your convenience, we will try it in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder.

Open the demos in Xcode. Find the configuration file “uiextensions_config.json” under “complete_pdf_viewer\Resource” or “complete_pdf_viewer_swift\Resource”.

Example: Remove “readingbookmark” and “search” feature modules, as well as the “highlight”
and “stamp” annotations.

You only need to update the configuration file as follows:

{
    "modules": {
        "thumbnail": true,
        "readingBookmark": false,
        "outline": true,
        "tools":{
            "Insert": true,
            "Eraser": true,
            "Line": true,
            "Arrow": true,
            "Selection": true, 
            "Underline": true, 
            "Replace": true, 
            "StrikeOut": true, 
            "Note": true, 
            "Highlight": false, 
            "Squiggly": true, 
            "Oval": true,  
            "Freetext": true, 
            "Stamp": false, 
            "Rectangle": true, 
            "Pencil": true
            "Textbox": true, 
            "Polygon": true, 
            "Cloud": true, 
            "Image": true, 
            "Distance": true, 
        }
        "attachment": true,
        "signature": true,
        "search": false,
        "pageNavigation": true,
        "form": true,
        "encryption": true
    }
}

Then, rebuild and run the demo to see the result. Following lists the comparison diagrams:
Before:

After:

The “readingbookmark” and “search” feature modules are removed.

Click Comment at the bottom bar, and then click the button:

Before:

After:

The “highlight” and “textbox” annotations are removed.

stopping point

Customize UI elements through APIs

In version 4.0, Foxit PDF SDK for iOS supports customizing to show or hide the whole top or bottom bar, and from version 5.0, it provides APIs to customize to show or hide a specific panel, the items in the top bar, View setting bar and More Menu view, which is convenient for developers to modify the UI elements in the context of the built-in UI framework.

Note: For your convenience, we will show you how to customize UI elements through APIs in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder. We assume that you have not modified the “uiextensions_config.json” file in the demos, which means that all of the built-in UI in the UI Extensions Component are enabled.

Customizing top/bottom bar

In the top/bottom bar (See Figure 4-2), you can do the following operations:

  1. Show or hide the top/bottom bar
  2. Show or hide a specific item in the top toolbar

Figure 4-2

Table 4-1 lists the related APIs which are used to customize the top/bottom bar

Table 4-1

(void)enableTopToolbar:(BOOL)isEnabledEnable or disable top toolbar.
(void)enableBottomToolbar:(BOOL)isEnabledEnable or disable bottom toolbar.
(void)setTopToolbarItemHiddenWithTag:
(NSUInteger)itemTag hidden:(BOOL)isHidden
Show or hide the item in the top bar.

The value of the parameter “itemTag” in setTopToolbarItemHiddenWithTag interface can be set as follows, which maps the features in the top bar.

Item nameitemTagNSUInteger
BackFS_TOPBAR_ITEM_BACK_TAG101
BookmarkFS_TOPBAR_ITEM_BOOKMARK_TAG100
SearchFS_TOPBAR_ITEM_SEARCH_TAG 103
MoreFS_TOPBAR_ITEM_MORE_TAG 102

In the following examples, we will show you how to customize the top/bottom bar through APIs in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder.

Open the demos in Xcode. Add the sample code to the “ViewController.m” (Objective-C) or “ViewController.swift” (Swift) (after the code that initializes UIExtensionsManager).

Example 1: Hide the whole top bar.

Objective-C:

[self.extensionsMgr enableTopToolbar:false];

Swift:

extensionsMgr.enableTopToolbar(false)

Before:

After:

Example 2: Hide the whole bottom bar.

Objective-C:

[self.extensionsMgr enableBottomToolbar:false];

Swift:

extensionsMgr.enableBottomToolbar(false)

Before:

After:

Example 3: Hide the more menu item in the top bar.

Objective-C:

[self.extensionsMgr setTopToolbarItemHiddenWithTag:FS_TOPBAR_ITEM_MORE_TAG hidden:YES];

Swift:

extensionsMgr.setTopToolbarItemHiddenWithTag(UInt(FS_TOPBAR_ITEM_MORE_TAG), hidden: true)

Before:

After:

For other items in the top bar, you can refer to the above example, and just need to change the value of the parameter “itemTag” in setTopToolbarItemHiddenWithTag interface.

To show one of the UI elements in the top bar, just set the opposite value for “true” and “false” in the above examples.

Customizing to show/hide a specific Panel

To show or hide a specific panel (See Figure 4-3, includes “Reading Bookmarks”, “Outline”, “Annotations” and “Attachments” panels, just clicks List at the bottom bar to find it), you only need to use the following API:

(void)setPanelHidden:(BOOL)isHidden type:(FSPanelType)type

Figure 4-3

Note: To show or hide a specific panel through APIs, please mark sure the corresponding features in the configuration file is set to “true”. Otherwise, the API settings will not have any effect.

In this section, we only give an example to show you how to show or hide a specific panel through APIs in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder. Just take the “Outline” panel as an example, and for others panels, you only need to change the FSPanelType. The corresponding relation between panels and FSPanelType are as follows:

PanelFSPanelType
Reading BookmarksFSPanelTypeReadingBookmark
OutlineFSPanelTypeOutline
AnnotationsFSPanelTypeAnnotation
Attachments FSPanelTypeAttachment

Open the demos in Xcode. Add the sample code to the “ViewController.m” (Objective-C) or “ViewController.swift” (Swift) (after the code that initializes UIExtensionsManager).

Example: Hide the “Outline” panel.

Objective-C:

[self.extensionsMgr.panelController setPanelHidden:true type:FSPanelTypeOutline];

Swift:

extensionsMgr.panelController.setPanelHidden(true, type: .outline)

Before:

After:

For Reading Bookmarks, Annotations, and Attachments panels, you only need to change the FSPanelType. Just try it.

Customizing to show/hide the UI elements in the View setting bar

To show or hide the UI elements in the View setting bar (See Figure 4-4, just clicks View at the bottom bar to find it), you only need to use the following API:

(void)setItem:(SettingItemType)itemType hidden:(BOOL)hidden;

Figure 4-4

The value of the parameter “itemType” can be set as follows, which maps the items in the View setting bar.

itemitemType
Single page modeSINGLE
Continuous page modeCONTINUOUS
Thumbnail THUMBNAIL
Auto-Brightness BRIGHTNESS
Night modeNIGHTMODEL
Reflow modeREFLOW
Screen lockLOCKSCREEN
Crop modeCROPPAGE
Pan and ZoomPANZOOM
Facing mode (only for iPad)DOUBLEPAGE

In this section, we only take “Reflow” item as an example to show you how to show or hide the UI elements in the View setting bar through APIs in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder. For other UI elements, you only need to change the “itemType“.

Open the demos in Xcode. Add the sample code to the “ViewController.m” (Objective-C) or “ViewController.swift” (Swift) (after the code that initializes UIExtensionsManager).

Example: Hide the “Reflow” item in the View setting bar.

Objective-C:

[self.extensionsMgr.settingBar setItem:REFLOW hidden:YES];

Swift:

extensionsMgr.settingBar.setItem(.REFLOW, hidden: true)

Before:

After:

For other items in the View setting bar, you can refer to the above example, and just need to change the value of the parameter “itemType” in setItem interface.

To show one of the UI elements in the View setting bar, just set the “hidden” to “false” in the above example.

Customizing to show/hide the UI elements in the More Menu view

To show or hide the UI elements in the More Menu view (See Figure 4-5, just click at the menu icon at the right top bar to find it), you can use the following APIs listed in the Table 4-2.

Table 4-2

(void)setMoreViewItemHiddenWithGroup:
(NSUInteger)groupTag hidden:(BOOL)isHidden
Set the enabled state of group
according to "groupTag".
(void)setMoreViewItemHiddenWithGroup:
(NSUInteger)groupTag andItemTag:(NSUInteger)itemTag
hidden:(BOOL)isHidden
Set the enabled state of item
according to "groupTag" and
"itemTag".

Figure 4-5

The value of the parameter “groupTag” in the setMoreViewItemHiddenWithGroup interface can be set as follows:

groupTagNSUInteger
TAG_GROUP_FILE1
TAG_GROUP_PROTECT 4
TAG_GROUP_FORM 7

groupTagitemTagNSUInteger
TAG_GROUP_FILETAG_ITEM_FILEINFO10
TAG_GROUP_FILETAG_ITEM_REDUCEFILESIZE11
TAG_GROUP_PROTECT TAG_ITEM_PASSWORD17
TAG_GROUP_FORM
TAG_ITEM_RESETFORM24
TAG_GROUP_FORM
TAG_ITEM_IMPORTFORM25
TAG_GROUP_FORM
TAG_ITEM_EXPORTFORM26

Note: If you want to show or hide an itemTag, please make sure the corresponding groupTag has not been hidden. Otherwise, the settings will not have any effect.

In this section, we only take “TAG_GROUP_FILE” (File in the view) and “TAG_ITEM_FILEINFO” (File Information in the view) as an example to show you how to show or hide the UI elements in the More Menu view through APIs in the “complete_pdf_viewer” (Objective-C) and “complete_pdf_viewer_swift” (Swift) demos found in the “samples” folder. For other UI elements, you can refer to the following examples and only need to change the parameter value in the setMoreViewItemHiddenWithGroup interfaces.

Open the demos in Xcode. Add the sample code to the “ViewController.m” (Objective-C) or “ViewController.swift” (Swift) (after the code that initializes UIExtensionsManager).

Example 1: Hide the “File” in the More Menu view.

Objective-C:

[self.extensionsMgr.more setMoreViewItemHiddenWithGroup:(TAG_GROUP_FILE) hidden:YES];

Swift:

self.extensionsMgr.more.setMoreViewItemHiddenWithGroup(UInt(TAG_GROUP_FILE), hidden: true)

Before:

After:

Example 2: Hide the “File Information” in the More Menu view.

Objective-C:

[self.extensionsMgr.more setMoreViewItemHiddenWithGroup:TAG_GROUP_FILE andItemTag:TAG_ITEM_FILEINFO hidden:YES];

Swift:

self.extensionsMgr.more.setMoreViewItemHiddenWithGroup(UInt(TAG_GROUP_FILE), andItemTag: UInt(TAG_ITEM_FILEINFO), hidden: true)

Before:

After:

For other items in the More Menu view, you can refer to the above examples, and just need to change the parameter value in the setMoreViewItemHiddenWithGroup interfaces.

To show one of the UI elements in the More Menu view, just set the “hidden” to “false” in the above examples.

Customize UI implementation through source code

In the previous sections, we have introduced how to customize the UI elements through APIs or configuration file in detail. Those changes are in the context of the built-in UI framework of Foxit PDF SDK for iOS. If you do not want to use the ready-made UI framework, you can redesign it through modifying the source code of the UI Extensions Component.

There is one thing to take note of. The source code of the UI Extensions Component is written in Objective-C, so you need to use Objective-C to modify the UI layout. If you are a Swift developer and not already familiar with Objective-C, you might only be able to customize the UI appearance that does not need writing code, such as icons and other UI resources.

To customize the UI implementation, you need to follow these steps:

First, add the following files into your app.

  • FoxitRDK.framework – The framework that includes the Foxit PDF SDK for iOS dynamic library and associated header files. It can be found in the “libs” folder.
  • uiextensions project – It is an open source library that contains some ready-to-use UI module implementations, which can help developers rapidly embed a fully functional PDF reader into their iOS app. Of course, developers are not forced to use the default UI, they can freely customize and design the UI for their specific apps through the “uiextensions” project. It can be found in the “libs/uiextensions_src” folder.

Tip: The built-in UI customization can be done in the uiextensions project, and then you can add the new uiextensionsDynamic.framework generated by the modified uiextensions project to your app instead of the whole uiextensions project.
Second, find the specific code or images related to the UI that you want to customize in the uiextensions project, then modify them based on your requirements.

Now, for your convenience, we will show you how to customize the UI implementation in the “viewer_ctrl_demo” project found in the “samples” folder.

UI Customization Example

Step 1: Add the uiextensions project into the demo.

Note: We will add the uiextensions project to the demo which is convenient for us to see the custom results. The demo already includes FoxitRDK.framework, so we just need to add the uiextensions project.

Load the “viewer_ctrl_demo” in XCode. Drag-and-drop “uiextensions.xcodeproj” found in the “libs/uiextensions_src” of the download package into the “viewer_ctrl_demo” project as shown in Figure 4-6.

Figure 4-6

Then, it will pop up a dialog box which prompts you whether to save the project in a new workspace as shown in Figure 4-7. Click Save.

Figure 4-7

Save the workspace to the “samples” folder, and name “custom_viewer” as shown in Figure 4-8. Click Save.

Figure 4-8

Now, the workspace looks like the Figure 4-9.

Figure 4-9

Congratulations! You have completed the first step

Step 2: Find and modify the code or images related to the UI that you want to customize.

Tip: If you just want to change the icons of the UI elements, you can do it in the uiextensionsDynamic.framework directly instead of importing the source code of uiextensions project. But the same is that you also need to find the icon’s name.

Now we will show you a simple example that changes one button’s icon in the search panel as shown in Figure 4-10.

Figure 4-10

To replace the icon we only need to find the place which stores the icon for this button, then use another icon with the same name to replace it.

Note: Foxit PDF SDK for iOS provides three sets of icons for different devices to make sure that your apps can run smoothly on every device. There are three folders used to store the image resources as follows:

  • Image: used for older devices with non-Retina display (e.g. iPad 2).
  • Image2x: used for iPhone 4/4s/5/5s/6/6s/7/7s/8.
  • Image3x: used for iPhone 6/6s/7/7s/8 Plus, which has the highest resolution.

An iPhone 8 Simulator will be used as an example to run the demo. In the uiextensions project, click “uiextensionsDynamic -> Resource -> png -> image2x -> Search” as shown in Figure 4 11. It’s easy to find the image that we want to replace. The resource files are stored according to the features, so you can locate the related code through the icon’s name.

Figure 4-11

Right now, just replace “search_showlist@2x.png” with your own icon in the “libs/uiextensions_src/uiextensions/Resource/png/image2x” folder. For example, we use the icon of the top search button (search@2x.png) to replace it.

After replacing, firstly build and run the uiextensionsDynamic_aggregate project as shown in Figure 4-12.

Figure 4-12

Note: The uiextensions project can generate a universal “.a” library through building uiextensions_aggregate, or generate a universal framework through building uiextensionsDynamic_aggregate, which can be used for both simulator and iOS device. In this section, we build uiextensionsDynamic_aggregate. The scripts used for generating the universal framework in the uiextension project is shown in Figure 4 12.
The uiextensionsDynamic.framework in the “libs” folder of the download package will be overwritten after building the uiextensionsDynamic_aggregate project successfully.
Then build and run the “viewer_ctrl_demo” project. After building successfully, try the search feature and we can see that the icon of the bottom search button has changed as shown in Figure 4 13.

Figure 4-13

This is just a simple example to show how to customize the UI implementation. You can refer to it and feel free to customize and design the UI for your specific apps through the uiextensions project.

Creating a Custom Tool

With Foxit PDF SDK for iOS, creating a custom tool is a simple process. There are several tools implemented in the UI Extensions Component already. These tools can be used as a base for developers to build upon or use as a reference to create a new tool. In order to create your own tool quickly, we suggest you take a look at the uiextension project found in the “libs” folder.

To create a new tool, the most important step is to declare a class that implements the “IToolHandler” interface.

In this section, we will make a Regional Screenshot Tool to show how to create a custom tool with Foxit PDF SDK for iOS. This tool can help the users who only want to select an area in a PDF page to capture, and then save it as an image. Now, let’s do it

Create a Regional Screenshot Tool in Objective-C

For convenience, we will build this tool based on the “viewer_ctrl_demo” project found in the “samples” folder. Steps required for implementing this tool are as follows:

  • Create a class named ScreenCaptureToolHandler that implements the “IToolHandler” interface.
  • Handle onPageViewLongPress and onDraw events.
  • Instantiate a ScreenCaptureToolHandler object, and then register it to the extensions manager.
  • Set the ScreenCaptureToolHandler object as the current tool handler

Step 1: Create a class named ScreenCaptureToolHandler that implements the “IToolHandler” interface.

a) Load the “viewer_ctrl_demo” project in Xcode. Create a class named “ScreenCaptureToolHandler” in the “Source” folder, and create the corresponding header file.

b) Let the ScreenCaptureToolHandler class implement the IToolHandler interface as follows:

 @interface ScreenCaptureToolHandler : NSObject<IToolHandler>

Step 2: Handle onTouchEvent and onDraw events.

Update ScreenCaptureToolHandler.h as follows:

 #import <foundation /Foundation.h>
#import <foxitrdk /FSPDFViewControl.h>
#import <uiextensionsdynamic /UIExtensionsManager.h>
@protocol IToolHandler;
@class TaskServer;
 
@interface ScreenCaptureToolHandler : NSObject<itoolhandler>
 
- (instancetype)initWithUIExtensionsManager:(UIExtensionsManager*)extensionsManager taskServer:(TaskServer*)taskServer;
@end
 
</itoolhandler></uiextensionsdynamic></foxitrdk></foundation>

Update ScreenCaptureToolHandler.h as follows:

 #import "ScreenCaptureToolHandler.h"
#import <imageio /ImageIO.h>
#import </imageio><imageio /CGImageDestination.h>
#import <mobilecoreservices /UTCoreTypes.h>
 
@interface ScreenCaptureToolHandler ()
 
@end
 
@implementation ScreenCaptureToolHandler {
    UIExtensionsManager* _extensionsManager;
    FSPDFViewCtrl* _pdfViewCtrl;
    TaskServer* _taskServer;
 
    CGPoint startPoint;
    CGPoint endPoint;
 
}
@synthesize type;
 
- (instancetype)initWithUIExtensionsManager:(UIExtensionsManager*)extensionsManager taskServer:(TaskServer*)taskServer
{
    self = [super init];
    if (self) {
        _extensionsManager = extensionsManager;
        _pdfViewCtrl = extensionsManager.pdfViewCtrl;
        _taskServer = taskServer;
    }
    return self;
}
 
-(NSString*)getName
{
    return @" ";
}
 
-(BOOL)isEnabled
{
    return YES;
}
 
-(void)onActivate
{
 
}
 
-(void)onDeactivate
{
 
}
 
// Save the image to a specified path.
- (void)saveJPGImage:(CGImageRef)imageRef path:(NSString *)path
{
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    CGImageDestinationRef dr = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeJPEG , 1, NULL);
 
    CGImageDestinationAddImage(dr, imageRef, NULL);
    CGImageDestinationFinalize(dr);
 
    CFRelease(dr);
}
 
// Handle the PageView Gesture and Touch event
- (BOOL)onPageViewLongPress:(int)pageIndex recognizer:(UILongPressGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        startPoint = [recognizer locationInView:[_pdfViewCtrl getPageView:pageIndex]];
        endPoint = startPoint;
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged)
    {
 
        endPoint = [recognizer locationInView:[_pdfViewCtrl getPageView:pageIndex]];
 
        // Refresh the page view, then the onDraw event will be triggered.
        [_pdfViewCtrl refresh:pageIndex];
    }
    else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled)
    {
        // Get the size of the Rect.
        CGSize size = {fabs(endPoint.x-startPoint.x), fabs(endPoint.y-startPoint.y)};
        CGPoint origin = {startPoint.x<endpoint .x?startPoint.x:endPoint.x, startPoint.y<endPoint.y?startPoint.y:endPoint.y};
        // Get the Rect.
        CGRect rect = {origin, size};
 
        int newDibWidth = rect.size.width;
        int newDibHeight = rect.size.height;
        if (newDibWidth < 1 || newDibHeight < 1)
        {
            return YES;
        }
 
        UIView* pageView = [_pdfViewCtrl getPageView:pageIndex];
        CGRect bound = pageView.bounds;
 
        // Create a bitmap with the size of the selected area.
        int imgSize = newDibWidth*newDibHeight*4;
        void* pBuff = malloc(imgSize);
        NSData* buff = [NSData dataWithBytes:pBuff length:imgSize];
 
        FSBitmap* fsbitmap = [[FSBitmap alloc] initWithWidth:newDibWidth height:newDibHeight format:FSBitmapDIBArgb buffer: buff pitch:newDibWidth*4];
        [fsbitmap fillRect:0xFFFFFFFF rect:nil];
        FSRenderer* fsrenderer = [[FSRenderer alloc] initWithBitmap:fsbitmap is_rgb_order:YES];
        FSPDFPage* page = [_pdfViewCtrl.currentDoc getPage:pageIndex];
 
        // Calculate the display matrix.
        FSMatrix2D* fsmatrix = [page getDisplayMatrix: -rect.origin.x top:-rect.origin.y width:bound.size.width height:bound.size.height rotate:0];
 
        // Set the render content, then start to render the selected area to the bitmap.
        [fsrenderer setRenderContentFlags:FSRendererRenderPage|FSRendererRenderAnnot];
        FSProgressive *progressive = [fsrenderer startRender:page matrix:fsmatrix pause:nil];
        if (progressive) {
            while (true) {
                if ([progressive resume] != FSProgressiveToBeContinued) {
                    break;
                }
            }
        }
 
        // Convert FSBitmap to CGImage.
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buff.bytes, imgSize, nil);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault|kCGImageAlphaLast;
 
        CGImageRef image = CGImageCreate(newDibWidth,newDibHeight, 8, 32, newDibWidth * 4,
                                         colorSpace, bitmapInfo,
                                         provider, NULL, YES, kCGRenderingIntentDefault);
 
        // Save the image to a specified path.
        NSString* jpgPath = @"/Users/Foxit/Desktop/ScreenCapture.jpg";
        [self saveJPGImage:image path:jpgPath];
 
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@""
                                                       message:@" The selected area was saved as a JPG stored in the /Users/Foxit/Desktop/ScreenCapture.jpg" delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"OK") otherButtonTitles:nil];
        [alert show];
 
        return YES;
    }
    return YES;
}
 
// Handle the drawing event.
-(void)onDraw:(int)pageIndex inContext:(CGContextRef)context
{
    if (_extensionsManager.currentToolHandler != self) {
        return;
    }
 
    CGContextSetLineWidth(context, 2);
    CGContextSetLineCap(context, kCGLineCapSquare);
    UIColor *color = [UIColor redColor];
    CGContextSetStrokeColorWithColor(context, [color CGColor]);
    CGPoint points[] = {startPoint,CGPointMake(endPoint.x, startPoint.y),endPoint,CGPointMake(startPoint.x, endPoint.y)};
    CGContextAddLines(context,points,4);
    CGContextClosePath(context);
    CGContextStrokePath(context);
}
 
- (BOOL)onPageViewTap:(int)pageIndex recognizer:(UITapGestureRecognizer *)recognizer
{
    return NO;
}
 
- (BOOL)onPageViewPan:(int)pageIndex recognizer:(UIPanGestureRecognizer *)recognizer
{
    return NO;
 
}
 
- (BOOL)onPageViewShouldBegin:(int)pageIndex recognizer:(UIGestureRecognizer *)gestureRecognizer
{
    if (_extensionsManager.currentToolHandler != self) {
        return NO;
    }
    return YES;
}
 
 
- (BOOL)onPageViewTouchesBegan:(int)pageIndex touches:(NSSet*)touches withEvent:(UIEvent*)event
{
    return NO;
}
 
- (BOOL)onPageViewTouchesMoved:(int)pageIndex touches:(NSSet *)touches withEvent:(UIEvent *)event
{
    return NO;
}
 
- (BOOL)onPageViewTouchesEnded:(int)pageIndex touches:(NSSet *)touches withEvent:(UIEvent *)event
{
    return NO;
}
 
- (BOOL)onPageViewTouchesCancelled:(int)pageIndex touches:(NSSet *)touches withEvent:(UIEvent *)event
{
    return NO;
}
 
@end

Note: In the above code, you should specify an existing path to save the image. Here, the path is “@”/Users/Foxit/Desktop/ScreenCapture.jpg””, please replace it with a valid path.

Step 3: In ViewController.m, instantiate a ScreenCaptureToolHandler object and then register it to the UIExtensionsManager.

#import "ScreenCaptureToolHandler.h"
...
 
@property (nonatomic, strong) ScreenCaptureToolHandler* screenCaptureToolHandler;
...
 
self.screenCaptureToolHandler = [[ScreenCaptureToolHandler alloc] initWithUIExtensionsManager: self.extensionsManager taskServer:nil];
[self.extensionsManager registerToolHandler:self.screenCaptureToolHandler];

Step 4: In ViewController.m, set the ScreenCaptureToolHandler object as the current tool handler.

Register the Doc event listener.

@interface ViewController () <isearcheventlistener ,UIExtensionsManagerDelegate, IDocEventListener>
...
[self.pdfViewCtrl registerDocEventListener:self];
</isearcheventlistener>

Set the current tool handler in the onDocOpened function:

- (void)onDocOpened:(FSPDFDoc *)document error:(int)error {
    [self.extensionsManager setCurrentToolHandler:self.screenCaptureToolHandler];    
}

Now, we have really finished creating a custom tool in Objective-C, build and run the demo. An iPhone 8 Simulator will be used as an example to run the project. After building the demo successfully, long press and select a rectangular area, and then a message box will be popped up as shown in Figure 5-1. It shows where the image (selected area) was saved to.

Figure 5-1

In order to verify whether the tool captures the selected area successfully, we need to find the screenshot. Go to “desktop”, we can see the image as shown in Figure 5-2.

 

Figure 5-2

As you can see we have successfully created a Regional Screenshot Tool in Objective-C. This is just an example to show how to create a custom tool with Foxit PDF SDK for iOS. You can refer to it or the demos to develop the tools you want.

Create a Regional Screenshot Tool in Swift

For convenience, we will build this tool based on the “viewer_ctrl_demo_swift” project found in the “samples\swift” folder. Steps required for implementing this tool are as follows:

  • Create a class named ScreenCaptureToolHandler that implements the “IToolHandler” interface.
  • Handle onPageViewLongPress and onDraw events.
  • Instantiate a ScreenCaptureToolHandler object, and then register it to the extensions manager.
  • Set the ScreenCaptureToolHandler object as the current tool handler

Step 1: Create a class named ScreenCaptureToolHandler that implements the “IToolHandler” interface.

a) Load the “viewer_ctrl_demo_swift” project in Xcode. Create a class named “ScreenCaptureToolHandler” in the “Source” folder.

b) Let the ScreenCaptureToolHandler class implement the IToolHandler interface as follows:

class ScreenCaptureToolHandler: NSObject, IToolHandler { }

Step 2: Handle onTouchEvent and onDraw events.

Update ScreenCaptureToolHandler.swift as follows:

import Foundation
import MobileCoreServices
import ImageIO
 
class ScreenCaptureToolHandler: NSObject, IToolHandler {
    public var type: FSAnnotType
 
    var extensionManager: UIExtensionsManager!
    var pdfViewCtrl: FSPDFViewCtrl!
 
    var startPoint = CGPoint()
    var endPoint = CGPoint()
 
    init(extensionsManager: UIExtensionsManager) {
        self.extensionManager = extensionsManager
        self.pdfViewCtrl = extensionsManager.pdfViewCtrl
        self.type = FSAnnotType.annotUnknownType
        super.init()
    }
 
    func getName() -> String {
        return " "
    }
 
    func isEnabled() -> Bool {
        return true
    }
 
    func onActivate() {
    }
 
    func onDeactivate() {
    }
 
    // Save the image to a specified path.
    func saveJPGImage(imageRef: CGImage, path: String) {
        let fileURL: CFURL = NSURL.fileURL(withPath: path) as CFURL
        let dr = CGImageDestinationCreateWithURL(fileURL, kUTTypeJPEG, 1, nil)!
        CGImageDestinationAddImage(dr, imageRef, nil)
        CGImageDestinationFinalize(dr)
    }
 
    // Handle the PageView Gesture and Touch event
    func onPageViewLongPress(_ pageIndex: Int32, recognizer: UILongPressGestureRecognizer) -> Bool {
 
        if recognizer.state == UIGestureRecognizerState.began {
            startPoint = recognizer.location(in: pdfViewCtrl.getPageView(pageIndex))
            endPoint = startPoint
        }
        else if recognizer.state == UIGestureRecognizerState.changed {
 
            endPoint = recognizer.location(in: pdfViewCtrl.getPageView(pageIndex))
 
            // Refresh the page view, then the onDraw event will be triggered.
            pdfViewCtrl.refresh(pageIndex)
        }
        else if recognizer.state == UIGestureRecognizerState.ended || recognizer.state == UIGestureRecognizerState.cancelled {
 
            // Get the size of the Rect.
            let size = CGSize(width: fabs(endPoint.x - startPoint.x), height: fabs(endPoint.y - startPoint.y))
            let origin = CGPoint(x: (startPoint.x < endPoint.x) ? startPoint.x : endPoint.x, y: (startPoint.y<endPoint.y) ? startPoint.y : endPoint.y)
            // Get the Rect.
            let rect = CGRect(origin: origin, size: size)
 
            let newDibwidth = rect.size.width
            let newDibHeight = rect.size.height
            if newDibwidth < 1 || newDibHeight < 1 {
                return true
            }
 
            let pageView = pdfViewCtrl.getPageView(pageIndex)
            let bound = pageView.bounds
 
            // Create a bitmap with the size of the selected area.
            let imgSize = newDibwidth * newDibHeight * 4
            let capacity: Int = Int(newDibwidth) * Int(newDibHeight) * 4
 
            let buff = UnsafeMutablePointer<UInt8>.allocate(capacity: capacity)
            let pBuff = NSData.init(bytes: UnsafeRawPointer(buff), length: capacity)
 
 
            let pitch: Int = Int(newDibwidth) * 4
            guard let fsbitmap = FSBitmap.init(width: Int32(newDibwidth), height: Int32(newDibHeight), format:FSBitmapDIBFormat.dibArgb , buffer: pBuff as Data, pitch: Int32(pitch)) else {
                return false
            }
            fsbitmap.fillRect(0xFFFFFFFF, rect: nil)
            let fsrenderer = FSRenderer.init(bitmap: fsbitmap, is_rgb_order: true)
            let page = pdfViewCtrl.currentDoc?.getPage(pageIndex)
 
            // Calculate the display matrix.
            let fsmatrix = page?.getDisplayMatrix(-Int32(rect.origin.x), top: -Int32(rect.origin.y), width: Int32(bound.size.width), height: Int32(bound.size.height), rotate: FSRotation.rotation0)
 
            // Set the render content, then start to render the selected area to the bitmap.
            fsrenderer?.setRenderContentFlags(UInt32(UInt8(FSRendererContentFlag.renderPage.rawValue) | UInt8(FSRendererContentFlag.renderAnnot.rawValue)))
            let progress = fsrenderer?.startRender(page, matrix: fsmatrix, pause: nil)
            if ((progress) != nil) {
 
                while (true) {
                    if (progress?.resume() != FSProgressiveState.toBeContinued)
                    {
                        break
                    }
                }
            }
 
            // Convert FSBitmap to CGImage.
            let releaseData: CGDataProviderReleaseDataCallback = {
                (info: UnsafeMutableRawPointer?, data:UnsafeRawPointer, size:Int) -> Void in
            }
 
            let provider: CGDataProvider = CGDataProvider.init(dataInfo: nil, data: pBuff.bytes, size: Int(imgSize), releaseData: releaseData)!
            let colorSpace = CGColorSpaceCreateDeviceRGB()
            let bitmapInfo: CGBitmapInfo = .byteOrderMask
 
            let image = CGImage(width: Int(newDibwidth), height: Int(newDibHeight), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: Int(newDibwidth) * 4, space: colorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
 
            // Save the image to a specified path.
            let jpgPath = "/Users/Foxit/Desktop/ScreenCapture.jpg"
            self.saveJPGImage(imageRef: image!, path: jpgPath)
 
            let alert = UIAlertView(title: "", message: " The selected area was saved as a JPG stored in the /Users/Foxit/Desktop/ScreenCapture.jpg", delegate: nil, cancelButtonTitle: NSLocalizedString("OK", comment: "OK"))
            alert.show()
            return true
        }
        return true
    }
 
    // Handle the drawing event.
    func onDraw(_ pageIndex: Int32, in context: CGContext) {
        context.setLineWidth(CGFloat(2))
        context.setLineCap(.square)
        let color = UIColor.red
        context.setStrokeColor(color.cgColor)
        let points = [startPoint, CGPoint(x: CGFloat(endPoint.x), y: CGFloat(startPoint.y)), endPoint, CGPoint(x: CGFloat(startPoint.x), y: CGFloat(endPoint.y))]
        context.addLines(between: points)
        context.closePath()
        context.strokePath()
    }
 
    func onPageViewTap(_ pageIndex: Int32, recognizer: UITapGestureRecognizer?) -> Bool {
        return false
    }
 
    func onPageViewPan(_ pageIndex: Int32, recognizer: UIPanGestureRecognizer) -> Bool {
        return false
    }
 
    func onPageViewShouldBegin(_ pageIndex: Int32, recognizer gestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
 
    func onPageViewTouchesBegan(_ pageIndex: Int32, touches: Set<anyhashable>, with event: UIEvent) -> Bool {
        return false
    }
 
    func onPageViewTouchesMoved(_ pageIndex: Int32, touches: Set</anyhashable><anyhashable>, with event: UIEvent) -> Bool {
        return false
    }
 
    func onPageViewTouchesEnded(_ pageIndex: Int32, touches: Set</anyhashable><anyhashable>, with event: UIEvent) -> Bool {
        return false
    }
 
    func onPageViewTouchesCancelled(_ pageIndex: Int32, touches: Set</anyhashable><anyhashable>, with event: UIEvent) -> Bool {
        return false
    }
}
 
</anyhashable>

Note: In the above code, you should specify an existing path to save the image. Here, the path is  “/Users/Foxit/Desktop/ScreenCapture.jpg” , please replace it with a valid path.

Step 3: In ViewController.swift, istantiate a ScreenCaptureToolHandler object and then register it to the UIExtensionsManager.

var screenCaptureToolHandler: ScreenCaptureToolHandler!
...
 
self.screenCaptureToolHandler = ScreenCaptureToolHandler.init(extensionsManager: self.extensionsManager)
self.extensionsManager.register(self.screenCaptureToolHandler)

Step 4:  In ViewController.swift, set the ScreenCaptureToolHandler object as the current tool handler.

Register the Doc event listener

class ViewController: UIViewController, UISearchBarDelegate, ISearchEventListener, IDocEventListener
...
self.pdfViewCtrl.register(self)

Set the current tool handler in the onDocOpened function:

func onDocOpened(_ document: FSPDFDoc?, error: Int32) {
    self.extensionsManager.currentToolHandler = self.screenCaptureToolHandler
}

Now, we have really finished creating a custom tool in Swift. Then, build and run the demo. After building the demo successfully, long press and select a rectangular area, and then a message box will be popped up (refer to Figure 5-1). Go to “desktop”, we will see the screenshot (refer to Figure 5-2).

This is just an example to show how to create a custom tool in Swift with Foxit PDF SDK for iOS. You can refer to it or the demos to develop the tools you want.

 

Technical Support

Reporting Problems

Foxit offers 24/7 support for its products and are fully supported by the PDF industry’s largest development team of support engineers. If you encounter any technical questions or bug issues when using Foxit PDF SDK for iOS, please submit the problem report to the Foxit support team at http://tickets.foxitsoftware.com/create.php. In order to better help you solve the problem, please provide the following information:

  • Contact details
  • Foxit PDF SDK for iOS product and version
  • Your Operating System and IDE version
  • Detailed description of the problem
  • Any other related information, such as log file or error screenshot

Contact Information

You can contact Foxit directly, please use the contact information as follows:

Foxit Support:

Sales Contact:

  • Phone: 1-866-680-3668
  • Email: sales@foxitsoftware.com

Support & General Contact:

  • Phone: 1-866-MYFOXIT or 1-866-693-6948
  • Email: support@foxitsoftware.com

 

Updated on August 24, 2018

Was this article helpful?

Related Articles