9 |
10 | @interface BranchContentMetadata(RNBranch)
11 |
12 | - (instancetype)initWithMap:(NSDictionary *)map;
13 |
14 | - (void)setQuantityWithNumber:(NSNumber *)quantity;
15 | - (void)setPriceWithString:(NSString *)price;
16 | - (void)setRatingAverageWithNumber:(NSNumber *)ratingAverage;
17 | - (void)setRatingCountWithNumber:(NSNumber *)ratingCount;
18 | - (void)setRatingMaxWithNumber:(NSNumber *)ratingMax;
19 | - (void)setLatitudeWithNumber:(NSNumber *)latitude;
20 | - (void)setLongitudeWithNumber:(NSNumber *)longitude;
21 | - (void)setImageCaptionsWithArray:(NSArray *)imageCaptions;
22 | - (void)setCustomMetadataWithDictionary:(NSDictionary *)customMetadata;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/app/src/release/java/com/branchreactnativetestbed/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.branchreactnativetestbed;
8 |
9 | import android.content.Context;
10 | import com.facebook.react.ReactInstanceManager;
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | public class ReactNativeFlipper {
17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
18 | // Do nothing as we don't want to initialize Flipper on Release.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ios/RNBranchProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchProperty.h
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 1/26/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /*
12 | * Utility class to represent dynamically all supported JS properties on BranchUniversalObject and BranchLinkProperties.
13 | */
14 | @interface RNBranchProperty : NSObject
15 | @property (nonatomic, nonnull) SEL setterSelector;
16 | @property (nonatomic, nonnull) Class type;
17 |
18 | + (instancetype _Nonnull) propertyWithSetterSelector:(SEL _Nonnull)selector type:(Class _Nonnull)type;
19 |
20 | - (instancetype _Nonnull) initWithSetterSelector:(SEL _Nonnull)selector type:(Class _Nonnull)type NS_DESIGNATED_INITIALIZER;
21 | - (instancetype _Nonnull)init NS_UNAVAILABLE;
22 |
23 | - (BOOL)isEqual:(id _Nullable )object;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbedTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/branch_sdk_react_native_appTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ios/BranchUniversalObject+RNBranch.h:
--------------------------------------------------------------------------------
1 | //
2 | // BranchUniversalObject+RNBranch.h
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 1/26/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | @class RNBranchProperty;
12 |
13 | @interface BranchUniversalObject(RNBranch)
14 |
15 | - (instancetype)initWithMap:(NSDictionary *)map;
16 |
17 | - (void)setAutomaticallyListOnSpotlightWithNumber:(NSNumber *)automaticallyListOnSpotlight;
18 | - (void)setContentIndexingMode:(NSString *)contentIndexingMode;
19 | - (void)setExpirationDateWithString:(NSString *)expirationDate;
20 | - (void)setPriceWithNumber:(NSNumber *)price;
21 | - (void)setLocallyIndexWithNumber:(NSNumber *)locallyIndex;
22 | - (void)setPubliclyIndexWithNumber:(NSNumber *)publiclyIndex;
23 | - (void)setContentMetadataWithMap:(NSDictionary *)map;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/native-tests/android/app/src/androidTest/java/io/branch/nativetests/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package io.branch.nativetests;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("io.branch.nativetests", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/MainApplicationModuleProvider.cpp:
--------------------------------------------------------------------------------
1 | #include "MainApplicationModuleProvider.h"
2 |
3 | #include
4 |
5 | namespace facebook {
6 | namespace react {
7 |
8 | std::shared_ptr MainApplicationModuleProvider(
9 | const std::string moduleName,
10 | const JavaTurboModule::InitParams ¶ms) {
11 | // Here you can provide your own module provider for TurboModules coming from
12 | // either your application or from external libraries. The approach to follow
13 | // is similar to the following (for a library called `samplelibrary`:
14 | //
15 | // auto module = samplelibrary_ModuleProvider(moduleName, params);
16 | // if (module != nullptr) {
17 | // return module;
18 | // }
19 | // return rncore_ModuleProvider(moduleName, params);
20 | return rncore_ModuleProvider(moduleName, params);
21 | }
22 |
23 | } // namespace react
24 | } // namespace facebook
25 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/src/services/LocalPushController.ts:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 | import PushNotification from 'react-native-push-notification';
3 | const branchChannelID = 'BranchChannelID';
4 | export const LocalNotification = (navigation: any, url: string) => {
5 | if (Platform.OS === 'ios') {
6 | sendNotification(url);
7 | } else {
8 | PushNotification.createChannel(
9 | {
10 | channelId: branchChannelID,
11 | channelName: 'BranchChannel',
12 | },
13 | () => {
14 | sendNotification(url);
15 | }
16 | );
17 | }
18 | navigation.goBack();
19 | };
20 | const sendNotification = (url: string) => {
21 | PushNotification.localNotification({
22 | channelId: branchChannelID,
23 | autoCancel: true,
24 | title: 'BranchTest',
25 | message: url,
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/docs/carthage.md:
--------------------------------------------------------------------------------
1 | # Installation using Carthage
2 |
3 | Carthage requires version ^3.0.1 of react-native-branch.
4 |
5 | Add react-native-branch to your project:
6 |
7 | ```bash
8 | yarn add react-native-branch@^3.0.1
9 | react-native link react-native-branch
10 | ```
11 |
12 | If you already have a Cartfile, add this to your Cartfile:
13 |
14 | ```
15 | github "BranchMetrics/ios-branch-deep-linking" "0.27.1"
16 | ```
17 |
18 | Now run `carthage build`.
19 |
20 | **Note:** The required version of the Branch SDK may differ. In that case,
21 | react-native-branch will throw an error at runtime to inform you of the
22 | correct version to add to your Cartfile.
23 |
24 | If you don't have a Cartfile, create a file called Cartfile in the ios
25 | subdirectory containing the line above.
26 |
27 | Now run `carthage bootstrap`.
28 |
29 | After running `carthage build|bootstrap`, the Branch framework will be found in
30 | Carthage/Build/iOS. Drag it into the Frameworks group in your project or add it
31 | to that group using Xcode.
32 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/java/com/branch_sdk_react_native_app/ReadLogPackage.java:
--------------------------------------------------------------------------------
1 | package io.branch.saas.sdk.testbed;
2 | import com.facebook.react.ReactPackage;
3 | import com.facebook.react.bridge.NativeModule;
4 | import com.facebook.react.bridge.ReactApplicationContext;
5 | import com.facebook.react.uimanager.ViewManager;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 |
12 | public class ReadLogPackage implements ReactPackage {
13 |
14 | @Override
15 | public List createViewManagers(ReactApplicationContext reactContext) {
16 | return Collections.emptyList();
17 | }
18 |
19 | @Override
20 | public List createNativeModules(
21 | ReactApplicationContext reactContext) {
22 | List modules = new ArrayList<>();
23 |
24 | modules.add(new io.branch.saas.sdk.testbed.ReadLogsModule(reactContext));
25 |
26 | return modules;
27 | }
28 | }
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'branch_sdk_react_native_app'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/react-native-gradle-plugin')
5 |
6 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
7 | include(":ReactAndroid")
8 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
9 | include(":ReactAndroid:hermes-engine")
10 | project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
11 | }
12 | include ':react-native-branch'
13 | project(':react-native-branch').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-branch/android')
14 |
15 | include ':react-native-push-notification'
16 | project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android')
--------------------------------------------------------------------------------
/runAllTests:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [[ "`uname -s`" != "Darwin" ]] ; then
4 | echo "Error: macOS required"
5 | exit -1
6 | fi
7 |
8 | # https://rvm.io/workflow/scripting
9 | # Load RVM into a shell session *as a function*
10 | if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
11 | # First try to load from a user install
12 | HAVE_RVM=1
13 | source "$HOME/.rvm/scripts/rvm"
14 | elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
15 | # Then try to load from a root install
16 | HAVE_RVM=1
17 | source "/usr/local/rvm/scripts/rvm"
18 | else
19 | echo "RVM not detected. Using local Ruby environment."
20 | fi
21 |
22 | if [[ "$HAVE_RVM" = 1 ]]; then
23 | rvm use
24 | fi
25 |
26 | PATH=${PATH}:/usr/local/bin
27 |
28 | if [[ -s "`which yarn`" ]] ; then
29 | HAVE_YARN=1
30 | yarn
31 | else
32 | echo "yarn not detected. Using npm install."
33 | npm install
34 | fi
35 |
36 | bundle check || bundle install
37 |
38 | if [[ "$HAVE_YARN" = 1 ]] ; then
39 | yarn lint
40 | yarn test
41 | else
42 | npm run lint
43 | npm test
44 | fi
45 |
46 | exit 0
47 |
--------------------------------------------------------------------------------
/native-tests/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/jdee/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/android/src/main/java/io/branch/rnbranch/RNBranchPackage.java:
--------------------------------------------------------------------------------
1 | package io.branch.rnbranch;
2 |
3 | import java.util.*;
4 |
5 | import com.facebook.react.ReactPackage;
6 | import com.facebook.react.bridge.JavaScriptModule;
7 | import com.facebook.react.bridge.NativeModule;
8 | import com.facebook.react.bridge.ReactApplicationContext;
9 | import com.facebook.react.uimanager.ViewManager;
10 |
11 |
12 | public class RNBranchPackage implements ReactPackage {
13 | @Override
14 | public List createNativeModules(
15 | ReactApplicationContext reactContext) {
16 | List modules = new ArrayList<>();
17 |
18 | modules.add(new RNBranchModule(reactContext));
19 |
20 | return modules;
21 | }
22 |
23 | // Depreciated RN 0.47
24 | public List> createJSModules() {
25 | return Collections.emptyList();
26 | }
27 |
28 | @Override
29 | public List createViewManagers(ReactApplicationContext reactContext) {
30 | return Collections.emptyList();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ios/RNBranchProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchProperty.m
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 1/26/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import "RNBranchProperty.h"
10 | #import "BranchUniversalObject+RNBranch.h"
11 |
12 | #import
13 |
14 | @implementation RNBranchProperty
15 |
16 | + (instancetype)propertyWithSetterSelector:(SEL)selector type:(Class)type
17 | {
18 | return [[self alloc] initWithSetterSelector:selector type:type];
19 | }
20 |
21 | - (instancetype)initWithSetterSelector:(SEL)selector type:(Class)type
22 | {
23 | self = [super init];
24 | if (self) {
25 | _setterSelector = selector;
26 | _type = type;
27 | }
28 | return self;
29 | }
30 |
31 | - (instancetype)init
32 | {
33 | @throw nil;
34 | }
35 |
36 | - (BOOL)isEqual:(id)object
37 | {
38 | if (![object isKindOfClass:self.class]) return NO;
39 |
40 | RNBranchProperty *other = object;
41 | return self.setterSelector == other.setterSelector && self.type == other.type;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/ios/RNBranchAgingDictionary.h:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchAgingDictionary.h
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 3/8/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RNBranchAgingDictionary : NSObject
12 |
13 | @property (nonatomic, readonly) NSTimeInterval ttl;
14 |
15 | #pragma mark - Object lifecycle
16 |
17 | - (instancetype _Nonnull)init NS_UNAVAILABLE;
18 | - (instancetype _Nonnull)initWithTtl:(NSTimeInterval)ttl NS_DESIGNATED_INITIALIZER;
19 |
20 | + (instancetype _Nonnull)dictionaryWithTtl:(NSTimeInterval)ttl;
21 |
22 | #pragma mark - Methods from NSMutableDictionary
23 |
24 | - (void)setObject:(ObjectType _Nonnull)object forKey:(KeyType _Nonnull)key;
25 | - (void)setObject:(ObjectType _Nonnull)object forKeyedSubscript:(KeyType _Nonnull)key;
26 |
27 | - (nullable ObjectType)objectForKey:(KeyType _Nonnull)key;
28 | - (nullable ObjectType)objectForKeyedSubscript:(KeyType _Nonnull)key;
29 |
30 | - (void)removeObjectForKey:(KeyType _Nonnull)key;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ios/react-native-branch-dev.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | # expect package.json in parent dir
4 | package_json_filename = File.expand_path("../package.json", __dir__)
5 |
6 | # load the spec from package.json
7 | spec = JSON.load(File.read(package_json_filename))
8 |
9 | Pod::Spec.new do |s|
10 | s.name = spec['name']
11 | s.version = spec['version']
12 | s.summary = spec['description']
13 | s.requires_arc = true
14 | s.authors = {
15 | 'rt2zz' => 'zack@root-two.com',
16 | 'Jimmy Dee' => 'jgvdthree@gmail.com'
17 | }
18 | s.license = spec['license']
19 | s.homepage = spec['homepage']
20 | s.platform = :ios, "9.0"
21 | s.source = { spec['repository']['type'].to_sym => spec['repository']['url'].sub(/^[a-z]+\+/, '') }
22 | s.source_files = [ "ios/*.h", "ios/*.m"]
23 | s.compiler_flags = %[-DRNBRANCH_VERSION=@\\"#{s.version}\\"]
24 | s.header_dir = 'RNBranch'
25 | s.dependency 'Branch' # No version specified
26 | s.dependency 'React' # to ensure the correct build order
27 | end
28 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/MainComponentsRegistry.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace facebook {
9 | namespace react {
10 |
11 | class MainComponentsRegistry
12 | : public facebook::jni::HybridClass {
13 | public:
14 | // Adapt it to the package you used for your Java class.
15 | constexpr static auto kJavaDescriptor =
16 | "Lcom/branch_sdk_react_native_app/newarchitecture/components/MainComponentsRegistry;";
17 |
18 | static void registerNatives();
19 |
20 | MainComponentsRegistry(ComponentFactory *delegate);
21 |
22 | private:
23 | static std::shared_ptr
24 | sharedProviderRegistry();
25 |
26 | static jni::local_ref initHybrid(
27 | jni::alias_ref,
28 | ComponentFactory *delegate);
29 | };
30 |
31 | } // namespace react
32 | } // namespace facebook
33 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "branchreactnativetestbed",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "lint": "eslint .",
9 | "start": "react-native start",
10 | "test": "jest"
11 | },
12 | "dependencies": {
13 | "react": "18.2.0",
14 | "react-native": "0.72.9",
15 | "react-native-branch": "6.9.0"
16 | },
17 | "devDependencies": {
18 | "@babel/core": "^7.20.0",
19 | "@babel/preset-env": "^7.20.0",
20 | "@babel/runtime": "^7.20.0",
21 | "@react-native-community/eslint-config": "^3.2.0",
22 | "@tsconfig/react-native": "^2.0.2",
23 | "@types/jest": "^29.2.1",
24 | "@types/react": "^18.0.24",
25 | "@types/react-test-renderer": "^18.0.0",
26 | "babel-jest": "^29.2.1",
27 | "eslint": "^8.19.0",
28 | "jest": "^29.2.1",
29 | "metro-react-native-babel-preset": "0.76.0",
30 | "prettier": "^2.4.1",
31 | "react-test-renderer": "18.2.0",
32 | "typescript": "4.8.4"
33 | },
34 | "jest": {
35 | "preset": "react-native"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Branch Metrics, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.swp
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 |
9 | # Runtime data
10 | pids
11 | *.pid
12 | *.seed
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directory
30 | node_modules
31 |
32 | # Optional npm cache directory
33 | .npm
34 |
35 | # Optional REPL history
36 | .node_repl_history
37 |
38 | # Auto-generated Xcode files
39 | *.xcuserstate
40 | *.xcuserdatad
41 | project.xcworkspace
42 | xcuserdata
43 |
44 | # OS X garbage
45 | *.DS_Store
46 |
47 | android/build
48 | *.iml
49 | .idea
50 |
51 | Pods
52 |
53 | # for now. not such a great idea. need to sort the bundler 1.x/2.x issue here.
54 | Gemfile.lock
55 |
56 | # yarn lock file, use `yarn import` to generate from package-lock.json
57 | yarn.lock
58 | branchreactnativetestbed/ios/.ruby-version
59 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbed/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/native-tests/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "29.0.2"
6 | minSdkVersion = 16
7 | compileSdkVersion = 29
8 | targetSdkVersion = 29
9 | supportLibVersion = "28.0.0"
10 | }
11 | repositories {
12 | google()
13 | jcenter()
14 | }
15 | dependencies {
16 | classpath('com.android.tools.build:gradle:3.6.2')
17 |
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | mavenLocal()
26 | maven {
27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
28 | url("$rootDir/../node_modules/react-native/android")
29 | }
30 | maven {
31 | // Android JSC is installed from npm
32 | url("$rootDir/../node_modules/jsc-android/dist")
33 | }
34 |
35 | google()
36 | jcenter()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/branch_sdk_react_native_app/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/gate-keeper.yml:
--------------------------------------------------------------------------------
1 | name: Gate Keeper
2 | on:
3 | push:
4 | env:
5 | NODE_VERSION: 16
6 |
7 | jobs:
8 | test-lint:
9 | name: Lint
10 | runs-on: [ ubuntu-latest ]
11 | steps:
12 | - name: Checkout ${{ github.ref_name }}
13 | uses: actions/checkout@v3
14 |
15 | - name: Install Node
16 | uses: actions/setup-node@v3
17 | with:
18 | node-version: ${{ env.NODE_VERSION }}
19 | cache: 'npm'
20 |
21 | - name: Install dependencies
22 | run: npm install
23 |
24 | - name: Lint tests
25 | run: npm run lint
26 |
27 | test-unit:
28 | name: Unit tests
29 | runs-on: [ ubuntu-latest ]
30 | steps:
31 | - name: Checkout ${{ github.ref_name }}
32 | uses: actions/checkout@v3
33 |
34 | - name: Install Node
35 | uses: actions/setup-node@v3
36 | with:
37 | node-version: ${{ env.NODE_VERSION }}
38 | cache: 'npm'
39 |
40 | - name: Install dependencies
41 | run: npm install
42 |
43 | - name: Run tests
44 | run: npm run test
45 |
46 | - name : upload codecov
47 | uses: codecov/codecov-action@v3
48 |
49 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 |
34 | # node.js
35 | #
36 | node_modules/
37 | npm-debug.log
38 | yarn-error.log
39 |
40 | # BUCK
41 | buck-out/
42 | \.buckd/
43 | *.keystore
44 | !debug.keystore
45 |
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/
52 |
53 | **/fastlane/report.xml
54 | **/fastlane/Preview.html
55 | **/fastlane/screenshots
56 | **/fastlane/test_output
57 |
58 | # Bundle artifact
59 | *.jsbundle
60 |
61 | # Ruby / CocoaPods
62 | /ios/Pods/
63 | /vendor/bundle/
64 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbed/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | # This workflow warns and then closes issues that have had no activity for a specified amount of time.
2 | #
3 | # You can adjust the behavior by modifying this file.
4 | # For more information, see:
5 | # https://github.com/actions/stale
6 | name: Mark stale issues
7 |
8 | on:
9 | schedule:
10 | - cron: '0 0 * * *'
11 |
12 | jobs:
13 | stale:
14 |
15 | runs-on: ubuntu-latest
16 | permissions:
17 | issues: write
18 |
19 | steps:
20 | - uses: actions/stale@v9
21 | with:
22 | repo-token: ${{ github.token }}
23 | days-before-issue-stale: 60
24 | days-before-close: 7
25 | stale-issue-message: 'This issue has been automatically marked as stale due to inactivity for 60 days. If this issue is still relevant, please respond with any updates or this issue will be closed in 7 days. If you believe this is a mistake, please comment to let us know. Thank you for your contributions.'
26 | stale-issue-label: 'no-issue-activity'
27 | close-issue-message: 'This issue has been closed due to inactivity. If this issue is still relevant, please reopen it or create a new one. Thank you for your contributions.'
28 | start-date: '2023-05-22'
29 |
--------------------------------------------------------------------------------
/react-native-branch.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | # expect package.json in current dir
4 | package_json_filename = File.expand_path("./package.json", __dir__)
5 |
6 | # load the spec from package.json
7 | spec = JSON.load(File.read(package_json_filename))
8 |
9 | Pod::Spec.new do |s|
10 | s.name = spec['name']
11 | s.version = spec['version']
12 | s.summary = spec['description']
13 | s.requires_arc = true
14 | s.authors = {
15 | 'rt2zz' => 'zack@root-two.com',
16 | 'Jimmy Dee' => 'jgvdthree@gmail.com'
17 | }
18 | s.license = spec['license']
19 | s.homepage = spec['homepage']
20 | s.platform = :ios, "12.0"
21 | s.source = { spec['repository']['type'].to_sym => spec['repository']['url'].sub(/^[a-z]+\+/, '') }
22 | s.source_files = [ "ios/*.h", "ios/*.m"]
23 | s.compiler_flags = %[-DRNBRANCH_VERSION=@\\"#{s.version}\\"]
24 | s.header_dir = 'RNBranch' # also sets generated module name
25 | s.dependency 'BranchSDK', '3.13.3'
26 | s.dependency 'React-Core' # to ensure the correct build order
27 |
28 | # Swift/Objective-C compatibility
29 | s.pod_target_xcconfig = {
30 | 'DEFINES_MODULE' => 'YES'
31 | }
32 | end
33 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | /ios/Pods/
60 | /vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Reference
2 | SDK-XXXX -- .
3 |
4 | ## Summary
5 |
6 |
7 | ## Motivation
8 |
9 |
10 | ## Type Of Change
11 |
12 | - [ ] Bug fix (non-breaking change which fixes an issue)
13 | - [ ] New feature (non-breaking change which adds functionality)
14 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
15 | - [ ] This change requires a documentation update
16 |
17 | ## Testing Instructions
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | cc @BranchMetrics/saas-sdk-devs for visibility.
30 |
--------------------------------------------------------------------------------
/ios/NSObject+RNBranch.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+RNBranch.m
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 1/26/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "NSObject+RNBranch.h"
12 | #import "RNBranchProperty.h"
13 |
14 | @implementation NSObject(RNBranch)
15 |
16 | + (NSDictionary *)supportedProperties
17 | {
18 | return @{};
19 | }
20 |
21 | - (void)setSupportedPropertiesWithMap:(NSDictionary *)map
22 | {
23 | for (NSString *key in map.allKeys) {
24 | RNBranchProperty *property = self.class.supportedProperties[key];
25 | if (!property) {
26 | RCTLogWarn(@"\"%@\" is not a supported property for %@.", key, NSStringFromClass(self.class));
27 | continue;
28 | }
29 |
30 | id value = map[key];
31 | Class type = property.type;
32 | if (![value isKindOfClass:type]) {
33 | RCTLogWarn(@"\"%@\" requires a value of type %@.", key, NSStringFromClass(type));
34 | continue;
35 | }
36 |
37 | #pragma clang diagnostic push
38 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
39 | [self performSelector:property.setterSelector withObject:value];
40 | #pragma clang diagnostic pop
41 | }
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | namespace facebook {
8 | namespace react {
9 |
10 | class MainApplicationTurboModuleManagerDelegate
11 | : public jni::HybridClass<
12 | MainApplicationTurboModuleManagerDelegate,
13 | TurboModuleManagerDelegate> {
14 | public:
15 | // Adapt it to the package you used for your Java class.
16 | static constexpr auto kJavaDescriptor =
17 | "Lcom/branch_sdk_react_native_app/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
18 |
19 | static jni::local_ref initHybrid(jni::alias_ref);
20 |
21 | static void registerNatives();
22 |
23 | std::shared_ptr getTurboModule(
24 | const std::string name,
25 | const std::shared_ptr jsInvoker) override;
26 | std::shared_ptr getTurboModule(
27 | const std::string name,
28 | const JavaTurboModule::InitParams ¶ms) override;
29 |
30 | /**
31 | * Test-only method. Allows user to verify whether a TurboModule can be
32 | * created by instances of this class.
33 | */
34 | bool canCreateTurboModule(std::string name);
35 | };
36 |
37 | } // namespace react
38 | } // namespace facebook
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 |
5 | [Configure Branch]: https://help.branch.io/developers-hub/docs/react-native-basic-integration#1-configure-branch-dashboard
6 | [Install Branch]: https://help.branch.io/developers-hub/docs/react-native-basic-integration#2-install-branch
7 | [Configure App]: https://help.branch.io/developers-hub/docs/react-native-basic-integration#3-configure-app
8 | [Initialize Branch]: https://help.branch.io/developers-hub/docs/react-native-basic-integration#4-initialize-branch
9 | [Validate Integration and Troubleshoot Issues]: https://help.branch.io/developers-hub/docs/react-native-basic-integration#5-validate-integration
10 | [Implement Features]: https://help.branch.io/developers-hub/docs/react-native-advanced-features
11 |
12 | # Branch React Native SDK
13 |
14 | Branch Metrics React Native SDK. Please see
15 | [the SDK documentation](https://help.branch.io/developers-hub/docs/react-native)
16 | for full details.
17 |
18 | - [Configure Branch]
19 | - [Install Branch]
20 | - [Configure App]
21 | - [Initialize Branch]
22 | - [Implement Features]
23 | - [Troubleshoot Issues]
24 |
25 | Please contact our [Support team](https://help.branch.io/using-branch/page/submit-a-ticket) for feedback or assistance with integration or
26 | troubleshooting.
27 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/java/com/branch_sdk_react_native_app/newarchitecture/components/MainComponentsRegistry.java:
--------------------------------------------------------------------------------
1 | package io.branch.saas.sdk.testbed.newarchitecture.components;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.proguard.annotations.DoNotStrip;
5 | import com.facebook.react.fabric.ComponentFactory;
6 | import com.facebook.soloader.SoLoader;
7 |
8 | /**
9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a
10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
11 | * folder for you).
12 | *
13 | * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
14 | * `newArchEnabled` property). Is ignored otherwise.
15 | */
16 | @DoNotStrip
17 | public class MainComponentsRegistry {
18 | static {
19 | SoLoader.loadLibrary("fabricjni");
20 | }
21 |
22 | @DoNotStrip private final HybridData mHybridData;
23 |
24 | @DoNotStrip
25 | private native HybridData initHybrid(ComponentFactory componentFactory);
26 |
27 | @DoNotStrip
28 | private MainComponentsRegistry(ComponentFactory componentFactory) {
29 | mHybridData = initHybrid(componentFactory);
30 | }
31 |
32 | @DoNotStrip
33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) {
34 | return new MainComponentsRegistry(componentFactory);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/src/common/common.style.ts:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 | import { resources } from '../components/constant/colors';
3 |
4 | export const styles = StyleSheet.create({
5 | container: {
6 | flex: 1,
7 | backgroundColor: '#fff',
8 | padding: 5,
9 | paddingBottom: 50,
10 | },
11 | input: {
12 | height: 40,
13 | borderWidth: 0.5,
14 | padding: 10,
15 | borderRadius: 4,
16 | marginTop: 10,
17 | color: resources.color.black,
18 | },
19 | dropDownContainer: {
20 | marginTop: 10,
21 | },
22 | buttonStyle: {
23 | marginTop: 15,
24 | padding: 10,
25 | backgroundColor: resources.color.purple_700,
26 | alignItems: 'center',
27 | justifyContent: 'center',
28 | borderRadius: 10,
29 | minWidth: 150,
30 | },
31 | titleStyle: {
32 | color: resources.color.white,
33 | fontWeight: '500',
34 | },
35 | dropdownContainer: {
36 | flexDirection: 'row',
37 | zIndex: 500,
38 | flex: 1,
39 | marginTop: 12,
40 | marginBottom: 12,
41 | },
42 | dropdownContainerTrackContent: {
43 | flexDirection: 'row',
44 | flex: 1,
45 | marginTop: 12,
46 | marginBottom: 12,
47 | },
48 | footerContainer: { flex: 1, marginLeft: 12, marginRight: 12, marginBottom: 50 },
49 | });
50 |
--------------------------------------------------------------------------------
/android/src/main/java/io/branch/rnbranch/AgingHash.java:
--------------------------------------------------------------------------------
1 | package io.branch.rnbranch;
2 |
3 | import java.util.HashMap;
4 | import java.util.Iterator;
5 |
6 | /**
7 | * Created by jdee on 3/8/17.
8 | */
9 |
10 | public class AgingHash {
11 | private long mTtlMillis;
12 | private HashMap> mHash = new HashMap<>();
13 |
14 | public AgingHash(long ttlMillis) {
15 | mTtlMillis = ttlMillis;
16 | }
17 |
18 | public long getTtlMillis() {
19 | return mTtlMillis;
20 | }
21 |
22 | public void put(KeyType key, ValueType value) {
23 | ageItems();
24 |
25 | AgingItem item = new AgingItem<>(value);
26 | mHash.put(key, item);
27 | }
28 |
29 | public ValueType get(KeyType key) {
30 | AgingItem item = mHash.get(key);
31 | if (item == null) return null;
32 |
33 | return item.get();
34 | }
35 |
36 | public void remove(KeyType key) {
37 | mHash.remove(key);
38 | }
39 |
40 | private void ageItems() {
41 | long now = System.currentTimeMillis();
42 |
43 | Iterator it = mHash.entrySet().iterator();
44 | while (it.hasNext()) {
45 | HashMap.Entry pair = (HashMap.Entry) it.next();
46 | AgingItem item = (AgingItem) pair.getValue();
47 | if (now - item.getAccessTime() >= mTtlMillis) {
48 | it.remove();
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/native-tests/ios/NativeTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIRequiredDeviceCapabilities
24 |
25 | armv7
26 |
27 | UISupportedInterfaceOrientations
28 |
29 | UIInterfaceOrientationPortrait
30 | UIInterfaceOrientationLandscapeLeft
31 | UIInterfaceOrientationLandscapeRight
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/native-tests/android/app/src/test/java/io/branch/nativetests/AgingItemUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.branch.nativetests;
2 |
3 | import org.junit.Test;
4 |
5 | import io.branch.rnbranch.AgingItem;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | /**
10 | * Created by jdee on 4/24/17.
11 | */
12 |
13 | public class AgingItemUnitTest {
14 | @Test
15 | public void testInitialization() {
16 | String value = "abc";
17 |
18 | long before = System.currentTimeMillis();
19 | AgingItem item = new AgingItem<>(value);
20 | long after = System.currentTimeMillis();
21 |
22 | // Access time initialized to initialization time.
23 | assertTrue(item.getAccessTime() >= before);
24 | assertTrue(item.getAccessTime() <= after);
25 |
26 | // get() returns the constructor argument.
27 | assertEquals(value, item.get());
28 | }
29 |
30 | @Test
31 | public void testAccessTime() {
32 | String value = "abc";
33 |
34 | AgingItem item = new AgingItem<>(value);
35 | long afterInitialization = System.currentTimeMillis();
36 |
37 | try {
38 | Thread.sleep(10);
39 | }
40 | catch (Exception e) {
41 | fail("Failed to sleep for 10 ms: " + e.getMessage());
42 | }
43 |
44 | item.get();
45 | long afterAccess = System.currentTimeMillis();
46 |
47 | // Access time updated after calling get()
48 | assertTrue(item.getAccessTime() >= afterInitialization);
49 | assertTrue(item.getAccessTime() <= afterAccess);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/_BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 |
17 | create_jar_targets(glob(["libs/*.jar"]))
18 |
19 | android_library(
20 | name = "all-libs",
21 | exported_deps = lib_deps,
22 | )
23 |
24 | android_library(
25 | name = "app-code",
26 | srcs = glob([
27 | "src/main/java/**/*.java",
28 | ]),
29 | deps = [
30 | ":all-libs",
31 | ":build_config",
32 | ":res",
33 | ],
34 | )
35 |
36 | android_build_config(
37 | name = "build_config",
38 | package = "com.branch_sdk_react_native_app",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.branch_sdk_react_native_app",
44 | res = "src/main/res",
45 | )
46 |
47 | android_binary(
48 | name = "app",
49 | keystore = "//android/keystores:debug",
50 | manifest = "src/main/AndroidManifest.xml",
51 | package_type = "debug",
52 | deps = [
53 | ":app-code",
54 | ],
55 | )
56 |
--------------------------------------------------------------------------------
/ios/RNBranch.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | extern NSString * _Nonnull const RNBranchLinkOpenedNotification;
8 | extern NSString * _Nonnull const RNBranchLinkOpenedNotificationErrorKey;
9 | extern NSString * _Nonnull const RNBranchLinkOpenedNotificationParamsKey;
10 | extern NSString * _Nonnull const RNBranchLinkOpenedNotificationUriKey;
11 | extern NSString * _Nonnull const RNBranchLinkOpenedNotificationBranchUniversalObjectKey;
12 | extern NSString * _Nonnull const RNBranchLinkOpenedNotificationLinkPropertiesKey;
13 |
14 |
15 | @interface RNBranch : NSObject
16 |
17 | @property (class, readonly, nonnull) Branch *branch;
18 |
19 | + (void)initSessionWithLaunchOptions:(NSDictionary * _Nullable)launchOptions isReferrable:(BOOL)isReferrable;
20 | + (BOOL)application:(UIApplication * _Nullable)application openURL:(NSURL * _Nullable)url options:(NSDictionary * _Nullable)options;
21 | + (BOOL)application:(UIApplication * _Nullable)application openURL:(NSURL * _Nullable)url sourceApplication:(NSString * _Nullable)sourceApplication annotation:(id _Nullable)annotation;
22 | #pragma clang diagnostic push
23 | #pragma clang diagnostic ignored "-Wpartial-availability"
24 | + (BOOL)continueUserActivity:(NSUserActivity * _Nonnull)userActivity;
25 | #pragma clang diagnostic pop
26 |
27 | // Must be called before any other static method below
28 | + (void)useTestInstance;
29 | + (void)deferInitializationForJSLoad;
30 |
31 | + (void)enableLogging;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp:
--------------------------------------------------------------------------------
1 | #include "MainApplicationTurboModuleManagerDelegate.h"
2 | #include "MainApplicationModuleProvider.h"
3 |
4 | namespace facebook {
5 | namespace react {
6 |
7 | jni::local_ref
8 | MainApplicationTurboModuleManagerDelegate::initHybrid(
9 | jni::alias_ref) {
10 | return makeCxxInstance();
11 | }
12 |
13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() {
14 | registerHybrid({
15 | makeNativeMethod(
16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
17 | makeNativeMethod(
18 | "canCreateTurboModule",
19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
20 | });
21 | }
22 |
23 | std::shared_ptr
24 | MainApplicationTurboModuleManagerDelegate::getTurboModule(
25 | const std::string name,
26 | const std::shared_ptr jsInvoker) {
27 | // Not implemented yet: provide pure-C++ NativeModules here.
28 | return nullptr;
29 | }
30 |
31 | std::shared_ptr
32 | MainApplicationTurboModuleManagerDelegate::getTurboModule(
33 | const std::string name,
34 | const JavaTurboModule::InitParams ¶ms) {
35 | return MainApplicationModuleProvider(name, params);
36 | }
37 |
38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
39 | std::string name) {
40 | return getTurboModule(name, nullptr) != nullptr ||
41 | getTurboModule(name, {.moduleName = name}) != nullptr;
42 | }
43 |
44 | } // namespace react
45 | } // namespace facebook
46 |
--------------------------------------------------------------------------------
/native-tests/ios/NativeTestsTests/NSObjectExtensionTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObjectExtensionTests.m
3 | // NativeTests
4 | //
5 | // Created by Jimmy Dee on 4/18/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 | #import
13 |
14 | @interface TestClass: NSObject
15 | @property (nonatomic, copy) NSString *foo;
16 | @end
17 |
18 | @implementation TestClass
19 |
20 | + (NSDictionary *)supportedProperties
21 | {
22 | return @{ @"foo": [RNBranchProperty propertyWithSetterSelector:@selector(setFoo:) type:NSString.class] };
23 | }
24 |
25 | @end
26 |
27 | @interface NSObjectExtensionTests : XCTestCase
28 | @property (nonatomic) TestClass *testClass;
29 | @end
30 |
31 | @implementation NSObjectExtensionTests
32 |
33 | - (void)setUp
34 | {
35 | [super setUp];
36 | self.testClass = [[TestClass alloc] init];
37 | }
38 |
39 | - (void)testSupportedProperties
40 | {
41 | [self.testClass setSupportedPropertiesWithMap:@{ @"foo": @"bar" }];
42 |
43 | XCTAssertEqualObjects(@"bar", self.testClass.foo);
44 | }
45 |
46 | - (void)testUnsupportedProperty
47 | {
48 | [self.testClass setSupportedPropertiesWithMap:@{ @"badKey": @"badKeyValue" }];
49 |
50 | // Also logs a diagnostic about an unsupported property. Does not modify the receiver.
51 | XCTAssertNil(self.testClass.foo);
52 | }
53 |
54 | - (void)testWrongValue
55 | {
56 | [self.testClass setSupportedPropertiesWithMap:@{ @"foo": @(1) }];
57 |
58 | // Also logs a diagnostic about a bad type. Does not modify the receiver.
59 | XCTAssertNil(self.testClass.foo);
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/Podfile:
--------------------------------------------------------------------------------
1 | require_relative '../node_modules/react-native/scripts/react_native_pods'
2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
3 |
4 | platform :ios, '12.4'
5 | install! 'cocoapods', :deterministic_uuids => false
6 |
7 | target 'branch_sdk_react_native_app' do
8 | config = use_native_modules!
9 | # Flags change depending on the env values.
10 | flags = get_default_flags()
11 |
12 | use_react_native!(
13 | :path => config[:reactNativePath],
14 | # to enable hermes on iOS, change `false` to `true` and then install pods
15 | :hermes_enabled => flags[:hermes_enabled],
16 | :fabric_enabled => flags[:fabric_enabled],
17 | # An absolute path to your application root.
18 | :app_path => "#{Pod::Config.instance.installation_root}/.."
19 | )
20 |
21 | target 'branch_sdk_react_native_appTests' do
22 | inherit! :complete
23 | # Pods for testing
24 | end
25 |
26 | # Enables Flipper.
27 | #
28 | # Note that if you have use_frameworks! enabled, Flipper will not work and
29 | # you should disable the next line.
30 | use_flipper!()
31 |
32 |
33 |
34 | post_install do |installer|
35 | react_native_post_install(installer)
36 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
37 | # Fix for build failure with Xcode-14 - https://github.com/facebook/react-native/issues/34673
38 | installer.pods_project.targets.each do |target|
39 | if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
40 | target.build_configurations.each do |config|
41 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
42 | end
43 | end
44 | end
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | THIS_DIR := $(call my-dir)
2 |
3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
4 |
5 | # If you wish to add a custom TurboModule or Fabric component in your app you
6 | # will have to include the following autogenerated makefile.
7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
8 | include $(CLEAR_VARS)
9 |
10 | LOCAL_PATH := $(THIS_DIR)
11 |
12 | # You can customize the name of your application .so file here.
13 | LOCAL_MODULE := branch_sdk_react_native_app_appmodules
14 |
15 | LOCAL_C_INCLUDES := $(LOCAL_PATH)
16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
18 |
19 | # If you wish to add a custom TurboModule or Fabric component in your app you
20 | # will have to uncomment those lines to include the generated source
21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
22 | #
23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
26 |
27 | # Here you should add any native library you wish to depend on.
28 | LOCAL_SHARED_LIBRARIES := \
29 | libfabricjni \
30 | libfbjni \
31 | libfolly_runtime \
32 | libglog \
33 | libjsi \
34 | libreact_codegen_rncore \
35 | libreact_debug \
36 | libreact_nativemodule_core \
37 | libreact_render_componentregistry \
38 | libreact_render_core \
39 | libreact_render_debug \
40 | libreact_render_graphics \
41 | librrc_view \
42 | libruntimeexecutor \
43 | libturbomodulejsijni \
44 | libyoga
45 |
46 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
47 |
48 | include $(BUILD_SHARED_LIBRARY)
49 |
--------------------------------------------------------------------------------
/ios/BranchLinkProperties+RNBranch.m:
--------------------------------------------------------------------------------
1 | //
2 | // BranchLinkProperties+RNBranch.m
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 1/26/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import "BranchLinkProperties+RNBranch.h"
10 | #import "NSObject+RNBranch.h"
11 | #import "RNBranchProperty.h"
12 |
13 | @implementation BranchLinkProperties(RNBranch)
14 |
15 | + (NSDictionary *)supportedProperties
16 | {
17 | static NSDictionary *_linkProperties;
18 | static dispatch_once_t once = 0;
19 | dispatch_once(&once, ^{
20 | _linkProperties =
21 | @{
22 | @"alias": [RNBranchProperty propertyWithSetterSelector:@selector(setAlias:) type:NSString.class],
23 | @"campaign": [RNBranchProperty propertyWithSetterSelector:@selector(setCampaign:) type:NSString.class],
24 | @"channel": [RNBranchProperty propertyWithSetterSelector:@selector(setChannel:) type:NSString.class],
25 | // @"duration": [RNBranchProperty propertyWithSetterSelector:@selector(setMatchDuration:) type:NSNumber.class], // deprecated
26 | @"feature": [RNBranchProperty propertyWithSetterSelector:@selector(setFeature:) type:NSString.class],
27 | @"stage": [RNBranchProperty propertyWithSetterSelector:@selector(setStage:) type:NSString.class],
28 | @"tags": [RNBranchProperty propertyWithSetterSelector:@selector(setTags:) type:NSArray.class]
29 | };
30 | });
31 |
32 | return _linkProperties;
33 | }
34 |
35 | - (instancetype)initWithMap:(NSDictionary *)map
36 | {
37 | self = [self init];
38 | if (self) {
39 | [self setSupportedPropertiesWithMap:map];
40 | }
41 | return self;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/test/RNBranchMock.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native'
2 |
3 | NativeModules.RNBranch = {
4 | INIT_SESSION_START: 'RNBranch.initSessionStart',
5 | INIT_SESSION_SUCCESS: 'RNBranch.initSessionSuccess',
6 | INIT_SESSION_ERROR: 'RNBranch.initSessionError',
7 |
8 | STANDARD_EVENT_ADD_TO_CART: 'ADD_TO_CART',
9 | STANDARD_EVENT_ADD_TO_WISHLIST: 'ADD_TO_WISHLIST',
10 | STANDARD_EVENT_VIEW_CART: 'VIEW_CART',
11 | STANDARD_EVENT_INITIATE_PURCHASE: 'INITIATE_PURCHASE',
12 | STANDARD_EVENT_ADD_PAYMENT_INFO: 'ADD_PAYMENT_INFO',
13 | STANDARD_EVENT_PURCHASE: 'PURCHASE',
14 | STANDARD_EVENT_VIEW_AD: 'VIEW_AD',
15 | STANDARD_EVENT_CLICK_AD: 'CLICK_AD',
16 |
17 | STANDARD_EVENT_SEARCH: 'SEARCH',
18 | STANDARD_EVENT_VIEW_ITEM: 'VIEW_ITEM',
19 | STANDARD_EVENT_VIEW_ITEMS: 'VIEW_ITEMS',
20 | STANDARD_EVENT_RATE: 'RATE',
21 | STANDARD_EVENT_SHARE: 'SHARE',
22 |
23 | STANDARD_EVENT_COMPLETE_REGISTRATION: 'COMPLETE_REGISTRATION',
24 | STANDARD_EVENT_COMPLETE_TUTORIAL: 'COMPLETE_TUTORIAL',
25 | STANDARD_EVENT_ACHIEVE_LEVEL: 'ACHIEVE_LEVEL',
26 | STANDARD_EVENT_UNLOCK_ACHIEVEMENT: 'UNLOCK_ACHIEVEMENT',
27 | STANDARD_EVENT_INVITE: 'INVITE',
28 | STANDARD_EVENT_LOGIN: 'LOGIN',
29 | STANDARD_EVENT_RESERVE: 'RESERVE',
30 | STANDARD_EVENT_SUBSCRIBE: 'SUBSCRIBE',
31 | STANDARD_EVENT_START_TRIAL: 'START_TRIAL',
32 |
33 | redeemInitSessionResult: jest.fn(() => Promise.resolve({
34 | params: {
35 | '+clicked_branch_link': false,
36 | '+is_first_session': false,
37 | },
38 | error: null,
39 | uri: null,
40 | })),
41 | notifyNativeToInit: jest.fn(() => Promise.resolve({
42 | })),
43 | }
44 |
45 | NativeModules.RNBranchEventEmitter = {
46 | addListener: jest.fn(eventType => {}),
47 | removeListener: jest.fn(count => {}),
48 | }
49 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | import groovy.json.JsonSlurper
3 |
4 | def DEFAULT_COMPILE_SDK_VERSION = 29
5 | def DEFAULT_MIN_SDK_VERSION = 16
6 | def DEFAULT_TARGET_SDK_VERSION = 29
7 |
8 | def getNpmVersion() {
9 | def packageJsonFile = file('../package.json')
10 | def packageJson = new JsonSlurper().parseText(packageJsonFile.text)
11 | return packageJson.version
12 | }
13 |
14 | repositories {
15 | mavenLocal()
16 | mavenCentral()
17 | maven {
18 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
19 | url "$rootDir/../node_modules/react-native/android"
20 | }
21 | maven {
22 | // Android JSC is installed from npm
23 | url "$rootDir/../node_modules/jsc-android/dist"
24 | }
25 | google()
26 | }
27 |
28 | def safeExtGet(prop, fallback) {
29 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
30 | }
31 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
32 |
33 | android {
34 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
35 |
36 | defaultConfig {
37 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
38 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
39 |
40 | versionCode 1
41 | versionName "1.0"
42 |
43 | buildConfigField("String", "RNBRANCH_VERSION", "\"${getNpmVersion()}\"")
44 | }
45 | }
46 |
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.19.0'
51 | }
52 |
--------------------------------------------------------------------------------
/native-tests/ios/NativeTestsTests/RNBranchAgingItemTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchAgingItemTests.m
3 | // NativeTests
4 | //
5 | // Created by Jimmy Dee on 4/24/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | @interface RNBranchAgingItemTests : XCTestCase
14 |
15 | @end
16 |
17 | @implementation RNBranchAgingItemTests
18 |
19 | - (void)testInitialization
20 | {
21 | NSString *expected = @"abc";
22 | NSTimeInterval beforeInitialization = [NSDate date].timeIntervalSince1970;
23 | RNBranchAgingItem *item = [[RNBranchAgingItem alloc] initWithItem:expected];
24 | NSTimeInterval afterInitialization = [NSDate date].timeIntervalSince1970;
25 |
26 | // Access time initialized to initialization time.
27 | XCTAssertGreaterThanOrEqual(item.accessTime, beforeInitialization);
28 | XCTAssertLessThanOrEqual(item.accessTime, afterInitialization);
29 |
30 | // item property returns the constructor argument.
31 | XCTAssertEqual(expected, item.item);
32 | }
33 |
34 | - (void)testAccessTime
35 | {
36 | NSString *expected = @"abc";
37 | RNBranchAgingItem *item = [[RNBranchAgingItem alloc] initWithItem:expected];
38 | NSTimeInterval afterInitialization = [NSDate date].timeIntervalSince1970;
39 |
40 | usleep(10000); // sleep for 10 ms
41 |
42 | NSString *value = item.item;
43 | NSTimeInterval afterAccess = [NSDate date].timeIntervalSince1970;
44 |
45 | // Access time updated after calling [item item].
46 | XCTAssertGreaterThanOrEqual(item.accessTime, afterInitialization);
47 | XCTAssertLessThanOrEqual(item.accessTime, afterAccess);
48 |
49 | // Avoid a complaint about an unused variable.
50 | XCTAssertEqual(expected, value);
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/RCTReadLogs.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTReadLogs.m
3 | // branch_sdk_react_native_app
4 | //
5 | // Created by Admin on 18/08/22.
6 | //
7 |
8 | #import
9 | // RCTCalendarModule.m
10 | #import "RCTReadlogs.h"
11 |
12 | @implementation RCTReadLogs
13 |
14 | // To export a module named RCTReadlogs
15 | RCT_EXPORT_MODULE();
16 |
17 | RCT_EXPORT_METHOD(clearLogs)
18 | {
19 | // RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
20 | NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
21 | NSError *error = nil;
22 | for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error]) {
23 | [[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:file] error:&error];
24 | }
25 | }
26 | RCT_EXPORT_METHOD(readLog:(RCTResponseSenderBlock)callback)
27 | {
28 |
29 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
30 | NSString *documentsDirectory = [paths objectAtIndex:0];
31 | NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
32 | NSString *myString = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
33 | callback(@[myString]);
34 | }
35 | RCT_EXPORT_METHOD(createLogFile)
36 | {
37 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
38 | NSString *documentsDirectory = [paths objectAtIndex:0];
39 | NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
40 | freopen([filePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
41 | }
42 | @end
43 |
--------------------------------------------------------------------------------
/native-tests/ios/NativeTestsTests/RNBranchPropertyTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchPropertyTests.m
3 | // NativeTests
4 | //
5 | // Created by Jimmy Dee on 4/18/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | @interface RNBranchPropertyTests : XCTestCase
14 |
15 | @end
16 |
17 | @implementation RNBranchPropertyTests
18 |
19 | - (void)testInitialization
20 | {
21 | RNBranchProperty *propertyA = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSURL.class];
22 |
23 | XCTAssertEqual(NSURL.class, propertyA.type);
24 | XCTAssertEqual(@selector(setURL:), propertyA.setterSelector);
25 | }
26 |
27 | - (void)testEquality
28 | {
29 | RNBranchProperty *propertyA = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSURL.class];
30 | RNBranchProperty *propertyB = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSURL.class];
31 |
32 | // This method was mainly introduced to simplify other tests.
33 | XCTAssert([propertyA isEqual:propertyB]);
34 | }
35 |
36 | - (void)testSelectorInequality
37 | {
38 | RNBranchProperty *propertyA = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSURL.class];
39 | RNBranchProperty *propertyB = [RNBranchProperty propertyWithSetterSelector:@selector(setContentDescription:) type:NSURL.class];
40 |
41 | XCTAssertFalse([propertyA isEqual:propertyB]);
42 | }
43 |
44 | - (void)testTypeInequality
45 | {
46 | RNBranchProperty *propertyA = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSURL.class];
47 | RNBranchProperty *propertyB = [RNBranchProperty propertyWithSetterSelector:@selector(setURL:) type:NSString.class];
48 |
49 | XCTAssertFalse([propertyA isEqual:propertyB]);
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/app/src/main/java/com/branchreactnativetestbed/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.branchreactnativetestbed;
2 |
3 | import android.content.Intent;
4 |
5 | import com.facebook.react.ReactActivity;
6 | import com.facebook.react.ReactActivityDelegate;
7 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
8 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
9 |
10 | import io.branch.rnbranch.RNBranchModule;
11 |
12 | public class MainActivity extends ReactActivity {
13 |
14 | /**
15 | * Returns the name of the main component registered from JavaScript. This is used to schedule
16 | * rendering of the component.
17 | */
18 | @Override
19 | protected String getMainComponentName() {
20 | return "branchreactnativetestbed";
21 | }
22 |
23 | /**
24 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
25 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
26 | * (aka React 18) with two boolean flags.
27 | */
28 | @Override
29 | protected ReactActivityDelegate createReactActivityDelegate() {
30 | return new DefaultReactActivityDelegate(
31 | this,
32 | getMainComponentName(),
33 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
34 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
35 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
36 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
37 | );
38 | }
39 |
40 | @Override
41 | public void onStart(){
42 | super.onStart();
43 | RNBranchModule.initSession(getIntent().getData(), this);
44 | }
45 |
46 | @Override
47 | public void onNewIntent(Intent intent) {
48 | super.onNewIntent(intent);
49 | RNBranchModule.onNewIntent(intent);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/build.gradle:
--------------------------------------------------------------------------------
1 | import org.apache.tools.ant.taskdefs.condition.Os
2 |
3 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
4 |
5 | buildscript {
6 | ext {
7 | buildToolsVersion = "31.0.0"
8 | minSdkVersion = 21
9 | compileSdkVersion = 31
10 | targetSdkVersion = 31
11 |
12 | if (System.properties['os.arch'] == "aarch64") {
13 | // For M1 Users we need to use the NDK 24 which added support for aarch64
14 | ndkVersion = "24.0.8215888"
15 | } else {
16 | // Otherwise we default to the side-by-side NDK version from AGP.
17 | ndkVersion = "21.4.7075529"
18 | }
19 | }
20 | repositories {
21 | google()
22 | mavenCentral()
23 | }
24 | dependencies {
25 | classpath("com.android.tools.build:gradle:7.1.1")
26 | classpath("com.facebook.react:react-native-gradle-plugin")
27 | classpath("de.undercouch:gradle-download-task:5.0.1")
28 | // NOTE: Do not place your application dependencies here; they belong
29 | // in the individual module build.gradle files
30 | }
31 | }
32 |
33 | allprojects {
34 | repositories {
35 | maven {
36 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
37 | url("$rootDir/../node_modules/react-native/android")
38 | }
39 | maven {
40 | // Android JSC is installed from npm
41 | url("$rootDir/../node_modules/jsc-android/dist")
42 | }
43 | mavenCentral {
44 | // We don't want to fetch react-native from Maven Central as there are
45 | // older versions over there.
46 | content {
47 | excludeGroup "com.facebook.react"
48 | }
49 | }
50 | google()
51 | maven { url 'https://www.jitpack.io' }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-branch",
3 | "version": "6.9.0",
4 | "description": "Branch Metrics React Native SDK",
5 | "main": "src/index.js",
6 | "types": "src/index.d.ts",
7 | "files": [
8 | "android",
9 | "branch.example.json",
10 | "ios",
11 | "!**/*-dev.podspec",
12 | "react-native-branch.podspec",
13 | "src"
14 | ],
15 | "scripts": {
16 | "lint": "eslint src test",
17 | "test": "jest --coverage"
18 | },
19 | "keywords": [
20 | "react-native",
21 | "react-component",
22 | "ios",
23 | "android",
24 | "branch",
25 | "metrics",
26 | "deeplink",
27 | "deep",
28 | "link",
29 | "attribution"
30 | ],
31 | "authors": [
32 | "Zack Story (https://github.com/rt2zz)",
33 | "Kevin Stumpf (https://github.com/kevinstumpf)",
34 | "Jimmy Dee (https://github.com/jdee)",
35 | "Ernest Cho (https://github.com/echo-branch)",
36 | "Benas Klastaitis (https://github.com/bklastaitis-branch)",
37 | "Gabriel De Luna (https://github.com/gdeluna-branch)"
38 | ],
39 | "license": "MIT",
40 | "repository": {
41 | "type": "git",
42 | "url": "git+https://github.com/BranchMetrics/react-native-branch-deep-linking-attribution.git"
43 | },
44 | "bugs": {
45 | "url": "https://github.com/BranchMetrics/react-native-branch-deep-linking-attribution/issues",
46 | "email": "support@branch.io"
47 | },
48 | "homepage": "https://help.branch.io/developers-hub/docs/react-native",
49 | "peerDependencies": {
50 | "react-native": ">= 0.60"
51 | },
52 | "devDependencies": {
53 | "@babel/core": "^7.20.0",
54 | "@babel/preset-env": "^7.20.0",
55 | "@babel/runtime": "^7.20.0",
56 | "@react-native-community/eslint-config": "^3.0.0",
57 | "babel-jest": "^29.2.1",
58 | "eslint": "^8.19.0",
59 | "eslint-config-rackt": "^1.1.1",
60 | "jest": "^29.2.1",
61 | "react": "18.2.0",
62 | "react-native": "0.71.4"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbed/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 |
6 | @implementation AppDelegate
7 |
8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
9 | {
10 | self.moduleName = @"branchreactnativetestbed";
11 | // You can add your custom initial props in the dictionary below.
12 | // They will be passed down to the ViewController used by React Native.
13 | self.initialProps = @{};
14 |
15 | [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
16 |
17 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
18 | }
19 |
20 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
21 | {
22 | #if DEBUG
23 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
24 | #else
25 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
26 | #endif
27 | }
28 |
29 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
30 | ///
31 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
32 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
33 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
34 | - (BOOL)concurrentRootEnabled
35 | {
36 | return true;
37 | }
38 |
39 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
40 | [RNBranch application:app openURL:url options:options];
41 | return YES;
42 | }
43 |
44 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler {
45 | [RNBranch continueUserActivity:userActivity];
46 | return YES;
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/native-tests/android/app/src/test/java/io/branch/nativetests/AgingHashUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.branch.nativetests;
2 |
3 | import org.junit.Test;
4 |
5 | import io.branch.rnbranch.AgingHash;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | /**
10 | * Created by jdee on 4/18/17.
11 | */
12 |
13 | public class AgingHashUnitTest {
14 | @Test
15 | public void testTtlInitialization() {
16 | AgingHash hash = new AgingHash<>(3600000);
17 |
18 | // getTtlMillis() returns the constructor argument.
19 | assertEquals(3600000, hash.getTtlMillis());
20 | }
21 |
22 | @Test
23 | public void testGetReturnsNullWhenNotFound() {
24 | AgingHash hash = new AgingHash<>(3600000);
25 |
26 | // get() returns null when the key is not present.
27 | assertNull(hash.get("key"));
28 | }
29 |
30 | @Test
31 | public void testPutAndGet() {
32 | AgingHash hash = new AgingHash<>(3600000);
33 | hash.put("key", "value");
34 |
35 | // get() returns a value if the key is present and has not expired.
36 | assertEquals(hash.get("key"), "value");
37 | }
38 |
39 | @Test
40 | public void testRemove() {
41 | AgingHash hash = new AgingHash<>(3600000);
42 | hash.put("key", "value");
43 | hash.remove("key");
44 |
45 | // get() returns null after remove() is called with the same key.
46 | assertNull(hash.get("key"));
47 | }
48 |
49 | @Test
50 | public void testExpiration() {
51 | AgingHash hash = new AgingHash<>(1);
52 | hash.put("key", "value");
53 |
54 | try {
55 | Thread.sleep(10);
56 | } catch(Exception e) {
57 | fail("Failed to sleep for 10 ms: " + e.getMessage());
58 | }
59 |
60 | // Deletes expired keys on insertion
61 | hash.put("newKey", "newValue");
62 | assertNull(hash.get("key"));
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Version of flipper SDK to use with React Native
28 | FLIPPER_VERSION=0.125.0
29 |
30 | # Use this property to specify which architecture you want to build.
31 | # You can also override it from the CLI using
32 | # ./gradlew -PreactNativeArchitectures=x86_64
33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
34 |
35 | # Use this property to enable support to the new architecture.
36 | # This will allow you to use TurboModules and the Fabric render in
37 | # your application. You should enable this flag either if you want
38 | # to write custom TurboModules/Fabric components OR use libraries that
39 | # are providing them.
40 | newArchEnabled=false
41 |
42 | # Use this property to enable or disable the Hermes JS engine.
43 | # If set to false, you will be using JSC instead.
44 | hermesEnabled=true
45 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/version-3.md:
--------------------------------------------------------------------------------
1 | # react-native-branch version 3.0
2 |
3 | This version is maintained to support versions of react-native < 0.60. If you
4 | are using react-native >= 0.60, please update to version 4.0 of this SDK.
5 |
6 | ## Installation
7 |
8 | 1. `yarn add react-native-branch`
9 | 2. (Optional) Add a branch.json file to the root of your app project. See https://rnbranch.app.link/branch-json.
10 | 3. `react-native link react-native-branch`
11 | 4. Install the native Branch SDK using [CocoaPods](./cocoapods.md) or [Carthage](./carthage.md).
12 | 5. Follow the [setup instructions](../README.md#setup).
13 |
14 | ## iOS imports
15 |
16 | Use the following to import the react-native-branch SDK depending on your
17 | configuration:
18 |
19 | Objective-C (static library, including Swift bridging header):
20 | ```Obj-C
21 | #import
22 | ```
23 |
24 | Objective-C (framework):
25 | ```Obj-C
26 | @import react_native_branch;
27 | ```
28 |
29 | Swift (framework):
30 | ```Swift
31 | import react_native_branch
32 | ```
33 |
34 | Version 4.0 provides one import for each language, independent of other
35 | configuration and settings.
36 |
37 |
38 | ## Gradle dependency
39 |
40 | If you use `react-native link`, no further change is necessary to your `app/build.gradle`.
41 |
42 | In a native app, import the `react-native-branch` project like this:
43 |
44 | ```gradle
45 | implementation project(':react-native-branch')
46 | ```
47 |
48 | If you're using an older version of Gradle, you may need `compile` rather than
49 | `implementation`. If you are already using the native Branch SDK in your app,
50 | it will now be imported from Maven via `react-native-branch` as a dependency.
51 | Remove any reference to `io.branch.sdk.android:library` from your dependencies
52 | to avoid conflicts.
53 |
54 | Also add the project to your `settings.gradle`:
55 |
56 | ```gradle
57 | include ':react-native-branch'
58 | project(':react-native-branch').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-branch/android')
59 | ```
60 |
61 | The location of your `node_modules` folder may vary.
62 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Version of flipper SDK to use with React Native
28 | FLIPPER_VERSION=0.125.0
29 |
30 | # Use this property to specify which architecture you want to build.
31 | # You can also override it from the CLI using
32 | # ./gradlew -PreactNativeArchitectures=x86_64
33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
34 |
35 | # Use this property to enable support to the new architecture.
36 | # This will allow you to use TurboModules and the Fabric render in
37 | # your application. You should enable this flag either if you want
38 | # to write custom TurboModules/Fabric components OR use libraries that
39 | # are providing them.
40 | newArchEnabled=false
41 |
42 | MYAPP_RELEASE_STORE_FILE=qentelli.jks
43 | MYAPP_RELEASE_KEY_ALIAS=qentelli
44 | MYAPP_RELEASE_STORE_PASSWORD=123456
45 | MYAPP_RELEASE_KEY_PASSWORD=123456
46 |
--------------------------------------------------------------------------------
/test/RNBranchModule.test.js:
--------------------------------------------------------------------------------
1 | import { Platform, NativeModules } from 'react-native';
2 |
3 | describe('RNBranch module', () => {
4 | let originalPlatform;
5 | let originalRNBranch;
6 |
7 | beforeEach(() => {
8 | jest.resetModules();
9 | originalPlatform = Platform.OS;
10 | originalRNBranch = NativeModules.RNBranch;
11 | });
12 |
13 | afterEach(() => {
14 | Platform.OS = originalPlatform;
15 | NativeModules.RNBranch = originalRNBranch;
16 | jest.restoreAllMocks();
17 | });
18 |
19 | describe('Platform-specific tests', () => {
20 | it('should use NativeModules.RNBranch for iOS', () => {
21 | Platform.OS = 'ios';
22 | NativeModules.RNBranch = { mockInit: jest.fn() };
23 |
24 | const RNBranch = require('../src/RNBranch').default;
25 | expect(RNBranch).not.toBeNull();
26 | expect(RNBranch).toBe(NativeModules.RNBranch);
27 | });
28 |
29 | it('should use NativeModules.RNBranch for Android', () => {
30 | Platform.OS = 'android';
31 | NativeModules.RNBranch = { mockInit: jest.fn() };
32 |
33 | const RNBranch = require('../src/RNBranch').default;
34 | expect(RNBranch).not.toBeNull();
35 | expect(RNBranch).toBe(NativeModules.RNBranch);
36 | });
37 |
38 | it('should throw an error for unsupported platforms', () => {
39 | Platform.OS = 'unsupportedPlatform';
40 |
41 | expect(() => {
42 | require('../src/RNBranch');
43 | }).toThrow('Unsupported platform');
44 | });
45 | });
46 |
47 | describe('Null tests', () => {
48 | it('should be null when NativeModules.RNBranch is null for iOS', () => {
49 | Platform.OS = 'ios';
50 | NativeModules.RNBranch = null;
51 |
52 | const RNBranch = require('../src/RNBranch').default;
53 | expect(RNBranch).toBeNull();
54 | });
55 |
56 | it('should be null when NativeModules.RNBranch is null for Android', () => {
57 | Platform.OS = 'android';
58 | NativeModules.RNBranch = null;
59 |
60 | const RNBranch = require('../src/RNBranch').default;
61 | expect(RNBranch).toBeNull();
62 | });
63 | });
64 | });
65 |
66 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/java/com/branch_sdk_react_native_app/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java:
--------------------------------------------------------------------------------
1 | package io.branch.saas.sdk.testbed.newarchitecture.modules;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.soloader.SoLoader;
8 | import java.util.List;
9 |
10 | /**
11 | * Class responsible to load the TurboModules. This class has native methods and needs a
12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
13 | * folder for you).
14 | *
15 | * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
16 | * `newArchEnabled` property). Is ignored otherwise.
17 | */
18 | public class MainApplicationTurboModuleManagerDelegate
19 | extends ReactPackageTurboModuleManagerDelegate {
20 |
21 | private static volatile boolean sIsSoLibraryLoaded;
22 |
23 | protected MainApplicationTurboModuleManagerDelegate(
24 | ReactApplicationContext reactApplicationContext, List packages) {
25 | super(reactApplicationContext, packages);
26 | }
27 |
28 | protected native HybridData initHybrid();
29 |
30 | native boolean canCreateTurboModule(String moduleName);
31 |
32 | public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
33 | protected MainApplicationTurboModuleManagerDelegate build(
34 | ReactApplicationContext context, List packages) {
35 | return new MainApplicationTurboModuleManagerDelegate(context, packages);
36 | }
37 | }
38 |
39 | @Override
40 | protected synchronized void maybeLoadOtherSoLibraries() {
41 | if (!sIsSoLibraryLoaded) {
42 | // If you change the name of your application .so file in the Android.mk file,
43 | // make sure you update the name here as well.
44 | SoLoader.loadLibrary("branch_sdk_react_native_app_appmodules");
45 | sIsSoLibraryLoaded = true;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/src/common/AppConfig.ts:
--------------------------------------------------------------------------------
1 | import { CreateContent } from './../helper/BranchHelper';
2 | import branch from 'react-native-branch';
3 | const emptyData = {
4 | key1: 'value1',
5 | };
6 | function isEmpty(obj: object) {
7 | return Object.keys(obj).length === 0;
8 | }
9 | export class AppConfig {
10 | static instance: AppConfig;
11 | branchUniverSalObject: {} | undefined;
12 |
13 | metaData = {};
14 |
15 | private constructor() {
16 | console.log('constructor called!');
17 | }
18 |
19 | public static getInstance(): AppConfig {
20 | if (!AppConfig.instance) {
21 | AppConfig.instance = new AppConfig();
22 | }
23 | return AppConfig.instance;
24 | }
25 |
26 | public async createBranchObject(props: CreateContent, metaData: any) {
27 | let customData = isEmpty(metaData) ? emptyData : metaData;
28 | this.branchUniverSalObject = await branch.createBranchUniversalObject(props.contentIdentifier, {
29 | title: props.contentTitle,
30 | contentDescription: props.contentDescription,
31 | contentImageUrl: props.imageURL,
32 | contentMetadata: {
33 | customMetadata: customData,
34 | },
35 | });
36 | return this.branchUniverSalObject;
37 | }
38 | public async createBranchObjectWithLocalIndex(props: CreateContent, metaData: any) {
39 | let customData = isEmpty(metaData) ? emptyData : metaData;
40 | this.branchUniverSalObject = await branch.createBranchUniversalObject(props.contentIdentifier, {
41 | title: props.contentTitle,
42 | locallyIndex: true,
43 | contentDescription: props.contentDescription,
44 | contentMetadata: {
45 | customMetadata: customData,
46 | },
47 | });
48 | return this.branchUniverSalObject;
49 | }
50 | public addMetaDataObject(metaData: any) {
51 | this.metaData = metaData;
52 | }
53 | public getMetaData(): object {
54 | return this.metaData;
55 | }
56 | public clearMetaData() {
57 | this.metaData = {};
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/src/components/TrackContent/TrackContentTab.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { NativeModules, StyleSheet } from 'react-native';
4 | import { TabBar, TabView } from 'react-native-tab-view';
5 |
6 | import TrackContentCommerce from './TrackContentCommerce';
7 | import TrackContentContentEvent from './TrackContentContentEvent';
8 | import TrackContentCustomEvent from './TrackContentCustomEvent';
9 | import TrackContentLifeCycle from './TrackContentLifeCycle';
10 | import { resources } from '../constant/colors';
11 | import { useRoute } from '@react-navigation/native';
12 |
13 | const { ReadLogs } = NativeModules;
14 | const styles = StyleSheet.create({
15 | tabBar: { backgroundColor: resources.color.purple_700 },
16 | label: { fontSize: 10 },
17 | indicator: { backgroundColor: '#ffffff' },
18 | });
19 | const renderTabBar = (props: any) => ;
20 |
21 | export default function TrackContentTab({ navigation }) {
22 | const routeMain = useRoute();
23 | const renderScene = ({ route }: any) => {
24 | switch (route.key) {
25 | case 'Commerce':
26 | return ;
27 | case 'Content':
28 | return ;
29 | case 'Lifecycle':
30 | return ;
31 | case 'Custom':
32 | return ;
33 | default:
34 | return null;
35 | }
36 | };
37 | const [index, setIndex] = React.useState(0);
38 | const [routes] = React.useState([
39 | { key: 'Commerce', title: 'Commerce' },
40 | { key: 'Content', title: 'Content' },
41 | { key: 'Lifecycle', title: 'Lifecycle' },
42 | { key: 'Custom', title: 'Custom' },
43 | ]);
44 |
45 | return ;
46 | }
47 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yml:
--------------------------------------------------------------------------------
1 | ---
2 | assignees: []
3 | body:
4 | -
5 | attributes:
6 | description: "What is the problem? A clear and concise description of what the bug is."
7 | label: "Describe the bug"
8 | placeholder: "Tell us what you see!"
9 | id: description
10 | type: textarea
11 | validations:
12 | required: true
13 | -
14 | attributes:
15 | description: "Please provide as much step-by-step detail as possible including logs, stack traces, and uncaught exceptions."
16 | label: "Steps to reproduce"
17 | value: |
18 | 1.
19 | 2.
20 | 3.
21 | id: steps
22 | type: textarea
23 | validations:
24 | required: true
25 | -
26 | attributes:
27 | description: "What did you expect to happen?"
28 | label: "Expected behavior"
29 | id: expected
30 | type: textarea
31 | validations:
32 | required: true
33 | -
34 | attributes:
35 | description: "What version of sdk are you seeing this issue on?"
36 | label: "SDK Version"
37 | placeholder: "5.5.0"
38 | id: sdk-version
39 | type: input
40 | validations:
41 | required: true
42 | -
43 | attributes:
44 | description: "What devices or emulators are you seeing this bug on?"
45 | label: Make and Model
46 | placeholder: "iPhone 13 / Samsung S21"
47 | id: device
48 | type: input
49 | validations:
50 | required: true
51 | -
52 | attributes:
53 | description: "What versions of the device OS?"
54 | label: OS
55 | placeholder: "iOS 15.6.1 / Android 12"
56 | id: os
57 | type: input
58 | validations:
59 | required: true
60 | -
61 | attributes:
62 | description: "Anything else that might be relevant for troubleshooting this bug. Any screenshots or videos that show the issue are very helpful."
63 | label: "Additional Information/Context"
64 | id: context
65 | type: textarea
66 | validations:
67 | required: false
68 |
69 | description: "Found a bug in the Branch React Native SDK? File it here."
70 | labels:
71 | - bug
72 | - needs-triage
73 | name: "🐞 Bug report"
74 | title: "(short issue description)"
75 |
--------------------------------------------------------------------------------
/ios/RNBranchAgingDictionary.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchAgingDictionary.m
3 | // RNBranch
4 | //
5 | // Created by Jimmy Dee on 3/8/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import "RNBranchAgingDictionary.h"
10 | #import "RNBranchAgingItem.h"
11 |
12 | @interface RNBranchAgingDictionary()
13 | @property (nonatomic) NSMutableDictionary *dictionary;
14 | @end
15 |
16 | @implementation RNBranchAgingDictionary
17 |
18 | #pragma mark - Object lifecycle
19 |
20 | + (instancetype)dictionaryWithTtl:(NSTimeInterval)ttl
21 | {
22 | return [[self alloc] initWithTtl:ttl];
23 | }
24 |
25 | - (instancetype)initWithTtl:(NSTimeInterval)ttl
26 | {
27 | self = [super init];
28 | if (self) {
29 | _ttl = ttl;
30 | _dictionary = [NSMutableDictionary dictionary];
31 | }
32 | return self;
33 | }
34 |
35 | - (instancetype)init
36 | {
37 | @throw nil;
38 | }
39 |
40 | #pragma mark - Methods from NSMutableDictionary
41 |
42 | - (void)setObject:(id)anObject forKey:(id)aKey
43 | {
44 | [self insertItem:anObject forKey:aKey];
45 | }
46 |
47 | - (void)setObject:(id)obj forKeyedSubscript:(id)key
48 | {
49 | [self insertItem:obj forKey:key];
50 | }
51 |
52 | - (id)objectForKey:(id)aKey
53 | {
54 | return [self itemForKey:aKey];
55 | }
56 |
57 | - (id)objectForKeyedSubscript:(id)key
58 | {
59 | return [self itemForKey:key];
60 | }
61 |
62 | - (void)removeObjectForKey:(id)key
63 | {
64 | [self.dictionary removeObjectForKey:key];
65 | }
66 |
67 | #pragma mark - Internal utilities
68 |
69 | - (void)insertItem:(id)obj forKey:(id)key
70 | {
71 | [self ageItems];
72 |
73 | self.dictionary[key] = [[RNBranchAgingItem alloc] initWithItem:obj];
74 | }
75 |
76 | - (id)itemForKey:(id)key
77 | {
78 | RNBranchAgingItem *item = self.dictionary[key];
79 | return item.item;
80 | }
81 |
82 | - (void)ageItems
83 | {
84 | NSTimeInterval now = [NSDate date].timeIntervalSince1970;
85 |
86 | NSArray *keys = self.dictionary.allKeys; // copy of allKeys
87 |
88 | for (NSString *key in keys) {
89 | RNBranchAgingItem *item = self.dictionary[key];
90 | if ((now - item.accessTime) >= self.ttl) {
91 | [self.dictionary removeObjectForKey:key];
92 | }
93 | }
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/jni/MainComponentsRegistry.cpp:
--------------------------------------------------------------------------------
1 | #include "MainComponentsRegistry.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace facebook {
9 | namespace react {
10 |
11 | MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
12 |
13 | std::shared_ptr
14 | MainComponentsRegistry::sharedProviderRegistry() {
15 | auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
16 |
17 | // Custom Fabric Components go here. You can register custom
18 | // components coming from your App or from 3rd party libraries here.
19 | //
20 | // providerRegistry->add(concreteComponentDescriptorProvider<
21 | // AocViewerComponentDescriptor>());
22 | return providerRegistry;
23 | }
24 |
25 | jni::local_ref
26 | MainComponentsRegistry::initHybrid(
27 | jni::alias_ref,
28 | ComponentFactory *delegate) {
29 | auto instance = makeCxxInstance(delegate);
30 |
31 | auto buildRegistryFunction =
32 | [](EventDispatcher::Weak const &eventDispatcher,
33 | ContextContainer::Shared const &contextContainer)
34 | -> ComponentDescriptorRegistry::Shared {
35 | auto registry = MainComponentsRegistry::sharedProviderRegistry()
36 | ->createComponentDescriptorRegistry(
37 | {eventDispatcher, contextContainer});
38 |
39 | auto mutableRegistry =
40 | std::const_pointer_cast(registry);
41 |
42 | mutableRegistry->setFallbackComponentDescriptor(
43 | std::make_shared(
44 | ComponentDescriptorParameters{
45 | eventDispatcher, contextContainer, nullptr}));
46 |
47 | return registry;
48 | };
49 |
50 | delegate->buildRegistryFunction = buildRegistryFunction;
51 | return instance;
52 | }
53 |
54 | void MainComponentsRegistry::registerNatives() {
55 | registerHybrid({
56 | makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
57 | });
58 | }
59 |
60 | } // namespace react
61 | } // namespace facebook
62 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbedTests/branchreactnativetestbedTests.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | #define TIMEOUT_SECONDS 600
8 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
9 |
10 | @interface branchreactnativetestbedTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation branchreactnativetestbedTests
15 |
16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
17 | {
18 | if (test(view)) {
19 | return YES;
20 | }
21 | for (UIView *subview in [view subviews]) {
22 | if ([self findSubviewInView:subview matching:test]) {
23 | return YES;
24 | }
25 | }
26 | return NO;
27 | }
28 |
29 | - (void)testRendersWelcomeScreen
30 | {
31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
33 | BOOL foundElement = NO;
34 |
35 | __block NSString *redboxError = nil;
36 | #ifdef DEBUG
37 | RCTSetLogFunction(
38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
39 | if (level >= RCTLogLevelError) {
40 | redboxError = message;
41 | }
42 | });
43 | #endif
44 |
45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
48 |
49 | foundElement = [self findSubviewInView:vc.view
50 | matching:^BOOL(UIView *view) {
51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
52 | return YES;
53 | }
54 | return NO;
55 | }];
56 | }
57 |
58 | #ifdef DEBUG
59 | RCTSetLogFunction(RCTDefaultLogFunction);
60 | #endif
61 |
62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/branch_sdk_react_native_appTests/branch_sdk_react_native_appTests.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | #define TIMEOUT_SECONDS 600
8 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
9 |
10 | @interface branch_sdk_react_native_appTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation branch_sdk_react_native_appTests
15 |
16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
17 | {
18 | if (test(view)) {
19 | return YES;
20 | }
21 | for (UIView *subview in [view subviews]) {
22 | if ([self findSubviewInView:subview matching:test]) {
23 | return YES;
24 | }
25 | }
26 | return NO;
27 | }
28 |
29 | - (void)testRendersWelcomeScreen
30 | {
31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
33 | BOOL foundElement = NO;
34 |
35 | __block NSString *redboxError = nil;
36 | #ifdef DEBUG
37 | RCTSetLogFunction(
38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
39 | if (level >= RCTLogLevelError) {
40 | redboxError = message;
41 | }
42 | });
43 | #endif
44 |
45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
48 |
49 | foundElement = [self findSubviewInView:vc.view
50 | matching:^BOOL(UIView *view) {
51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
52 | return YES;
53 | }
54 | return NO;
55 | }];
56 | }
57 |
58 | #ifdef DEBUG
59 | RCTSetLogFunction(RCTDefaultLogFunction);
60 | #endif
61 |
62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/android/app/src/main/java/com/branch_sdk_react_native_app/MainActivity.java:
--------------------------------------------------------------------------------
1 | package io.branch.saas.sdk.testbed;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.ReactRootView;
6 | import io.branch.rnbranch.*;
7 | import android.content.Intent;
8 | public class MainActivity extends ReactActivity {
9 |
10 | // Override onStart:
11 | @Override
12 | protected void onStart() {
13 | super.onStart();
14 | RNBranchModule.initSession(getIntent().getData(), this);
15 | }
16 |
17 | // Override onNewIntent:
18 | @Override
19 | public void onNewIntent(Intent intent) {
20 | super.onNewIntent(intent);
21 | RNBranchModule.onNewIntent(intent);
22 | }
23 | /**
24 | * Returns the name of the main component registered from JavaScript. This is used to schedule
25 | * rendering of the component.
26 | */
27 | @Override
28 | protected String getMainComponentName() {
29 | return "branch_sdk_react_native_app";
30 | }
31 |
32 | /**
33 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
34 | * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
35 | * (Paper).
36 | */
37 | @Override
38 | protected ReactActivityDelegate createReactActivityDelegate() {
39 | return new MainActivityDelegate(this, getMainComponentName());
40 | }
41 |
42 | public static class MainActivityDelegate extends ReactActivityDelegate {
43 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
44 | super(activity, mainComponentName);
45 | }
46 |
47 | @Override
48 | protected ReactRootView createRootView() {
49 | ReactRootView reactRootView = new ReactRootView(getContext());
50 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
51 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
52 | return reactRootView;
53 | }
54 |
55 | @Override
56 | protected boolean isConcurrentRootEnabled() {
57 | // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
58 | // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
59 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/native-tests/ios/NativeTestsTests/RNBranchAgingDictionaryTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNBranchAgingDictionaryTests.m
3 | // NativeTests
4 | //
5 | // Created by Jimmy Dee on 4/13/17.
6 | // Copyright © 2017 Branch Metrics. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | @interface RNBranchAgingDictionaryTests : XCTestCase
14 | @end
15 |
16 | @implementation RNBranchAgingDictionaryTests
17 |
18 | - (void)testTtlInitialization {
19 | RNBranchAgingDictionary *dictionary = [RNBranchAgingDictionary dictionaryWithTtl:3600.0];
20 |
21 | // ttl property returns the constructor argument.
22 | XCTAssertEqual(3600.0, dictionary.ttl);
23 | }
24 |
25 | - (void)testValueIsNullWhenKeyNotFound
26 | {
27 | RNBranchAgingDictionary *dictionary = [RNBranchAgingDictionary dictionaryWithTtl:3600.0];
28 |
29 | // key access returns nil when the key is not present.
30 | XCTAssertNil(dictionary[@"key"]);
31 | XCTAssertNil([dictionary objectForKey:@"key"]);
32 | }
33 |
34 | - (void)testInsertionAndRetrieval
35 | {
36 | RNBranchAgingDictionary *dictionary = [RNBranchAgingDictionary dictionaryWithTtl:3600.0];
37 |
38 | NSString *value1 = @"value1", *value2 = @"value2";
39 | dictionary[@"key1"] = value1;
40 | [dictionary setObject:value2 forKey:@"key2"];
41 |
42 | // access returns a value if the key is present and has not expired.
43 | XCTAssertEqual(value1, dictionary[@"key1"]);
44 | XCTAssertEqual(value1, [dictionary objectForKey:@"key1"]);
45 |
46 | XCTAssertEqual(value2, dictionary[@"key2"]);
47 | XCTAssertEqual(value2, [dictionary objectForKey:@"key2"]);
48 | }
49 |
50 | - (void)testRemoval
51 | {
52 | RNBranchAgingDictionary *dictionary = [RNBranchAgingDictionary dictionaryWithTtl:3600.0];
53 |
54 | dictionary[@"key"] = @"value";
55 | [dictionary removeObjectForKey:@"key"];
56 |
57 | // access returns nil after a key is removed.
58 | XCTAssertNil(dictionary[@"key"]);
59 | }
60 |
61 | - (void)testExpiration
62 | {
63 | RNBranchAgingDictionary *dictionary = [RNBranchAgingDictionary dictionaryWithTtl:1e-3]; // 1 ms TTL
64 |
65 | dictionary[@"key1"] = @"value1";
66 |
67 | usleep(10000); // sleep for 10 ms
68 |
69 | dictionary[@"key2"] = @"value2";
70 |
71 | // Deletes expired keys on insertion
72 | XCTAssertNil(dictionary[@"key1"]);
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/Podfile:
--------------------------------------------------------------------------------
1 | require_relative '../node_modules/react-native/scripts/react_native_pods'
2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
3 |
4 | platform :ios, min_ios_version_supported
5 | prepare_react_native_project!
6 |
7 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
8 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
9 | #
10 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
11 | # ```js
12 | # module.exports = {
13 | # dependencies: {
14 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
15 | # ```
16 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
17 |
18 | linkage = ENV['USE_FRAMEWORKS']
19 | if linkage != nil
20 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
21 | use_frameworks! :linkage => linkage.to_sym
22 | end
23 |
24 | target 'branchreactnativetestbed' do
25 | config = use_native_modules!
26 |
27 | # Flags change depending on the env values.
28 | flags = get_default_flags()
29 |
30 | use_react_native!(
31 | :path => config[:reactNativePath],
32 | # Hermes is now enabled by default. Disable by setting this flag to false.
33 | # Upcoming versions of React Native may rely on get_default_flags(), but
34 | # we make it explicit here to aid in the React Native upgrade process.
35 | :hermes_enabled => flags[:hermes_enabled],
36 | :fabric_enabled => flags[:fabric_enabled],
37 | # Enables Flipper.
38 | #
39 | # Note that if you have use_frameworks! enabled, Flipper will not work and
40 | # you should disable the next line.
41 | :flipper_configuration => flipper_config,
42 | # An absolute path to your application root.
43 | :app_path => "#{Pod::Config.instance.installation_root}/.."
44 | )
45 |
46 | target 'branchreactnativetestbedTests' do
47 | inherit! :complete
48 | # Pods for testing
49 | end
50 |
51 | post_install do |installer|
52 | react_native_post_install(
53 | installer,
54 | # Set `mac_catalyst_enabled` to `true` in order to apply patches
55 | # necessary for Mac Catalyst builds
56 | :mac_catalyst_enabled => false
57 | )
58 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/app/src/main/java/com/branchreactnativetestbed/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.branchreactnativetestbed;
2 |
3 | import android.app.Application;
4 | import com.facebook.react.PackageList;
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
9 | import com.facebook.react.defaults.DefaultReactNativeHost;
10 | import com.facebook.soloader.SoLoader;
11 | import java.util.List;
12 | import io.branch.rnbranch.RNBranchModule;
13 |
14 |
15 | public class MainApplication extends Application implements ReactApplication {
16 |
17 | private final ReactNativeHost mReactNativeHost =
18 | new DefaultReactNativeHost(this) {
19 | @Override
20 | public boolean getUseDeveloperSupport() {
21 | return BuildConfig.DEBUG;
22 | }
23 |
24 | @Override
25 | protected List getPackages() {
26 | @SuppressWarnings("UnnecessaryLocalVariable")
27 | List packages = new PackageList(this).getPackages();
28 | // Packages that cannot be autolinked yet can be added manually here, for example:
29 | // packages.add(new MyReactNativePackage());
30 | return packages;
31 | }
32 |
33 | @Override
34 | protected String getJSMainModuleName() {
35 | return "index";
36 | }
37 |
38 | @Override
39 | protected boolean isNewArchEnabled() {
40 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
41 | }
42 |
43 | @Override
44 | protected Boolean isHermesEnabled() {
45 | return BuildConfig.IS_HERMES_ENABLED;
46 | }
47 | };
48 |
49 | @Override
50 | public ReactNativeHost getReactNativeHost() {
51 | return mReactNativeHost;
52 | }
53 |
54 | @Override
55 | public void onCreate() {
56 | super.onCreate();
57 |
58 | SoLoader.init(this, /* native exopackage */ false);
59 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
60 | // If you opted-in for the New Architecture, we load the native entry point for this app.
61 | DefaultNewArchitectureEntryPoint.load();
62 | }
63 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
64 |
65 | RNBranchModule.enableLogging();
66 | RNBranchModule.getAutoInstance(this);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ios/BranchEvent+RNBranch.m:
--------------------------------------------------------------------------------
1 | //
2 | // BranchEvent+RNBranch.m
3 | // Branch-SDK
4 | //
5 | // Created by Jimmy Dee on 11/28/17.
6 | //
7 |
8 | #import "BranchEvent+RNBranch.h"
9 | #import "NSObject+RNBranch.h"
10 | #import "RNBranchProperty.h"
11 |
12 | @implementation BranchEvent(RNBranch)
13 |
14 | + (NSDictionary *)supportedProperties
15 | {
16 | static NSDictionary *_eventProperties;
17 | static dispatch_once_t once = 0;
18 | dispatch_once(&once, ^{
19 | _eventProperties =
20 | @{
21 | @"transactionID": [RNBranchProperty propertyWithSetterSelector:@selector(setTransactionID:) type:NSString.class],
22 | @"currency": [RNBranchProperty propertyWithSetterSelector:@selector(setCurrency:) type:NSString.class],
23 | @"revenue": [RNBranchProperty propertyWithSetterSelector:@selector(setRevenueWithString:) type:NSString.class],
24 | @"shipping": [RNBranchProperty propertyWithSetterSelector:@selector(setShippingWithString:) type:NSString.class],
25 | @"tax": [RNBranchProperty propertyWithSetterSelector:@selector(setTaxWithString:) type:NSString.class],
26 | @"coupon": [RNBranchProperty propertyWithSetterSelector:@selector(setCoupon:) type:NSString.class],
27 | @"affiliation": [RNBranchProperty propertyWithSetterSelector:@selector(setAffiliation:) type:NSString.class],
28 | @"description": [RNBranchProperty propertyWithSetterSelector:@selector(setEventDescription:) type:NSString.class],
29 | @"searchQuery": [RNBranchProperty propertyWithSetterSelector:@selector(setSearchQuery:) type:NSString.class],
30 | @"customData": [RNBranchProperty propertyWithSetterSelector:@selector(setCustomData:) type:NSDictionary.class],
31 | @"alias": [RNBranchProperty propertyWithSetterSelector:@selector(setAlias:) type:NSString.class]
32 | };
33 | });
34 |
35 | return _eventProperties;
36 | }
37 |
38 | - (instancetype)initWithName:(NSString *)eventName map:(NSDictionary *)map
39 | {
40 | self = [self initWithName:eventName];
41 | if (self) {
42 | [self setSupportedPropertiesWithMap:map];
43 | }
44 | return self;
45 | }
46 |
47 | - (void)setRevenueWithString:(NSString *)revenue
48 | {
49 | self.revenue = [NSDecimalNumber decimalNumberWithString:revenue];
50 | }
51 |
52 | - (void)setShippingWithString:(NSString *)shipping
53 | {
54 | self.shipping = [NSDecimalNumber decimalNumberWithString:shipping];
55 | }
56 |
57 | - (void)setTaxWithString:(NSString *)tax
58 | {
59 | self.tax = [NSDecimalNumber decimalNumberWithString:tax];
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/ios/branch_sdk_react_native_app/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | branch_sdk_react_native_app
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleTypeRole
27 | Editor
28 | CFBundleURLName
29 | io.Branch.Timber
30 | CFBundleURLSchemes
31 |
32 | Timber
33 |
34 |
35 |
36 | CFBundleVersion
37 | 1
38 | LSRequiresIPhoneOS
39 |
40 | NSAppTransportSecurity
41 |
42 | NSExceptionDomains
43 |
44 | localhost
45 |
46 | NSExceptionAllowsInsecureHTTPLoads
47 |
48 |
49 |
50 |
51 | NSLocationWhenInUseUsageDescription
52 |
53 | UIBackgroundModes
54 |
55 | remote-notification
56 |
57 | UILaunchStoryboardName
58 | LaunchScreen
59 | UIRequiredDeviceCapabilities
60 |
61 | armv7
62 |
63 | UISupportedInterfaceOrientations
64 |
65 | UIInterfaceOrientationPortrait
66 | UIInterfaceOrientationLandscapeLeft
67 | UIInterfaceOrientationLandscapeRight
68 |
69 | UIViewControllerBasedStatusBarAppearance
70 |
71 | branch_key
72 |
73 | live
74 | key_live_nf8w3l1WBpzWdlC00KsLNdmbuEccK6Yr
75 | test
76 | key_test_om2EWe1WBeBYmpz9Z1mdpopouDmoN72T
77 |
78 | branch_universal_link_domains
79 |
80 | timber.app.link
81 | timber-alternate.app.link
82 | timber.test-app.link
83 | timber-alternate.test.app.link
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/native-tests/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/branch-sdk-automation-testbed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "branch_sdk_react_native_app",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "start": "react-native start",
9 | "test": "jest",
10 | "link": "react-native link",
11 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
12 | "android-build": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && cd android && ./gradlew assembleDebug",
13 | "android-release": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/build/intermediates/res/merged/release/ && rm -rf android/app/src/main/res/drawable-* && rm -rf android/app/src/main/res/raw/* && cd android && ./gradlew assembleRelease && cd .."
14 | },
15 | "dependencies": {
16 | "@react-native-community/push-notification-ios": "^1.10.1",
17 | "@react-navigation/native": "^6.0.11",
18 | "@react-navigation/native-stack": "^6.7.0",
19 | "@react-navigation/stack": "^6.3.0",
20 | "@types/react-native-push-notification": "^8.1.1",
21 | "react": "18.0.0",
22 | "react-native": "0.69.1",
23 | "react-native-branch": "6.4.0-alpha.0",
24 | "react-native-dropdown-picker": "^5.4.2",
25 | "react-native-json-tree": "^1.3.0",
26 | "react-native-keyboard-aware-scroll-view": "^0.9.5",
27 | "react-native-modal": "^13.0.1",
28 | "react-native-pager-view": "^5.4.25",
29 | "react-native-push-notification": "^8.1.1",
30 | "react-native-safe-area-context": "^4.3.1",
31 | "react-native-screens": "^3.15.0",
32 | "react-native-tab-view": "^3.1.1",
33 | "react-native-webview": "^11.23.0"
34 | },
35 | "devDependencies": {
36 | "@babel/core": "^7.12.9",
37 | "@babel/runtime": "^7.12.5",
38 | "@react-native-community/cli": "latest",
39 | "@react-native-community/eslint-config": "^2.0.0",
40 | "@tsconfig/react-native": "^2.0.0",
41 | "@types/jest": "^26.0.23",
42 | "@types/react-native": "^0.69.1",
43 | "@types/react-test-renderer": "^18.0.0",
44 | "@typescript-eslint/eslint-plugin": "^5.29.0",
45 | "@typescript-eslint/parser": "^5.29.0",
46 | "babel-jest": "^26.6.3",
47 | "eslint": "^7.32.0",
48 | "jest": "^26.6.3",
49 | "metro-react-native-babel-preset": "^0.70.3",
50 | "react-test-renderer": "18.0.0",
51 | "typescript": "^4.4.4"
52 | },
53 | "resolutions": {
54 | "@types/react": "^18"
55 | },
56 | "jest": {
57 | "preset": "react-native",
58 | "moduleFileExtensions": [
59 | "ts",
60 | "tsx",
61 | "js",
62 | "jsx",
63 | "json",
64 | "node"
65 | ]
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/ios/branchreactnativetestbed/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | branch_universal_link_domains
6 |
7 | bnctestbed.app.link
8 | bnctestbed-alternate.app.link
9 | bnctestbed.test.app.link
10 | bnctestbed-alternate.test.app.link
11 |
12 | CFBundleURLTypes
13 |
14 |
15 | CFBundleTypeRole
16 | Editor
17 | CFBundleURLSchemes
18 |
19 | branchtest
20 |
21 | CFBundleURLName
22 | org.reactjs.native.example.branchreactnativetestbed
23 |
24 |
25 | CFBundleDevelopmentRegion
26 | en
27 | CFBundleDisplayName
28 | branchreactnativetestbed
29 | CFBundleExecutable
30 | $(EXECUTABLE_NAME)
31 | CFBundleIdentifier
32 | $(PRODUCT_BUNDLE_IDENTIFIER)
33 | CFBundleInfoDictionaryVersion
34 | 6.0
35 | CFBundleName
36 | $(PRODUCT_NAME)
37 | CFBundlePackageType
38 | APPL
39 | CFBundleShortVersionString
40 | $(MARKETING_VERSION)
41 | CFBundleSignature
42 | ????
43 | CFBundleURLTypes
44 |
45 |
46 | CFBundleTypeRole
47 | Editor
48 | CFBundleURLSchemes
49 |
50 | branchtest
51 |
52 |
53 |
54 | CFBundleVersion
55 | $(CURRENT_PROJECT_VERSION)
56 | LSRequiresIPhoneOS
57 |
58 | NSAppTransportSecurity
59 |
60 | NSExceptionDomains
61 |
62 | localhost
63 |
64 | NSExceptionAllowsInsecureHTTPLoads
65 |
66 |
67 |
68 |
69 | NSLocationWhenInUseUsageDescription
70 |
71 | UILaunchStoryboardName
72 | LaunchScreen
73 | UIRequiredDeviceCapabilities
74 |
75 | armv7
76 |
77 | UISupportedInterfaceOrientations
78 |
79 | UIInterfaceOrientationPortrait
80 | UIInterfaceOrientationLandscapeLeft
81 | UIInterfaceOrientationLandscapeRight
82 |
83 | UIViewControllerBasedStatusBarAppearance
84 |
85 | branch_key
86 |
87 | live
88 | key_live_hcnegAumkH7Kv18M8AOHhfgiohpXq5tB
89 | test
90 | key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Reporting Issues and Asking Questions
2 |
3 | Before opening an issue, please search the [issue tracker](https://github.com/branchmetrics/react-native-branch/issues) to make sure your issue hasn’t already been reported.
4 |
5 | ### Help Us Help You
6 |
7 | Take some time to structure your code and question in a way that is easy to read to entice people to answer it. For example, we encourage you to use syntax highlighting, indentation, and split text in paragraphs.
8 |
9 | ## Development
10 |
11 | Visit the [issue tracker](https://github.com/branchmetrics/react-native-branch/issues) to find a list of open issues that need attention.
12 |
13 | To get started developing:
14 | 1. fork the repo
15 | 2. clone react-native-branch locally
16 | 3. `cd react-native-branch && npm i`
17 |
18 | Before submitting a PR, test the new functionality or bugfix in android & ios, and if possible write a unit test.
19 |
20 | ### Testing and Linting
21 |
22 | All contributions must pass `npm run lint` and `npm test` before being accepted.
23 |
24 | #### Native Unit Tests
25 |
26 | All contributions must also pass native unit testing. The native tests depend on the native React source
27 | from node_modules. To run the native unit tests:
28 |
29 | ```
30 | yarn
31 | bundle install
32 | bundle exec fastlane test_android
33 | bundle exec fastlane test_ios
34 | ```
35 |
36 | There is also a `runAllTests` script at the repository root for convenience, which also runs `npm run lint` and `npm test`.
37 | This script requires macOS because it runs the iOS tests.
38 |
39 | Notes on native unit tests and Fastlane:
40 |
41 | - CI uses Ruby 2.4.0. There is no specific Ruby requirement, but it's best to use a fairly current version.
42 | - The Android tests require the `ANDROID_HOME` environment variable to be properly set to point to the location of the
43 | Android SDK. If not set, the `test_android` lane will set it to `~/Library/Android/sdk`, which is the default location
44 | on a Mac. Either:
45 | ```
46 | export ANDROID_HOME=/path/to/android/sdk
47 | bundle exec fastlane test_android
48 | ```
49 | or
50 | ```
51 | ANDROID_HOME=/path/to/android/sdk bundle exec fastlane test_android
52 | ```
53 | - The iOS tests must be run on macOS with Xcode 8 installed.
54 | - You can also run the native unit tests in Android Studio or Xcode if you prefer, using the projects under native-tests. You must install the NPM dependencies for this repo first.
55 | - There is no need to run `pod install` or even install CocoaPods in order to run the unit tests.
56 | - If you don't have access to macOS and are not changing anything in the iOS codebase, there is no need to
57 | run the iOS unit tests. They will run in CI. If anything fails the error will be reported there.
58 |
59 | ### Docs
60 |
61 | Improvements to the documentation are always welcome. In the docs we abide by typographic rules, so instead of ' you should use ’. Same goes for “ ” and dashes (—) where appropriate. These rules only apply to the text, not to code blocks.
62 |
63 | ## Thanks
64 |
65 | Thank you for contributing!
66 |
--------------------------------------------------------------------------------
/branchreactnativetestbed/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------