Skip to content

Commit 3bd9ef2

Browse files
Merge pull request #727 from BranchMetrics/SDK-1406
[SDK-1406] Exposed QR code methods
2 parents abd5891 + 1c2bb6b commit 3bd9ef2

File tree

6 files changed

+173
-7
lines changed

6 files changed

+173
-7
lines changed

android/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def safeExtGet(prop, fallback) {
4444
}
4545
}
4646

47-
dependencies {
48-
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
49-
implementation 'com.facebook.react:react-native:+' // From node_modules
50-
api 'io.branch.sdk.android:library:5.1.5'
51-
}
47+
dependencies {
48+
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
49+
implementation 'com.facebook.react:react-native:+' // From node_modules
50+
api 'io.branch.sdk.android:library:5.2.0'
51+
}

android/src/main/java/io/branch/rnbranch/RNBranchModule.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import android.content.Intent;
66
import android.content.IntentFilter;
77
import android.content.BroadcastReceiver;
8+
import android.graphics.Bitmap;
89
import android.net.Uri;
10+
import android.util.Base64;
911

1012
import androidx.annotation.Nullable;
1113
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -21,12 +23,14 @@
2123
import io.branch.referral.*;
2224
import io.branch.referral.Branch.BranchLinkCreateListener;
2325
import io.branch.referral.BuildConfig;
26+
import io.branch.referral.QRCode.BranchQRCode;
2427
import io.branch.referral.util.*;
2528
import io.branch.referral.Branch;
2629
import io.branch.indexing.*;
2730

2831
import org.json.*;
2932

33+
import java.io.IOException;
3034
import java.text.ParseException;
3135
import java.text.SimpleDateFormat;
3236
import java.util.*;
@@ -681,6 +685,56 @@ public void openURL(String url, ReadableMap options) {
681685
mActivity.startActivity(intent);
682686
}
683687

688+
@ReactMethod
689+
public void getBranchQRCode(ReadableMap branchQRCodeSettingsMap, ReadableMap branchUniversalObjectMap, ReadableMap linkPropertiesMap, ReadableMap controlParamsMap, final Promise promise) {
690+
691+
BranchUniversalObject branchUniversalObject = createBranchUniversalObject(branchUniversalObjectMap);
692+
LinkProperties linkProperties = createLinkProperties(linkPropertiesMap, controlParamsMap);
693+
BranchQRCode qrCode = createBranchQRCode(branchQRCodeSettingsMap);
694+
695+
try {
696+
qrCode.getQRCodeAsData(getReactApplicationContext().getCurrentActivity(), branchUniversalObject, linkProperties, new BranchQRCode.BranchQRCodeDataHandler() {
697+
@Override
698+
public void onSuccess(byte[] qrCodeData) {
699+
String qrCodeString = Base64.encodeToString(qrCodeData, Base64.DEFAULT);
700+
promise.resolve(qrCodeString);
701+
}
702+
703+
@Override
704+
public void onFailure(Exception e) {
705+
Log.d("Failed to get QR Code", e.getMessage());
706+
promise.reject("Failed to get QR Code", e.getMessage());
707+
}
708+
});
709+
} catch (IOException e) {
710+
e.printStackTrace();
711+
Log.d("Failed to get QR Code", e.getMessage());
712+
promise.reject("Failed to get QR Code", e.getMessage());
713+
}
714+
}
715+
716+
public BranchQRCode createBranchQRCode(ReadableMap branchQRCodeSettingsMap) {
717+
BranchQRCode branchQRCode = new BranchQRCode();
718+
719+
if (branchQRCodeSettingsMap.hasKey("codeColor")) branchQRCode.setCodeColor(branchQRCodeSettingsMap.getString("codeColor"));
720+
if (branchQRCodeSettingsMap.hasKey("backgroundColor")) branchQRCode.setBackgroundColor(branchQRCodeSettingsMap.getString("backgroundColor"));
721+
if (branchQRCodeSettingsMap.hasKey("centerLogo")) branchQRCode.setCenterLogo(branchQRCodeSettingsMap.getString("centerLogo"));
722+
if (branchQRCodeSettingsMap.hasKey("width")) branchQRCode.setWidth(branchQRCodeSettingsMap.getInt("width"));
723+
if (branchQRCodeSettingsMap.hasKey("margin")) branchQRCode.setMargin(branchQRCodeSettingsMap.getInt("margin"));
724+
725+
if (branchQRCodeSettingsMap.hasKey("imageFormat")) {
726+
String imageFormat = branchQRCodeSettingsMap.getString("imageFormat");
727+
if (imageFormat != null ) {
728+
if (imageFormat.equals("JPEG")) {
729+
branchQRCode.setImageFormat(BranchQRCode.BranchImageFormat.JPEG);
730+
} else {
731+
branchQRCode.setImageFormat(BranchQRCode.BranchImageFormat.PNG);
732+
}
733+
}
734+
}
735+
return branchQRCode;
736+
}
737+
684738
public static BranchEvent createBranchEvent(String eventName, ReadableMap params) {
685739
BranchEvent event;
686740
try {

ios/RNBranch.m

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,95 @@ - (BranchUniversalObject *)findUniversalObjectWithIdent:(NSString *)ident reject
672672
[self.class.branch handleATTAuthorizationStatus:authorizationStatus];
673673
}
674674

675+
#pragma mark getBranchQRCode
676+
RCT_EXPORT_METHOD(
677+
getBranchQRCode:(NSDictionary *)qrCodeSettingsMap
678+
withUniversalObject:(NSDictionary *)universalObjectProperties
679+
withLinkProperties:(NSDictionary *)linkPropertiesMap
680+
withControlParams:(NSDictionary *)controlParamsMap
681+
resolver:(RCTPromiseResolveBlock)resolve
682+
rejecter:(RCTPromiseRejectBlock)reject
683+
) {
684+
685+
BranchLinkProperties *linkProperties = [self createLinkProperties:linkPropertiesMap withControlParams:controlParamsMap];
686+
BranchUniversalObject *universalObject = [[BranchUniversalObject alloc] initWithMap:universalObjectProperties];
687+
688+
BranchQRCode *qrCode = [BranchQRCode new];
689+
690+
if (qrCodeSettingsMap[@"codeColor"]) {
691+
qrCode.codeColor = [self colorWithHexString:qrCodeSettingsMap[@"codeColor"]];
692+
}
693+
if (qrCodeSettingsMap[@"backgroundColor"]) {
694+
qrCode.backgroundColor = [self colorWithHexString:qrCodeSettingsMap[@"backgroundColor"]];
695+
}
696+
if (qrCodeSettingsMap[@"centerLogo"]) {
697+
qrCode.centerLogo = qrCodeSettingsMap[@"centerLogo"];
698+
}
699+
if (qrCodeSettingsMap[@"width"]) {
700+
qrCode.width = qrCodeSettingsMap[@"width"];
701+
}
702+
if (qrCodeSettingsMap[@"margin"]) {
703+
qrCode.margin = qrCodeSettingsMap[@"margin"];
704+
}
705+
if (qrCodeSettingsMap[@"imageFormat"]) {
706+
if ([qrCodeSettingsMap[@"imageFormat"] isEqual:@"JPEG"]) {
707+
qrCode.imageFormat = BranchQRCodeImageFormatJPEG;
708+
} else {
709+
qrCode.imageFormat = BranchQRCodeImageFormatPNG;
710+
}
711+
}
712+
713+
[qrCode getQRCodeAsData:universalObject linkProperties:linkProperties completion:^(NSData * _Nonnull qrCodeData, NSError * _Nonnull error) {
714+
if (!error) {
715+
NSString* imageString = [qrCodeData base64EncodedStringWithOptions:nil];
716+
resolve(imageString);
717+
} else {
718+
reject(@"RNBranch::Error", error.localizedDescription, error);
719+
}
720+
}];
721+
}
722+
723+
- (UIColor *) colorWithHexString: (NSString *) hexString {
724+
NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
725+
CGFloat alpha, red, blue, green;
726+
switch ([colorString length]) {
727+
case 3: // #RGB
728+
alpha = 1.0f;
729+
red = [self colorComponentFrom: colorString start: 0 length: 1];
730+
green = [self colorComponentFrom: colorString start: 1 length: 1];
731+
blue = [self colorComponentFrom: colorString start: 2 length: 1];
732+
break;
733+
case 4: // #ARGB
734+
alpha = [self colorComponentFrom: colorString start: 0 length: 1];
735+
red = [self colorComponentFrom: colorString start: 1 length: 1];
736+
green = [self colorComponentFrom: colorString start: 2 length: 1];
737+
blue = [self colorComponentFrom: colorString start: 3 length: 1];
738+
break;
739+
case 6: // #RRGGBB
740+
alpha = 1.0f;
741+
red = [self colorComponentFrom: colorString start: 0 length: 2];
742+
green = [self colorComponentFrom: colorString start: 2 length: 2];
743+
blue = [self colorComponentFrom: colorString start: 4 length: 2];
744+
break;
745+
case 8: // #AARRGGBB
746+
alpha = [self colorComponentFrom: colorString start: 0 length: 2];
747+
red = [self colorComponentFrom: colorString start: 2 length: 2];
748+
green = [self colorComponentFrom: colorString start: 4 length: 2];
749+
blue = [self colorComponentFrom: colorString start: 6 length: 2];
750+
break;
751+
default:
752+
RCTLogError(@"RNBranch::Error: Invalid color value. It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB");
753+
break;
754+
}
755+
return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
756+
}
757+
758+
- (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length {
759+
NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
760+
NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
761+
unsigned hexComponent;
762+
[[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
763+
return hexComponent / 255.0;
764+
}
765+
675766
@end

react-native-branch.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Pod::Spec.new do |s|
2222
s.source_files = [ "ios/*.h", "ios/*.m"]
2323
s.compiler_flags = %[-DRNBRANCH_VERSION=@\\"#{s.version}\\"]
2424
s.header_dir = 'RNBranch' # also sets generated module name
25-
s.dependency 'Branch', '1.42.0'
25+
s.dependency 'Branch', '1.43.1'
2626
s.dependency 'React-Core' # to ensure the correct build order
2727

2828
# Swift/Objective-C compatibility

src/index.d.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,15 @@ interface BranchUniversalObject {
291291
release: () => void;
292292
}
293293

294+
interface BranchQRCodeSettings {
295+
codeColor?: string;
296+
backgroundColor?: string;
297+
centerLogo?: string;
298+
width?: number;
299+
margin?: number;
300+
imageFormat?: string;
301+
}
302+
294303
interface Branch {
295304
subscribe: BranchSubscribe;
296305
initSessionTtl?: number;
@@ -312,7 +321,13 @@ interface Branch {
312321
) => Promise<BranchUniversalObject>;
313322
handleATTAuthorizationStatus: (
314323
ATTAuthorizationStatus:ATTAuthorizationStatus
315-
) => void
324+
) => void;
325+
getBranchQRCode: (
326+
settings: BranchQRCodeSettings,
327+
branchUniversalObject: BranchUniversalObjectOptions,
328+
linkProperties: BranchLinkProperties,
329+
controlParams: BranchLinkControlParams,
330+
) => Promise<string>;
316331
setPreInstallCampaign: (campaign: string) => void;
317332
setPreInstallPartner: (partner: string) => void;
318333
}

src/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,15 @@ class Branch {
114114
/*** BranchUniversalObject ***/
115115
createBranchUniversalObject = createBranchUniversalObject
116116

117+
/*** BranchQRCode ***/
118+
getBranchQRCode = (qrCodeSettings = {}, branchUniversalObject = {}, linkProperties = {}, controlParams = {}) => {
119+
return RNBranch.getBranchQRCode(qrCodeSettings, branchUniversalObject, linkProperties, controlParams);
120+
}
121+
117122
/*** PreInstall Parameters ***/
118123
setPreInstallCampaign = (campaign) => RNBranch.setPreinstallCampaign(campaign)
119124
setPreInstallPartner = (partner) => RNBranch.setPreinstallPartner(partner)
125+
120126
}
121127

122128
export { Branch, BranchEvent, BranchSubscriber }

0 commit comments

Comments
 (0)