Creating the native iOS part of the plug-in
All the files for the iOS native part need to be placed in the src/ios folder. The iOS native part will consist of the following files:
- Objective-C source code
- Fraud prevention SDK (iOS Framework)
Objective-C source code
The Objective-C source code needed in the plug-in will be divided into two classes:
src/ios/GahPlugin.h which is the main entry point in the iOS native part.
#import <Cordova/CDVPlugin.h>
/**
* GAH cordova plugin wrapping the GAH SDK.
*/
@interface GahPlugin : CDVPlugin
/**
* Initializes GAH SDK.
*/
- (void)initialize:(CDVInvokedUrlCommand*)command;
/**
* Retrieves the visit id.
*/
- (void)visitId:(CDVInvokedUrlCommand*)command;
/**
* Starts prefetch of data, caches signals. Call on applicaiton start, after GAH has been initialized.
*/
- (void)startPrefetch:(CDVInvokedUrlCommand*)command;
/**
* Stops prefetch of data. Call before application end, or when GAH will not be further used.
*/
- (void)stopPrefetch:(CDVInvokedUrlCommand*)command;
/**
* Clears the transaction resources. Call after each transaction (login, transfer funds etc.).
*/
- (void)clearTransaction:(CDVInvokedUrlCommand*)command;
/**
* Checks if signal collection is completed. Needs to be called before {@code getVisiId},
* to check if all signals are collected.
*/
- (void)isSignalCollectionCompleted:(CDVInvokedUrlCommand*)command;
/**
* Sets the transaction as critical(high value trasfer etc.).
*/
- (void)setTransactionAsCritical:(CDVInvokedUrlCommand*)command;
@end
src/ios/GahPlugin.m
#import "GahPlugin.h"
#import "GAHRiskEngineIntegration.h"
@interface GahPlugin()
@property(nonatomic, strong) GAHRiskEngineIntegration* integrationEngine;
@end
@implementation GahPlugin
#pragma mark override
- (void)pluginInitialize {
self.integrationEngine = [[GAHRiskEngineIntegration alloc] init];
}
#pragma mark public
- (void)initialize:(CDVInvokedUrlCommand*)command {
NSString* gahUrl = (NSString*)[command.arguments objectAtIndex:0];
NSString* tmxOrgId = (NSString*)[command.arguments objectAtIndex:1];
NSString* tmxFpServerUrl = (NSString*)[command.arguments objectAtIndex:2];
if (gahUrl == nil || gahUrl.length == 0) {
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Missing mandatory parameter: GAH URL"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
[_integrationEngine initializeGAH:gahUrl tmxOrgId:tmxOrgId tmxFpServerUrl:tmxFpServerUrl];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Initialization ok"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
- (void)visitId:(CDVInvokedUrlCommand*)command {
[_integrationEngine requestVisitID:self.commandDelegate callbackId:command.callbackId];
}
- (void)startPrefetch:(CDVInvokedUrlCommand*)command {
[_integrationEngine startPrefetchingCollection];
}
- (void)stopPrefetch:(CDVInvokedUrlCommand*)command {
[_integrationEngine stopPrefetchingCollection];
}
- (void)clearTransaction:(CDVInvokedUrlCommand*)command {
[_integrationEngine clearResources];
}
- (void)isSignalCollectionCompleted:(CDVInvokedUrlCommand*)command {
[_integrationEngine isSignalCollectionCompleted:self.commandDelegate callbackId:command.callbackId];
}
- (void)setTransactionAsCritical:(CDVInvokedUrlCommand*)command {
[_integrationEngine setTransactionAsCritical];
}
@end
src/ios/GAHRiskEngineIntegration.h* which is a helper class
#import <Foundation/Foundation.h>
#import <GAHRiskEngine/GAHRiskEngine.h>
#import <GAHRiskEngine/GAHGemaltoSignalConfig.h>
#import <GAHRiskEngine/BehavioSecIOSSDK.h>
#import <Cordova/CDVPlugin.h>
/**
* This class is holding business logic to communicate with GAHRiskEngine
* It initiates the App backend server call post getting response from GAHRiskEngine
*/
@interface GAHRiskEngineIntegration : NSObject
/**
* Initializes the GAH SDK.
*
* @param url
* GAH back end url.
* @param tmxOrgId
* Thread Matrix SDK organization id.
* @param tmxFpServerUrl
* Thread Matrix SDK server url.
*/
- (void) initializeGAH: (NSString*) url tmxOrgId:(NSString*) tmxOrgId tmxFpServerUrl:(NSString*) tmxFpServerUrl;
/**
* Clears transaction data after every transaction
*/
-(void)clearResources;
/*!
* startPrefetchingCollections - Starts all provider signal collection prefetch
*/
- (void)startPrefetchingCollection;
/**
* Stops pre-fetching of signals
*/
- (void)stopPrefetchingCollection;
/**
* Requests the Visit ID value from GAHRiskEngine.
*
* @param delegate
* Callback back to javascript.
* @param callbackId Callback id.
*/
-(void)requestVisitID:(id <CDVCommandDelegate>) delegate callbackId:(NSString*) callbackId;
/**
* Sets the transaction as critical.
*/
- (void)setTransactionAsCritical;
/**
* Checks if signal collection is completed.
*
* @param delegate
* Callback back to javascript.
* @param callbackId Callback id.
*/
- (void)isSignalCollectionCompleted:(id <CDVCommandDelegate>) delegate callbackId:(NSString*) callbackId;
@end
src/ios/GAHRiskEngineIntegration.m
#import "GAHRiskEngineIntegration.h"
#import <GAHRiskEngine/GAHRiskEngine.h>
#import <GAHRiskEngine/GAHCoreConfig.h>
#import <GAHRiskEngine/GAHGemaltoSignalConfig.h>
#import <GAHRiskEngine/GAHBSecConfig.h>
#import <GAHRiskEngine/GAHTMXConfig.h>
#import <GAHRiskEngine/GAHSignalGroupConstants.h>
@implementation GAHRiskEngineIntegration
- (void) initializeGAH: (NSString*) url tmxOrgId:(NSString*) tmxOrgId tmxFpServerUrl:(NSString*) tmxFpServerUrl {
GAHCoreConfig * reConfig = [GAHCoreConfig sharedConfigurationWithUrl:url];
GAHGemaltoSignalConfig *signalConfig = [GAHGemaltoSignalConfig sharedConfiguration];
GAHBSecConfig * bsecConfig = [GAHBSecConfig sharedConfiguration];
NSSet* configObejcts;
if ((tmxOrgId != nil && tmxOrgId.length > 0) && ((tmxFpServerUrl != nil && tmxFpServerUrl.length > 0))) {
GAHTMXConfig * tmxConfig = [GAHTMXConfig sharedConfigurationWithOrgID:tmxOrgId andFingerprintServer:tmxFpServerUrl];
configObejcts = [NSSet setWithObjects:reConfig,signalConfig,bsecConfig,tmxConfig, nil];
} else {
configObejcts = [NSSet setWithObjects:reConfig,signalConfig,bsecConfig, nil];
}
[GAHCore initialize:configObejcts];
}
-(void)requestVisitID:(id <CDVCommandDelegate>) delegate callbackId:(NSString*) callbackId {
[GAHCore requestVisitID:^(NSString *visitID) {
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:visitID];
[delegate sendPluginResult:result callbackId:callbackId];
} failure:^(NSInteger errorCode, NSString *errorMessage) {
NSString* error = [NSString stringWithFormat:@"Error message: %@, error code: %lu", errorMessage, (long) errorCode];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error];
[delegate sendPluginResult:result callbackId:callbackId];
}];
}
- (void)startPrefetchingCollection {
[GAHCore startPrefetchSignals];
}
- (void)stopPrefetchingCollection {
[GAHCore stopPrefetchSignals];
}
- (void)setTransactionAsCritical {
[GAHCore setTransactionAsCritical];
}
- (void)isSignalCollectionCompleted:(id <CDVCommandDelegate>) delegate callbackId:(NSString*) callbackId {
[GAHCore requestPrefetchStatus:^(NSInteger statusCode, NSString *statusMessage) {
if (statusCode == 2100) {
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:statusMessage];
[delegate sendPluginResult:result callbackId:callbackId];
} else {
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:statusMessage];
[delegate sendPluginResult:result callbackId:callbackId];
}
}];
}
-( void)clearResources {
[GAHCore clearTransactionResources];
}
`
@end
Add Risk Management SDK
Copy the debug and release libraries into src/ios/libs/debug/ and src/ios/libs/release/.
Updating the main plugin.xml file
After we have added all the necessary files for the iOS platform, we need to update the plugin.xml file
<?xml version='1.0' encoding='utf-8'?>
<plugin id="com.gemalto.plugin.gah" version="0.2" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>GahPlugin</name>
<js-module name="GahPlugin" src="www/GahPlugin.js">
<clobbers target="GahPlugin" />
</js-module>
<!-- ios -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="GahPlugin">
<param name="ios-package" value="GahPlugin"/>
</feature>
</config-file>
<config-file parent="NSLocationWhenInUseUsageDescription" target="*-Info.plist">
<string>required this permission</string>
</config-file>
<!-- Objective-C source code -->
<header-file src="src/ios/GahPlugin.h"/>
<source-file src="src/ios/GahPlugin.m"/>
<header-file src="src/ios/GAHRiskEngineIntegration.h"/>
<source-file src="src/ios/GAHRiskEngineIntegration.m"/>
<!-- FPP SDK libraries -->
<framework src="src/ios/libs/debug/GAHRiskEngine.framework" embed="false" custom="true"/>
<!-- <framework src="src/ios/libs/release/GAHRiskEngine.framework" embed="false" custom="true"/> -->
</platform>
<!-- android -->
<platform name="android">
<!-- android permissions -->
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
</config-file>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="GahPlugin" >
<param name="android-package" value="com.gemalto.plugin.gah.GahPlugin"/>
</feature>
</config-file>
<!-- java source code -->
<source-file src="src/android/GahPlugin.java" target-dir="src/com/gemalto/plugin/gah" />
<source-file src="src/android/GAHRiskEngineIntegration.java" target-dir="src/com/gemalto/plugin/gah" />
<!-- gradle file -->
<framework src="src/android/gahBuild.gradle" custom="true" type="gradleReference" />
<!-- FPP SDK jar file -->
<resource-file src="src/android/libs/debug/GAHRiskEngine.jar" target="libs/debug/GAHRiskEngine.jar" />
<resource-file src="src/android/libs/release/GAHRiskEngine.jar" target="libs/release/GAHRiskEngine.jar" />
<!-- FPP SDK native libraries -->
<resource-file src="src/android/libs/debug/arm64-v8a/libmedlc_shared.so" target="libs/debug/arm64-v8a/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/arm64-v8a/libmedlc_shared.so" target="libs/release/arm64-v8a/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/arm64-v8a/libtdm-5.4-73-jni.so" target="libs/debug/arm64-v8a/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/release/arm64-v8a/libtdm-5.4-73-jni.so" target="libs/release/arm64-v8a/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/debug/armeabi-v7a/libmedlc_shared.so" target="libs/debug/armeabi-v7a/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/armeabi-v7a/libmedlc_shared.so" target="libs/release/armeabi-v7a/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/armeabi-v7a/libtdm-5.4-73-jni.so" target="libs/debug/armeabi-v7a/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/release/armeabi-v7a/libtdm-5.4-73-jni.so" target="libs/release/armeabi-v7a/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/debug/x86/libmedlc_shared.so" target="libs/debug/x86/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/x86/libmedlc_shared.so" target="libs/release/x86/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/x86/libtdm-5.4-73-jni.so" target="libs/debug/x86/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/release/x86/libtdm-5.4-73-jni.so" target="libs/release/x86/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/debug/x86_64/libmedlc_shared.so" target="libs/debug/x86_64/libmedlc_shared.so" />
<resource-file src="src/android/libs/release/x86_64/libmedlc_shared.so" target="libs/release/x86_64/libmedlc_shared.so" />
<resource-file src="src/android/libs/debug/x86_64/libtdm-5.4-73-jni.so" target="libs/debug/x86_64/libtdm-5.4-73-jni.so" />
<resource-file src="src/android/libs/release/x86_64/libtdm-5.4-73-jni.so" target="libs/release/x86_64/libtdm-5.4-73-jni.so" />
</platform>
</plugin>
iOS limitations
The GahPlugin for the iOS platform currently has some limitations.
No automatic debug/release build
The Risk Management SDK has two library variants:
- debug
- release
For production the Release version of the library should always be used. Unfortunately the GahPlugin does not switch the library version automatically based on the build type. This currently needs to be performed manually in the plug-in. See file plugin.xml and comment and uncomment these two lines based on the build type:
<!-- FPP SDK libraries -->
<framework src="src/ios/libs/debug/GAHRiskEngine.framework" embed="false" custom="true"/>
<!-- <framework src="src/ios/libs/release/GAHRiskEngine.framework" embed="false" custom="true"/> -->
Manual build settings
Updating the build settings with additional build flags and framework search path has to be done manually in the generated project.