Authoring iOS Custom Modules for Pega Mobile Client
Note: Custom modules and this article are intended only for experienced iOS developers. Creating a custom module requires advanced knowledge and skills in developing native mobile apps.
Custom Modules are a Pega Mobile Client feature allowing custom native code to run in the context of a Pega application running inside the client. Custom modules can be used for integrating native libraries, adding features, and addressing requirements for devices or Apple-iOS features specific to a user's use-cases.
Prerequisites Custom Module DevKit is a part of Pega Mobile Client that can be obtained through Digital Delivery. The version of DevKit that you download and use has to match the version of Pega Mobile Client that is being used on Mobile Channel, and has the following additional requirements for its use:
- macOS computer with Xcode development environment and developer command-line tools installed.
- Java Runtime Environment (JRE) version 1.8 configured.
- Optional: Safari Web Inspector configured to work with a device or simulator.
Note: This article assumes that the developer already has basic Swift/iOS knowledge, so the article won't be covering these aspects of Custom Modules. Please bear in mind that developing a custom module requires the ability to develop native code, and work with Xcode IDE as well as the command-line tools being a part of Custom Module DevKit.
This article will cover the essentials of developing a PMC Custom Module:
- Creating a module
- Basic concepts
- Running the module from DevKit when targeting the Pega Mobile Client application
- Calling the APIs provided by a custom module from the JavaScript context
- Deploying the module to an instance
Creating a module To create a new module, unzip the Module DevKit package, navigate to its root in the terminal, and then enter the following command:
./gradlew createModule --moduleDirectory=<path_to_new_module_directory> --moduleName=<module_name>
For example:
./gradlew createModule --moduleDirectory=/Users/dev/modules --moduleName=SampleModule
Note: Creating modules in the Module DevKit package root directory is not recommended, as doing so will make migrating to newer DevKit versions more difficult.
The above command will initialize an empty module project with the necessary configuration already in place. Once you have entered and run the command, open the ModuleDevKit.xcworkspace project by using Xcode.
Basic concepts The generated sample project has a Cocoa Framework with 2 run schemes: Device and Simulator. The project has 2 classes that are relevant to Pega integration: an application plugin and WebView plugin subclasses.
Application Plugin The application plugin is the entry point for a custom module, and provides access to `UIApplicationDelegate` methods. The application plugin will receive the application's life cycle method invocations at runtime. Application plugins are also where you register the WebView Plugins. Each application plugin type has to be registered in the framework's Info.plist file in order to be properly instantiated by the Pega Mobile Client. This is done by adding the plugin type name to the array stored under PMSApplicationPluginClasses in that key. For more information on application plugins, see the documents on writing application plugins, in the docs folder available in the Module DevKit package root directory.
WebViewPlugin subclass The WebViewPlugin subclass provides an extension point to the web view and allows custom JavaScript APIs to be exposed. These APIs can then be leveraged by applications created using Pega Platform. Each web view manages a set of instances of all registered plugins. PMC web view plugins consist of 2 parts: a protocol conforming to PMJSExport protocol, which defines methods and properties exposed to JavaScript, and the class implementing that protocol.
The following code is an example of PMSWebViewPlugin subclass that is generated while creating a new module:
@objc
protocol SampleModuleWebViewPluginExport: PMSJSExport {
func sayHello(_ name: PMSJSValue, promise: PMSJSPromise)
}
class SampleModuleWebViewPlugin: PMSWebViewPlugin, SampleModuleWebViewPluginExport {
static let name = "samplePlugin"
func sayHello(_ name: PMSJSValue, promise: PMSJSPromise) {
...
}
}
For information on further aspects of developing WebView Plugins, see the document in the Module DevKit docs directory.
Note: The Info.plist of a custom module framework must expose at least one application plugin. Depending on the use case there may be either no WebViewPlugin required, or multiple WebViewPlugins that can be registered by a single ApplicationPlugin.
Knowing the basic custom module elements, it is now possible to have a look at the WebView plugin method that is being exposed by a plugin. The WebView plugin method has a simple implementation of sayHello(name: promise) method that returns a greeting for a given name. For example:
class SampleModuleWebViewPlugin: PMSWebViewPlugin, SampleModuleWebViewPluginExport {
...
func sayHello(_ name: PMSJSValue, promise: PMSJSPromise) {
promise.resolve(with: PMSJSValue("Hello \(name.stringValue)!"))
}
}
The second important element of the WebView plugin is the "name" static property, which defines the name under which the module will expose its APIs in a window.pms.plugins object. The plugin converts the name to camel case, so that SampleModule will be available as a window.pms.plugins.sampleModule for JavaScript to invoke.
Running the module from DevKit To run the module, navigate to the existing Mobile Channel page, or create one. From the icons on the right side of the screen, click the Pega Mobile Preview icon, and then click the "Copy link" button. Paste the link into ModuleDevKit.plist as the value for the PMMobileChannelURL key.
Next, select a run scheme (Device or Simulator), and then select the appropriate target. When running on a device, you must additionally set up the project code's signing settings, by selecting the proper development team and then adjusting the application identifier on the "Signing & Capabilities" tab, under Project settings. Finally, click the run button.
The PMC should then boot, fetch the channel configuration, and launch the app. DevKit won't apply any branding to LaunchScreen, and uses the default launch screen instead.
Calling the APIs provided by a custom module from the JavaScript context
At this point, it is not yet possible to invoke the custom module JavaScript API from the Pega Platform UI, but it can be invoked from the Safari Web Inspector JavaScript console. To do so, pick a web view of the running app (either on the simulator or on the device). In the Web Inspector window, navigate to the Console tab and enter the following command:
window.pms.plugins.samplePlugin.sayHello("Developer").then(function(result) {
console.log(result)
})
When the code runs, the results are printed to the Xcode debugger console. The results returned by the native code can then be easily examined while developing the native module code.
Deploying the module
Pega Platform 8.4 and later Starting from Pega Platform 8.4, the Custom Module DevKit includes a task that provides for seamless packaging and uploading of custom modules. To package and upload a custom module, navigate to the root of the Custom Module DevKit package and enter the following command:
./gradlew uploadModule --moduleName=<module_name> -PmobileChannelUrl=<channel_url> -Pusername=<username> -Ppassword=<password>
The channel URL in the above command is the same URL that was placed in ModuleDevKit.plist when running the module code for the first time.
Once you have entered and run the above command, the module will be available to be added in the Custom modules section of the Configuration tab in the Mobile Channel. When you add the module there, it will be included in the next build of your mobile app.
Pega Platform 8.3 For earlier versions of Pega Platform use the package task, which will build the framework package. Navigate to the root of the Custom Module DevKit package, and then enter and run the following command
./gradlew packageModule --moduleName=<module_name> --moduleTarget=<Device|Simulator>
For example:
./gradlew packageModule --moduleName=SampleModule --moduleTarget=Device
A zip file is created and saved with the custom module's name inside the "build" directory in the root Custom Module DevKit folder. You can then download the branding assets template file from Branding assets templates for Pega Mobile Client
Unzip the framework package from the "build" directory into a new directory called "modules-ios", in the root of the downloaded template package. Then upload the zipped assets files to the Mobile Channel, and build the app. Your module will be included in the next build of your mobile app.
To learn more about integrating your Custom Module with Pega Platform UI please refer to Invoking Pega Mobile Client Custom Modules from the Pega Platform UI.
***Edited by Moderator Marije to update URL pointing to outdaded community sites***