Skip to content

Commit

Permalink
Support for custom params in BUO.userCompletedAction
Browse files Browse the repository at this point in the history
  • Loading branch information
jdee committed Mar 14, 2017
1 parent ca1f45a commit 03fa03a
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 21 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ let branchUniversalObject = branch.createBranchUniversalObject('canonicalIdentif
title: 'Cool Content!',
contentDescription: 'Cool Content Description'})
let actionResult = await branchUniversalObject.userCompletedAction(RegisterViewEvent)
let customActionResult = await branchUniversalObject.userCompletedAction('Custom Action', { key: 'value' })

let shareOptions = { messageHeader: 'Check this out', messageBody: 'No really, check this out!' }
let linkProperties = { feature: 'share', channel: 'RNApp' }
Expand Down
28 changes: 26 additions & 2 deletions android/src/main/java/io/branch/rnbranch/RNBranchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ public void userCompletedAction(String event, ReadableMap appState) throws JSONE
}

@ReactMethod
public void userCompletedActionOnUniversalObject(String ident, String event, Promise promise) {
public void userCompletedActionOnUniversalObject(String ident, String event, ReadableMap state, Promise promise) {
BranchUniversalObject universalObject = findUniversalObjectOrReject(ident, promise);
if (universalObject == null) return;

universalObject.userCompletedAction(event);
universalObject.userCompletedAction(event, convertMapToParams(state));
promise.resolve(null);
}

Expand Down Expand Up @@ -693,4 +693,28 @@ private static WritableArray convertJsonToArray(JSONArray jsonArray) throws JSON
}
return array;
}

// Convert an arbitrary ReadableMap to a string-string hash of custom params for userCompletedAction.
private static HashMap<String, String> convertMapToParams(ReadableMap map) {
if (map == null) return null;

HashMap<String, String> hash = new HashMap<>();

ReadableMapKeySetIterator iterator = map.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
switch (map.getType(key)) {
case String:
hash.put(key, map.getString(key));
case Boolean:
hash.put(key, "" + map.getBoolean(key));
case Number:
hash.put(key, "" + map.getDouble(key));
default:
Log.w(REACT_CLASS, "Unsupported data type in params, ignoring");
}
}

return hash;
}
}
2 changes: 2 additions & 0 deletions ios/BranchUniversalObject+RNBranch.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@

- (instancetype)initWithMap:(NSDictionary *)map;

- (void)userCompletedAction:(NSString *)action withState:(NSDictionary *)state;

@end
58 changes: 58 additions & 0 deletions ios/BranchUniversalObject+RNBranch.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#import <React/RCTLog.h>

#import <Branch/BranchConstants.h>

#import "BranchUniversalObject+RNBranch.h"
#import "NSObject+RNBranch.h"
#import "RNBranchProperty.h"
Expand Down Expand Up @@ -93,4 +95,60 @@ - (void)setExpirationDateWithString:(NSString *)expirationDate
self.expirationDate = [NSDate dateWithTimeIntervalSince1970:timegm(&expiration)];
}

#pragma mark - Code to support userCompletedAction:withState:

/*
* Until the native SDK supports this, the following is largely lifted from BUO.m.
*/

- (void)userCompletedAction:(NSString *)action withState:(NSDictionary *)state
{
NSMutableDictionary *actionPayload = [[NSMutableDictionary alloc] init];
NSDictionary *linkParams = [self getParamsForServerRequest];
if (self.canonicalIdentifier && linkParams) {
actionPayload[BNCCanonicalIdList] = @[self.canonicalIdentifier];
actionPayload[self.canonicalIdentifier] = linkParams;

// Add in custom params
[actionPayload addEntriesFromDictionary:state];

[[Branch getInstance] userCompletedAction:action withState:actionPayload];
if (self.automaticallyListOnSpotlight && [action isEqualToString:BNCRegisterViewEvent])
[self listOnSpotlight];
}
}

- (NSDictionary *)getParamsForServerRequest {
NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];
[self safeSetValue:self.canonicalIdentifier forKey:BRANCH_LINK_DATA_KEY_CANONICAL_IDENTIFIER onDict:temp];
[self safeSetValue:self.canonicalUrl forKey:BRANCH_LINK_DATA_KEY_CANONICAL_URL onDict:temp];
[self safeSetValue:self.title forKey:BRANCH_LINK_DATA_KEY_OG_TITLE onDict:temp];
[self safeSetValue:self.contentDescription forKey:BRANCH_LINK_DATA_KEY_OG_DESCRIPTION onDict:temp];
[self safeSetValue:self.imageUrl forKey:BRANCH_LINK_DATA_KEY_OG_IMAGE_URL onDict:temp];
if (self.contentIndexMode == ContentIndexModePrivate) {
[self safeSetValue:@(0) forKey:BRANCH_LINK_DATA_KEY_PUBLICLY_INDEXABLE onDict:temp];
}
else {
[self safeSetValue:@(1) forKey:BRANCH_LINK_DATA_KEY_PUBLICLY_INDEXABLE onDict:temp];
}
[self safeSetValue:self.keywords forKey:BRANCH_LINK_DATA_KEY_KEYWORDS onDict:temp];
[self safeSetValue:@(1000 * [self.expirationDate timeIntervalSince1970]) forKey:BRANCH_LINK_DATA_KEY_CONTENT_EXPIRATION_DATE onDict:temp];
[self safeSetValue:self.type forKey:BRANCH_LINK_DATA_KEY_CONTENT_TYPE onDict:temp];
[self safeSetValue:self.currency forKey:BNCPurchaseCurrency onDict:temp];
if (self.price) {
// have to add if statement because safeSetValue only accepts objects so even if self.price is not set
// a valid NSNumber object will be created and the request will have amount:0 in all cases.
[self safeSetValue:[NSNumber numberWithFloat:self.price] forKey:BNCPurchaseAmount onDict:temp];
}

[temp addEntriesFromDictionary:[self.metadata copy]];
return [temp copy];
}

- (void)safeSetValue:(NSObject *)value forKey:(NSString *)key onDict:(NSMutableDictionary *)dict {
if (value) {
dict[key] = value;
}
}

@end
15 changes: 15 additions & 0 deletions ios/RNBranch.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,21 @@ - (BranchUniversalObject *)findUniversalObjectWithIdent:(NSString *)ident reject
resolve(NSNull.null);
}

#pragma mark userCompletedActionOnUniversalObject
RCT_EXPORT_METHOD(
userCompletedActionOnUniversalObject:(NSString *)identifier
event:(NSString *)event
state:(NSDictionary *)state
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject
) {
BranchUniversalObject *branchUniversalObject = [self findUniversalObjectWithIdent:identifier rejecter:reject];
if (!branchUniversalObject) return;

[branchUniversalObject userCompletedAction:event withState:state];
resolve(NSNull.null);
}

#pragma mark showShareSheet
RCT_EXPORT_METHOD(
showShareSheet:(NSString *)identifier
Expand Down
4 changes: 2 additions & 2 deletions src/branchUniversalObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export default async function createBranchUniversalObject(identifier, options =
if (Platform.OS !== 'ios') return Promise.resolve()
return this._tryFunction(RNBranch.listOnSpotlight)
},
userCompletedAction(event) {
return this._tryFunction(RNBranch.userCompletedActionOnUniversalObject, event)
userCompletedAction(event, state = {}) {
return this._tryFunction(RNBranch.userCompletedActionOnUniversalObject, event, state)
},
release() {
RNBranch.releaseUniversalObject(this.ident)
Expand Down
17 changes: 0 additions & 17 deletions testbed/testbed_cocoapods/android/app/app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,5 @@
<orderEntry type="library" exported="" name="imagepipeline-okhttp3-0.11.0" level="project" />
<orderEntry type="library" exported="" name="react-native-0.42.0" level="project" />
<orderEntry type="module" module-name="react-native-branch" exported="" />
<orderEntry type="library" exported="" name="okhttp-ws-2.5.0" level="project" />
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
<orderEntry type="library" exported="" name="stetho-okhttp-1.2.0" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.8.1" level="project" />
<orderEntry type="library" exported="" name="fresco-0.8.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.8.1" level="project" />
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="drawee-0.8.1" level="project" />
<orderEntry type="library" exported="" name="react-native-0.20.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
</component>
</module>

0 comments on commit 03fa03a

Please sign in to comment.