Skip to content

Commit 356a36c

Browse files
Merge pull request #698 from BranchMetrics/gdeluna-branch/INTENG-13785
Add content items support in sendBranchEvent Remove sendCommerceEvent Fix bug where custom data would clobber other fields when creating event in Android plugin Update iOS SDK to 1.40.2 Update Android SDK to 5.0.15
2 parents eb21b2e + b2725c5 commit 356a36c

File tree

4 files changed

+70
-197
lines changed

4 files changed

+70
-197
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "branch-cordova-sdk",
33
"description": "Branch Metrics Cordova SDK",
44
"main": "src/index.js",
5-
"version": "4.2.4",
5+
"version": "5.0.0",
66
"homepage": "https://github.com/BranchMetrics/cordova-ionic-phonegap-branch-deep-linking",
77
"repository": {
88
"type": "git",

plugin.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ SOFTWARE.
2424
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
2525
xmlns:android="http://schemas.android.com/apk/res/android"
2626
id="branch-cordova-sdk"
27-
version="4.2.4">
27+
version="5.0.0">
2828

2929
<!-- Description -->
3030
<name>branch-cordova-sdk</name>
@@ -63,7 +63,7 @@ SOFTWARE.
6363
<!-- Manifest configuration is done via a js script. We should move it to this config in the future. -->
6464

6565
<source-file src="src/android/io/branch/BranchSDK.java" target-dir="src/io/branch" />
66-
<framework src="io.branch.sdk.android:library:5.0.8"/>
66+
<framework src="io.branch.sdk.android:library:5.0.15"/>
6767
</platform>
6868

6969
<!-- iOS -->
@@ -87,7 +87,7 @@ SOFTWARE.
8787
<source url="https://cdn.cocoapods.org/"/>
8888
</config>
8989
<pods>
90-
<pod name="Branch" spec="~> 1.39.2" />
90+
<pod name="Branch" spec="~> 1.40.2" />
9191
</pods>
9292
</podspec>
9393
</platform>

src/android/io/branch/BranchSDK.java

Lines changed: 57 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package io.branch;
22

3+
import android.annotation.TargetApi;
34
import android.app.Activity;
45
import android.content.Intent;
5-
import android.util.Log;
6-
import android.annotation.TargetApi;
76
import android.net.Uri;
87
import android.os.Build;
8+
import android.util.Log;
99

1010
import org.apache.cordova.CallbackContext;
1111
import org.apache.cordova.CordovaPlugin;
1212
import org.apache.cordova.PluginResult;
13-
1413
import org.json.JSONArray;
1514
import org.json.JSONException;
1615
import org.json.JSONObject;
@@ -20,22 +19,18 @@
2019

2120
import io.branch.indexing.BranchUniversalObject;
2221
import io.branch.referral.Branch;
23-
import io.branch.referral.PrefHelper;
2422
import io.branch.referral.BranchError;
2523
import io.branch.referral.BranchViewHandler;
24+
import io.branch.referral.ServerRequestGetCPID.BranchCrossPlatformIdListener;
25+
import io.branch.referral.ServerRequestGetLATD.BranchLastAttributedTouchDataListener;
2626
import io.branch.referral.SharingHelper;
2727
import io.branch.referral.util.BRANCH_STANDARD_EVENT;
28+
import io.branch.referral.util.BranchCPID;
2829
import io.branch.referral.util.BranchEvent;
29-
import io.branch.referral.util.CommerceEvent;
30+
import io.branch.referral.util.ContentMetadata;
3031
import io.branch.referral.util.CurrencyType;
31-
import io.branch.referral.util.Product;
32-
import io.branch.referral.util.ProductCategory;
3332
import io.branch.referral.util.ShareSheetStyle;
3433

35-
import io.branch.referral.ServerRequestGetLATD.BranchLastAttributedTouchDataListener;
36-
import io.branch.referral.ServerRequestGetCPID.BranchCrossPlatformIdListener;
37-
import io.branch.referral.util.BranchCPID;
38-
3934
public class BranchSDK extends CordovaPlugin {
4035

4136
static class BranchLinkProperties extends io.branch.referral.util.LinkProperties {
@@ -147,13 +142,6 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
147142
}
148143
cordova.getActivity().runOnUiThread(r);
149144
return true;
150-
} else if (action.equals("sendCommerceEvent")) {
151-
if (args.length() < 1 && args.length() > 2) {
152-
callbackContext.error(String.format("Parameter mismatched. 1-2 is required but %d is given", args.length()));
153-
return false;
154-
}
155-
cordova.getActivity().runOnUiThread(r);
156-
return true;
157145
} else if (action.equals("sendBranchEvent")) {
158146
if (args.length() < 1 && args.length() > 2) {
159147
callbackContext.error(String.format("Parameter mismatched. 1-2 is required but %d is given", args.length()));
@@ -627,91 +615,6 @@ private void userCompletedAction(String action, JSONObject metaData, CallbackCon
627615

628616
}
629617

630-
/**
631-
* <p>A void call to indicate that the user has performed a specific commerce event and for that to be
632-
* reported to the Branch API.</p>
633-
*
634-
* @param action A {@link String} value to be passed as an commerce event that the user has
635-
* carried out.
636-
* @param metaData A {@link JSONObject} containing app-defined meta-data to be attached to a
637-
* user action that has just been completed.
638-
* @param callbackContext A callback to execute at the end of this method
639-
*/
640-
private void sendCommerceEvent(JSONObject action, JSONObject metaData, CallbackContext callbackContext) throws JSONException {
641-
642-
CommerceEvent commerce = new CommerceEvent();
643-
Iterator<String> keys = action.keys();
644-
while (keys.hasNext()) {
645-
String key = keys.next();
646-
String val;
647-
try {
648-
val = action.getString(key);
649-
} catch (JSONException e) {
650-
e.printStackTrace();
651-
callbackContext.error("Invalid key-value for " + key);
652-
return;
653-
}
654-
if (key.equals("revenue")) {
655-
commerce.setRevenue(Double.parseDouble(val));
656-
} else if (key.equals("currency")) {
657-
commerce.setCurrencyType(CurrencyType.values()[Integer.parseInt(val)]);
658-
} else if (key.equals("transactionID")) {
659-
commerce.setTransactionID(val);
660-
} else if (key.equals("coupon")) {
661-
commerce.setCoupon(val);
662-
} else if (key.equals("shipping")) {
663-
commerce.setShipping(Double.parseDouble(val));
664-
} else if (key.equals("tax")) {
665-
commerce.setTax(Double.parseDouble(val));
666-
} else if (key.equals("affiliation")) {
667-
commerce.setAffiliation(val);
668-
} else if (key.equals("products")) {
669-
JSONArray products = new JSONArray();
670-
try {
671-
products = action.getJSONArray(key);
672-
} catch (JSONException e) {
673-
e.printStackTrace();
674-
callbackContext.error("Invalid key-value for " + key);
675-
return;
676-
}
677-
for (int i = 0; i < products.length(); ++i) {
678-
Product product = new Product();
679-
JSONObject item = products.getJSONObject(i);
680-
keys = item.keys();
681-
while (keys.hasNext()) {
682-
key = keys.next();
683-
try {
684-
val = item.getString(key);
685-
} catch (JSONException e) {
686-
e.printStackTrace();
687-
callbackContext.error("Invalid key-value for product for " + key);
688-
return;
689-
}
690-
if (key.equals("sku")) {
691-
product.setSku(val);
692-
} else if (key.equals("name")) {
693-
product.setName(val);
694-
} else if (key.equals("price")) {
695-
product.setPrice(Double.parseDouble(val));
696-
} else if (key.equals("quantity")) {
697-
product.setQuantity(Integer.parseInt(val));
698-
} else if (key.equals("brand")) {
699-
product.setBrand(val);
700-
} else if (key.equals("category")) {
701-
product.setCategory(ProductCategory.values()[Integer.parseInt(val)]);
702-
} else if (key.equals("variant")) {
703-
product.setVariant(val);
704-
}
705-
}
706-
commerce.addProduct(product);
707-
}
708-
}
709-
}
710-
711-
this.instance.sendCommerceEvent(commerce, metaData, new BranchViewEventsListener(callbackContext));
712-
713-
}
714-
715618
public void sendBranchEvent(String eventName, CallbackContext callbackContext) throws JSONException {
716619

717620
BranchEvent event;
@@ -768,19 +671,67 @@ public void sendBranchEvent(String eventName, JSONObject metaData, CallbackConte
768671
event.setCustomerEventAlias(metaData.getString("customerEventAlias"));
769672
} else if (key.equals("customData")) {
770673
JSONObject customData = metaData.getJSONObject("customData");
771-
keys = customData.keys();
674+
Iterator<String> customDataKeys = customData.keys();
772675

773-
while (keys.hasNext()) {
774-
String keyValue = (String) keys.next();
676+
while (customDataKeys.hasNext()) {
677+
String keyValue = (String) customDataKeys.next();
775678
event.addCustomDataProperty(keyValue, customData.getString(keyValue));
776679
}
680+
} else if (key.equals("contentMetadata")) {
681+
JSONArray contentMetadata = metaData.getJSONArray("contentMetadata");
682+
for (int i = 0; i < contentMetadata.length(); i++) {
683+
JSONObject item = contentMetadata.getJSONObject(i);
684+
BranchUniversalObject universalObject = this.getContentItem(item);
685+
event.addContentItems(universalObject);
686+
}
777687
}
778688

779689
}
780690
event.logEvent(this.activity);
781691
//callbackContext.success();
782692
}
783693

694+
private BranchUniversalObject getContentItem(JSONObject item) throws JSONException {
695+
BranchUniversalObject universalObject = new BranchUniversalObject();
696+
ContentMetadata contentMetadata = new ContentMetadata();
697+
Iterator<String> keys = item.keys();
698+
while (keys.hasNext()) {
699+
String key = keys.next();
700+
701+
switch (key) {
702+
case "quantity":
703+
contentMetadata.setQuantity(Double.parseDouble(item.getString(key)));
704+
break;
705+
case "price":
706+
contentMetadata.price = Double.parseDouble(item.getString(key));
707+
break;
708+
case "currency":
709+
String currencyString = item.getString(key);
710+
CurrencyType currency = CurrencyType.getValue(currencyString);
711+
if (currency != null) {
712+
contentMetadata.currencyType = currency;
713+
}
714+
break;
715+
case "productName":
716+
contentMetadata.setProductName(item.getString(key));
717+
break;
718+
case "productBrand":
719+
contentMetadata.setProductBrand(item.getString(key));
720+
break;
721+
case "sku":
722+
contentMetadata.setSku(item.getString(key));
723+
break;
724+
default:
725+
contentMetadata.addCustomMetadata(key, item.getString(key));
726+
break;
727+
}
728+
}
729+
730+
universalObject.setContentMetadata(contentMetadata);
731+
732+
return universalObject;
733+
}
734+
784735
/**
785736
* @access protected
786737
* @class BranchUniversalObjectWrapper
@@ -1222,8 +1173,6 @@ public void run() {
12221173
} else if (this.args.length() == 1) {
12231174
userCompletedAction(this.args.getString(0), this.callbackContext);
12241175
}
1225-
} else if (this.action.equals("sendCommerceEvent")) {
1226-
sendCommerceEvent(this.args.getJSONObject(0), this.args.getJSONObject(1), this.callbackContext);
12271176
} else if (this.action.equals("sendBranchEvent")) {
12281177
if (this.args.length() == 2) {
12291178
sendBranchEvent(this.args.getString(0), this.args.getJSONObject(1), this.callbackContext);

src/ios/BranchSDK.m

Lines changed: 9 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -301,95 +301,19 @@ -(void)sendBranchEvent:(CDVInvokedUrlCommand*)command
301301
else if ([key isEqualToString:@"customData"] && [[metadata objectForKey:key] isKindOfClass:[NSMutableDictionary class]]) {
302302
event.customData = [metadata objectForKey:key];
303303
}
304+
else if ([key isEqualToString:@"contentMetadata"]){
305+
NSMutableArray *mArray = [[NSMutableArray alloc]init];
306+
307+
for (NSDictionary *dataDictionary in [metadata objectForKey:key]){
308+
BranchUniversalObject *contentItem = [BranchUniversalObject objectWithDictionary:(dataDictionary)];
309+
[mArray addObject:contentItem];
310+
}
311+
event.contentItems = [mArray copy];
312+
}
304313
}
305314
[event logEvent];
306315
}
307316

308-
- (void)sendCommerceEvent:(CDVInvokedUrlCommand*)command
309-
{
310-
NSDictionary *data = [command.arguments objectAtIndex:0];
311-
NSDictionary *metadata;
312-
BNCCommerceEvent *commerce = [[BNCCommerceEvent alloc] init];
313-
NSArray *categories = [NSArray arrayWithObjects:BNCProductCategoryAnimalSupplies, BNCProductCategoryApparel, BNCProductCategoryArtsEntertainment, BNCProductCategoryBabyToddler, BNCProductCategoryBusinessIndustrial, BNCProductCategoryCamerasOptics, BNCProductCategoryElectronics, BNCProductCategoryFoodBeverageTobacco, BNCProductCategoryFurniture, BNCProductCategoryHardware, BNCProductCategoryHealthBeauty, BNCProductCategoryHomeGarden, BNCProductCategoryLuggageBags, BNCProductCategoryMature, BNCProductCategoryMedia, BNCProductCategoryOfficeSupplies, BNCProductCategoryReligious, BNCProductCategorySoftware, BNCProductCategorySportingGoods, BNCProductCategoryToysGames, BNCProductCategoryVehiclesParts, nil];
314-
NSArray *currencies = [NSArray arrayWithObjects:@"AED", @"AFN", @"ALL", @"AMD", @"ANG", @"AOA", @"ARS", @"AUD", @"AWG", @"AZN", @"BAM", @"BBD", @"BDT", @"BGN", @"BHD", @"BIF", @"BMD", @"BND", @"BOB", @"BOV", @"BRL", @"BSD", @"BTN", @"BWP", @"BYN", @"BYR", @"BZD", @"CAD", @"CDF", @"CHE", @"CHF", @"CHW", @"CLF", @"CLP", @"CNY", @"COP", @"COU", @"CRC", @"CUC", @"CUP", @"CVE", @"CZK", @"DJF", @"DKK", @"DOP", @"DZD", @"EGP", @"ERN", @"ETB", @"EUR", @"FJD", @"FKP", @"GBP", @"GEL", @"GHS", @"GIP", @"GMD", @"GNF", @"GTQ", @"GYD", @"HKD", @"HNL", @"HRK", @"HTG", @"HUF", @"IDR", @"ILS", @"INR", @"IQD", @"IRR", @"ISK", @"JMD", @"JOD", @"JPY", @"KES", @"KGS", @"KHR", @"KMF", @"KPW", @"KRW", @"KWD", @"KYD", @"KZT", @"LAK", @"LBP", @"LKR", @"LRD", @"LSL", @"LYD", @"MAD", @"MDL", @"MGA", @"MKD", @"MMK", @"MNT", @"MOP", @"MRO", @"MUR", @"MVR", @"MWK", @"MXN", @"MXV", @"MYR", @"MZN", @"NAD", @"NGN", @"NIO", @"NOK", @"NPR", @"NZD", @"OMR", @"PAB", @"PEN", @"PGK", @"PHP", @"PKR", @"PLN", @"PYG", @"QAR", @"RON", @"RSD", @"RUB", @"RWF", @"SAR", @"SBD", @"SCR", @"SDG", @"SEK", @"SGD", @"SHP", @"SLL", @"SOS", @"SRD", @"SSP", @"STD", @"SYP", @"SZL", @"THB", @"TJS", @"TMT", @"TND", @"TOP", @"TRY", @"TTD", @"TWD", @"TZS", @"UAH", @"UGX", @"USD", @"USN", @"UYI", @"UYU", @"UZS", @"VEF", @"VND", @"VUV", @"WST", @"XAF", @"XAG", @"XAU", @"XBA", @"XBB", @"XBC", @"XBD", @"XCD", @"XDR", @"XFU", @"XOF", @"XPD", @"XPF", @"XPT", @"XSU", @"XTS", @"XUA", @"XXX", @"YER", @"ZAR", @"ZMW", nil];
315-
316-
if ([command.arguments count] == 2) {
317-
metadata = [command.arguments objectAtIndex:1];
318-
}
319-
320-
for (id key in data) {
321-
if ([key isEqualToString:@"revenue"]) {
322-
NSString *value = ([[data objectForKey:key] isKindOfClass:[NSString class]]) ? [data objectForKey:key] : [[data objectForKey:key] stringValue];
323-
commerce.revenue = [NSDecimalNumber decimalNumberWithString:value];
324-
}
325-
else if ([key isEqualToString:@"currency"]) {
326-
NSString *value = ([[data objectForKey:key] isKindOfClass:[NSString class]]) ? [data objectForKey:key] : [[data objectForKey:key] stringValue];
327-
commerce.currency = [currencies objectAtIndex:[value intValue]];
328-
}
329-
else if ([key isEqualToString:@"transactionID"]) {
330-
commerce.transactionID = [data objectForKey:key];
331-
}
332-
else if ([key isEqualToString:@"shipping"]) {
333-
NSString *value = ([[data objectForKey:key] isKindOfClass:[NSString class]]) ? [data objectForKey:key] : [[data objectForKey:key] stringValue];
334-
commerce.shipping = [NSDecimalNumber decimalNumberWithString:value];
335-
}
336-
else if ([key isEqualToString:@"tax"]) {
337-
NSString *value = ([[data objectForKey:key] isKindOfClass:[NSString class]]) ? [data objectForKey:key] : [[data objectForKey:key] stringValue];
338-
commerce.tax = [NSDecimalNumber decimalNumberWithString:value];
339-
}
340-
else if ([key isEqualToString:@"coupon"]) {
341-
commerce.coupon = [data objectForKey:key];
342-
}
343-
else if ([key isEqualToString:@"affiliation"]) {
344-
commerce.affiliation = [data objectForKey:key];
345-
}
346-
else if ([key isEqualToString:@"products"] && [[data objectForKey:key] isKindOfClass:[NSArray class]]) {
347-
NSMutableArray *products = [[NSMutableArray alloc] init];
348-
NSArray *dataProducts = [data objectForKey:key];
349-
for (NSDictionary *dataDictionary in dataProducts) {
350-
BNCProduct *product = [[BNCProduct alloc] init];
351-
for (id key in dataDictionary) {
352-
if ([key isEqualToString:@"sku"]) {
353-
product.sku = [dataDictionary objectForKey:key];
354-
}
355-
else if ([key isEqualToString:@"name"]) {
356-
product.name = [dataDictionary objectForKey:key];
357-
}
358-
else if ([key isEqualToString:@"price"]) {
359-
NSString *value = ([[dataDictionary objectForKey:key] isKindOfClass:[NSString class]]) ? [dataDictionary objectForKey:key] : [[dataDictionary objectForKey:key] stringValue];
360-
product.price = [NSDecimalNumber decimalNumberWithString:value];
361-
}
362-
else if ([key isEqualToString:@"quantity"]) {
363-
NSString *value = ([[dataDictionary objectForKey:key] isKindOfClass:[NSString class]]) ? [dataDictionary objectForKey:key] : [[dataDictionary objectForKey:key] stringValue];
364-
product.quantity = [NSNumber numberWithInt:[value intValue]];
365-
}
366-
else if ([key isEqualToString:@"brand"]) {
367-
product.brand = [dataDictionary objectForKey:key];
368-
}
369-
else if ([key isEqualToString:@"category"]) {
370-
NSString *value = ([[dataDictionary objectForKey:key] isKindOfClass:[NSString class]]) ? [dataDictionary objectForKey:key] : [[dataDictionary objectForKey:key] stringValue];
371-
product.category = [categories objectAtIndex:[value intValue]];
372-
}
373-
else if ([key isEqualToString:@"variant"]) {
374-
product.variant = [dataDictionary objectForKey:key];
375-
}
376-
}
377-
[products addObject:product];
378-
}
379-
commerce.products = products;
380-
}
381-
}
382-
383-
[[Branch getInstance] sendCommerceEvent:commerce metadata:metadata withCompletion:^(NSDictionary *response, NSError *error) {
384-
CDVPluginResult *pluginResult = nil;
385-
if (!error) {
386-
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @"Success"];
387-
} else {
388-
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[error localizedDescription]];
389-
}
390-
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
391-
}];
392-
}
393317

394318
- (void)logout:(CDVInvokedUrlCommand*)command
395319
{

0 commit comments

Comments
 (0)