Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add basic eager initialization #124

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@

<config-file target="res/xml/config.xml" parent="/*">
<feature name="Adjust">
<param name="android-package" value="com.adjust.sdk.AdjustCordova"/>
<param name="android-package" value="com.adjust.sdk.EagerAdjustCordova"/>
<param name="onload" value="true" />
</feature>
</config-file>

<source-file src="src/android/AdjustCordova.java" target-dir="src/com/adjust/sdk" />
<source-file src="src/android/AdjustCordovaUtils.java" target-dir="src/com/adjust/sdk" />
<source-file src="src/android/BufferedCallbackContext.java" target-dir="src/com/adjust/sdk" />
<source-file src="src/android/EagerAdjustCordova.java" target-dir="src/com/adjust/sdk" />
<lib-file src="src/android/adjust-android.jar" target-dir="libs" />

<framework src="com.google.android.gms:play-services-analytics:+" />
Expand All @@ -69,13 +71,17 @@
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Adjust">
<param name="ios-package" value="AdjustCordova"/>
<param name="ios-package" value="EagerAdjustCordova"/>
<param name="onload" value="true" />
</feature>
</config-file>

<header-file src="src/ios/AdjustCordova.h" />
<source-file src="src/ios/AdjustCordova.m" />
<header-file src="src/ios/EagerAdjustCordova.h" />
<source-file src="src/ios/EagerAdjustCordova.m" />
<header-file src="src/ios/EagerAdjustBuffer.h" />
<source-file src="src/ios/EagerAdjustBuffer.m" />
<header-file src="src/ios/AdjustCordovaDelegate.h" />
<source-file src="src/ios/AdjustCordovaDelegate.m" />

Expand Down
32 changes: 32 additions & 0 deletions src/android/BufferedCallbackContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.adjust.sdk;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;

import java.util.ArrayList;

class BufferedCallbackContext extends CallbackContext {
private ArrayList<PluginResult> results = new ArrayList();

public BufferedCallbackContext(String callbackId, CordovaWebView webView) {
super(callbackId, webView);
}

@Override
public void sendPluginResult(PluginResult pluginResult) {
super.sendPluginResult(pluginResult);
results.add(pluginResult);
}

/**
* Calls `sendPluginResult` on callbackContext instance, with all buffered PluginResults.
*
* @param callbackContext
*/
public void replayResults(CallbackContext callbackContext) {
for (PluginResult result : results) {
callbackContext.sendPluginResult(result);
}
}
}
128 changes: 128 additions & 0 deletions src/android/EagerAdjustCordova.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.adjust.sdk;

import android.os.Bundle;

import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_CREATE;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_ATTRIBUTION_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_DEFERRED_DEEPLINK_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_EVENT_TRACKING_FAILED_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_EVENT_TRACKING_SUCCEEDED_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_SESSION_TRACKING_FAILED_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.COMMAND_SET_SESSION_TRACKING_SUCCEEDED_CALLBACK;
import static com.adjust.sdk.AdjustCordovaUtils.KEY_APP_TOKEN;
import static com.adjust.sdk.AdjustCordovaUtils.KEY_ENVIRONMENT;

public class EagerAdjustCordova extends AdjustCordova {

// DO NOT CHANGE (Used in MainActivity)
private final String AdjustTokenKey = "adjust_token";
private final String EnvironmentKey = "environment";

// Adjust event callbacks to set
private final List<String> callbacks = Arrays.asList(
COMMAND_SET_ATTRIBUTION_CALLBACK,
COMMAND_SET_EVENT_TRACKING_SUCCEEDED_CALLBACK,
COMMAND_SET_EVENT_TRACKING_FAILED_CALLBACK,
COMMAND_SET_SESSION_TRACKING_SUCCEEDED_CALLBACK,
COMMAND_SET_SESSION_TRACKING_FAILED_CALLBACK,
COMMAND_SET_DEFERRED_DEEPLINK_CALLBACK);

private Map<String, BufferedCallbackContext> callbackContextMap = new HashMap<>();

@Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);

for (String callback : callbacks) {
setBufferedCallback(callback);
}
initializeSdk();
}

/**
* Sets `COMMAND_SET_*_CALLBACK` callback as a placeholder until we call
* setCallback from JS.
* This enables us to buffer the result of the callback incase
* JS is slow in calling setCallback.
*/
private void setBufferedCallback(String action) {
BufferedCallbackContext bufferedCallbackContext = new BufferedCallbackContext(action, webView);
JSONArray empty = new JSONArray();
try {
this.execute(action, empty, bufferedCallbackContext);
} catch (JSONException e) {
e.printStackTrace();
}
}

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
handleCallback(action, callbackContext);
return super.execute(action, args, callbackContext);
}

/**
* Stores BufferedCallbacks to the Map as a placeholder callback,
* for when the JS is slower in setting the callback for each action.
* BufferedCallback stores the result (if invoked) and passes the
* result via the `sendPluginResult` call to the callback to JS.
*
* @param action
* @param callbackContext
*/
private void handleCallback(String action, CallbackContext callbackContext) {
// Only handle callbacks for specified commands
if (!callbacks.contains(action)) return;

BufferedCallbackContext bufferedCallback = callbackContextMap.remove(action);
if (bufferedCallback != null) {
bufferedCallback.replayResults(callbackContext);
} else if (callbackContext instanceof BufferedCallbackContext) {
callbackContextMap.put(action, (BufferedCallbackContext) callbackContext);
}
}

// Initializer function to call the `execute` method with the required arguments for init.
private void initializeSdk() {

// Getting data from extras
Bundle extras = this.cordova.getActivity().getIntent().getExtras();

// If no eager initialization params were set, e.g. in Debug UI, don't do initialize eagerly.
if (extras == null) return;

try {
String appToken = extras.getString(AdjustTokenKey);
boolean isDebug = extras.getBoolean(EnvironmentKey, false);

JSONObject data = new JSONObject();
data.put(KEY_APP_TOKEN, appToken);
data.put(
KEY_ENVIRONMENT,
isDebug
? AdjustConfig.ENVIRONMENT_SANDBOX
: AdjustConfig.ENVIRONMENT_PRODUCTION
);

JSONArray dataArray = new JSONArray();
dataArray.put(data);

JSONArray jsonArray = new JSONArray();
jsonArray.put(dataArray);

execute(COMMAND_CREATE, jsonArray, null);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
8 changes: 7 additions & 1 deletion src/ios/AdjustCordovaDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <objc/runtime.h>
#import <Cordova/CDVPluginResult.h>
#import "AdjustCordovaDelegate.h"
#import "EagerAdjustBuffer.h"

static dispatch_once_t onceToken;
static AdjustCordovaDelegate *defaultInstance = nil;
Expand Down Expand Up @@ -108,6 +109,7 @@ - (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_attributionCallbackId];
[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_attributionCallbackId];
}

- (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessResponseData {
Expand All @@ -128,6 +130,7 @@ - (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessRespo
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_eventSucceededCallbackId];
[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_attributionCallbackId];
}

- (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponseData {
Expand All @@ -149,6 +152,7 @@ - (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponse
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_eventFailedCallbackId];
[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_eventFailedCallbackId];
}

- (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSuccessResponseData {
Expand All @@ -167,6 +171,7 @@ - (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSucces
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_sessionSucceededCallbackId];
[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_sessionSucceededCallbackId];
}

- (void)adjustSessionTrackingFailedWananbe:(ADJSessionFailure *)sessionFailureResponseData {
Expand All @@ -186,14 +191,15 @@ - (void)adjustSessionTrackingFailedWananbe:(ADJSessionFailure *)sessionFailureRe
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_sessionFailedCallbackId];
[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_sessionFailedCallbackId];
}

- (BOOL)adjustDeeplinkResponseWannabe:(NSURL *)deeplink {
NSString *path = [deeplink absoluteString];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:path];
pluginResult.keepCallback = [NSNumber numberWithBool:YES];
[_adjustCordovaCommandDelegate sendPluginResult:pluginResult callbackId:_deferredDeeplinkCallbackId];

[[EagerAdjustBuffer getInstance] addPluginResult:pluginResult andCallbackId:_deferredDeeplinkCallbackId];
return _shouldLaunchDeferredDeeplink;
}

Expand Down
9 changes: 9 additions & 0 deletions src/ios/EagerAdjustBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import "AdjustCordovaDelegate.h"

@interface EagerAdjustBuffer : NSObject

+ (id)getInstance;
- (void)addPluginResult:(CDVPluginResult*)result andCallbackId:(NSString *)callbackId;
- (void)replayResultsWithCommand:(id <CDVCommandDelegate>) commandDelegate;

@end
41 changes: 41 additions & 0 deletions src/ios/EagerAdjustBuffer.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#import "EagerAdjustBuffer.h"


@implementation EagerAdjustBuffer

static EagerAdjustBuffer *defaultInstance = nil;
static dispatch_once_t onceToken;
NSMutableDictionary<NSString*, NSMutableArray*> *results;

+ (id)getInstance {
dispatch_once(&onceToken, ^{
defaultInstance = [[EagerAdjustBuffer alloc] init];
results = [NSMutableDictionary new];
});

return defaultInstance;
}


- (void)addPluginResult:(CDVPluginResult*)result andCallbackId:(NSString *)callbackId {
NSMutableArray *callBackResults = [results objectForKey:callbackId];
if(callBackResults != nil) {
[callBackResults addObject:result];
} else {
callBackResults = [NSMutableArray arrayWithObject:result];
}
[results setObject:callBackResults forKey:callbackId];
}

- (void)replayResultsWithCommand:(id <CDVCommandDelegate>) commandDelegate {
for(NSString *callbackId in results.allKeys) {
NSMutableArray *callBackResults = [results objectForKey:callbackId];
for (CDVPluginResult *result in callBackResults) {
[commandDelegate sendPluginResult:result callbackId:callbackId];
}
[results removeObjectForKey:callbackId];
}

}

@end
6 changes: 6 additions & 0 deletions src/ios/EagerAdjustCordova.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#import "AdjustCordova.h"


@interface EagerAdjustCordova : AdjustCordova

@end
77 changes: 77 additions & 0 deletions src/ios/EagerAdjustCordova.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#import "EagerAdjustCordova.h"
#import "EagerAdjustBuffer.h"

#define KEY_APP_TOKEN @"appToken"
#define KEY_ENVIRONMENT @"environment"

@implementation EagerAdjustCordova

- (void)pluginInitialize {
[super pluginInitialize];
[self initializeEagerly];
}

- (void)initCallbacks {
[self setAttributionCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setAttributionCallback" className:@"EagerAdjustCordova" methodName:@"setAttributionCallback"]];
[self setEventTrackingSucceededCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setEventTrackingSucceededCallback" className:@"EagerAdjustCordova" methodName:@"setEventTrackingSucceededCallback"]];
[self setEventTrackingFailedCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setEventTrackingFailedCallback" className:@"EagerAdjustCordova" methodName:@"setEventTrackingFailedCallback"]];
[self setSessionTrackingSucceededCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setSessionTrackingSucceededCallback" className:@"EagerAdjustCordova" methodName:@"setSessionTrackingSucceededCallback"]];
[self setSessionTrackingFailedCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setSessionTrackingFailedCallback" className:@"EagerAdjustCordova" methodName:@"setSessionTrackingFailedCallback"]];
[self setDeferredDeeplinkCallback:[[CDVInvokedUrlCommand alloc] initWithArguments:@[] callbackId:@"setDeferredDeeplinkCallback" className:@"EagerAdjustCordova" methodName:@"setDeferredDeeplinkCallback"]];
}

- (void)initializeEagerly {
[self initCallbacks];
if([self.appDelegate respondsToSelector:@selector(getAdjustToken)] && [self.appDelegate respondsToSelector:@selector(getEnvironment)]) {

NSString *adjustKey = [self.appDelegate performSelector:@selector(getAdjustToken)];
NSString *environment = [self.appDelegate performSelector:@selector(getEnvironment)];

NSArray *commandArray = @[[self createCommandWithKey:adjustKey andEnvironment:environment]];
CDVInvokedUrlCommand *command = [[CDVInvokedUrlCommand alloc] initWithArguments:commandArray callbackId:nil className:nil methodName:nil];
[super create:command];
}
}

- (NSString *)createCommandWithKey:(NSString *)adjustKey andEnvironment:(NSString *)environment {

NSDictionary *dic = @{KEY_APP_TOKEN: adjustKey,
KEY_ENVIRONMENT : environment
};

NSData *data = [NSJSONSerialization dataWithJSONObject:@[dic] options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return jsonString;
}

- (void)setAttributionCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setAttributionCallback:command];
}

- (void)setEventTrackingSucceededCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setEventTrackingSucceededCallback:command];
}

- (void)setEventTrackingFailedCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setEventTrackingFailedCallback:command];
}

- (void)setSessionTrackingSucceededCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setSessionTrackingSucceededCallback:command];
}

- (void)setSessionTrackingFailedCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setSessionTrackingFailedCallback:command];
}

- (void)setDeferredDeeplinkCallback:(CDVInvokedUrlCommand *)command {
[[EagerAdjustBuffer getInstance] replayResultsWithCommand:self.commandDelegate];
[super setDeferredDeeplinkCallback:command];
}

@end
Loading