Blog Post

How to Expose Native iOS APIs to Cordova

Illustration: How to Expose Native iOS APIs to Cordova

We recently updated our Cordova library to add the annotation manipulation API, and today we’re excited to announce that we’ve further extended the APIs of our Cordova library to add the document processing API.

In our native SDKs, we expose a lot of APIs for full customization, but we only use a subset of those APIs in our Cordova library. In this article, we’ll show you how to bring native iOS APIs to Cordova, which makes it easier for everyone to fork and customize our open source repository or to expose native iOS code to Cordova in general.

In this tutorial, we’ll go through how we implemented the recently added processAnnotations API that allows you to export documents with embedded, flattened, or removed annotations.

So let’s get started!

Declaring the Cordova JavaScript API

First, we declare the JavaScript API in pspdfkit.js to make it available to Cordova.

We can achieve this using the cordova.exec command, like so:

// Document Processing.
exports.processAnnotations = function (
	annotationChange,
	processedDocumentPath,
	callback,
	annotationType,
) {
	if (platform === 'ios') {
		executeAction(callback, 'processAnnotations', [
			annotationChange,
			processedDocumentPath,
			annotationType,
		]);
	} else {
		console.log('Not implemented on ' + platform + '.');
	}
};

For more details, please take a look at the official Cordova JavaScript interface guide.

Implementing the Objective-C Logic

Now that we’ve declared the JavaScript API in Cordova, we need to implement the functionality in Objective-C in PSPDFKitPlugin.m:

- (void)processAnnotations:(CDVInvokedUrlCommand *)command {
    PSPDFAnnotationChange change = (PSPDFAnnotationChange)[self optionsValueForKeys:@[[command argumentAtIndex:0]] ofType:@"PSPDFAnnotationChange" withDefault:PSPDFAnnotationChangeEmbed];
    NSURL *processedDocumentURL = [self writableFileURLWithPath:[command argumentAtIndex:1] override:YES copyIfNeeded:NO];

    // The annotation type is optional. We default to `All` if it's not specified.
    NSString *typeString = [command argumentAtIndex:2] ?: [command argumentAtIndex:3];
    PSPDFAnnotationType type = PSPDFAnnotationTypeAll;
    if (typeString.length > 0) {
        type = (PSPDFAnnotationType) [self optionsValueForKeys:@[typeString] ofType:@"PSPDFAnnotationType" withDefault:PSPDFAnnotationTypeAll];
    }

    PSPDFDocument *document = self.pdfController.document;
    VALIDATE_DOCUMENT(document)

    // Create a processor configuration with the current document.
    PSPDFProcessorConfiguration *configuration = [[PSPDFProcessorConfiguration alloc] initWithDocument:document];

    // Modify annotations.
    [configuration modifyAnnotationsOfTypes:type change:change];

    // Create the PDF processor and write the processed file.
    PSPDFProcessor *processor = [[PSPDFProcessor alloc] initWithConfiguration:configuration securityOptions:nil];
    NSError *error;
    BOOL success = [processor writeToFileURL:processedDocumentURL error:&error];
    if (success) {
        [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:success] callbackId:command.callbackId];
    }
    else {
        CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
                                                      messageAsDictionary:@{@"localizedDescription": error.localizedDescription, @"domain": error.domain}];
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }
}

Next, you’ll learn how to use the API.

Using the API in Cordova JavaScript Code

Now that we’ve exposed the API to process annotations to our Cordova plugin, here’s how we can use it in our app’s JavaScript code:

// Flatten ink annotations from the current document.
PSPDFKit.processAnnotations(
	'flatten',
	'pdf/processed.pdf',
	function (success, error) {
		if (success) {
			console.log('Successfully processed annotation');
		} else {
			console.log('An error has occurred: ' + error);
		}
	},
	'Ink',
);

That’s all!

Forking

If you come across any missing APIs that you think would be useful to have, feel free to reach out to us. We’re happy to help!

However, if your use case is very specific, and if making native APIs available in our official Cordova library doesn’t make sense, you can fork the repository and implement the new API in your fork.

Information

PSPDFKit for iOS comes with several sample projects, like the Catalog app, which is a great source of Swift code that you can use as a reference to write Objective-C code to bridge to Cordova.

Conclusion

We hope this article will help you improve Cordova libraries, be it the PSPDFKit one or other ones.

Explore related topics

Share post
Free trial Ready to get started?
Free trial