├── .azurepipelines ├── build-shared-ios-1ES.yml ├── build-test-app-android.yml ├── pack-npm-artifacts-1ES.yml └── publish-maven-1ES.yml ├── .clang-format ├── .config └── CredScanSuppressions.json ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── problem_report.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── AppCenterReactNativeShared ├── .gitignore ├── .npmignore ├── LICENSE ├── Products │ ├── AppCenterReactNativeShared.podspec │ ├── AppCenterReactNativeShared │ │ └── LICENSE │ └── local.podspec ├── android │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── proguard-rules.pro │ ├── publish.gradle │ ├── settings.gradle │ ├── src │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── microsoft │ │ │ └── appcenter │ │ │ └── reactnative │ │ │ └── shared │ │ │ └── AppCenterReactNativeShared.java │ └── version.gradle ├── append-silicon.sh ├── ios │ ├── .gitignore │ ├── AppCenterReactNativeShared.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── AppCenterReactNativeShared.xcscheme │ ├── AppCenterReactNativeShared.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── AppCenterReactNativeShared │ │ ├── AppCenterReactNativeShared.h │ │ ├── AppCenterReactNativeShared.m │ │ ├── Global.xcconfig │ │ └── Support │ │ │ └── module.modulemap │ ├── Podfile │ ├── Podfile.lock │ ├── build-framework.sh │ ├── build-silicon.sh │ ├── build-xcframework.sh │ └── post-clone.sh ├── prepare-local-podspec.sh └── zip-framework.sh ├── CHANGELOG.md ├── LICENSE ├── README.md ├── SECURITY.md ├── TestApp ├── .bundle │ └── config ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── CMakeLists.txt │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ └── appcenter-config.json │ │ │ ├── cpp │ │ │ └── native-lib.cpp │ │ │ ├── java │ │ │ └── com │ │ │ │ └── testapp │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainApplication.kt │ │ │ │ ├── TestAppNativeModule.kt │ │ │ │ └── TestAppNativePackage.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── app │ ├── App.js │ ├── AttachmentsProvider.js │ ├── Constants.android.js │ ├── Constants.ios.js │ ├── SharedStyles.js │ ├── assets │ │ ├── add.png │ │ ├── analytics.png │ │ ├── crashes.png │ │ ├── dials.png │ │ ├── fuel.png │ │ └── remove.png │ └── screens │ │ ├── AnalyticsScreen.js │ │ ├── AppCenterScreen.js │ │ ├── CrashesScreen.js │ │ ├── PropertiesConfiguratorView.js │ │ └── TransmissionScreen.js ├── appcenter-post-clone.sh ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── AppCenter-Config.plist │ ├── Podfile │ ├── Podfile.lock │ ├── TestApp.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── TestApp.xcscheme │ ├── TestApp.xcworkspace │ │ └── contents.xcworkspacedata │ ├── TestApp │ │ ├── AppCenter-Config.plist │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ ├── TestAppNative.h │ │ ├── TestAppNative.m │ │ └── main.m │ ├── TestAppNative.h │ ├── TestAppNative.m │ └── TestAppTests │ │ ├── Info.plist │ │ └── TestAppTests.m ├── jest.config.js ├── metro.config.js ├── package.json ├── prepare-local-sdk-integration.sh ├── prepare-npm-sdk-integration.sh ├── put-azure-credentials.zh ├── react-native.config.js └── tsconfig.json ├── ThirdPartyNotices.txt ├── appcenter-analytics ├── .eslintrc ├── .gitignore ├── .npmignore ├── Analytics.d.ts ├── Analytics.js ├── LICENSE ├── README.md ├── __tests__ │ └── Analytics.js ├── android │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── appcenter │ │ └── reactnative │ │ └── analytics │ │ ├── AppCenterReactNativeAnalyticsModule.java │ │ ├── AppCenterReactNativeAnalyticsPackage.java │ │ └── ReactNativeUtils.java ├── appcenter-analytics.podspec ├── ios │ ├── AppCenterReactNativeAnalytics.xcodeproj │ │ └── project.pbxproj │ └── AppCenterReactNativeAnalytics │ │ ├── AppCenterReactNativeAnalytics.h │ │ └── AppCenterReactNativeAnalytics.m ├── jest │ └── setup.js ├── package.json ├── react-native.config.js ├── scripts │ └── postlink.js └── test │ └── AppCenterAnalyticsMock.js ├── appcenter-crashes ├── .eslintrc ├── .gitignore ├── .npmignore ├── Crashes.d.ts ├── Crashes.js ├── LICENSE ├── README.md ├── android │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── appcenter │ │ └── reactnative │ │ └── crashes │ │ ├── AppCenterReactNativeCrashesListener.java │ │ ├── AppCenterReactNativeCrashesModule.java │ │ ├── AppCenterReactNativeCrashesPackage.java │ │ ├── AppCenterReactNativeCrashesUtils.java │ │ └── RNUtils.java ├── appcenter-crashes.podspec ├── ios │ ├── AppCenterReactNativeCrashes.xcodeproj │ │ └── project.pbxproj │ └── AppCenterReactNativeCrashes │ │ ├── AppCenterReactNativeCrashes.h │ │ ├── AppCenterReactNativeCrashes.m │ │ ├── AppCenterReactNativeCrashesDelegate.h │ │ ├── AppCenterReactNativeCrashesDelegate.m │ │ ├── AppCenterReactNativeCrashesUtils.h │ │ └── AppCenterReactNativeCrashesUtils.m ├── package.json ├── react-native.config.js ├── scripts │ └── postlink.js └── test │ └── AppCenterCrashesMock.js ├── appcenter-link-scripts ├── .eslintrc ├── .gitignore ├── package.json └── src │ ├── android │ ├── AppCenterConfig.js │ └── index.js │ ├── index.js │ └── ios │ ├── AppCenterConfig.js │ ├── AppDelegate.js │ ├── PodFile.js │ └── index.js ├── appcenter ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── AppCenter.d.ts ├── AppCenter.js ├── LICENSE ├── README.md ├── android │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── appcenter │ │ └── reactnative │ │ └── appcenter │ │ ├── AppCenterReactNativeModule.java │ │ ├── AppCenterReactNativePackage.java │ │ └── ReactNativeUtils.java ├── appcenter-core.podspec ├── appcenter-log.js ├── ios │ ├── AppCenterReactNative.xcodeproj │ │ └── project.pbxproj │ └── AppCenterReactNative │ │ ├── AppCenterReactNative.h │ │ └── AppCenterReactNative.m ├── package.json ├── react-native.config.js ├── scripts │ └── postlink.js └── test │ └── AppCenterMock.js ├── clang-format-changed-files.sh └── scripts ├── bump-android-sdk-version.sh ├── bump-ios-sdk-version.sh ├── bump-wrapper-sdk-version.sh ├── eslint.sh ├── npm-pack.sh ├── put-maven-secrets-gradle.sh └── update-app-secrets.sh /.azurepipelines/build-test-app-android.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | - develop 4 | pr: 5 | - master 6 | 7 | pool: 8 | vmImage: macos-latest 9 | 10 | jobs: 11 | - job: 12 | displayName: Build and CodeQL TestApp Android 13 | steps: 14 | - checkout: self 15 | submodules: recursive 16 | 17 | - task: CodeQL3000Init@0 18 | displayName: CodeQL Initialize 19 | 20 | - task: JavaToolInstaller@0 21 | inputs: 22 | versionSpec: '17' 23 | jdkArchitectureOption: 'x64' 24 | jdkSourceOption: 'PreInstalled' 25 | displayName: 'Use Java 17' 26 | 27 | - task: Bash@3 28 | displayName: Run prepare-npm-sdk-integration script 29 | inputs: 30 | filePath: TestApp/prepare-npm-sdk-integration.sh 31 | arguments: "android" 32 | workingDirectory: TestApp 33 | 34 | - task: Gradle@3 35 | displayName: Build TestApp 36 | inputs: 37 | gradleWrapperFile: TestApp/android/gradlew 38 | workingDirectory: TestApp/android 39 | tasks: assembleRelease 40 | publishJUnitResults: false 41 | 42 | - task: CodeQL3000Finalize@0 43 | displayName: CodeQL Finalize -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | ColumnLimit: 140 3 | UseTab: Never 4 | -------------------------------------------------------------------------------- /.config/CredScanSuppressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "tool": "Credential Scanner", 3 | "suppressions": [ 4 | { 5 | "file": "/TestApp/android/keystores/debug.keystore.properties", 6 | "_justification": "CSCAN-GENERAL0060 used only in TestApp" 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @microsoft/appcenter-fte 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for the React Native SDK for App Center 4 | title: '' 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/problem_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Problem report 3 | about: Report a problem using the SDK 4 | title: '' 5 | labels: support 6 | assignees: '' 7 | 8 | --- 9 | 10 | 16 | 17 | ### **Description** 18 | 19 | Please describe the issue you are facing using the SDK. 20 | 21 | ### **Repro Steps** 22 | 23 | Please list the steps used to reproduce your issue. 24 | 25 | 1. 26 | 2. 27 | 28 | ### **Details** 29 | 30 | 1. Which version of the App Center SDK are you using? 31 | - e.g. 1.5.0 32 | 2. Which OS version did you experience the issue on? 33 | - e.g. Android 8.1.0, iOS 11 34 | 3. What device version did you see this error on? Were you using an emulator or a physical device? 35 | - e.g. Google Pixel 2 emulator, iPhone X physical device 36 | 4. What third party libraries are you using? 37 | - example 38 | 5. Run the following command and paste the output below: `react-native info` 39 | 40 | Place output here 41 | 42 | 6. If you're developing for React Native iOS, run the following command and paste the output below: `pod --version` 43 | 44 | Place output here 45 | 46 | 7. Please enable verbose logging for your app using `[MSAppCenter setLogLevel: MSLogLevelVerbose];` before your call to `[AppCenterReactNative register];` (or any other SDK registration). For Android, use `AppCenter.setLogLevel(android.util.Log.VERBOSE);` before your `SoLoader.init` call (you will need to `import com.microsoft.appcenter.AppCenter;`). Include the logs here: 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | Things to consider before you submit the PR: 11 | 12 | * [ ] Has `CHANGELOG.md` been updated? 13 | * [ ] Are tests passing locally? 14 | * [ ] Are the files formatted correctly? 15 | * [ ] Did you test your change with either the sample apps that are included in the repository or with a blank app that uses your change? 16 | 17 | ## Description 18 | 19 | A few sentences describing the overall goals of the pull request. 20 | 21 | ## Related PRs or issues 22 | 23 | List related PRs and other issues. 24 | 25 | ## Misc 26 | 27 | Add what's missing, notes on what you tested, additional thoughts or questions. 28 | -------------------------------------------------------------------------------- /.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 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | *.class 32 | *.project 33 | *.prefs 34 | .classpath 35 | 36 | # node.js 37 | # 38 | node_modules/ 39 | npm-debug.log 40 | package-lock.json 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | android/app/libs 46 | android/keystores/debug.keystore 47 | 48 | *.keystore 49 | *~ 50 | 51 | # credentials 52 | .npmrc 53 | 54 | #typescript 55 | artifacts/ 56 | 57 | # Android release generated files 58 | **/app/**/release/** 59 | 60 | # Shared framework builds for both platforms 61 | AppCenterReactNativeShared/Products/AppCenterReactNativeShared/Release-iphoneos/ 62 | AppCenterReactNativeShared/Products/AppCenterReactNativeShared/Release-iphonesimulator/ 63 | 64 | # xcframework build 65 | AppCenterReactNativeShared/Products/AppCenterReactNativeShared/AppCenterReactNativeShared.xcframework 66 | 67 | # Temporary zip file generated by script 68 | AppCenterReactNativeShared/Products/AppCenter-SDK-ReactNative-iOS-Pod-*.zip 69 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | #Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | ### Node 48 | 49 | # Logs 50 | logs 51 | *.log 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | 58 | # Directory for instrumented libs generated by jscoverage/JSCover 59 | lib-cov 60 | 61 | # Coverage directory used by tools like istanbul 62 | coverage 63 | 64 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 65 | .grunt 66 | 67 | # node-waf configuration 68 | .lock-wscript 69 | 70 | # Compiled binary addons (http://nodejs.org/api/addons.html) 71 | build/Release 72 | 73 | # Dependency directory 74 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 75 | node_modules 76 | 77 | # Intellij project files 78 | *.iml 79 | *.ipr 80 | *.iws 81 | .idea/ 82 | 83 | #Gradle 84 | .gradletasknamecache 85 | .gradle/ 86 | build/ 87 | bin/ 88 | 89 | # Built application files 90 | *.apk 91 | *.ap_ 92 | 93 | # Files for the Dalvik VM 94 | *.dex 95 | 96 | # Java class files 97 | *.class 98 | 99 | # Generated files 100 | bin/ 101 | gen/ 102 | 103 | # Gradle files 104 | .gradle/ 105 | build/ 106 | */build/ 107 | *.classpath 108 | 109 | # Local configuration file (sdk path, etc) 110 | local.properties 111 | 112 | # Proguard folder generated by Eclipse 113 | proguard/ 114 | 115 | # Log Files 116 | *.log 117 | 118 | # Android Studio Navigation editor temp files 119 | .navigation/ 120 | 121 | # Android Studio captures folder 122 | captures/ -------------------------------------------------------------------------------- /AppCenterReactNativeShared/.npmignore: -------------------------------------------------------------------------------- 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 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | 29 | # Don't publish example apps 30 | Examples/ -------------------------------------------------------------------------------- /AppCenterReactNativeShared/LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /AppCenterReactNativeShared/Products/AppCenterReactNativeShared.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'AppCenterReactNativeShared' 3 | s.version = '5.0.3' 4 | s.summary = 'React Native plugin for Visual Studio App Center' 5 | s.license = { :type => 'MIT', :file => 'AppCenterReactNativeShared/LICENSE' } 6 | s.homepage = 'https://github.com/microsoft/appcenter-sdk-react-native' 7 | s.documentation_url = "https://docs.microsoft.com/en-us/appcenter/" 8 | s.author = { 'Microsoft' => 'appcentersdk@microsoft.com' } 9 | s.source = { :http => "https://github.com/microsoft/appcenter-sdk-react-native/releases/download/#{s.version}/AppCenter-SDK-ReactNative-iOS-Pod-#{s.version}.zip" } 10 | s.platform = :ios, '12.0' 11 | s.requires_arc = true 12 | s.vendored_frameworks = 'AppCenterReactNativeShared/AppCenterReactNativeShared.xcframework' 13 | s.dependency 'AppCenter/Core', '5.0.6' 14 | end 15 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/Products/AppCenterReactNativeShared/LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /AppCenterReactNativeShared/Products/local.podspec: -------------------------------------------------------------------------------- 1 | # This podspec is intended to be used as local pod reference during development, 2 | # while the `AppCenterReactNativeShared.podspec` is only used in the official SDK releases. 3 | 4 | Pod::Spec.new do |s| 5 | s.name = 'AppCenterReactNativeShared' 6 | s.version = '5.0.3' 7 | s.summary = 'React Native plugin for Visual Studio App Center' 8 | s.license = { :type => 'MIT', :file => 'AppCenterReactNativeShared/LICENSE' } 9 | s.homepage = 'https://github.com/microsoft/appcenter-sdk-react-native' 10 | s.documentation_url = "https://docs.microsoft.com/en-us/appcenter/" 11 | s.author = { 'Microsoft' => 'appcentersdk@microsoft.com' } 12 | system("SRCROOT=#{__dir__}/../ios #{__dir__}/../prepare-local-podspec.sh") 13 | s.source = { :http => "file://#{__dir__}/AppCenter-SDK-ReactNative-iOS-Pod-#{s.version}.zip"} 14 | s.platform = :ios, '12.0' 15 | s.requires_arc = true 16 | s.vendored_frameworks = 'AppCenterReactNativeShared/AppCenterReactNativeShared.xcframework' 17 | s.dependency 'AppCenter/Core', '5.0.6' 18 | end 19 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:4.2.1' 9 | } 10 | } 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | } 16 | 17 | apply from: 'publish.gradle' 18 | apply from: 'version.gradle' 19 | 20 | apply plugin: 'maven-publish' 21 | apply plugin: 'signing' 22 | apply plugin: 'com.android.library' 23 | 24 | def wasSigned = false 25 | 26 | def ext = rootProject.ext 27 | 28 | // Setup signing values. 29 | ext."signing.keyId" = ext.mavenSigningKeyId 30 | ext."signing.secretKeyRingFile" = ext.mavenSecretKeyPath 31 | ext."signing.password" = ext.mavenPublicKeyPassword 32 | 33 | android { 34 | compileSdkVersion 29 35 | buildToolsVersion '29.0.2' 36 | 37 | defaultConfig { 38 | minSdkVersion 21 39 | targetSdkVersion 29 40 | versionCode 69 41 | versionName '5.0.3' 42 | group groupId 43 | version versionName 44 | buildConfigField 'String', "SDK_NAME", "\"appcenter.react-native\"" 45 | buildConfigField 'String', 'VERSION_NAME', "\"${ext.versionName}\"" 46 | 47 | ndk { 48 | abiFilters "armeabi-v7a", "x86" 49 | } 50 | consumerProguardFiles 'proguard-rules.pro' 51 | } 52 | } 53 | 54 | task sourcesJar(type: Jar) { 55 | afterEvaluate { 56 | from android.sourceSets.main.java.srcDirs 57 | classifier = 'sources' 58 | } 59 | } 60 | 61 | publishing { 62 | repositories { 63 | maven { 64 | url = uri("${System.env.BUILD_DIR}") 65 | } 66 | } 67 | 68 | afterEvaluate { project -> 69 | publications { 70 | maven(MavenPublication) { 71 | from components.release 72 | 73 | artifact sourcesJar 74 | 75 | pom { 76 | packaging = 'aar' 77 | name = project.name 78 | description = sdkDescription 79 | url = siteUrl 80 | 81 | // Set identifiers of assemble. 82 | groupId = ext.groupId 83 | artifactId = project.name 84 | 85 | // Set license information. 86 | licenses { 87 | license { 88 | name = licenseName 89 | url = licenseSite 90 | } 91 | } 92 | 93 | // Set information about developers. 94 | developers { 95 | developer { 96 | id = developerId 97 | name = developerName 98 | email = developerEmail 99 | } 100 | } 101 | 102 | // Set information about connection with developers. 103 | scm { 104 | connection = gitUrl 105 | developerConnection = gitUrl 106 | url = siteUrl 107 | } 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | dependencies { 115 | api 'com.microsoft.appcenter:appcenter:5.0.6' 116 | } 117 | 118 | artifacts { 119 | archives sourcesJar 120 | } 121 | 122 | signing { 123 | required { gradle.taskGraph.hasTask("publish") } 124 | sign publishing.publications 125 | } -------------------------------------------------------------------------------- /AppCenterReactNativeShared/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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/AppCenterReactNativeShared/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip 6 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/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 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # The following options are set by default. 2 | # Make sure they are always set, even if the default proguard config changes. 3 | -dontskipnonpubliclibraryclasses 4 | -verbose -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/publish.gradle: -------------------------------------------------------------------------------- 1 | // Bintray constants 2 | 3 | ext { 4 | siteUrl = 'https://github.com/Microsoft/appcenter-sdk-react-native' 5 | gitUrl = 'https://github.com/Microsoft/appcenter-sdk-react-native.git' 6 | groupId = 'com.microsoft.appcenter.reactnative' 7 | sdkDescription = 'AppCenter SDK for React Native Android' 8 | 9 | Properties properties = new Properties() 10 | File file = rootProject.file('local.properties') 11 | 12 | if (file.exists()) { 13 | properties.load(file.newDataInputStream()) 14 | } 15 | 16 | mavenUser = properties.getProperty("maven.user") 17 | mavenKey = properties.getProperty("maven.key") 18 | mavenRepoUrl = properties.getProperty("maven.repoUrl") 19 | mavenSigningKeyId = properties.getProperty("maven.signingKeyId") 20 | mavenPublicKeyPassword = properties.getProperty("maven.publicKeyPassword") 21 | mavenSecretKeyPath = properties.getProperty("maven.secretKeyPath") 22 | 23 | licenseName = 'The MIT License (MIT)' 24 | licenseSite = 'https://opensource.org/licenses/MIT' 25 | licenseCode = 'MIT' 26 | 27 | developerId = 'microsoft' 28 | developerName = 'Microsoft' 29 | developerEmail = 'appcentersdk@microsoft.com' 30 | } -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':AppCenterReactNativeShared' 2 | 3 | rootProject.name = 'appcenter-react-native' 4 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/src/main/java/com/microsoft/appcenter/reactnative/shared/AppCenterReactNativeShared.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.shared; 5 | 6 | import android.app.Application; 7 | import android.text.TextUtils; 8 | 9 | import com.microsoft.appcenter.AppCenter; 10 | import com.microsoft.appcenter.ingestion.models.WrapperSdk; 11 | import com.microsoft.appcenter.utils.AppCenterLog; 12 | 13 | import org.json.JSONObject; 14 | 15 | import java.io.InputStream; 16 | 17 | import static com.microsoft.appcenter.utils.AppCenterLog.LOG_TAG; 18 | 19 | public class AppCenterReactNativeShared { 20 | 21 | private static final String APPCENTER_CONFIG_ASSET = "appcenter-config.json"; 22 | 23 | private static final String APP_SECRET_KEY = "app_secret"; 24 | 25 | private static final String START_AUTOMATICALLY_KEY = "start_automatically"; 26 | 27 | private static Application sApplication; 28 | 29 | private static JSONObject sConfiguration; 30 | 31 | private static String sAppSecret; 32 | 33 | private static boolean sStartAutomatically; 34 | 35 | @SuppressWarnings("unused") 36 | public static synchronized void configureAppCenter(Application application) { 37 | if (sApplication != null) { 38 | return; 39 | } 40 | sApplication = application; 41 | WrapperSdk wrapperSdk = new WrapperSdk(); 42 | wrapperSdk.setWrapperSdkVersion(com.microsoft.appcenter.reactnative.shared.BuildConfig.VERSION_NAME); 43 | wrapperSdk.setWrapperSdkName(com.microsoft.appcenter.reactnative.shared.BuildConfig.SDK_NAME); 44 | AppCenter.setWrapperSdk(wrapperSdk); 45 | readConfigurationFile(); 46 | if (!sStartAutomatically) { 47 | AppCenterLog.debug(LOG_TAG, "Configure not to start automatically."); 48 | return; 49 | } 50 | 51 | /* Get app secret from appcenter-config.json file. */ 52 | if (TextUtils.isEmpty(sAppSecret)) { 53 | 54 | /* No app secret is a special case in SDK where there is no default transmission target. */ 55 | AppCenterLog.debug(LOG_TAG, "Configure without secret."); 56 | AppCenter.configure(application); 57 | } else { 58 | AppCenterLog.debug(LOG_TAG, "Configure with secret."); 59 | AppCenter.configure(application, sAppSecret); 60 | } 61 | } 62 | 63 | private static void readConfigurationFile() { 64 | try { 65 | AppCenterLog.debug(LOG_TAG, "Reading " + APPCENTER_CONFIG_ASSET); 66 | InputStream configStream = sApplication.getAssets().open(APPCENTER_CONFIG_ASSET); 67 | int size = configStream.available(); 68 | byte[] buffer = new byte[size]; 69 | 70 | //noinspection ResultOfMethodCallIgnored 71 | configStream.read(buffer); 72 | configStream.close(); 73 | String jsonContents = new String(buffer, "UTF-8"); 74 | sConfiguration = new JSONObject(jsonContents); 75 | if (sAppSecret == null) { 76 | sAppSecret = sConfiguration.optString(APP_SECRET_KEY); 77 | sStartAutomatically = sConfiguration.optBoolean(START_AUTOMATICALLY_KEY, true); 78 | } 79 | } catch (Exception e) { 80 | AppCenterLog.error(LOG_TAG, "Failed to parse appcenter-config.json", e); 81 | sConfiguration = new JSONObject(); 82 | } 83 | } 84 | 85 | public static synchronized void setAppSecret(String secret) { 86 | sAppSecret = secret; 87 | } 88 | 89 | public static synchronized void setStartAutomatically(boolean startAutomatically) { 90 | sStartAutomatically = startAutomatically; 91 | } 92 | 93 | public static synchronized JSONObject getConfiguration() { 94 | return sConfiguration; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/android/version.gradle: -------------------------------------------------------------------------------- 1 | // Bintray constants 2 | 3 | ext { 4 | versionName = '5.0.1' 5 | } -------------------------------------------------------------------------------- /AppCenterReactNativeShared/append-silicon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. 5 | 6 | # Builds arm64 slices under Xcode 12 and appends them to xcramework built under Xcode 11. 7 | # Usage: export SRCROOT=`pwd` && ./append-silicon.sh 8 | # Note: This script should be called after build-xcframework succeed under Xcode 11. 9 | 10 | set -e 11 | 12 | export FMK_NAME=AppCenterReactNativeShared 13 | PRODUCT_DIRECTORY=`pwd`/Products/AppCenterReactNativeShared 14 | XCODE_11_PRODUCT_DIRECTORY=`pwd`/Products/AppCenterReactNativeShared-xcode11 15 | 16 | if [ ! -d "${PRODUCT_DIRECTORY}" ] || [ -z "$(ls -A $PRODUCT_DIRECTORY)" ]; then 17 | echo "Directory $PRODUCT_DIRECTORY does not exist or is empty" 18 | exit 1 19 | fi 20 | if [ -d "${XCODE_11_PRODUCT_DIRECTORY}" ]; then 21 | echo "Clean $XCODE_11_PRODUCT_DIRECTORY directory" 22 | rm -rf "${XCODE_11_PRODUCT_DIRECTORY}" 23 | fi 24 | 25 | echo "Copy resources built with Xcode 11 to another folder" 26 | cp -R $PRODUCT_DIRECTORY $XCODE_11_PRODUCT_DIRECTORY 27 | 28 | echo "Clean directory for new Xcode build products" 29 | rm -rf "${PRODUCT_DIRECTORY}" 30 | 31 | echo "Build xcframeworks with new Xcode" 32 | export SRCROOT=`pwd`/ios 33 | export IOS_PLATFORMS="maccatalyst iphonesimulator" 34 | 35 | ./ios/build-silicon.sh 36 | 37 | append_to_framework() { 38 | if [ ! -e "$1" ]; then 39 | return 1 40 | fi 41 | local binary="$1/$FMK_NAME" 42 | [[ ! -e "$binary" ]] && binary="$1/$FMK_NAME" 43 | lipo "$binary" "$2/$FMK_NAME" -create -output "$binary" 44 | lipo -info "$binary" 45 | } 46 | 47 | append_to_xcframework() { 48 | append_to_framework \ 49 | "$XCODE_11_PRODUCT_DIRECTORY/$FMK_NAME.xcframework/$1/$FMK_NAME.framework" \ 50 | "$PRODUCT_DIRECTORY/Release-$2/$FMK_NAME.framework" 51 | } 52 | 53 | echo "Append arm64 slices to binaries built under Xcode 11" 54 | append_to_xcframework ios-i386_x86_64-simulator iphonesimulator 55 | append_to_xcframework ios-x86_64-maccatalyst maccatalyst 56 | 57 | for framework in $XCODE_11_PRODUCT_DIRECTORY/$FMK_NAME.xcframework/*/$FMK_NAME.framework; do 58 | xcframeworks+=( -framework "$framework") 59 | echo $framework 60 | done 61 | 62 | echo "Clean product directory for the full xcframework" 63 | rm -rf "${PRODUCT_DIRECTORY}" 64 | 65 | echo "Repackage xcframework with additional architectures" 66 | xcodebuild -create-xcframework "${xcframeworks[@]}" -output "$PRODUCT_DIRECTORY/$FMK_NAME.xcframework" 67 | 68 | echo "Copy the license file to the products directory (required for cocoapods)" 69 | cp -f "$XCODE_11_PRODUCT_DIRECTORY/LICENSE" "$PRODUCT_DIRECTORY" 70 | 71 | ls "$PRODUCT_DIRECTORY/$FMK_NAME.xcframework" 72 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/.gitignore: -------------------------------------------------------------------------------- 1 | Pods/ -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared.xcodeproj/xcshareddata/xcschemes/AppCenterReactNativeShared.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared/AppCenterReactNativeShared.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @class MSACWrapperSdk; 7 | 8 | @interface AppCenterReactNativeShared : NSObject 9 | 10 | + (void)setAppSecret:(NSString *)secret; 11 | 12 | + (NSString *)getAppSecret; 13 | 14 | + (void)configureAppCenter; 15 | 16 | + (MSACWrapperSdk *)getWrapperSdk; 17 | 18 | + (void)setWrapperSdk:(MSACWrapperSdk *)sdk; 19 | 20 | + (void)setStartAutomatically:(BOOL)shouldStartAutomatically; 21 | 22 | + (NSDictionary *)getConfiguration; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared/AppCenterReactNativeShared.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import "AppCenterReactNativeShared.h" 5 | #import 6 | #import 7 | 8 | @implementation AppCenterReactNativeShared 9 | 10 | static NSString *const kAppCenterSecretKey = @"AppSecret"; 11 | static NSString *const kAppCenterStartAutomaticallyKey = @"StartAutomatically"; 12 | static NSString *const kAppCenterConfigResource = @"AppCenter-Config"; 13 | 14 | static NSString *appSecret; 15 | static BOOL startAutomatically; 16 | static MSACWrapperSdk *wrapperSdk; 17 | static NSDictionary *configuration; 18 | 19 | + (void)setAppSecret:(NSString *)secret { 20 | appSecret = secret; 21 | } 22 | 23 | + (NSString *)getAppSecret { 24 | if (appSecret == nil) { 25 | NSString *plistPath = [[NSBundle mainBundle] pathForResource:kAppCenterConfigResource ofType:@"plist"]; 26 | configuration = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 27 | appSecret = [configuration objectForKey:kAppCenterSecretKey]; 28 | 29 | // Read start automatically flag, by default it's true if not set. 30 | id rawStartAutomatically = [configuration objectForKey:kAppCenterStartAutomaticallyKey]; 31 | if ([rawStartAutomatically isKindOfClass:[NSNumber class]]) { 32 | startAutomatically = [rawStartAutomatically boolValue]; 33 | } else { 34 | startAutomatically = YES; 35 | } 36 | } 37 | return appSecret; 38 | } 39 | 40 | + (void)configureAppCenter { 41 | if (!wrapperSdk) { 42 | MSACWrapperSdk *wrapperSdk = [[MSACWrapperSdk alloc] initWithWrapperSdkVersion:@"5.0.3" 43 | wrapperSdkName:@"appcenter.react-native" 44 | wrapperRuntimeVersion:nil 45 | liveUpdateReleaseLabel:nil 46 | liveUpdateDeploymentKey:nil 47 | liveUpdatePackageHash:nil]; 48 | [self setWrapperSdk:wrapperSdk]; 49 | [AppCenterReactNativeShared getAppSecret]; 50 | if (startAutomatically) { 51 | if ([appSecret length] == 0) { 52 | [MSACAppCenter configure]; 53 | } else { 54 | [MSACAppCenter configureWithAppSecret:appSecret]; 55 | } 56 | } 57 | } 58 | } 59 | 60 | + (MSACWrapperSdk *)getWrapperSdk { 61 | return wrapperSdk; 62 | } 63 | 64 | + (void)setWrapperSdk:(MSACWrapperSdk *)sdk { 65 | wrapperSdk = sdk; 66 | [MSACAppCenter setWrapperSdk:sdk]; 67 | } 68 | 69 | + (void)setStartAutomatically:(BOOL)shouldStartAutomatically { 70 | startAutomatically = shouldStartAutomatically; 71 | } 72 | 73 | + (NSDictionary *)getConfiguration { 74 | return configuration; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared/Global.xcconfig: -------------------------------------------------------------------------------- 1 | // This flag adds -fembed-bitcode-marker in the release configuration 2 | // but we require the full bitcode flag -fembed-bitcode in this case. 3 | ENABLE_BITCODE = NO; 4 | 5 | OTHER_CFLAGS = -Wshorten-64-to-32 -Wall -fstack-protector-strong -fpie 6 | 7 | // Use empty bitcode marker in simulators and debug configurations for real devices. 8 | OTHER_CFLAGS[sdk=iphonesimulator*] = $(OTHER_CFLAGS) -fembed-bitcode-marker 9 | OTHER_CFLAGS[config=Debug][sdk=iphoneos*] = $(OTHER_CFLAGS) -fembed-bitcode-marker 10 | 11 | // Activate full bitcode on release configuration for real devices. 12 | OTHER_CFLAGS[config=Release][sdk=iphoneos*] = $(OTHER_CFLAGS) -fembed-bitcode 13 | 14 | APPLICATION_EXTENSION_API_ONLY = YES; 15 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/AppCenterReactNativeShared/Support/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module AppCenterReactNativeShared { 2 | umbrella header "AppCenterReactNativeShared.h" 3 | 4 | export * 5 | module * { export * } 6 | 7 | link framework "Foundation" 8 | } 9 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/Podfile: -------------------------------------------------------------------------------- 1 | target 'AppCenterReactNativeShared' do 2 | # Comment the next line if you don't want to use dynamic frameworks 3 | use_frameworks! 4 | 5 | # Pods for AppCenterReactNativeShared 6 | pod 'AppCenter', '5.0.4' 7 | 8 | end 9 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AppCenter (5.0.4): 3 | - AppCenter/Analytics (= 5.0.4) 4 | - AppCenter/Crashes (= 5.0.4) 5 | - AppCenter/Analytics (5.0.4): 6 | - AppCenter/Core 7 | - AppCenter/Core (5.0.4) 8 | - AppCenter/Crashes (5.0.4): 9 | - AppCenter/Core 10 | 11 | DEPENDENCIES: 12 | - AppCenter (= 5.0.4) 13 | 14 | SPEC REPOS: 15 | trunk: 16 | - AppCenter 17 | 18 | SPEC CHECKSUMS: 19 | AppCenter: 85c92db0759d2792a65eb61d6842d2e86611a49a 20 | 21 | PODFILE CHECKSUM: 69989a70468a0621e600e50ec2d32be4b77147d0 22 | 23 | COCOAPODS: 1.16.2 24 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/build-framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. 5 | 6 | # Builds a framework for a platform provided in the first argument. 7 | # Usage: ./build-framework.sh 8 | 9 | set -e 10 | 11 | # Read arguments 12 | CURRENT_PLATFORM=$1 13 | BUILD_ARGUMENTS=$2 14 | 15 | if [ -z "$CURRENT_PLATFORM" ]; then 16 | echo "Build platform argument should be provided" 17 | exit 1 18 | fi 19 | 20 | # Open the source directory 21 | cd $SRCROOT 22 | 23 | # Cleaning previous build 24 | xcodebuild -workspace "${FMK_NAME}.xcworkspace" -configuration "Release" -scheme "${FMK_NAME}" -quiet clean 25 | 26 | # Building framework 27 | if [ ${CURRENT_PLATFORM} == "maccatalyst" ]; then 28 | xcodebuild $BUILD_ARGUMENTS -workspace "${FMK_NAME}.xcworkspace" -configuration "Release" -scheme "${FMK_NAME}" -destination 'platform=macOS,variant=Mac Catalyst' -derivedDataPath "$DERIVED_DATA_PATH" 29 | else 30 | xcodebuild $BUILD_ARGUMENTS -workspace "${FMK_NAME}.xcworkspace" -configuration "Release" -scheme "${FMK_NAME}" -sdk "${CURRENT_PLATFORM}" -derivedDataPath "$DERIVED_DATA_PATH" 31 | fi 32 | 33 | # Create and renew Release-*platform* temporary framework folder 34 | INSTALL_DIR=${TEMP_DIR}/Release-${CURRENT_PLATFORM} 35 | FMK_DIR=${INSTALL_DIR}/${FMK_NAME}.framework 36 | 37 | mkdir -p "${INSTALL_DIR}" 38 | mkdir -p "${FMK_DIR}" 39 | 40 | BINARY_PATH="${WRK_DIR}/Release-${CURRENT_PLATFORM}/lib${FMK_NAME}.a" 41 | HEADERS_DIR="${WRK_DIR}/Release-${CURRENT_PLATFORM}/include/${FMK_NAME}/" 42 | MODULEMAP_PATH="${SRCROOT}/${FMK_NAME}/Support/module.modulemap" 43 | 44 | mkdir -p "${FMK_DIR}/Headers" 45 | mkdir -p "${FMK_DIR}/Modules" 46 | 47 | # Copy the swift import file to the temporary framework folder. 48 | cp -f "${MODULEMAP_PATH}" "${FMK_DIR}/Modules/" 49 | 50 | # Copies the headers files to the temporary framework folder. 51 | cp -R "${HEADERS_DIR}/" "${FMK_DIR}/Headers/" 52 | 53 | # Copies the static library files to the temporary framework folder. 54 | cp -R "${BINARY_PATH}" "${FMK_DIR}/${FMK_NAME}" 55 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/build-silicon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. 5 | 6 | # Builds arm64 slices under Xcode 12 for provided IOS_PLATFORMS argument. 7 | # Usage: ./build-silicon.sh 8 | # Note: Requires SRCROOT, IOS_PLATFORMS, FMK_NAME. 9 | 10 | set -e 11 | 12 | PRODUCTS_DIR=${SRCROOT}/../Products 13 | ZIP_FOLDER=${FMK_NAME} 14 | export TEMP_DIR=${PRODUCTS_DIR}/${ZIP_FOLDER} 15 | 16 | # Working dir will be deleted after the framework creation. 17 | export DERIVED_DATA_PATH=build 18 | export WRK_DIR=${DERIVED_DATA_PATH}/Build/Products 19 | 20 | # Cleaning the old build 21 | if [ -d "${TEMP_DIR}" ]; then 22 | rm -rf "${TEMP_DIR}" 23 | fi 24 | 25 | for sdk in $IOS_PLATFORMS; do 26 | $SRCROOT/build-framework.sh $sdk "ONLY_ACTIVE_ARCH=NO ARCHS=arm64" 27 | done 28 | 29 | # Remove build folder 30 | rm -r "${SRCROOT}/${DERIVED_DATA_PATH}" 31 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/build-xcframework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. 5 | 6 | # Builds initial(no arm64 for iphonesimulator and maccatalyst slices) xcframework under Xcode 11.3 or the final xcframework if is used under Xcode 12+. 7 | # Usage: export SRCROOT=`pwd` && ./build-xcframework.sh 8 | 9 | set -e 10 | 11 | # Sets the target folders and the final framework product. 12 | export FMK_NAME=AppCenterReactNativeShared 13 | IOS_PLATFORMS="iphoneos iphonesimulator maccatalyst" 14 | PRODUCTS_DIR=${SRCROOT}/../Products 15 | ZIP_FOLDER=${FMK_NAME} 16 | export TEMP_DIR=${PRODUCTS_DIR}/${ZIP_FOLDER} 17 | 18 | # Directory of final xcframework 19 | INSTALL_DIR_XCFRAMEWORK=${TEMP_DIR}/${FMK_NAME}.xcframework 20 | 21 | # Working dir will be deleted after the framework creation. 22 | export DERIVED_DATA_PATH=build 23 | export WRK_DIR=${DERIVED_DATA_PATH}/Build/Products 24 | 25 | # # Cleaning the oldest. 26 | if [ -d "${TEMP_DIR}" ]; then 27 | rm -rf "${TEMP_DIR}" 28 | fi 29 | 30 | for sdk in $IOS_PLATFORMS; do 31 | export INSTALL_DIR=${TEMP_DIR}/Release-${sdk} 32 | export FMK_DIR=${INSTALL_DIR}/${FMK_NAME}.framework 33 | 34 | $SRCROOT/build-framework.sh $sdk 35 | 36 | frameworks+=( -framework "${FMK_DIR}") 37 | done 38 | 39 | # Building final xcframework 40 | xcodebuild -create-xcframework "${frameworks[@]}" -output "${INSTALL_DIR_XCFRAMEWORK}" 41 | 42 | # Copies the license file to the products directory (required for cocoapods) 43 | cp -f "../LICENSE" "${TEMP_DIR}" 44 | 45 | for sdk in $IOS_PLATFORMS; do 46 | # Remove temporary install folders 47 | rm -r ${TEMP_DIR}/Release-${sdk} 48 | done 49 | 50 | # Remove build folder 51 | rm -r "${SRCROOT}/${DERIVED_DATA_PATH}" 52 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/ios/post-clone.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "Update pod repository" 3 | pod repo update 4 | echo "Installing pods for AppCenterReactNativeShared in `pwd`" 5 | pod install 6 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/prepare-local-podspec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Build AppCenterReactNativeShared.framework 4 | (cd $SRCROOT; $SRCROOT/build-xcframework.sh) 5 | 6 | # Generate AppCenter-SDK-ReactNative-iOS-Pod-{version}.zip 7 | podspecFile=local.podspec $SRCROOT/../zip-framework.sh 8 | -------------------------------------------------------------------------------- /AppCenterReactNativeShared/zip-framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd Products 3 | 4 | # podspecFile is parameterized but its default value is AppCenterReactNativeShared.podspec when it's not set. 5 | # Specifically, AppCenterReactNativeShared.podspec is used in the release process and local.podspec is used for local development. 6 | podspecFile="${podspecFile:-AppCenterReactNativeShared.podspec}" 7 | wrapperSdkString=$(grep s.version ${podspecFile}) 8 | [[ ${wrapperSdkString} =~ ([0-9]+.[0-9]+.[0-9]+) ]] 9 | wrapperSdkVersion="${BASH_REMATCH[1]}" 10 | zipfilename="AppCenter-SDK-ReactNative-iOS-Pod-${wrapperSdkVersion}.zip" 11 | if [ -f $zipfilename ] ; then 12 | rm $zipfilename 13 | echo " removed old zip" 14 | fi 15 | cp ../LICENSE AppCenterReactNativeShared 16 | zip -ry $zipfilename AppCenterReactNativeShared 17 | echo "output is here: Products/$zipfilename" 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center SDK for React Native 2 | Copyright (c) Microsoft Corporation 3 | All rights reserved. 4 | MIT License 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM Version](https://img.shields.io/npm/v/appcenter.svg)](https://www.npmjs.com/package/appcenter) 2 | [![NPM Downloads](https://img.shields.io/npm/dm/appcenter.svg)](https://www.npmjs.com/package/appcenter) 3 | [![license](https://img.shields.io/badge/license-MIT%20License-00AAAA.svg)](https://github.com/Microsoft/appcenter-sdk-react-native/blob/master/LICENSE) 4 | 5 | # Visual Studio App Center SDK for React Native 6 | 7 | App Center is your continuous integration, delivery and learning solution for iOS and Android apps. 8 | Get faster release cycles, higher-quality apps, and the insights to build what users want. 9 | 10 | The App Center SDK uses a modular architecture so you can use any or all of the following services: 11 | 12 | 1. **App Center Analytics**: App Center Analytics helps you understand user behavior and customer engagement to improve your app. The SDK automatically captures session count, device properties like model, OS version, etc. You can define your own custom events to measure things that matter to you. All the information captured is available in the App Center portal for you to analyze the data. 13 | 14 | 2. **App Center Crashes**: App Center Crashes will automatically generate a crash log every time your app crashes. The log is first written to the device's storage and when the user starts the app again, the crash report will be sent to App Center. Collecting crashes works for both beta and live apps, i.e. those submitted to the App Store. Crash logs contain valuable information for you to help fix the crash. 15 | 16 | # Visual Studio App Center CodePush Standalone Version 17 | 18 | For teams or organizations looking to self-host CodePush, we now offer the [CodePush Standalone Version](https://github.com/microsoft/code-push-server) which is compatible with this SDK. It allows you to set up and manage CodePush as a self-hosted service, giving you more control over your infrastructure and data. Visit the repository for installation instructions, usage guides, and more. 19 | 20 | 21 | ## 1. Get started 22 | 23 | It is super easy to use App Center. Have a look at our [get started documentation](https://docs.microsoft.com/en-us/appcenter/sdk/getting-started/react-native) and onboard your app within minutes. Our [detailed documentation](https://docs.microsoft.com/en-us/appcenter/sdk/) is available as well. 24 | 25 | ## 2. Contributing 26 | 27 | We are looking forward to your contributions via pull requests. 28 | 29 | ### 2.1 Code of Conduct 30 | 31 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 32 | 33 | ### 2.2 Contributor License 34 | 35 | You must sign a [Contributor License Agreement](https://cla.microsoft.com/) before submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to submit a request via the [form](https://cla.microsoft.com/) and then electronically sign the CLA when you receive the email containing the link to the document. You need to sign the CLA only once to cover submission to any Microsoft OSS project. 36 | 37 | ## 3. Contact 38 | 39 | ### 3.1 Support 40 | 41 | App Center SDK support is provided directly within the App Center portal. Any time you need help, just log in to [App Center](https://appcenter.ms), then click the blue chat button in the lower-right corner of any page and our dedicated support team will respond to your questions and feedback. For additional information, see the [App Center Help Center](https://intercom.help/appcenter/getting-started/welcome-to-app-center-support). 42 | 43 | ### 3.2 Twitter 44 | We're on Twitter as [@VSAppCenter](https://www.twitter.com/VSAppCenter). 45 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /TestApp/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /TestApp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /TestApp/.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 | 36 | # node.js 37 | # 38 | node_modules/ 39 | npm-debug.log 40 | yarn-error.log 41 | 42 | # fastlane 43 | # 44 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 45 | # screenshots whenever they are needed. 46 | # For more information about the recommended setup visit: 47 | # https://docs.fastlane.tools/best-practices/source-control/ 48 | 49 | **/fastlane/report.xml 50 | **/fastlane/Preview.html 51 | **/fastlane/screenshots 52 | **/fastlane/test_output 53 | 54 | # Bundle artifact 55 | *.jsbundle 56 | 57 | # Ruby / CocoaPods 58 | /ios/Pods/ 59 | /vendor/bundle/ 60 | 61 | # Temporary files created by Metro to check the health of the file watcher 62 | .metro-health-check* 63 | 64 | # testing 65 | /coverage 66 | -------------------------------------------------------------------------------- /TestApp/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /TestApp/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /TestApp/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper 7 | # bound in the template on Cocoapods with next React Native release. 8 | gem 'cocoapods', '>= 1.13', '< 1.15' 9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' 10 | -------------------------------------------------------------------------------- /TestApp/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | activesupport (6.1.7.8) 9 | concurrent-ruby (~> 1.0, >= 1.0.2) 10 | i18n (>= 1.6, < 2) 11 | minitest (>= 5.1) 12 | tzinfo (~> 2.0) 13 | zeitwerk (~> 2.3) 14 | addressable (2.8.7) 15 | public_suffix (>= 2.0.2, < 7.0) 16 | algoliasearch (1.27.5) 17 | httpclient (~> 2.8, >= 2.8.3) 18 | json (>= 1.5.1) 19 | atomos (0.1.3) 20 | base64 (0.2.0) 21 | claide (1.1.0) 22 | cocoapods (1.14.3) 23 | addressable (~> 2.8) 24 | claide (>= 1.0.2, < 2.0) 25 | cocoapods-core (= 1.14.3) 26 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 27 | cocoapods-downloader (>= 2.1, < 3.0) 28 | cocoapods-plugins (>= 1.0.0, < 2.0) 29 | cocoapods-search (>= 1.0.0, < 2.0) 30 | cocoapods-trunk (>= 1.6.0, < 2.0) 31 | cocoapods-try (>= 1.1.0, < 2.0) 32 | colored2 (~> 3.1) 33 | escape (~> 0.0.4) 34 | fourflusher (>= 2.3.0, < 3.0) 35 | gh_inspector (~> 1.0) 36 | molinillo (~> 0.8.0) 37 | nap (~> 1.0) 38 | ruby-macho (>= 2.3.0, < 3.0) 39 | xcodeproj (>= 1.23.0, < 2.0) 40 | cocoapods-core (1.14.3) 41 | activesupport (>= 5.0, < 8) 42 | addressable (~> 2.8) 43 | algoliasearch (~> 1.0) 44 | concurrent-ruby (~> 1.1) 45 | fuzzy_match (~> 2.0.4) 46 | nap (~> 1.0) 47 | netrc (~> 0.11) 48 | public_suffix (~> 4.0) 49 | typhoeus (~> 1.0) 50 | cocoapods-deintegrate (1.0.5) 51 | cocoapods-downloader (2.1) 52 | cocoapods-plugins (1.0.0) 53 | nap 54 | cocoapods-search (1.0.1) 55 | cocoapods-trunk (1.6.0) 56 | nap (>= 0.8, < 2.0) 57 | netrc (~> 0.11) 58 | cocoapods-try (1.2.0) 59 | colored2 (3.1.2) 60 | concurrent-ruby (1.3.4) 61 | escape (0.0.4) 62 | ethon (0.16.0) 63 | ffi (>= 1.15.0) 64 | ffi (1.17.0) 65 | fourflusher (2.3.1) 66 | fuzzy_match (2.0.4) 67 | gh_inspector (1.1.3) 68 | httpclient (2.8.3) 69 | i18n (1.14.6) 70 | concurrent-ruby (~> 1.0) 71 | json (2.7.2) 72 | minitest (5.25.1) 73 | molinillo (0.8.0) 74 | nanaimo (0.3.0) 75 | nap (1.1.0) 76 | netrc (0.11.0) 77 | nkf (0.2.0) 78 | public_suffix (4.0.7) 79 | rexml (3.3.9) 80 | ruby-macho (2.5.1) 81 | typhoeus (1.4.1) 82 | ethon (>= 0.9.0) 83 | tzinfo (2.0.6) 84 | concurrent-ruby (~> 1.0) 85 | xcodeproj (1.25.0) 86 | CFPropertyList (>= 2.3.3, < 4.0) 87 | atomos (~> 0.1.3) 88 | claide (>= 1.0.2, < 2.0) 89 | colored2 (~> 3.1) 90 | nanaimo (~> 0.3.0) 91 | rexml (>= 3.3.2, < 4.0) 92 | zeitwerk (2.6.18) 93 | 94 | PLATFORMS 95 | ruby 96 | 97 | DEPENDENCIES 98 | activesupport (>= 6.1.7.5, < 7.1.0) 99 | cocoapods (>= 1.13, < 1.15) 100 | 101 | RUBY VERSION 102 | ruby 2.6.10p210 103 | 104 | BUNDLED WITH 105 | 2.3.15 106 | -------------------------------------------------------------------------------- /TestApp/README.md: -------------------------------------------------------------------------------- 1 | # Test Application for App Center React Native SDK 2 | 3 | This test application serves as a tool to verify and test the integration of the App Center React Native SDK. It supports two integration methods for the SDK: 4 | 5 | 1. **Using Source Code** 6 | 2. **Using the NPM Package** 7 | 8 | --- 9 | 10 | ## Integration Methods 11 | 12 | ### 1. Using Source Code 13 | 14 | To integrate the App Center SDK from source: 15 | 16 | 1. Run the following script: 17 | ```bash 18 | ./prepare-local-sdk-integration.sh 19 | ``` 20 | 21 | 2. Build and run the application on your target platform (Android or iOS). 22 | 23 | --- 24 | 25 | ### 2. Using the NPM Package 26 | 27 | To integrate the App Center SDK via the NPM package: 28 | 29 | 1. Run the following script: 30 | ```bash 31 | ./prepare-npm-sdk-integration.sh 32 | ``` 33 | 34 | 2. Build and run the application on your target platform (Android or iOS). 35 | 36 | --- 37 | 38 | ## Notes 39 | 40 | - **iOS:** 41 | - After running the scripts, you may need to perform the following steps manually: 42 | 1. Navigate to the `ios` directory. 43 | 2. Run `pod install`. 44 | 3. Open the `.xcworkspace` file in Xcode and build the project. 45 | 46 | - **Android:** 47 | - Ensure **Java 17** is installed and configured as the default Java version in your environment. 48 | 49 | -------------------------------------------------------------------------------- /TestApp/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shipped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(); 17 | }); 18 | -------------------------------------------------------------------------------- /TestApp/android/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. All rights reserved. 2 | # Licensed under the MIT License. 3 | 4 | # Sets the minimum version of CMake required to build your native library. 5 | # This ensures that a certain set of CMake features is available to 6 | # your build. 7 | 8 | cmake_minimum_required(VERSION 3.4.1) 9 | 10 | # Specifies a library name, specifies whether the library is STATIC or 11 | # SHARED, and provides relative paths to the source code. You can 12 | # define multiple libraries by adding multiple add_library() commands, 13 | # and CMake builds them for you. When you build your app, Gradle 14 | # automatically packages shared libraries with your APK. 15 | 16 | add_library( # Specifies the name of the library. 17 | native-lib 18 | 19 | # Sets the library as a shared library. 20 | SHARED 21 | 22 | # Provides a relative path to your source file(s). 23 | src/main/cpp/native-lib.cpp ) 24 | 25 | # Specifies a path to native header files. 26 | include_directories(src/main/cpp/include/) 27 | -------------------------------------------------------------------------------- /TestApp/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 /usr/local/Cellar/android-sdk/24.3.3/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 | -------------------------------------------------------------------------------- /TestApp/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/assets/appcenter-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_secret": "{RN_ANDROID_INT}" 3 | } -------------------------------------------------------------------------------- /TestApp/android/app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Microsoft Corporation 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "android/log.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" 14 | { 15 | #endif 16 | 17 | #pragma clang diagnostic push 18 | #pragma clang diagnostic ignored "-Wunused-parameter" 19 | #pragma ide diagnostic ignored "OCDFAInspection" 20 | #pragma clang diagnostic ignored "-Wmissing-noreturn" 21 | #pragma ide diagnostic ignored "cppcoreguidelines-avoid-magic-numbers" 22 | 23 | static std::vector data; 24 | 25 | void 26 | Java_com_testapp_TestAppNativeModule_nativeAllocateLargeBuffer( 27 | JNIEnv *env, 28 | jobject obj) { 29 | size_t size = 128 * 1024 * 1024; 30 | void *buffer = malloc(size); 31 | memset(buffer, 42, size); 32 | data.push_back(buffer); 33 | } 34 | #pragma clang diagnostic pop 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/java/com/testapp/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.testapp 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | override fun getMainComponentName(): String = "TestApp" 15 | 16 | /** 17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 19 | */ 20 | override fun createReactActivityDelegate(): ReactActivityDelegate = 21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 22 | } 23 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/java/com/testapp/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.testapp 2 | 3 | import android.app.Application 4 | import android.util.Log 5 | import com.facebook.react.PackageList 6 | import com.facebook.react.ReactApplication 7 | import com.facebook.react.ReactHost 8 | import com.facebook.react.ReactNativeHost 9 | import com.facebook.react.ReactPackage 10 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 11 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 12 | import com.facebook.react.defaults.DefaultReactNativeHost 13 | import com.facebook.react.flipper.ReactNativeFlipper 14 | import com.facebook.soloader.SoLoader 15 | 16 | import com.microsoft.appcenter.AppCenter 17 | import com.testapp.TestAppNativePackage 18 | 19 | class MainApplication : Application(), ReactApplication { 20 | 21 | override val reactNativeHost: ReactNativeHost = 22 | object : DefaultReactNativeHost(this) { 23 | override fun getPackages(): List = 24 | PackageList(this).packages.apply { 25 | // Packages that cannot be autolinked yet can be added manually here, for example: 26 | add(TestAppNativePackage()) 27 | } 28 | 29 | override fun getJSMainModuleName(): String = "index" 30 | 31 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 32 | 33 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 34 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 35 | } 36 | 37 | override val reactHost: ReactHost 38 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost) 39 | 40 | override fun onCreate() { 41 | super.onCreate() 42 | 43 | AppCenter.setLogLevel(Log.VERBOSE) 44 | TestAppNativeModule.initManualSessionTrackerState(this) 45 | TestAppNativeModule.initSecrets(this) 46 | 47 | SoLoader.init(this, false) 48 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 49 | // If you opted-in for the New Architecture, we load the native entry point for this app. 50 | load() 51 | } 52 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/java/com/testapp/TestAppNativeModule.kt: -------------------------------------------------------------------------------- 1 | package com.testapp 2 | 3 | import android.content.Context 4 | import android.content.SharedPreferences 5 | import android.os.Handler 6 | import android.os.Looper 7 | import android.util.Log 8 | import com.facebook.react.bridge.BaseJavaModule 9 | import com.facebook.react.bridge.Promise 10 | import com.facebook.react.bridge.ReactMethod 11 | import com.microsoft.appcenter.crashes.model.TestCrashException 12 | import com.microsoft.appcenter.reactnative.shared.AppCenterReactNativeShared 13 | import com.microsoft.appcenter.analytics.Analytics 14 | import java.util.concurrent.atomic.AtomicInteger 15 | 16 | class TestAppNativeModule(context: Context) : BaseJavaModule() { 17 | 18 | companion object { 19 | private const val DEMO_APP_NATIVE = "TestAppNative" 20 | private const val APP_SECRET = "app_secret" 21 | private const val START_AUTOMATICALLY = "start_automatically" 22 | private const val MANUAL_SESSION_TRACKER_ENABLED_KEY = "manual_session_tracker_enabled" 23 | 24 | init { 25 | System.loadLibrary("native-lib") 26 | } 27 | 28 | fun initSecrets(context: Context) { 29 | val sharedPreferences = context.getSharedPreferences(DEMO_APP_NATIVE, Context.MODE_PRIVATE) 30 | val secretOverride = sharedPreferences.getString(APP_SECRET, null) 31 | AppCenterReactNativeShared.setAppSecret(secretOverride) 32 | val startAutomaticallyOverride = sharedPreferences.getBoolean(START_AUTOMATICALLY, true) 33 | AppCenterReactNativeShared.setStartAutomatically(startAutomaticallyOverride) 34 | } 35 | 36 | fun initManualSessionTrackerState(context: Context) { 37 | val sharedPreferences = context.getSharedPreferences(DEMO_APP_NATIVE, Context.MODE_PRIVATE) 38 | val isManualSessionTrackerEnabled = sharedPreferences.getBoolean(MANUAL_SESSION_TRACKER_ENABLED_KEY, false) 39 | if (isManualSessionTrackerEnabled) { 40 | Analytics.enableManualSessionTracker() 41 | } 42 | } 43 | } 44 | 45 | private val sharedPreferences: SharedPreferences = 46 | context.getSharedPreferences(name, Context.MODE_PRIVATE) 47 | 48 | private external fun nativeAllocateLargeBuffer() 49 | 50 | override fun getName(): String { 51 | return DEMO_APP_NATIVE 52 | } 53 | 54 | @ReactMethod 55 | fun saveManualSessionTrackerState(state: Boolean) { 56 | sharedPreferences.edit() 57 | .putBoolean(MANUAL_SESSION_TRACKER_ENABLED_KEY, state) 58 | .apply() 59 | } 60 | 61 | @ReactMethod 62 | fun getManualSessionTrackerState(promise: Promise) { 63 | promise.resolve(if (sharedPreferences.getBoolean(MANUAL_SESSION_TRACKER_ENABLED_KEY, false)) 1 else 0) 64 | } 65 | 66 | @ReactMethod 67 | fun configureStartup(secretString: String?, startAutomatically: Boolean) { 68 | sharedPreferences.edit() 69 | .putString(APP_SECRET, secretString ?: "") 70 | .putBoolean(START_AUTOMATICALLY, startAutomatically) 71 | .apply() 72 | } 73 | 74 | @ReactMethod 75 | fun generateTestCrash() { 76 | throw TestCrashException() 77 | } 78 | 79 | @ReactMethod 80 | fun produceLowMemoryWarning() { 81 | val atomicInteger = AtomicInteger(0) 82 | val handler = Handler(Looper.getMainLooper()) 83 | handler.post(object : Runnable { 84 | override fun run() { 85 | nativeAllocateLargeBuffer() 86 | Log.d("TestApp", "Memory allocated: ${atomicInteger.addAndGet(128)}MB") 87 | handler.post(this) 88 | } 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/java/com/testapp/TestAppNativePackage.kt: -------------------------------------------------------------------------------- 1 | package com.testapp 2 | 3 | import com.facebook.react.ReactPackage 4 | import com.facebook.react.bridge.NativeModule 5 | import com.facebook.react.bridge.ReactApplicationContext 6 | import com.facebook.react.uimanager.ViewManager 7 | 8 | class TestAppNativePackage : ReactPackage { 9 | override fun createNativeModules(reactContext: ReactApplicationContext): List { 10 | return listOf(TestAppNativeModule(reactContext)) 11 | } 12 | 13 | override fun createViewManagers(reactContext: ReactApplicationContext): List> { 14 | return emptyList() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ASK_JAVASCRIPT 3 | ALWAYS_SEND 4 | TestApp 5 | 6 | -------------------------------------------------------------------------------- /TestApp/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /TestApp/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 21 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "25.1.8937393" 8 | kotlinVersion = "1.8.0" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | // maven { 24 | // credentials { 25 | // username = readFromLocalProperties('AZURE_USERNAME') 26 | // password = readFromLocalProperties('AZURE_PASSWORD') 27 | // } 28 | // url "https://msmobilecenter.pkgs.visualstudio.com/_packaging/AppCenter/maven/v1/" 29 | // } 30 | mavenLocal() 31 | mavenCentral() 32 | google() 33 | jcenter() 34 | // maven { 35 | // // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 36 | // url "$rootDir/../node_modules/react-native/android" 37 | // } 38 | } 39 | } 40 | 41 | apply plugin: "com.facebook.react.rootproject" 42 | -------------------------------------------------------------------------------- /TestApp/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 | # Use this property to specify which architecture you want to build. 28 | # You can also override it from the CLI using 29 | # ./gradlew -PreactNativeArchitectures=x86_64 30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 31 | 32 | # Use this property to enable support to the new architecture. 33 | # This will allow you to use TurboModules and the Fabric render in 34 | # your application. You should enable this flag either if you want 35 | # to write custom TurboModules/Fabric components OR use libraries that 36 | # are providing them. 37 | newArchEnabled=false 38 | 39 | # Use this property to enable or disable the Hermes JS engine. 40 | # If set to false, you will be using JSC instead. 41 | hermesEnabled=true 42 | -------------------------------------------------------------------------------- /TestApp/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /TestApp/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /TestApp/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 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 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 %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 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 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /TestApp/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'TestApp' 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 | -------------------------------------------------------------------------------- /TestApp/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TestApp", 3 | "displayName": "TestApp" 4 | } 5 | -------------------------------------------------------------------------------- /TestApp/app/Constants.android.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const Constants = { 5 | targetTokens: [{ 6 | label: 'Parent Target Token', 7 | key: '{RN_ANDROID_PARENT_TARGET_TOKEN_INT}' 8 | }, 9 | { 10 | label: 'Child Target Token', 11 | key: '{RN_ANDROID_CHILD1_TARGET_TOKEN_INT}' 12 | }, 13 | { 14 | label: 'Grandchild Target Token', 15 | key: '{RN_ANDROID_CHILD2_TARGET_TOKEN_INT}' 16 | }] 17 | }; 18 | 19 | module.exports = Constants; 20 | -------------------------------------------------------------------------------- /TestApp/app/Constants.ios.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const Constants = { 5 | targetTokens: [{ 6 | label: 'Parent Target Token', 7 | key: '{RN_IOS_PARENT_TARGET_TOKEN_INT}' 8 | }, 9 | { 10 | label: 'Child Target Token', 11 | key: '{RN_IOS_CHILD1_TARGET_TOKEN_INT}' 12 | }, 13 | { 14 | label: 'Grandchild Target Token', 15 | key: '{RN_IOS_CHILD2_TARGET_TOKEN_INT}' 16 | }] 17 | }; 18 | 19 | module.exports = Constants; 20 | -------------------------------------------------------------------------------- /TestApp/app/SharedStyles.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | import { StyleSheet, Platform } from 'react-native'; 5 | 6 | export default StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | backgroundColor: 'whitesmoke', 10 | ...Platform.select({ 11 | ios: { 12 | paddingTop: 25 13 | } 14 | }) 15 | }, 16 | header: { 17 | marginLeft: 10, 18 | marginTop: 10, 19 | fontSize: 12 20 | }, 21 | item: { 22 | flex: 1, 23 | flexDirection: 'row', 24 | justifyContent: 'space-between', 25 | alignItems: 'center', 26 | padding: 10, 27 | height: 44, 28 | borderWidth: StyleSheet.hairlineWidth, 29 | borderColor: 'gray', 30 | backgroundColor: 'white' 31 | }, 32 | itemStretchable: { 33 | flex: 1, 34 | flexDirection: 'row', 35 | justifyContent: 'space-between', 36 | alignItems: 'center', 37 | padding: 10, 38 | borderWidth: StyleSheet.hairlineWidth, 39 | borderColor: 'gray', 40 | backgroundColor: 'white' 41 | }, 42 | itemTitle: { 43 | color: 'black', 44 | marginRight: 5 45 | }, 46 | itemButton: { 47 | color: 'cornflowerblue', 48 | textAlign: 'center', 49 | width: '100%' 50 | }, 51 | itemInput: { 52 | flex: 1, 53 | padding: 5, 54 | marginTop: -5, 55 | marginBottom: -5, 56 | textAlign: 'right' 57 | }, 58 | underlinedItemInput: { 59 | flex: 1, 60 | padding: 5, 61 | marginTop: -5, 62 | marginBottom: -5, 63 | textAlign: 'right', 64 | borderBottomWidth: 1 65 | }, 66 | modalSelector: { 67 | borderColor: 'gray', 68 | backgroundColor: 'white' 69 | }, 70 | modalTextInput: { 71 | borderBottomWidth: 1, 72 | borderBottomColor: 'gray', 73 | }, 74 | modalItem: { 75 | flexDirection: 'row', 76 | alignItems: 'center', 77 | marginHorizontal: 8, 78 | marginVertical: 8 79 | }, 80 | modalButton: { 81 | flex: 0.5, 82 | padding: 16, 83 | borderColor: 'grey', 84 | borderWidth: 1, 85 | }, 86 | dialogInput: { 87 | ...Platform.select({ 88 | ios: { 89 | backgroundColor: 'lightgrey' 90 | } 91 | }) 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /TestApp/app/assets/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/add.png -------------------------------------------------------------------------------- /TestApp/app/assets/analytics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/analytics.png -------------------------------------------------------------------------------- /TestApp/app/assets/crashes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/crashes.png -------------------------------------------------------------------------------- /TestApp/app/assets/dials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/dials.png -------------------------------------------------------------------------------- /TestApp/app/assets/fuel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/fuel.png -------------------------------------------------------------------------------- /TestApp/app/assets/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/appcenter-sdk-react-native/7ebe78209b43d61f35442be0f5800ab89d5b06ad/TestApp/app/assets/remove.png -------------------------------------------------------------------------------- /TestApp/app/screens/PropertiesConfiguratorView.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | import React, { Component } from 'react'; 5 | import { View, Text, TextInput, Image, FlatList, TouchableOpacity, StyleSheet } from 'react-native'; 6 | 7 | import AddIcon from '../assets/add.png'; 8 | import RemoveIcon from '../assets/remove.png'; 9 | 10 | export default class PropertiesConfiguratorView extends Component { 11 | render() { 12 | return ( 13 | 14 | { if (this.props.allowChanges) this.props.onPropertyAdded(); }}> 15 | 16 | 17 | 18 | Add property 19 | 20 | 21 | ( 25 | 26 | this.props.onPropertyRemoved(item.name)}> 27 | 28 | 29 | 30 | this.props.onPropertyChanged(item.name, { name: text, value: item.value })}>{item.name} 31 | 32 | this.props.onPropertyChanged(item.name, { name: item.name, value: text })}>{item.value} 33 | ) 34 | } 35 | keyExtractor={(item, index) => index.toString()} 36 | /> 37 | 38 | ); 39 | } 40 | } 41 | 42 | const Divider = () => ; 43 | 44 | const styles = StyleSheet.create({ 45 | container: { 46 | backgroundColor: 'white', 47 | padding: 10, 48 | flexDirection: 'column' 49 | }, 50 | addPropertyContainer: { 51 | flexDirection: 'row', 52 | alignItems: 'center' 53 | }, 54 | propertiesList: { 55 | marginTop: 10 56 | }, 57 | propertyContainer: { 58 | flex: 1, 59 | flexDirection: 'row', 60 | alignItems: 'center' 61 | }, 62 | propertyInput: { 63 | flex: 0.5, 64 | padding: 5, 65 | height: 35, 66 | fontSize: 17, 67 | borderColor: 'grey', 68 | borderWidth: 0.3 69 | }, 70 | addIcon: { 71 | height: 24, 72 | width: 24 73 | }, 74 | removeIcon: { 75 | height: 26, 76 | width: 26 77 | } 78 | }); 79 | -------------------------------------------------------------------------------- /TestApp/appcenter-post-clone.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "Executing post clone script in `pwd`" 3 | echo $NPM_RC | base64 --decode > $APPCENTER_SOURCE_DIRECTORY/TestApp/.npmrc 4 | # Delete everything except TestApp folder 5 | rm -rf ../appcenter* ../AppCenterReactNativeShared 6 | 7 | echo 'Create local.properties file if it does not exist' 8 | touch -a android/local.properties 9 | ./put-azure-credentials.zh $USER_ACCOUNT $ACCESS_TOKEN 10 | 11 | echo 'Setting AppSecrets' 12 | cd .. && ./scripts/update-app-secrets.sh PROD && cd TestApp 13 | 14 | echo 'Add private cocoapods repository' 15 | pod repo add $REPO_NAME https://$USER_ACCOUNT:$ACCESS_TOKEN@$PRIVATE_REPO_BASE_URL/$REPO_NAME 16 | pod repo update 17 | cd ios && pod install 18 | 19 | # Remove all NDKs except NDK 21 to avoid failures on App Center CI with error: 20 | # > No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi 21 | echo 'Clean unnessesary NDKs' 22 | cd $NDK_PATH 23 | 24 | # Enable extended globbing for using regular expression in rm command. 25 | shopt -s extglob 26 | rm -rf !($NDK_VERSION_FOR_BUILD) 27 | 28 | echo 'NDKs after clean:' 29 | ls $NDK_PATH -------------------------------------------------------------------------------- /TestApp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /TestApp/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | // import App from './App'; 7 | import App from './app/App'; 8 | 9 | import {name as appName} from './app.json'; 10 | 11 | AppRegistry.registerComponent(appName, () => App); 12 | -------------------------------------------------------------------------------- /TestApp/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /TestApp/ios/AppCenter-Config.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AppSecret 6 | {RN_IOS_INT} 7 | 8 | 9 | -------------------------------------------------------------------------------- /TestApp/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target 'TestApp' do 29 | config = use_native_modules! 30 | 31 | use_react_native!( 32 | :path => config[:reactNativePath], 33 | # Enables Flipper. 34 | # 35 | # Note that if you have use_frameworks! enabled, Flipper will not work and 36 | # you should disable the next line. 37 | :flipper_configuration => flipper_config, 38 | # An absolute path to your application root. 39 | :app_path => "#{Pod::Config.instance.installation_root}/.." 40 | ) 41 | 42 | target 'TestAppTests' do 43 | inherit! :complete 44 | # Pods for testing 45 | end 46 | 47 | # Ensure the correct AppCenterReactNativeShared is used 48 | pod 'AppCenterReactNativeShared', :path => '../../AppCenterReactNativeShared/Products/local.podspec' 49 | 50 | post_install do |installer| 51 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 52 | react_native_post_install( 53 | installer, 54 | config[:reactNativePath], 55 | :mac_catalyst_enabled => false 56 | ) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp.xcodeproj/xcshareddata/xcschemes/TestApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/AppCenter-Config.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AppSecret 6 | {RN_IOS_INT} 7 | 8 | 9 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import "TestAppNative.h" 4 | #import 5 | #import 6 | #import 7 | #import 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @implementation AppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.moduleName = @"TestApp"; 18 | // You can add your custom initial props in the dictionary below. 19 | // They will be passed down to the ViewController used by React Native. 20 | self.initialProps = @{}; 21 | 22 | [MSACAppCenter setLogLevel:MSACLogLevelVerbose]; 23 | 24 | id appSecret = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppSecret"]; 25 | if ([appSecret isKindOfClass:[NSString class]]) { 26 | [AppCenterReactNativeShared setAppSecret:appSecret]; 27 | } 28 | 29 | id startAutomatically = [[NSUserDefaults standardUserDefaults] objectForKey:@"StartAutomatically"]; 30 | if ([startAutomatically isKindOfClass:[NSNumber class]]) { 31 | [AppCenterReactNativeShared setStartAutomatically:[startAutomatically boolValue]]; 32 | } 33 | BOOL sessionAuto = [[NSUserDefaults standardUserDefaults] boolForKey:@"ManualSessionTrackerEnabled"]; 34 | if (sessionAuto) { 35 | [MSACAnalytics enableManualSessionTracker]; 36 | } 37 | 38 | [AppCenterReactNative register]; 39 | [AppCenterReactNativeAnalytics registerWithInitiallyEnabled:true]; 40 | [AppCenterReactNativeCrashes registerWithAutomaticProcessing]; 41 | 42 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 43 | } 44 | 45 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 46 | { 47 | return [self getBundleURL]; 48 | } 49 | 50 | - (NSURL *)getBundleURL 51 | { 52 | #if DEBUG 53 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 54 | #else 55 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 56 | #endif 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/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 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | TestApp 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 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | 30 | NSAllowsArbitraryLoads 31 | 32 | NSAllowsLocalNetworking 33 | 34 | 35 | NSLocationWhenInUseUsageDescription 36 | 37 | UILaunchStoryboardName 38 | LaunchScreen 39 | UIRequiredDeviceCapabilities 40 | 41 | armv7 42 | 43 | UISupportedInterfaceOrientations 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 3B52.1 14 | 15 | 16 | 17 | NSPrivacyAccessedAPIType 18 | NSPrivacyAccessedAPICategoryUserDefaults 19 | NSPrivacyAccessedAPITypeReasons 20 | 21 | CA92.1 22 | 23 | 24 | 25 | NSPrivacyAccessedAPIType 26 | NSPrivacyAccessedAPICategorySystemBootTime 27 | NSPrivacyAccessedAPITypeReasons 28 | 29 | 35F9.1 30 | 31 | 32 | 33 | NSPrivacyCollectedDataTypes 34 | 35 | NSPrivacyTracking 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/TestAppNative.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @interface TestAppNative : NSObject 7 | @end 8 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/TestAppNative.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import "TestAppNative.h" 5 | 6 | #if __has_include() 7 | #import 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #else 14 | #import "RCTAssert.h" 15 | #import "RCTBridgeModule.h" 16 | #import "RCTConvert.h" 17 | #import "RCTEventDispatcher.h" 18 | #import "RCTRootView.h" 19 | #import "RCTUtils.h" 20 | #endif 21 | 22 | @interface TestAppNative () 23 | 24 | @property NSMutableArray *buffers; 25 | 26 | @property size_t allocated; 27 | 28 | @end 29 | 30 | @implementation TestAppNative 31 | 32 | static int const blockSize = 256 * 1024 * 1024; 33 | static NSString* const kAppCenterSecretKey = @"AppSecret"; 34 | static NSString* const kAppCenterStartAutomaticallyKey = @"StartAutomatically"; 35 | static NSString* const kManualSessionTrackerEnabled = @"ManualSessionTrackerEnabled"; 36 | 37 | - (instancetype) init { 38 | self = [super init]; 39 | if (self) { 40 | _buffers = [NSMutableArray new]; 41 | _allocated = 0; 42 | } 43 | return self; 44 | } 45 | 46 | RCT_EXPORT_MODULE(); 47 | 48 | RCT_EXPORT_METHOD(configureStartup:(NSString*)secretString 49 | :(BOOL)startAutomatically) 50 | { 51 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 52 | if (secretString == nil) { 53 | secretString = @""; 54 | } 55 | [userDefaults setObject:secretString forKey:kAppCenterSecretKey]; 56 | [userDefaults setBool:startAutomatically forKey:kAppCenterStartAutomaticallyKey]; 57 | } 58 | 59 | RCT_EXPORT_METHOD(saveManualSessionTrackerState:(BOOL)state) 60 | { 61 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 62 | [userDefaults setBool:state forKey:kManualSessionTrackerEnabled]; 63 | } 64 | 65 | RCT_EXPORT_METHOD(getManualSessionTrackerState:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) 66 | { 67 | if ([[NSUserDefaults standardUserDefaults] boolForKey:kManualSessionTrackerEnabled]){ 68 | resolve(@(1)); 69 | } else { 70 | resolve(@(0)); 71 | } 72 | } 73 | 74 | RCT_EXPORT_METHOD(generateTestCrash) 75 | { 76 | int* p = 0; 77 | *p = 0; 78 | } 79 | 80 | RCT_EXPORT_METHOD(produceLowMemoryWarning) 81 | { 82 | const size_t blockSize = 128 * 1024 * 1024; 83 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ 84 | void *buffer = malloc(blockSize); 85 | memset(buffer, 42, blockSize); 86 | [self.buffers addObject:[NSValue valueWithPointer:buffer]]; 87 | self.allocated += blockSize; 88 | NSLog(@"Allocated %zu MB", self.allocated / (1024 * 1024)); 89 | [self produceLowMemoryWarning]; 90 | }); 91 | } 92 | 93 | + (BOOL)requiresMainQueueSetup 94 | { 95 | return YES; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TestApp/ios/TestApp/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /TestApp/ios/TestAppNative.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @interface TestAppNative : NSObject 7 | @end 8 | -------------------------------------------------------------------------------- /TestApp/ios/TestAppNative.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import "TestAppNative.h" 5 | 6 | #if __has_include() 7 | #import 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #else 14 | #import "RCTAssert.h" 15 | #import "RCTBridgeModule.h" 16 | #import "RCTConvert.h" 17 | #import "RCTEventDispatcher.h" 18 | #import "RCTRootView.h" 19 | #import "RCTUtils.h" 20 | #endif 21 | 22 | @interface TestAppNative () 23 | 24 | @property NSMutableArray *buffers; 25 | 26 | @property size_t allocated; 27 | 28 | @end 29 | 30 | @implementation TestAppNative 31 | 32 | static int const blockSize = 256 * 1024 * 1024; 33 | static NSString* const kAppCenterSecretKey = @"AppSecret"; 34 | static NSString* const kAppCenterStartAutomaticallyKey = @"StartAutomatically"; 35 | static NSString* const kManualSessionTrackerEnabled = @"ManualSessionTrackerEnabled"; 36 | 37 | - (instancetype) init { 38 | self = [super init]; 39 | if (self) { 40 | _buffers = [NSMutableArray new]; 41 | _allocated = 0; 42 | } 43 | return self; 44 | } 45 | 46 | RCT_EXPORT_MODULE(); 47 | 48 | RCT_EXPORT_METHOD(configureStartup:(NSString*)secretString 49 | :(BOOL)startAutomatically) 50 | { 51 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 52 | if (secretString == nil) { 53 | secretString = @""; 54 | } 55 | [userDefaults setObject:secretString forKey:kAppCenterSecretKey]; 56 | [userDefaults setBool:startAutomatically forKey:kAppCenterStartAutomaticallyKey]; 57 | } 58 | 59 | RCT_EXPORT_METHOD(saveManualSessionTrackerState:(BOOL)state) 60 | { 61 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 62 | [userDefaults setBool:state forKey:kManualSessionTrackerEnabled]; 63 | } 64 | 65 | RCT_EXPORT_METHOD(getManualSessionTrackerState:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) 66 | { 67 | if ([[NSUserDefaults standardUserDefaults] boolForKey:kManualSessionTrackerEnabled]){ 68 | resolve(@(1)); 69 | } else { 70 | resolve(@(0)); 71 | } 72 | } 73 | 74 | RCT_EXPORT_METHOD(generateTestCrash) 75 | { 76 | int* p = 0; 77 | *p = 0; 78 | } 79 | 80 | RCT_EXPORT_METHOD(produceLowMemoryWarning) 81 | { 82 | const size_t blockSize = 128 * 1024 * 1024; 83 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ 84 | void *buffer = malloc(blockSize); 85 | memset(buffer, 42, blockSize); 86 | [self.buffers addObject:[NSValue valueWithPointer:buffer]]; 87 | self.allocated += blockSize; 88 | NSLog(@"Allocated %zu MB", self.allocated / (1024 * 1024)); 89 | [self produceLowMemoryWarning]; 90 | }); 91 | } 92 | 93 | + (BOOL)requiresMainQueueSetup 94 | { 95 | return YES; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TestApp/ios/TestAppTests/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 | -------------------------------------------------------------------------------- /TestApp/ios/TestAppTests/TestAppTests.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 TestAppTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation TestAppTests 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 | -------------------------------------------------------------------------------- /TestApp/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /TestApp/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /TestApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TestApp", 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-native-async-storage/async-storage": "^2.0.0", 14 | "@react-navigation/bottom-tabs": "^7.0.3", 15 | "@react-navigation/native": "^7.0.1", 16 | "appcenter": "file:appcenter-5.0.3.tgz", 17 | "appcenter-analytics": "file:appcenter-analytics-5.0.3.tgz", 18 | "appcenter-crashes": "file:appcenter-crashes-5.0.3.tgz", 19 | "appcenter-link-scripts": "file:appcenter-link-scripts-5.0.3.tgz", 20 | "react": "18.2.0", 21 | "react-native": "0.73.9", 22 | "react-native-file-access": "^3.1.1", 23 | "react-native-image-picker": "^7.1.2", 24 | "react-native-modal-selector": "^2.1.2", 25 | "react-native-safe-area-context": "^4.14.0", 26 | "react-native-screens": "~4.4.0" 27 | }, 28 | "devDependencies": { 29 | "@babel/core": "^7.20.0", 30 | "@babel/preset-env": "^7.20.0", 31 | "@babel/runtime": "^7.20.0", 32 | "@react-native/babel-preset": "0.73.21", 33 | "@react-native/eslint-config": "0.73.2", 34 | "@react-native/metro-config": "0.73.5", 35 | "@react-native/typescript-config": "0.73.1", 36 | "@types/react": "^18.2.6", 37 | "@types/react-test-renderer": "^18.0.0", 38 | "babel-jest": "^29.6.3", 39 | "eslint": "^8.19.0", 40 | "jest": "^29.6.3", 41 | "prettier": "2.8.8", 42 | "react-test-renderer": "18.2.0", 43 | "typescript": "5.0.4" 44 | }, 45 | "engines": { 46 | "node": ">=18" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /TestApp/prepare-local-sdk-integration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo 'Bundling AppcenterReactNativeShared...' 5 | # Java 11 version is required for running gradle tasks 6 | java_version=$(java -version 2>&1 | awk -F[\".] 'NR==1{print $2}') 7 | if [[ "$java_version" != "11" ]]; then 8 | echo "Java 11 is required. Current version: $java_version" 9 | exit 1 10 | fi 11 | cd ../AppCenterReactNativeShared/android && ./gradlew publishToMavenLocal && cd ../../TestApp 12 | 13 | echo 'Removing existing appcenter* packages...' 14 | rm -rf node_modules/appcenter* 15 | 16 | echo "Packing appcenter* packages..." 17 | npm pack ../appcenter 18 | npm pack ../appcenter-analytics 19 | npm pack ../appcenter-crashes 20 | npm pack ../appcenter-link-scripts 21 | 22 | echo "Installing appcenter* packages..." 23 | npm install appcenter*.tgz 24 | 25 | echo "workaround for macs on arm64" 26 | npm install react-native-fs --save --legacy-peer-deps 27 | 28 | echo "Cleanup appcenter*.tgz" 29 | rm appcenter*.tgz 30 | 31 | echo "Installing other packages..." 32 | npm install 33 | 34 | echo "Updating CocoaPods repos..." 35 | pod repo update 36 | 37 | echo "Install shared framework pods..." 38 | (cd ../AppCenterReactNativeShared/ios && pod install) 39 | 40 | # for testing with not released apple and android sdks, you will need to provide the storage access key 41 | echo "Running pod install and building shared framework..." 42 | (cd ios && pod install --repo-update) 43 | -------------------------------------------------------------------------------- /TestApp/prepare-npm-sdk-integration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | npm uninstall --save appcenter appcenter-analytics appcenter-crashes appcenter-link-scripts 5 | 6 | npm install --save appcenter appcenter-analytics appcenter-crashes 7 | 8 | pod repo update 9 | 10 | (cd ios && pod install) 11 | -------------------------------------------------------------------------------- /TestApp/put-azure-credentials.zh: -------------------------------------------------------------------------------- 1 | cat >> android/local.properties << EOL 2 | AZURE_USERNAME=${1:-$AZURE_USERNAME} 3 | AZURE_PASSWORD=${2:-$AZURE_PASSWORD} 4 | EOL -------------------------------------------------------------------------------- /TestApp/react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | project: { 3 | ios: { 4 | automaticPodsInstallation: true 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /TestApp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /appcenter-analytics/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "plugins": [ 8 | "react" 9 | ], 10 | "extends": "airbnb", 11 | "rules": { 12 | "comma-dangle": 0, 13 | "react/prop-types": 0, 14 | "no-use-before-define": 0, 15 | "radix": 0, 16 | "no-param-reassign": 0, 17 | "react/jsx-filename-extension": 0, 18 | "no-mixed-operators": 0, 19 | "import/prefer-default-export": 0, 20 | "import/no-extraneous-dependencies": 0, 21 | "no-plusplus": 0, 22 | "react/prefer-stateless-function": 0, 23 | "class-methods-use-this": 0, 24 | "max-len": 0, 25 | "jsx-a11y/href-no-hash": 0, 26 | "indent": 0, 27 | "import/no-unresolved": 0, 28 | "no-console": 0, 29 | "max-classes-per-file": 0 30 | } 31 | } -------------------------------------------------------------------------------- /appcenter-analytics/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | #Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | ### Node 48 | 49 | # Logs 50 | logs 51 | *.log 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | 58 | # Directory for instrumented libs generated by jscoverage/JSCover 59 | lib-cov 60 | 61 | # Coverage directory used by tools like istanbul 62 | coverage 63 | 64 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 65 | .grunt 66 | 67 | # node-waf configuration 68 | .lock-wscript 69 | 70 | # Compiled binary addons (http://nodejs.org/api/addons.html) 71 | build/Release 72 | 73 | # Dependency directory 74 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 75 | node_modules 76 | 77 | # Intellij project files 78 | *.iml 79 | *.ipr 80 | *.iws 81 | .idea/ 82 | 83 | #Gradle 84 | .gradletasknamecache 85 | .gradle/ 86 | build/ 87 | bin/ 88 | 89 | # Built application files 90 | *.apk 91 | *.ap_ 92 | 93 | # Files for the Dalvik VM 94 | *.dex 95 | 96 | # Java class files 97 | *.class 98 | 99 | # Generated files 100 | bin/ 101 | gen/ 102 | 103 | # Gradle files 104 | .gradle/ 105 | build/ 106 | */build/ 107 | 108 | # Local configuration file (sdk path, etc) 109 | local.properties 110 | 111 | # Proguard folder generated by Eclipse 112 | proguard/ 113 | 114 | # Log Files 115 | *.log 116 | 117 | # Android Studio Navigation editor temp files 118 | .navigation/ 119 | 120 | # Android Studio captures folder 121 | captures/ 122 | 123 | # npm5 124 | package-lock.json 125 | -------------------------------------------------------------------------------- /appcenter-analytics/.npmignore: -------------------------------------------------------------------------------- 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 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | 29 | # Don't publish example apps 30 | Examples/ -------------------------------------------------------------------------------- /appcenter-analytics/Analytics.d.ts: -------------------------------------------------------------------------------- 1 | export function trackEvent( 2 | eventName: string, 3 | properties?: { [name: string]: string } 4 | ): Promise; 5 | export function isEnabled(): Promise; 6 | export function setEnabled(enabled: boolean): Promise; 7 | export function startSession(): Promise; -------------------------------------------------------------------------------- /appcenter-analytics/LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center Analytics Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /appcenter-analytics/README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio App Center SDK for React Native 2 | ## App Center Analytics Module 3 | 4 | App Center is your continuous integration, delivery and learning solution for iOS and Android apps. Get faster release cycles, higher-quality apps, and the insights to build what users want. 5 | 6 | App Center Analytics helps you understand user behavior and customer engagement to improve your app. The SDK automatically captures session count, device properties like model, OS version, etc. You can define your own custom events to measure things that matter to you. All the information captured is available in the App Center portal for you to analyze the data. 7 | -------------------------------------------------------------------------------- /appcenter-analytics/android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. 4 | */ 5 | 6 | apply plugin: 'com.android.library' 7 | 8 | android { 9 | namespace "com.microsoft.appcenter.reactnative.analytics" 10 | compileSdkVersion rootProject.properties.get('compileSdkVersion', 29) 11 | buildToolsVersion rootProject.properties.get('buildToolsVersion', '29.0.2') 12 | 13 | defaultConfig { 14 | minSdkVersion 21 15 | targetSdkVersion rootProject.properties.get('targetSdkVersion', 29) 16 | versionCode 69 17 | versionName '5.0.3' 18 | ndk { 19 | abiFilters 'armeabi-v7a', 'x86' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(include: ['*.jar'], dir: 'libs') 26 | //noinspection GradleDynamicVersion 27 | implementation 'com.facebook.react:react-native:+' 28 | api 'com.microsoft.appcenter:appcenter-analytics:5.0.6' 29 | // For testing with TestApp 30 | // api files('../../../../AppCenterReactNativeShared/android/build/outputs/aar/appcenter-react-native-release.aar') 31 | api 'com.microsoft.appcenter.reactnative:appcenter-react-native:5.0.3' 32 | } 33 | -------------------------------------------------------------------------------- /appcenter-analytics/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /appcenter-analytics/android/src/main/java/com/microsoft/appcenter/reactnative/analytics/AppCenterReactNativeAnalyticsPackage.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.analytics; 5 | 6 | import android.app.Application; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.JavaScriptModule; 10 | import com.facebook.react.bridge.NativeModule; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.uimanager.ViewManager; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.List; 17 | 18 | public class AppCenterReactNativeAnalyticsPackage implements ReactPackage { 19 | private static final String ENABLE_IN_JS = "ENABLE_IN_JS"; 20 | private AppCenterReactNativeAnalyticsModule module; 21 | 22 | public AppCenterReactNativeAnalyticsPackage(Application application, boolean startEnabled) { 23 | // We create the module early because the Analytics package depends on the 24 | // onResume event to determine whether the app is foregrounded, and so 25 | // automatic session management doesn't work if we start it too late 26 | this.module = new AppCenterReactNativeAnalyticsModule(application, startEnabled); 27 | } 28 | 29 | public AppCenterReactNativeAnalyticsPackage(Application application, String startEnabled) { 30 | if (startEnabled.equals(ENABLE_IN_JS)){ 31 | this.module = new AppCenterReactNativeAnalyticsModule(application, false); 32 | } else { 33 | this.module = new AppCenterReactNativeAnalyticsModule(application, true); 34 | } 35 | 36 | } 37 | 38 | 39 | @Override 40 | public List createNativeModules(ReactApplicationContext reactContext) { 41 | List modules = new ArrayList<>(); 42 | modules.add(this.module); 43 | return modules; 44 | } 45 | 46 | // No @Override to support applications using React Native 0.47.0 or later 47 | public List> createJSModules() { 48 | return Collections.emptyList(); 49 | } 50 | 51 | @Override 52 | public List createViewManagers(ReactApplicationContext reactContext) { 53 | return Collections.emptyList(); 54 | } 55 | } -------------------------------------------------------------------------------- /appcenter-analytics/appcenter-analytics.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, './package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = package['name'] 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.license = package['license'] 10 | s.homepage = package['homepage'] 11 | s.documentation_url = "https://docs.microsoft.com/en-us/appcenter/" 12 | 13 | s.author = { 'Microsoft' => 'appcentersdk@microsoft.com' } 14 | s.source = { :git => "https://github.com/microsoft/appcenter-sdk-react-native.git" } 15 | s.source_files = "ios/AppCenterReactNativeAnalytics/**/*.{h,m}" 16 | s.platform = :ios, '12.0' 17 | s.requires_arc = true 18 | 19 | s.vendored_frameworks = 'AppCenterReactNativeShared/AppCenterReactNativeShared.framework' 20 | 21 | s.dependency 'AppCenterReactNativeShared', '~> 5.0' 22 | s.dependency 'AppCenter/Analytics', '~> 5.0' 23 | s.dependency 'React-Core' 24 | s.static_framework = true 25 | end 26 | -------------------------------------------------------------------------------- /appcenter-analytics/ios/AppCenterReactNativeAnalytics/AppCenterReactNativeAnalytics.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @interface AppCenterReactNativeAnalytics : NSObject 7 | 8 | + (void)registerWithInitiallyEnabled:(BOOL)enabled; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /appcenter-analytics/jest/setup.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | jest.mock('NativeModules', () => ({ 5 | AppCenterReactNativeAnalytics: { 6 | isEnabled: jest.fn(), 7 | trackEvent: jest.fn(), 8 | setEnabled: jest.fn(), 9 | getTransmissionTarget: jest.fn(() => new Promise((resolve) => resolve())), 10 | setTransmissionTargetAppName: jest.fn(), 11 | setTransmissionTargetAppVersion: jest.fn(), 12 | setTransmissionTargetAppLocale: jest.fn(), 13 | setTransmissionTargetEventProperty: jest.fn(), 14 | removeTransmissionTargetEventProperty: jest.fn(), 15 | collectTransmissionTargetDeviceId: jest.fn(), 16 | isTransmissionTargetEnabled: jest.fn(), 17 | setTransmissionTargetEnabled: jest.fn(), 18 | trackTransmissionTargetEvent: jest.fn(), 19 | getChildTransmissionTarget: jest.fn(() => new Promise((resolve) => resolve())) 20 | } 21 | })); 22 | -------------------------------------------------------------------------------- /appcenter-analytics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appcenter-analytics", 3 | "version": "5.0.3", 4 | "description": "React Native plugin for AppCenter Analytics", 5 | "main": "Analytics.js", 6 | "types": "Analytics.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/Microsoft/appcenter-sdk-react-native.git" 10 | }, 11 | "keywords": [ 12 | "react-native", 13 | "appcenter", 14 | "analytics" 15 | ], 16 | "author": "Microsoft Corporation", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/Microsoft/appcenter-sdk-react-native/issues" 20 | }, 21 | "homepage": "https://github.com/Microsoft/appcenter-sdk-react-native/blob/master/appcenter-analytics/README.md", 22 | "dependencies": { 23 | "appcenter": "5.0.3" 24 | }, 25 | "rnpm": { 26 | "android": { 27 | "packageInstance": "new AppCenterReactNativeAnalyticsPackage(MainApplication.this, getResources().getString(R.string.appCenterAnalytics_whenToEnableAnalytics))" 28 | }, 29 | "commands": { 30 | "postlink": "node node_modules/appcenter-analytics/scripts/postlink" 31 | } 32 | }, 33 | "devDependencies": { 34 | "babel-eslint": "7.2.3", 35 | "eslint": "6.8.0", 36 | "eslint-config-airbnb": "18.2.1", 37 | "eslint-plugin-import": "2.22.1", 38 | "eslint-plugin-jsx-a11y": "6.4.1", 39 | "eslint-plugin-react": "7.21.5", 40 | "jest": "24.8.0", 41 | "react": "16.6.3", 42 | "react-native": "0.57.3" 43 | }, 44 | "jest": { 45 | "preset": "react-native", 46 | "setupFilesAfterEnv": [ 47 | "./jest/setup.js" 48 | ], 49 | "transform": { 50 | "^.+\\.js$": "/node_modules/react-native/jest/preprocessor.js" 51 | } 52 | }, 53 | "scripts": { 54 | "lint": "./node_modules/.bin/eslint .", 55 | "test": "jest" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /appcenter-analytics/react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dependency: { 3 | platforms: { 4 | ios: {}, 5 | android: { 6 | packageInstance: 'new AppCenterReactNativeAnalyticsPackage(getApplication(), getResources().getString(R.string.appCenterAnalytics_whenToEnableAnalytics))' 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /appcenter-analytics/scripts/postlink.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const rnpmlink = require('appcenter-link-scripts'); 5 | 6 | // Configure Android first. 7 | let promise; 8 | if (rnpmlink.android.checkIfAndroidDirectoryExists()) { 9 | console.log('Configuring AppCenter Analytics for Android'); 10 | promise = rnpmlink.android.initAppCenterConfig() 11 | .then(() => { 12 | rnpmlink.android.patchStrings('appCenterAnalytics_whenToEnableAnalytics', 'ALWAYS_SEND'); 13 | rnpmlink.android.removeAndroidDuplicateLinks(); 14 | }).catch((e) => { 15 | console.error(`Could not configure AppCenter Analytics for Android. Error Reason - ${e.message}`); 16 | return Promise.resolve(); 17 | }); 18 | } else { 19 | promise = Promise.resolve(); 20 | } 21 | 22 | // Then iOS even if Android failed. 23 | if (rnpmlink.ios.checkIfAppDelegateExists()) { 24 | promise 25 | .then(() => { 26 | console.log('Configuring AppCenter Analytics for iOS'); 27 | return rnpmlink.ios.initAppCenterConfig(); 28 | }) 29 | .then(() => { 30 | const code = '[AppCenterReactNativeAnalytics registerWithInitiallyEnabled:true]; // Initialize AppCenter analytics'; 31 | return rnpmlink.ios.initInAppDelegate('#import ', code, /.*\[AppCenterReactNativeAnalytics register.*/g); 32 | }) 33 | .then((file) => { 34 | console.log(`Added code to initialize iOS Analytics SDK in ${file}`); 35 | return rnpmlink.ios.addPodDeps( 36 | [ 37 | { pod: 'AppCenter/Analytics', version: '5.0.6' }, 38 | { pod: 'AppCenterReactNativeShared', version: '5.0.3' } // in case people don't link appcenter (core) 39 | ], 40 | { platform: 'ios', version: '9.0' } 41 | ); 42 | }) 43 | .catch((e) => { 44 | console.error(`Could not configure AppCenter Analytics for iOS. Error Reason - ${e.message}`); 45 | return Promise.resolve(); 46 | }); 47 | } 48 | -------------------------------------------------------------------------------- /appcenter-analytics/test/AppCenterAnalyticsMock.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | jest.mock('appcenter-analytics', () => ({ 5 | trackEvent: jest.fn(), 6 | isEnabled: jest.fn(), 7 | setEnabled: jest.fn() 8 | })); 9 | -------------------------------------------------------------------------------- /appcenter-crashes/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "plugins": [ 8 | "react" 9 | ], 10 | "extends": "airbnb", 11 | "rules": { 12 | "comma-dangle": 0, 13 | "react/prop-types": 0, 14 | "no-use-before-define": 0, 15 | "radix": 0, 16 | "no-param-reassign": 0, 17 | "react/jsx-filename-extension": 0, 18 | "no-mixed-operators": 0, 19 | "import/prefer-default-export": 0, 20 | "import/no-extraneous-dependencies": 0, 21 | "no-plusplus": 0, 22 | "react/prefer-stateless-function": 0, 23 | "class-methods-use-this": 0, 24 | "max-len": 0, 25 | "jsx-a11y/href-no-hash": 0, 26 | "indent": 0, 27 | "import/no-unresolved": 0, 28 | "no-console": 0 29 | } 30 | } -------------------------------------------------------------------------------- /appcenter-crashes/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | #Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | ### Node 48 | 49 | # Logs 50 | logs 51 | *.log 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | 58 | # Directory for instrumented libs generated by jscoverage/JSCover 59 | lib-cov 60 | 61 | # Coverage directory used by tools like istanbul 62 | coverage 63 | 64 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 65 | .grunt 66 | 67 | # node-waf configuration 68 | .lock-wscript 69 | 70 | # Compiled binary addons (http://nodejs.org/api/addons.html) 71 | build/Release 72 | 73 | # Dependency directory 74 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 75 | node_modules 76 | 77 | # Intellij project files 78 | *.iml 79 | *.ipr 80 | *.iws 81 | .idea/ 82 | 83 | #Gradle 84 | .gradletasknamecache 85 | .gradle/ 86 | build/ 87 | bin/ 88 | 89 | # Built application files 90 | *.apk 91 | *.ap_ 92 | 93 | # Files for the Dalvik VM 94 | *.dex 95 | 96 | # Java class files 97 | *.class 98 | 99 | # Generated files 100 | bin/ 101 | gen/ 102 | 103 | # Gradle files 104 | .gradle/ 105 | build/ 106 | */build/ 107 | 108 | # Local configuration file (sdk path, etc) 109 | local.properties 110 | 111 | # Proguard folder generated by Eclipse 112 | proguard/ 113 | 114 | # Log Files 115 | *.log 116 | 117 | # Android Studio Navigation editor temp files 118 | .navigation/ 119 | 120 | # Android Studio captures folder 121 | captures/ 122 | 123 | # npm5 124 | package-lock.json 125 | -------------------------------------------------------------------------------- /appcenter-crashes/.npmignore: -------------------------------------------------------------------------------- 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 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | 29 | # Don't publish example apps 30 | Examples/ -------------------------------------------------------------------------------- /appcenter-crashes/Crashes.d.ts: -------------------------------------------------------------------------------- 1 | export enum UserConfirmation { 2 | DONT_SEND = 0, 3 | SEND = 1, 4 | ALWAYS_SEND = 2 5 | } 6 | 7 | export interface CrashesListener { 8 | onBeforeSending?: (report: ErrorReport) => void; 9 | onSendingSucceeded?: (report: ErrorReport) => void; 10 | onSendingFailed?: (report: ErrorReport) => void; 11 | getErrorAttachments?: (report: ErrorReport) => Promise; 12 | shouldProcess?: (report: ErrorReport) => boolean; 13 | shouldAwaitUserConfirmation?: () => boolean; 14 | } 15 | 16 | export class ErrorAttachmentLog { 17 | public static attachmentWithText(text: string, fileName?: string): ErrorAttachmentLog; 18 | public static attachmentWithBinary( 19 | data: string, 20 | fileName: string | null, 21 | contentType: string 22 | ): ErrorAttachmentLog; 23 | } 24 | 25 | export class ExceptionModel { 26 | wrapperSdkName: string; 27 | type: string; 28 | message: string; 29 | stackTrace: string; 30 | public static createFromError(error: Error): ExceptionModel; 31 | public static createFromTypeAndMessage(type: string, message: string, stacktrace: string): ExceptionModel; 32 | } 33 | 34 | export interface Device { 35 | sdkName: string; 36 | sdkVersion: string; 37 | model: string; 38 | oemName: string; 39 | osName: string; 40 | osVersion: string; 41 | osBuild: string; 42 | osApiLevel?: number; 43 | locale: string; 44 | timeZoneOffset: number; 45 | screenSize?: string; 46 | appVersion: string; 47 | carrierName?: string; 48 | carrierCountry?: string; 49 | appBuild: string; 50 | appNamespace: string; 51 | } 52 | 53 | export interface ErrorReport { 54 | id: string; 55 | threadName?: string; 56 | appErrorTime: string | number; 57 | appStartTime: string | number; 58 | exception?: string; 59 | exceptionReason?: string; 60 | device: Device; 61 | signal?: string; 62 | appProcessIdentifier?: number; 63 | } 64 | 65 | export function generateTestCrash(): Promise; 66 | export function hasCrashedInLastSession(): Promise; 67 | export function hasReceivedMemoryWarningInLastSession(): Promise; 68 | export function lastSessionCrashReport(): Promise; 69 | export function isEnabled(): Promise; 70 | export function setEnabled(shouldEnable: boolean): Promise; 71 | export function trackError( 72 | error: ExceptionModel, 73 | properties?: { [name: string]: string }, 74 | attachments?: ErrorAttachmentLog[] 75 | ): void; 76 | export function notifyUserConfirmation(userConfirmation: UserConfirmation): void; 77 | export function setListener(crashesListener: CrashesListener): Promise; 78 | -------------------------------------------------------------------------------- /appcenter-crashes/LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center Error Reporting Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /appcenter-crashes/README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio App Center SDK for React Native 2 | ## App Center Crashes Module 3 | 4 | App Center is your continuous integration, delivery and learning solution for iOS and Android apps. Get faster release cycles, higher-quality apps, and the insights to build what users want. 5 | 6 | App Center Crashes will automatically generate a crash log every time your app crashes. The log is first written to the device's storage and when the user starts the app again, the crash report will be sent to App Center. Collecting crashes works for both beta and live apps, i.e. those submitted to the App Store. Crash logs contain valuable information for you to help fix the crash. 7 | -------------------------------------------------------------------------------- /appcenter-crashes/android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. 4 | */ 5 | 6 | apply plugin: 'com.android.library' 7 | 8 | android { 9 | namespace "com.microsoft.appcenter.reactnative.crashes" 10 | compileSdkVersion rootProject.properties.get('compileSdkVersion', 29) 11 | buildToolsVersion rootProject.properties.get('buildToolsVersion', '29.0.2') 12 | 13 | defaultConfig { 14 | minSdkVersion 21 15 | targetSdkVersion rootProject.properties.get('targetSdkVersion', 29) 16 | versionCode 69 17 | versionName '5.0.3' 18 | ndk { 19 | abiFilters 'armeabi-v7a', 'x86' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(include: ['*.jar'], dir: 'libs') 26 | //noinspection GradleDynamicVersion 27 | implementation 'com.facebook.react:react-native:+' 28 | api 'com.microsoft.appcenter:appcenter-crashes:5.0.6' 29 | // For testing with TestApp 30 | // api files('../../../../AppCenterReactNativeShared/android/build/outputs/aar/appcenter-react-native-release.aar') 31 | api 'com.microsoft.appcenter.reactnative:appcenter-react-native:5.0.3' 32 | } 33 | -------------------------------------------------------------------------------- /appcenter-crashes/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /appcenter-crashes/android/src/main/java/com/microsoft/appcenter/reactnative/crashes/AppCenterReactNativeCrashesPackage.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.crashes; 5 | 6 | import android.app.Application; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.JavaScriptModule; 10 | import com.facebook.react.bridge.NativeModule; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.uimanager.ViewManager; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.List; 17 | 18 | 19 | public class AppCenterReactNativeCrashesPackage implements ReactPackage { 20 | 21 | private AppCenterReactNativeCrashesModule mCrashesModule; 22 | 23 | private static final String WHEN_TO_SEND_CRASHES_ASK_JAVASCRIPT = "ASK_JAVASCRIPT"; 24 | 25 | public AppCenterReactNativeCrashesPackage(Application application, String crashListenerType) { 26 | // Construct the module up-front to enable crash reporting ASAP 27 | AppCenterReactNativeCrashesUtils.logDebug("Creating crashes module with crashListener " + crashListenerType); 28 | boolean automaticProcessing = !crashListenerType.equals(WHEN_TO_SEND_CRASHES_ASK_JAVASCRIPT); 29 | this.mCrashesModule = new AppCenterReactNativeCrashesModule(application, automaticProcessing); 30 | } 31 | 32 | @Override 33 | public List createNativeModules(ReactApplicationContext reactContext) { 34 | // enable JS integrations from this point 35 | this.mCrashesModule.setReactApplicationContext(reactContext); 36 | 37 | AppCenterReactNativeCrashesUtils.logDebug("Returning list containing crashes module"); 38 | List modules = new ArrayList(); 39 | modules.add(this.mCrashesModule); 40 | return modules; 41 | } 42 | 43 | // No @Override to support applications using React Native 0.47.0 or later 44 | public List> createJSModules() { 45 | return Collections.emptyList(); 46 | } 47 | 48 | @Override 49 | public List createViewManagers(ReactApplicationContext reactContext) { 50 | return Collections.emptyList(); 51 | } 52 | } -------------------------------------------------------------------------------- /appcenter-crashes/android/src/main/java/com/microsoft/appcenter/reactnative/crashes/RNUtils.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.crashes; 5 | 6 | import com.facebook.react.bridge.Arguments; 7 | import com.facebook.react.bridge.WritableArray; 8 | import com.facebook.react.bridge.WritableMap; 9 | 10 | import org.json.JSONArray; 11 | import org.json.JSONException; 12 | import org.json.JSONObject; 13 | 14 | import java.util.Iterator; 15 | 16 | public class RNUtils { 17 | 18 | public static WritableMap convertJsonObjectToWritableMap(JSONObject jsonObj) throws JSONException { 19 | WritableMap map = Arguments.createMap(); 20 | Iterator it = jsonObj.keys(); 21 | while(it.hasNext()){ 22 | String key = it.next(); 23 | Object obj; 24 | obj = jsonObj.get(key); 25 | if (obj instanceof JSONObject) 26 | map.putMap(key, convertJsonObjectToWritableMap((JSONObject) obj)); 27 | else if (obj instanceof JSONArray) 28 | map.putArray(key, convertJsonArrayToWritableArray((JSONArray) obj)); 29 | else if (obj instanceof String) 30 | map.putString(key, (String) obj); 31 | else if (obj instanceof Double) 32 | map.putDouble(key, (Double) obj); 33 | else if (obj instanceof Integer) 34 | map.putInt(key, (Integer) obj); 35 | else if (obj instanceof Boolean) 36 | map.putBoolean(key, (Boolean) obj); 37 | else if (obj == null) 38 | map.putNull(key); 39 | else 40 | throw new JSONException("Unrecognized object: " + obj); 41 | } 42 | return map; 43 | } 44 | 45 | private static WritableArray convertJsonArrayToWritableArray(JSONArray jsonArr) throws JSONException { 46 | WritableArray arr = Arguments.createArray(); 47 | for (int i=0; i 'appcentersdk@microsoft.com' } 14 | 15 | s.source = { :git => "https://github.com/microsoft/appcenter-sdk-react-native.git" } 16 | s.source_files = "ios/AppCenterReactNativeCrashes/**/*.{h,m}" 17 | s.platform = :ios, '12.0' 18 | s.requires_arc = true 19 | 20 | s.vendored_frameworks = 'AppCenterReactNativeShared/AppCenterReactNativeShared.framework' 21 | 22 | s.dependency 'AppCenterReactNativeShared', '~> 5.0' 23 | s.dependency 'AppCenter/Crashes', '~> 5.0' 24 | s.dependency 'React-Core' 25 | s.static_framework = true 26 | end 27 | -------------------------------------------------------------------------------- /appcenter-crashes/ios/AppCenterReactNativeCrashes/AppCenterReactNativeCrashes.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | // Support React Native headers both in the React namespace, where they are in RN version 0.40+, 7 | // and no namespace, for older versions of React Native 8 | #if __has_include() 9 | #import 10 | #else 11 | #import "RCTEventEmitter.h" 12 | #endif 13 | 14 | @interface AppCenterReactNativeCrashes : RCTEventEmitter 15 | 16 | + (void)register; 17 | + (void)registerWithAutomaticProcessing; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /appcenter-crashes/ios/AppCenterReactNativeCrashes/AppCenterReactNativeCrashesDelegate.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | // Support React Native headers both in the React namespace, where they are in RN version 0.40+, 7 | // and no namespace, for older versions of React Native 8 | #if __has_include() 9 | #import 10 | #else 11 | #import "RCTEventEmitter.h" 12 | #endif 13 | 14 | @protocol MSACCrashesDelegate; 15 | 16 | @interface AppCenterReactNativeCrashesDelegate : NSObject 17 | 18 | @property RCTEventEmitter* eventEmitter; 19 | 20 | - (NSArray *)supportedEvents; 21 | - (void)startObserving; 22 | - (void)stopObserving; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /appcenter-crashes/ios/AppCenterReactNativeCrashes/AppCenterReactNativeCrashesDelegate.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | #import "AppCenterReactNativeCrashesDelegate.h" 6 | #import "AppCenterReactNativeCrashesUtils.h" 7 | 8 | static NSString *ON_BEFORE_SENDING_EVENT = @"AppCenterErrorReportOnBeforeSending"; 9 | static NSString *ON_SENDING_FAILED_EVENT = @"AppCenterErrorReportOnSendingFailed"; 10 | static NSString *ON_SENDING_SUCCEEDED_EVENT = @"AppCenterErrorReportOnSendingSucceeded"; 11 | 12 | @implementation AppCenterReactNativeCrashesDelegate 13 | { 14 | bool hasListeners; 15 | } 16 | 17 | - (NSArray *)supportedEvents 18 | { 19 | return @[ON_BEFORE_SENDING_EVENT, ON_SENDING_FAILED_EVENT, ON_SENDING_SUCCEEDED_EVENT]; 20 | } 21 | 22 | - (void)startObserving { 23 | hasListeners = YES; 24 | } 25 | 26 | - (void)stopObserving { 27 | hasListeners = NO; 28 | } 29 | 30 | - (void)crashes:(MSACCrashes *)crashes willSendErrorReport:(MSACErrorReport *)errorReport 31 | { 32 | if (hasListeners) { 33 | [self.eventEmitter sendEventWithName:ON_BEFORE_SENDING_EVENT body:convertReportToJS(errorReport)]; 34 | } 35 | } 36 | 37 | - (void)crashes:(MSACCrashes *)crashes didSucceedSendingErrorReport:(MSACErrorReport *)errorReport 38 | { 39 | if (hasListeners) { 40 | [self.eventEmitter sendEventWithName:ON_SENDING_SUCCEEDED_EVENT body:convertReportToJS(errorReport)]; 41 | } 42 | } 43 | 44 | - (void)crashes:(MSACCrashes *)crashes didFailSendingErrorReport:(MSACErrorReport *)errorReport withError:(NSError *)sendError 45 | { 46 | if (hasListeners) { 47 | [self.eventEmitter sendEventWithName:ON_SENDING_FAILED_EVENT body:convertReportToJS(errorReport)]; 48 | } 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /appcenter-crashes/ios/AppCenterReactNativeCrashes/AppCenterReactNativeCrashesUtils.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @class MSACErrorReport; 7 | 8 | NSDictionary* convertReportToJS(MSACErrorReport* report); 9 | NSArray* convertReportsToJS(NSArray* reports); 10 | NSArray* convertJSAttachmentsToNativeAttachments(NSArray* jsAttachments); 11 | -------------------------------------------------------------------------------- /appcenter-crashes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appcenter-crashes", 3 | "version": "5.0.3", 4 | "description": "React Native plugin for AppCenter Crashes", 5 | "main": "Crashes.js", 6 | "types": "Crashes.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/Microsoft/appcenter-sdk-react-native.git" 10 | }, 11 | "keywords": [ 12 | "react-native", 13 | "appcenter", 14 | "error", 15 | "reporting", 16 | "crash" 17 | ], 18 | "author": "Microsoft Corporation", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/Microsoft/appcenter-sdk-react-native/issues" 22 | }, 23 | "homepage": "https://github.com/Microsoft/appcenter-sdk-react-native/blob/master/appcenter-crashes/README.md", 24 | "dependencies": { 25 | "appcenter": "5.0.3" 26 | }, 27 | "rnpm": { 28 | "android": { 29 | "packageInstance": "new AppCenterReactNativeCrashesPackage(MainApplication.this, getResources().getString(R.string.appCenterCrashes_whenToSendCrashes))" 30 | }, 31 | "commands": { 32 | "postlink": "node node_modules/appcenter-crashes/scripts/postlink" 33 | } 34 | }, 35 | "devDependencies": { 36 | "babel-eslint": "7.2.3", 37 | "eslint": "6.8.0", 38 | "eslint-config-airbnb": "18.2.1", 39 | "eslint-plugin-import": "2.22.1", 40 | "eslint-plugin-jsx-a11y": "6.4.1", 41 | "eslint-plugin-react": "7.21.5" 42 | }, 43 | "scripts": { 44 | "lint": "./node_modules/.bin/eslint ." 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /appcenter-crashes/react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dependency: { 3 | platforms: { 4 | ios: {}, 5 | android: { 6 | packageInstance: 'new AppCenterReactNativeCrashesPackage(getApplication(), getResources().getString(R.string.appCenterCrashes_whenToSendCrashes))' 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /appcenter-crashes/scripts/postlink.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const rnpmlink = require('appcenter-link-scripts'); 5 | 6 | // Configure Android first. 7 | let promise; 8 | if (rnpmlink.android.checkIfAndroidDirectoryExists()) { 9 | console.log('Configuring AppCenter Crashes for Android'); 10 | promise = rnpmlink.android.initAppCenterConfig() 11 | .then(() => { 12 | rnpmlink.android.patchStrings('appCenterCrashes_whenToSendCrashes', 13 | 'ALWAYS_SEND'); 14 | rnpmlink.android.removeAndroidDuplicateLinks(); 15 | }).catch((e) => { 16 | console.error(`Could not configure AppCenter Crashes for Android. Error Reason - ${e.message}`); 17 | return Promise.resolve(); 18 | }); 19 | } else { 20 | promise = Promise.resolve(); 21 | } 22 | 23 | // Then iOS even if Android failed. 24 | if (rnpmlink.ios.checkIfAppDelegateExists()) { 25 | promise 26 | .then(() => { 27 | console.log('Configuring AppCenter Crashes for iOS'); 28 | return rnpmlink.ios.initAppCenterConfig(); 29 | }) 30 | .then(() => { 31 | const code = '[AppCenterReactNativeCrashes registerWithAutomaticProcessing]; // Initialize AppCenter crashes'; 32 | return rnpmlink.ios.initInAppDelegate('#import ', code, /.*\[AppCenterReactNativeCrashes register.*/g); 33 | }) 34 | .then((file) => { 35 | console.log(`Added code to initialize iOS Crashes SDK in ${file}`); 36 | return rnpmlink.ios.addPodDeps( 37 | [ 38 | { pod: 'AppCenter/Crashes', version: '5.0.6' }, 39 | { pod: 'AppCenterReactNativeShared', version: '5.0.3' } // in case people don't link appcenter (core) 40 | ], 41 | { platform: 'ios', version: '9.0' } 42 | ); 43 | }) 44 | .catch((e) => { 45 | console.error(`Could not configure AppCenter Crashes for iOS. Error Reason - ${e.message}`); 46 | return Promise.resolve(); 47 | }); 48 | } 49 | -------------------------------------------------------------------------------- /appcenter-crashes/test/AppCenterCrashesMock.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | jest.mock('appcenter-crashes', () => ({ 5 | generateTestCrash: jest.fn(), 6 | hasCrashedInLastSession: jest.fn(), 7 | lastSessionCrashReport: jest.fn(), 8 | hasReceivedMemoryWarningInLastSession: jest.fn(), 9 | isEnabled: jest.fn(), 10 | setEnabled: jest.fn(), 11 | notifyUserConfirmation: jest.fn(), 12 | setListener: jest.fn(), 13 | })); 14 | -------------------------------------------------------------------------------- /appcenter-link-scripts/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "es6": true 5 | }, 6 | "plugins": [ 7 | "react" 8 | ], 9 | "extends": "airbnb", 10 | "rules": { 11 | "comma-dangle": 0, 12 | "react/prop-types": 0, 13 | "no-use-before-define": 0, 14 | "radix": 0, 15 | "no-param-reassign": 0, 16 | "react/jsx-filename-extension": 0, 17 | "no-mixed-operators": 0, 18 | "import/prefer-default-export": 0, 19 | "import/no-extraneous-dependencies": 0, 20 | "no-plusplus": 0, 21 | "react/prefer-stateless-function": 0, 22 | "class-methods-use-this": 0, 23 | "max-len": 0, 24 | "jsx-a11y/href-no-hash": 0, 25 | "indent": 0, 26 | "import/no-unresolved": 0, 27 | "no-console": 0, 28 | "no-multi-spaces": [2, { "ignoreEOLComments": true }], 29 | "func-names": 0, 30 | "no-useless-escape": 0, 31 | "import/no-dynamic-require": 0 32 | } 33 | } -------------------------------------------------------------------------------- /appcenter-link-scripts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /appcenter-link-scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appcenter-link-scripts", 3 | "version": "5.0.3", 4 | "description": "Node module that contains common functionality needed to link appcenter-* modules", 5 | "main": "src/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/microsoft/appcenter-sdk-react-native.git" 9 | }, 10 | "keywords": [ 11 | "react-native", 12 | "appcenter" 13 | ], 14 | "author": "Microsoft Corporation", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/microsoft/appcenter-sdk-react-native/issues" 18 | }, 19 | "homepage": "https://github.com/microsoft/appcenter-sdk-react-native#readme", 20 | "dependencies": { 21 | "debug": "4.3.1", 22 | "glob": "5.0.15", 23 | "mkdirp": "0.5.3", 24 | "plist": "^3.0.2", 25 | "which": "1.2.11", 26 | "xcode": "2.0.0" 27 | }, 28 | "devDependencies": { 29 | "babel-eslint": "7.2.3", 30 | "eslint": "6.8.0", 31 | "eslint-config-airbnb": "18.2.1", 32 | "eslint-plugin-import": "2.22.1", 33 | "eslint-plugin-jsx-a11y": "6.4.1", 34 | "eslint-plugin-react": "7.21.5" 35 | }, 36 | "scripts": { 37 | "lint": "./node_modules/.bin/eslint ." 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /appcenter-link-scripts/src/android/AppCenterConfig.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | 7 | const mkdirp = require('mkdirp'); 8 | const glob = require('glob'); 9 | const debug = require('debug')('appcenter-link:android:AppCenterConfig'); 10 | 11 | /** 12 | * Class to get and set values in AppCenter Config file for Android - aka appcenter-config.json 13 | */ 14 | const AppCenterConfig = function (file) { 15 | this.AppCenterConfigPath = file; 16 | this.AppCenterConfig = {}; 17 | try { 18 | this.AppCenterConfig = JSON.parse(fs.readFileSync(this.AppCenterConfigPath), 'utf-8'); 19 | debug('Read contents from ', file); 20 | } catch (e) { 21 | debug('Could not find ', e.message); 22 | } 23 | }; 24 | 25 | AppCenterConfig.prototype.get = function (key) { 26 | return this.AppCenterConfig[key]; 27 | }; 28 | 29 | AppCenterConfig.prototype.set = function (key, value) { 30 | this.AppCenterConfig[key] = value; 31 | }; 32 | 33 | AppCenterConfig.prototype.save = function () { 34 | try { 35 | mkdirp.sync(path.dirname(this.AppCenterConfigPath)); 36 | } catch (e) { 37 | debug(e.message); 38 | } 39 | fs.writeFileSync(this.AppCenterConfigPath, JSON.stringify(this.AppCenterConfig, null, 4)); 40 | debug(`Saved App secret to ${this.AppCenterConfigPath}`); 41 | return this.AppCenterConfigPath; 42 | }; 43 | 44 | AppCenterConfig.searchForFile = function (cwd) { 45 | const AppCenterConfigPaths = glob.sync('**/appcenter-config.json', { 46 | ignore: ['node_modules/**', '**/build/**'], 47 | cwd: cwd || process.cwd() 48 | }); 49 | if (AppCenterConfigPaths.length > 1) { 50 | debug(AppCenterConfigPaths); 51 | throw new Error(`Found more than one appcenter-config.json in this project and hence could not write App Secret. 52 | Please add "app_secret" to the correct appcenter-config.json file 53 | appcenter-config.json found at ${AppCenterConfigPaths} 54 | `); 55 | } else if (AppCenterConfigPaths.length === 1) { 56 | return AppCenterConfigPaths[0]; 57 | } else { 58 | return path.join('android', 'app', 'src', 'main', 'assets', 'appcenter-config.json'); 59 | } 60 | }; 61 | 62 | module.exports = AppCenterConfig; 63 | -------------------------------------------------------------------------------- /appcenter-link-scripts/src/index.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const android = require('./android'); 5 | const ios = require('./ios'); 6 | 7 | module.exports = { 8 | android, 9 | ios 10 | }; 11 | -------------------------------------------------------------------------------- /appcenter-link-scripts/src/ios/AppDelegate.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const fs = require('fs'); 5 | const debug = require('debug')('appcenter-link:ios:AppDelegate'); 6 | 7 | const AppDelegate = function (file) { 8 | this.appDelegatePath = file; 9 | this.appDelegateContents = fs.readFileSync(this.appDelegatePath, 'utf-8'); 10 | debug('Read contents for appDelegate from ', file); 11 | }; 12 | 13 | AppDelegate.prototype.addHeader = function (header) { 14 | if (this.appDelegateContents.indexOf(header) === -1) { 15 | const match = this.appDelegateContents.match(/#import "AppDelegate.h"[ \t]*\r*\n/); 16 | if (match === null) { 17 | throw Error(` 18 | Could not find line '#import "AppDelegate.h"' in file AppDelegate.m. 19 | Update AppDelegate.m so that text is present, as we match on it and insert '${header}' after for AppCenter SDK integration. 20 | `); 21 | } 22 | 23 | const existingLine = match[0]; 24 | this.appDelegateContents = this.appDelegateContents.replace(existingLine, `${existingLine}${header}\n`); 25 | debug('Added header', header, 'to file', this.appDelegatePath); 26 | } else { 27 | debug(`"${header}"" header already added to AppDelegate.m`); 28 | } 29 | }; 30 | 31 | AppDelegate.prototype.addInitCode = function (code, oldCodeRegExp) { 32 | const oldCodeMatches = oldCodeRegExp ? this.appDelegateContents.match(oldCodeRegExp) : null; 33 | if (oldCodeMatches && oldCodeMatches.length > 1) { 34 | for (let i = 1; i < oldCodeMatches.length; i++) { 35 | this.appDelegateContents = this.appDelegateContents.replace(oldCodeMatches[i], ''); 36 | debug(`Removed duplicate ${oldCodeRegExp} lines from AppDelegate.m`); 37 | } 38 | } 39 | if (this.appDelegateContents.indexOf(code) === -1) { 40 | /* If old code not found, add new content. */ 41 | if (!oldCodeMatches) { 42 | /* Find the beginning of the didFinishLaunchingWithOptions method. */ 43 | const match = this.appDelegateContents.match(/[^\n]*didFinishLaunchingWithOptions[^{]*{[\s]*/); 44 | if (match === null) { 45 | throw Error('Could not find the start of the didFinishLaunchingWithOptions method in the AppDelegate.m file.'); 46 | } 47 | 48 | const existingLine = match[0]; 49 | this.appDelegateContents = this.appDelegateContents.replace(existingLine, `${existingLine}${code}\n `); 50 | debug('Added code', code, 'to file', this.appDelegatePath); 51 | } 52 | } else { 53 | debug(`Looks like ${code} is already added to AppDelegate.m`); 54 | } 55 | }; 56 | 57 | AppDelegate.prototype.save = function () { 58 | fs.writeFileSync(this.appDelegatePath, this.appDelegateContents); 59 | debug('Saved appDelegate', this.appDelegatePath); 60 | return this.appDelegatePath; 61 | }; 62 | 63 | module.exports = AppDelegate; 64 | -------------------------------------------------------------------------------- /appcenter/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | __tests__/* 3 | -------------------------------------------------------------------------------- /appcenter/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "plugins": [ 8 | "react" 9 | ], 10 | "extends": "airbnb", 11 | "rules": { 12 | "comma-dangle": 0, 13 | "react/prop-types": 0, 14 | "no-use-before-define": 0, 15 | "radix": 0, 16 | "no-param-reassign": 0, 17 | "react/jsx-filename-extension": 0, 18 | "no-mixed-operators": 0, 19 | "import/prefer-default-export": 0, 20 | "import/no-extraneous-dependencies": 0, 21 | "no-plusplus": 0, 22 | "react/prefer-stateless-function": 0, 23 | "class-methods-use-this": 0, 24 | "max-len": 0, 25 | "jsx-a11y/href-no-hash": 0, 26 | "indent": 0, 27 | "import/no-unresolved": 0, 28 | "no-console": 0, 29 | "no-multi-spaces": [2, { "ignoreEOLComments": true }] 30 | } 31 | } -------------------------------------------------------------------------------- /appcenter/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | #Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | ### Node 48 | 49 | # Logs 50 | logs 51 | *.log 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | 58 | # Directory for instrumented libs generated by jscoverage/JSCover 59 | lib-cov 60 | 61 | # Coverage directory used by tools like istanbul 62 | coverage 63 | 64 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 65 | .grunt 66 | 67 | # node-waf configuration 68 | .lock-wscript 69 | 70 | # Compiled binary addons (http://nodejs.org/api/addons.html) 71 | build/Release 72 | 73 | # Dependency directory 74 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 75 | node_modules 76 | 77 | # Intellij project files 78 | *.iml 79 | *.ipr 80 | *.iws 81 | .idea/ 82 | 83 | #Gradle 84 | .gradletasknamecache 85 | .gradle/ 86 | build/ 87 | bin/ 88 | 89 | # Built application files 90 | *.apk 91 | *.ap_ 92 | 93 | # Files for the Dalvik VM 94 | *.dex 95 | 96 | # Java class files 97 | *.class 98 | 99 | # Generated files 100 | bin/ 101 | gen/ 102 | 103 | # Gradle files 104 | .gradle/ 105 | build/ 106 | */build/ 107 | 108 | # Local configuration file (sdk path, etc) 109 | local.properties 110 | 111 | # Proguard folder generated by Eclipse 112 | proguard/ 113 | 114 | # Log Files 115 | *.log 116 | 117 | # Android Studio Navigation editor temp files 118 | .navigation/ 119 | 120 | # Android Studio captures folder 121 | captures/ 122 | 123 | # npm5 124 | package-lock.json 125 | -------------------------------------------------------------------------------- /appcenter/.npmignore: -------------------------------------------------------------------------------- 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 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | 29 | # Don't publish example apps 30 | Examples/ -------------------------------------------------------------------------------- /appcenter/AppCenter.d.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | export enum LogLevel { 5 | VERBOSE = 2, 6 | DEBUG = 3, 7 | INFO = 4, 8 | WARNING = 5, 9 | ERROR = 6, 10 | ASSERT = 7, 11 | NONE = 99 12 | } 13 | 14 | /** 15 | * @deprecated Use `LogLevel` instead. 16 | */ 17 | export enum AppCenterLogLevel { 18 | VERBOSE = 2, 19 | DEBUG = 3, 20 | INFO = 4, 21 | WARNING = 5, 22 | ERROR = 6, 23 | ASSERT = 7, 24 | NONE = 99 25 | } 26 | 27 | export function setLogLevel(logLevel: LogLevel | AppCenterLogLevel): Promise; 28 | export function getLogLevel(): Promise; 29 | export function getSdkVersion(): string; 30 | export function isEnabled(): Promise; 31 | export function setEnabled(enabled: boolean): Promise; 32 | export function isNetworkRequestsAllowed(): Promise; 33 | export function setNetworkRequestsAllowed(isAllowed: boolean): Promise; 34 | export function setUserId(userId: string | null): Promise; 35 | export function setDataResidencyRegion(dataResidencyRegion: string | null): Promise; 36 | export function getInstallId(): Promise; 37 | -------------------------------------------------------------------------------- /appcenter/AppCenter.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const ReactNative = require('react-native'); 5 | 6 | const { AppCenterReactNative } = ReactNative.NativeModules; 7 | const AppCenterLog = require('appcenter/appcenter-log'); 8 | const PackageJson = require('./package.json'); 9 | 10 | const AppCenter = { 11 | LogLevel: { 12 | VERBOSE: AppCenterLog.LogLevelVerbose, // Logging will be very chatty 13 | DEBUG: AppCenterLog.LogLevelDebug, // Debug information will be logged 14 | INFO: AppCenterLog.LogLevelInfo, // Information will be logged 15 | WARNING: AppCenterLog.LogLevelWarning, // Errors and warnings will be logged 16 | ERROR: AppCenterLog.LogLevelError, // Errors will be logged 17 | ASSERT: AppCenterLog.LogLevelAssert, // Only critical errors will be logged 18 | NONE: AppCenterLog.LogLevelNone // Logging is disabled 19 | }, 20 | 21 | /** 22 | * @deprecated Use `LogLevel.VERBOSE` instead. 23 | */ 24 | LogLevelVerbose: AppCenterLog.LogLevelVerbose, 25 | 26 | /** 27 | * @deprecated Use `LogLevel.DEBUG` instead. 28 | */ 29 | LogLevelDebug: AppCenterLog.LogLevelDebug, 30 | 31 | /** 32 | * @deprecated Use `LogLevel.INFO` instead. 33 | */ 34 | LogLevelInfo: AppCenterLog.LogLevelInfo, 35 | 36 | /** 37 | * @deprecated Use `LogLevel.WARNING` instead. 38 | */ 39 | LogLevelWarning: AppCenterLog.LogLevelWarning, 40 | 41 | /** 42 | * @deprecated Use `LogLevel.ERROR` instead. 43 | */ 44 | LogLevelError: AppCenterLog.LogLevelError, 45 | 46 | /** 47 | * @deprecated Use `LogLevel.ASSERT` instead. 48 | */ 49 | LogLevelAssert: AppCenterLog.LogLevelAssert, 50 | 51 | /** 52 | * @deprecated Use `LogLevel.NONE` instead. 53 | */ 54 | LogLevelNone: AppCenterLog.LogLevelNone, 55 | 56 | // async - returns a Promise 57 | startFromLibrary(service) { 58 | return AppCenterReactNative.startFromLibrary(service); 59 | }, 60 | 61 | // async - returns a Promise 62 | getLogLevel() { 63 | return AppCenterReactNative.getLogLevel(); 64 | }, 65 | 66 | // async - returns a Promise 67 | setLogLevel(logLevel) { 68 | return AppCenterReactNative.setLogLevel(logLevel); 69 | }, 70 | 71 | // async - returns a Promise 72 | setUserId(userId) { 73 | return AppCenterReactNative.setUserId(userId); 74 | }, 75 | 76 | // async - returns a Promise 77 | setDataResidencyRegion(dataResidencyRegion) { 78 | return AppCenterReactNative.setDataResidencyRegion(dataResidencyRegion); 79 | }, 80 | 81 | // async - returns a Promise 82 | getInstallId() { 83 | return AppCenterReactNative.getInstallId(); 84 | }, 85 | 86 | // async - returns a Promise 87 | isEnabled() { 88 | return AppCenterReactNative.isEnabled(); 89 | }, 90 | 91 | // async - returns a Promise 92 | setEnabled(enabled) { 93 | return AppCenterReactNative.setEnabled(enabled); 94 | }, 95 | 96 | // async - returns a Promise 97 | isNetworkRequestsAllowed() { 98 | return AppCenterReactNative.isNetworkRequestsAllowed(); 99 | }, 100 | 101 | // async - returns a Promise 102 | setNetworkRequestsAllowed(isAllowed) { 103 | return AppCenterReactNative.setNetworkRequestsAllowed(isAllowed); 104 | }, 105 | 106 | getSdkVersion() { 107 | return PackageJson.version; 108 | } 109 | }; 110 | 111 | module.exports = AppCenter; 112 | -------------------------------------------------------------------------------- /appcenter/LICENSE: -------------------------------------------------------------------------------- 1 | Visual Studio App Center Plugin for React Native 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | -------------------------------------------------------------------------------- /appcenter/README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio App Center SDK for React Native 2 | 3 | App Center is your continuous integration, delivery and learning solution for iOS and Android apps. Get faster release cycles, higher-quality apps, and the insights to build what users want. 4 | -------------------------------------------------------------------------------- /appcenter/android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. 4 | */ 5 | 6 | apply plugin: 'com.android.library' 7 | 8 | android { 9 | namespace "com.microsoft.appcenter.reactnative.appcenter" 10 | compileSdkVersion rootProject.properties.get('compileSdkVersion', 29) 11 | buildToolsVersion rootProject.properties.get('buildToolsVersion', '29.0.2') 12 | 13 | defaultConfig { 14 | minSdkVersion 21 15 | targetSdkVersion rootProject.properties.get('targetSdkVersion', 29) 16 | versionCode 69 17 | versionName '5.0.3' 18 | ndk { 19 | abiFilters 'armeabi-v7a', 'x86' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(include: ['*.jar'], dir: 'libs') 26 | //noinspection GradleDynamicVersion 27 | implementation 'com.facebook.react:react-native:+' 28 | api 'com.microsoft.appcenter:appcenter:5.0.6' 29 | // For testing with TestApp 30 | // api files('../../../../AppCenterReactNativeShared/android/build/outputs/aar/appcenter-react-native-release.aar') 31 | api 'com.microsoft.appcenter.reactnative:appcenter-react-native:5.0.3' 32 | } 33 | -------------------------------------------------------------------------------- /appcenter/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /appcenter/android/src/main/java/com/microsoft/appcenter/reactnative/appcenter/AppCenterReactNativeModule.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.appcenter; 5 | 6 | import android.app.Application; 7 | 8 | import com.facebook.react.bridge.BaseJavaModule; 9 | import com.facebook.react.bridge.Promise; 10 | import com.facebook.react.bridge.ReactMethod; 11 | import com.facebook.react.bridge.ReadableMap; 12 | import com.microsoft.appcenter.AppCenter; 13 | import com.microsoft.appcenter.reactnative.shared.AppCenterReactNativeShared; 14 | import com.microsoft.appcenter.utils.AppCenterLog; 15 | import com.microsoft.appcenter.utils.async.AppCenterConsumer; 16 | 17 | import java.util.UUID; 18 | 19 | import static com.microsoft.appcenter.AppCenter.LOG_TAG; 20 | 21 | @SuppressWarnings("WeakerAccess") 22 | public class AppCenterReactNativeModule extends BaseJavaModule { 23 | 24 | private final Application mApplication; 25 | 26 | public AppCenterReactNativeModule(Application application) { 27 | mApplication = application; 28 | AppCenterReactNativeShared.configureAppCenter(application); 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "AppCenterReactNative"; 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | @ReactMethod 38 | public void startFromLibrary(ReadableMap service) { 39 | String type = service.getString("bindingType"); 40 | try { 41 | AppCenter.startFromLibrary(mApplication, new Class[]{ Class.forName(type) }); 42 | } catch (ClassNotFoundException e) { 43 | AppCenterLog.error(LOG_TAG, "Unable to resolve App Center module", e); 44 | } 45 | } 46 | 47 | @ReactMethod 48 | public void setEnabled(boolean enabled, final Promise promise) { 49 | AppCenter.setEnabled(enabled).thenAccept(new AppCenterConsumer() { 50 | 51 | @Override 52 | public void accept(Void result) { 53 | promise.resolve(result); 54 | } 55 | }); 56 | } 57 | 58 | @ReactMethod 59 | public void isEnabled(final Promise promise) { 60 | AppCenter.isEnabled().thenAccept(new AppCenterConsumer() { 61 | 62 | @Override 63 | public void accept(Boolean enabled) { 64 | promise.resolve(enabled); 65 | } 66 | }); 67 | } 68 | 69 | @ReactMethod 70 | public void setLogLevel(int logLevel) { 71 | AppCenter.setLogLevel(logLevel); 72 | } 73 | 74 | @ReactMethod 75 | public void getLogLevel(final Promise promise) { 76 | int logLevel = AppCenter.getLogLevel(); 77 | promise.resolve(logLevel); 78 | } 79 | 80 | @ReactMethod 81 | public void getInstallId(final Promise promise) { 82 | AppCenter.getInstallId().thenAccept(new AppCenterConsumer() { 83 | 84 | @Override 85 | public void accept(UUID installId) { 86 | promise.resolve(installId == null ? null : installId.toString()); 87 | } 88 | }); 89 | } 90 | 91 | @ReactMethod 92 | public void setUserId(String userId) { 93 | AppCenter.setUserId(userId); 94 | } 95 | 96 | @ReactMethod 97 | public void setDataResidencyRegion(String dataResidencyRegion) { 98 | AppCenter.setDataResidencyRegion(dataResidencyRegion); 99 | } 100 | 101 | @ReactMethod 102 | public void setNetworkRequestsAllowed(boolean isAllowed) { 103 | AppCenter.setNetworkRequestsAllowed(isAllowed); 104 | } 105 | 106 | @ReactMethod 107 | public void isNetworkRequestsAllowed(final Promise promise) { 108 | boolean isAllowed = AppCenter.isNetworkRequestsAllowed(); 109 | promise.resolve(isAllowed); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /appcenter/android/src/main/java/com/microsoft/appcenter/reactnative/appcenter/AppCenterReactNativePackage.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.appcenter.reactnative.appcenter; 5 | 6 | import android.app.Application; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.JavaScriptModule; 10 | import com.facebook.react.bridge.NativeModule; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.uimanager.ViewManager; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.List; 17 | 18 | public class AppCenterReactNativePackage implements ReactPackage { 19 | private AppCenterReactNativeModule module; 20 | 21 | public AppCenterReactNativePackage(Application application) { 22 | this.module = new AppCenterReactNativeModule(application); 23 | } 24 | 25 | @Override 26 | public List createNativeModules(ReactApplicationContext reactContext) { 27 | List modules = new ArrayList<>(); 28 | modules.add(this.module); 29 | return modules; 30 | } 31 | 32 | // No @Override to support applications using React Native 0.47.0 or later 33 | public List> createJSModules() { 34 | return Collections.emptyList(); 35 | } 36 | 37 | @Override 38 | public List createViewManagers(ReactApplicationContext reactContext) { 39 | return Collections.emptyList(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /appcenter/appcenter-core.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, './package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | # The name is hardcoded due to a name conflict, resulting in the error 'Errno::ENOENT - No such file or directory @ rb_sysopen - appcenter.podspec.json' error. 7 | # See https://github.com/microsoft/appcenter-sdk-react-native/issues/760 8 | s.name = 'appcenter-core' 9 | s.version = package['version'] 10 | s.summary = package['description'] 11 | s.license = package['license'] 12 | s.homepage = package['homepage'] 13 | s.documentation_url = "https://docs.microsoft.com/en-us/appcenter/" 14 | 15 | s.author = { 'Microsoft' => 'appcentersdk@microsoft.com' } 16 | 17 | s.source = { :git => "https://github.com/microsoft/appcenter-sdk-react-native.git" } 18 | s.source_files = "ios/AppCenterReactNative/**/*.{h,m}" 19 | s.platform = :ios, '12.0' 20 | s.requires_arc = true 21 | 22 | s.vendored_frameworks = 'AppCenterReactNativeShared/AppCenterReactNativeShared.framework' 23 | s.dependency 'AppCenterReactNativeShared', '~> 5.0' 24 | s.dependency 'React-Core' 25 | s.static_framework = true 26 | end 27 | -------------------------------------------------------------------------------- /appcenter/appcenter-log.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const ReactNative = require('react-native'); 5 | 6 | const { AppCenterReactNative } = ReactNative.NativeModules; 7 | 8 | function format(tag, msg) { 9 | return `[${tag}] ${msg}`; 10 | } 11 | 12 | const AppCenterLog = { 13 | LogLevelVerbose: 2, 14 | LogLevelDebug: 3, 15 | LogLevelInfo: 4, 16 | LogLevelWarning: 5, 17 | LogLevelError: 6, 18 | LogLevelAssert: 7, 19 | LogLevelNone: 99, 20 | 21 | warn(tag, msg) { 22 | AppCenterReactNative.getLogLevel().then((logLevel) => { 23 | if (logLevel <= AppCenterLog.LogLevelWarning) { 24 | console.warn(format(tag, msg)); 25 | } 26 | }); 27 | }, 28 | 29 | error(tag, msg) { 30 | AppCenterReactNative.getLogLevel().then((logLevel) => { 31 | if (logLevel <= AppCenterLog.LogLevelError) { 32 | console.error(format(tag, msg)); 33 | } 34 | }); 35 | } 36 | }; 37 | 38 | module.exports = AppCenterLog; 39 | -------------------------------------------------------------------------------- /appcenter/ios/AppCenterReactNative/AppCenterReactNative.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import 5 | 6 | @interface AppCenterReactNative : NSObject 7 | 8 | + (void) register; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /appcenter/ios/AppCenterReactNative/AppCenterReactNative.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | #import "AppCenterReactNative.h" 5 | 6 | #if __has_include() 7 | #import 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #else 14 | #import "RCTAssert.h" 15 | #import "RCTBridgeModule.h" 16 | #import "RCTConvert.h" 17 | #import "RCTEventDispatcher.h" 18 | #import "RCTRootView.h" 19 | #import "RCTUtils.h" 20 | #endif 21 | 22 | #import 23 | #import 24 | 25 | @interface AppCenterReactNative () 26 | @end 27 | 28 | @implementation AppCenterReactNative 29 | 30 | RCT_EXPORT_MODULE(); 31 | 32 | + (void)register 33 | { 34 | [AppCenterReactNativeShared configureAppCenter]; 35 | } 36 | 37 | RCT_EXPORT_METHOD(startFromLibrary:(NSDictionary*)service 38 | resolver:(RCTPromiseResolveBlock)resolve 39 | rejecter:(RCTPromiseRejectBlock)reject) 40 | { 41 | id bindingType = [service objectForKey:@"bindingType"]; 42 | if ([bindingType isKindOfClass:[NSString class]]) { 43 | id serviceClass = NSClassFromString(bindingType); 44 | if (serviceClass) { 45 | [MSACAppCenter startFromLibraryWithServices:@[serviceClass]]; 46 | } 47 | } 48 | resolve(nil); 49 | } 50 | 51 | RCT_EXPORT_METHOD(setEnabled:(BOOL)enabled 52 | resolver:(RCTPromiseResolveBlock)resolve 53 | rejecter:(RCTPromiseRejectBlock)reject) 54 | { 55 | [MSACAppCenter setEnabled:enabled]; 56 | resolve(nil); 57 | } 58 | 59 | RCT_EXPORT_METHOD(isEnabled:(RCTPromiseResolveBlock)resolve 60 | rejecter:(RCTPromiseRejectBlock)reject) 61 | { 62 | resolve([NSNumber numberWithBool:[MSACAppCenter isEnabled]]); 63 | } 64 | 65 | RCT_EXPORT_METHOD(setLogLevel:(NSInteger)logLevel 66 | resolver:(RCTPromiseResolveBlock)resolve 67 | rejecter:(RCTPromiseRejectBlock)reject) 68 | { 69 | [MSACAppCenter setLogLevel:logLevel]; 70 | resolve(nil); 71 | } 72 | 73 | RCT_EXPORT_METHOD(getLogLevel:(RCTPromiseResolveBlock)resolve 74 | rejecter:(RCTPromiseRejectBlock)reject) 75 | { 76 | resolve([NSNumber numberWithInt:[MSACAppCenter logLevel]]); 77 | } 78 | 79 | RCT_EXPORT_METHOD(getInstallId:(RCTPromiseResolveBlock)resolve 80 | rejecter:(RCTPromiseRejectBlock)reject) 81 | { 82 | resolve([[MSACAppCenter installId] UUIDString]); 83 | } 84 | 85 | RCT_EXPORT_METHOD(setUserId:(NSString *)userId 86 | resolver:(RCTPromiseResolveBlock)resolve 87 | rejecter:(RCTPromiseRejectBlock)reject) 88 | { 89 | [MSACAppCenter setUserId:userId]; 90 | resolve(nil); 91 | } 92 | 93 | RCT_EXPORT_METHOD(setDataResidencyRegion:(NSString *)dataResidencyRegion 94 | resolver:(RCTPromiseResolveBlock)resolve 95 | rejecter:(RCTPromiseRejectBlock)reject) 96 | { 97 | [MSACAppCenter setDataResidencyRegion:dataResidencyRegion]; 98 | resolve(nil); 99 | } 100 | 101 | RCT_EXPORT_METHOD(setNetworkRequestsAllowed:(BOOL)isAllowed 102 | resolver:(RCTPromiseResolveBlock)resolve 103 | rejecter:(RCTPromiseRejectBlock)reject) 104 | { 105 | [MSACAppCenter setNetworkRequestsAllowed:isAllowed]; 106 | resolve(nil); 107 | } 108 | 109 | RCT_EXPORT_METHOD(isNetworkRequestsAllowed:(RCTPromiseResolveBlock)resolve 110 | rejecter:(RCTPromiseRejectBlock)reject) 111 | { 112 | resolve([NSNumber numberWithBool:[MSACAppCenter isNetworkRequestsAllowed]]); 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /appcenter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appcenter", 3 | "version": "5.0.3", 4 | "description": "Node module that contains common functionality needed to appcenter-* modules", 5 | "main": "AppCenter.js", 6 | "types": "AppCenter.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/microsoft/appcenter-sdk-react-native.git" 10 | }, 11 | "keywords": [ 12 | "react-native", 13 | "appcenter" 14 | ], 15 | "author": "Microsoft Corporation", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/microsoft/appcenter-sdk-react-native/issues" 19 | }, 20 | "homepage": "https://github.com/Microsoft/appcenter-sdk-react-native/blob/master/appcenter/README.md", 21 | "dependencies": { 22 | "appcenter-link-scripts": "5.0.3" 23 | }, 24 | "rnpm": { 25 | "android": { 26 | "packageInstance": "new AppCenterReactNativePackage(MainApplication.this)" 27 | }, 28 | "commands": { 29 | "postlink": "node node_modules/appcenter/scripts/postlink" 30 | } 31 | }, 32 | "devDependencies": { 33 | "babel-eslint": "7.2.3", 34 | "babel-jest": "25.1.0", 35 | "babel-preset-react-native": "4.0.0", 36 | "eslint": "6.8.0", 37 | "eslint-config-airbnb": "18.2.1", 38 | "eslint-plugin-import": "2.22.1", 39 | "eslint-plugin-jsx-a11y": "6.4.1", 40 | "eslint-plugin-react": "7.21.5", 41 | "react": "16.6.3", 42 | "react-native": "0.57.3" 43 | }, 44 | "scripts": { 45 | "lint": "./node_modules/.bin/eslint ." 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /appcenter/react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dependency: { 3 | platforms: { 4 | ios: {}, 5 | android: { 6 | packageInstance: 'new AppCenterReactNativePackage(getApplication())' 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /appcenter/scripts/postlink.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | const rnpmlink = require('appcenter-link-scripts'); 5 | 6 | // Configure Android first. 7 | let promise = null; 8 | if (rnpmlink.android.checkIfAndroidDirectoryExists()) { 9 | console.log('Configuring AppCenter Analytics for Android'); 10 | promise = rnpmlink.android.initAppCenterConfig() 11 | .then(() => { 12 | rnpmlink.android.removeAndroidDuplicateLinks(); 13 | }).catch((e) => { 14 | console.error(`Could not configure AppCenter for Android. Error Reason - ${e.message}`); 15 | return Promise.resolve(); 16 | }); 17 | } else { 18 | promise = Promise.resolve(); 19 | } 20 | 21 | // Then iOS even if Android failed. 22 | if (rnpmlink.ios.checkIfAppDelegateExists()) { 23 | promise 24 | .then(() => { 25 | console.log('Configuring AppCenter for iOS'); 26 | return rnpmlink.ios.initAppCenterConfig(); 27 | }) 28 | .then(() => { 29 | const code = '[AppCenterReactNative register]; // Initialize AppCenter'; 30 | return rnpmlink.ios.initInAppDelegate('#import ', code); 31 | }) 32 | .then((file) => { 33 | console.log(`Added code to initialize iOS AppCenter SDK in ${file}`); 34 | return rnpmlink.ios.addPodDeps( 35 | [{ pod: 'AppCenterReactNativeShared', version: '5.0.3' }], 36 | { platform: 'ios', version: '9.0' } 37 | ); 38 | }) 39 | .catch((e) => { 40 | console.error(`Could not configure AppCenter for iOS. Error Reason - ${e.message}`); 41 | return Promise.resolve(); 42 | }); 43 | } 44 | return promise; 45 | -------------------------------------------------------------------------------- /appcenter/test/AppCenterMock.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | jest.mock('appcenter', () => ({ 5 | getLogLevel: jest.fn(), 6 | setLogLevel: jest.fn(), 7 | getInstallId: jest.fn(), 8 | setUserId: jest.fn(), 9 | setDataResidencyRegion: jest.fn(), 10 | isEnabled: jest.fn(), 11 | setEnabled: jest.fn(), 12 | getSdkVersion: jest.fn() 13 | })); 14 | -------------------------------------------------------------------------------- /clang-format-changed-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. 5 | 6 | # This script runs clang_format on all .h, .m, and .mm files that have changes from develop branch. 7 | # Before running this, ensure that your local develop branch is up to date. 8 | upstream=$(git remote -v | grep -i "microsoft/" | awk '{print $1}' | uniq) 9 | git fetch $upstream 10 | i=0 11 | for modified_file in $(git diff $upstream/develop --diff-filter=ACMR --name-only -- *.h *.m *.mm) 12 | do 13 | if [[ $modified_file != *"Vendor/"* ]] 14 | then 15 | clang-format -i -style=file $modified_file 16 | exit_code=$? 17 | if [ $exit_code -ne 0 ] 18 | then 19 | echo "Failed to format file: "$modified_file 20 | else 21 | ((i++)) 22 | fi 23 | fi 24 | done 25 | echo "Formatted "$i" file(s)." 26 | -------------------------------------------------------------------------------- /scripts/bump-android-sdk-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Update App Center React Native SDK to reference a new version of App Center Android SDK 3 | 4 | set -e 5 | 6 | while [ "$1" != "" ]; do 7 | PARAM=`echo $1 | awk -F= '{print $1}'` 8 | VALUE=`echo $1 | awk -F= '{print $2}'` 9 | case $PARAM in 10 | --newAndroidSdkVersion) 11 | newAndroidSdkVersion=$VALUE ;; 12 | *) 13 | esac 14 | shift 15 | done 16 | 17 | # Exit if newAndroidSdkVersion has not been set 18 | if [ -z $newAndroidSdkVersion ]; then 19 | echo "--newAndroidSdkVersion cannot be empty. Please pass in new android sdk version as parameter." 20 | exit 1 21 | fi 22 | 23 | # Find out the old android sdk version 24 | oldAndroidSdkVersionString=$(grep com.microsoft.appcenter:appcenter ./appcenter/android/build.gradle) 25 | [[ ${oldAndroidSdkVersionString} =~ ([0-9]+.[0-9]+.[0-9]+) ]] 26 | oldAndroidSdkVersion="${BASH_REMATCH[1]}" 27 | 28 | # Exit if old android sdk is not set 29 | if [ -z $oldAndroidSdkVersion ]; then 30 | echo "oldAndroidSdkVersion cannot be empty" 31 | exit 1 32 | fi 33 | 34 | echo "React-Native Android version $oldAndroidSdkVersion will be updated to $newAndroidSdkVersion" 35 | 36 | # Update android sdk version in build.gradle for appcenter, appcenter-crashes, appcenter-analytics, 37 | # AppCenterReactNativeShared projects 38 | for file in \ 39 | "appcenter/android/build.gradle" \ 40 | "appcenter-analytics/android/build.gradle" \ 41 | "appcenter-crashes/android/build.gradle" \ 42 | "AppCenterReactNativeShared/android/build.gradle" 43 | do 44 | sed -E -i '' "s#(com\.microsoft\.appcenter:appcenter.*:)([^:'])+#\1$newAndroidSdkVersion#g" $file 45 | done 46 | 47 | echo "done." 48 | -------------------------------------------------------------------------------- /scripts/bump-ios-sdk-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Update App Center React Native SDK to reference a new version of App Center iOS SDK 3 | 4 | set -e 5 | 6 | while [ "$1" != "" ]; do 7 | PARAM=`echo $1 | awk -F= '{print $1}'` 8 | VALUE=`echo $1 | awk -F= '{print $2}'` 9 | case $PARAM in 10 | --newiOSSdkVersion) 11 | newiOSSdkVersion=$VALUE ;; 12 | *) 13 | esac 14 | shift 15 | done 16 | 17 | # Exit if newiOSSdkVersion has not been set 18 | if [ -z $newiOSSdkVersion ]; then 19 | echo "--newiOSSdkVersion cannot be empty. Please pass in new iOS sdk version as parameter." 20 | exit 1 21 | fi 22 | 23 | # Find out the old iOS sdk version 24 | oldiOSSdkVersionString=$(grep AppCenter/Core ./AppCenterReactNativeShared/Products/AppCenterReactNativeShared.podspec) 25 | [[ ${oldiOSSdkVersionString} =~ ([0-9]+.[0-9]+.[0-9]+) ]] 26 | oldiOSSdkVersion="${BASH_REMATCH[1]}" 27 | 28 | # Exit if old iOS sdk version is not set 29 | if [ -z $oldiOSSdkVersion ]; then 30 | echo "oldiOSSdkVersion cannot be empty" 31 | exit 1 32 | fi 33 | 34 | echo "React-Native iOS version $oldiOSSdkVersion will be updated to $newiOSSdkVersion" 35 | 36 | # Update iOS sdk version in postlink.js for appcenter-crashes, appcenter-analytics projects 37 | fileContent="$(cat ./appcenter-crashes/scripts/postlink.js)" 38 | echo "${fileContent/\'AppCenter\/Crashes\', version\: \'$oldiOSSdkVersion\'/'AppCenter/Crashes', version: '$newiOSSdkVersion'}" > ./appcenter-crashes/scripts/postlink.js 39 | 40 | fileContent="$(cat ./appcenter-analytics/scripts/postlink.js)" 41 | echo "${fileContent/\'AppCenter\/Analytics\', version\: \'$oldiOSSdkVersion\'/'AppCenter/Analytics', version: '$newiOSSdkVersion'}" > ./appcenter-analytics/scripts/postlink.js 42 | 43 | # Update iOS sdk version in AppCenterReactNativeShared podspec 44 | fileContent="$(cat ./AppCenterReactNativeShared/Products/AppCenterReactNativeShared.podspec)" 45 | echo "${fileContent/s.dependency \'AppCenter\/Core\', \'$oldiOSSdkVersion\'/s.dependency 'AppCenter/Core', '$newiOSSdkVersion'}" > ./AppCenterReactNativeShared/Products/AppCenterReactNativeShared.podspec 46 | 47 | # Update wrapper sdk version in local.podspec, 48 | # so that local.podspec is in sync with AppCenterReactNativeShared.podspec. 49 | fileContent="$(cat ./AppCenterReactNativeShared/Products/local.podspec)" 50 | echo "${fileContent/s.dependency \'AppCenter\/Core\', \'$oldiOSSdkVersion\'/s.dependency 'AppCenter/Core', '$newiOSSdkVersion'}" > ./AppCenterReactNativeShared/Products/local.podspec 51 | 52 | echo "done." 53 | -------------------------------------------------------------------------------- /scripts/eslint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # ESLint should be installed locally in order to work reliably. 5 | # Please make sure ESLint is only installed locally not globally. 6 | 7 | directories=("appcenter" "appcenter-analytics" "appcenter-crashes" "appcenter-link-scripts" "TestApp") 8 | for directory in "${directories[@]}" 9 | do 10 | cd ${directory} 11 | rm -f package-lock.json 12 | if [ "$directory" = "TestApp" ]; then 13 | ./prepare-local-sdk-integration.sh 14 | else 15 | npm install 16 | fi 17 | npm run lint 18 | cd .. 19 | done 20 | -------------------------------------------------------------------------------- /scripts/npm-pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo "Packing appcenter* packages..." 5 | npm pack ./appcenter 6 | npm pack ./appcenter-analytics 7 | npm pack ./appcenter-crashes 8 | npm pack ./appcenter-link-scripts 9 | 10 | echo "Move appcenter*.tgz into sub-directory ./packages" 11 | mkdir -p packages 12 | cp appcenter*.tgz ./packages 13 | rm appcenter*.tgz 14 | -------------------------------------------------------------------------------- /scripts/put-maven-secrets-gradle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cat >> AppCenterReactNativeShared/android/local.properties << EOL 3 | maven.user=${1:-$MAVEN_USER} 4 | maven.key=${2:-$MAVEN_KEY} 5 | maven.signingKeyId=${3:-$GDP_SIGNING_KEY_ID} 6 | maven.secretKeyPath=${4:-$GDP_KEY_SECRET_PATH} 7 | maven.publicKeyPassword=${5:-$GDP_KEY_PASSWORD} 8 | EOL 9 | -------------------------------------------------------------------------------- /scripts/update-app-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Replace app-secret's and tokens values in test apps. Update TestApp by default. 3 | 4 | # Usage: 5 | # ./scripts/update-app-secrets.sh 6 | 7 | # Dynamic constants. 8 | appName="TestApp" 9 | appPrefix="INT" 10 | 11 | # Constants for iOS and Android. 12 | declare -a platformConstants=( 13 | "RN_IOS_${appPrefix}" 14 | "RN_IOS_TARGET_TOKEN_${appPrefix}" 15 | "RN_IOS_PARENT_TARGET_TOKEN_${appPrefix}" 16 | "RN_IOS_CHILD1_TARGET_TOKEN_${appPrefix}" 17 | "RN_IOS_CHILD2_TARGET_TOKEN_${appPrefix}" 18 | 19 | "RN_ANDROID_${appPrefix}" 20 | "RN_ANDROID_TARGET_TOKEN_${appPrefix}" 21 | "RN_ANDROID_PARENT_TARGET_TOKEN_${appPrefix}" 22 | "RN_ANDROID_CHILD1_TARGET_TOKEN_${appPrefix}" 23 | "RN_ANDROID_CHILD2_TARGET_TOKEN_${appPrefix}") 24 | 25 | # Files which should be changed. 26 | declare -a targetFiles=("${appName}/app/Constants.android.js" 27 | "${appName}/app/Constants.ios.js" 28 | "${appName}/app/screens/AppCenterScreen.js" 29 | "${appName}/ios/${appName}/AppCenter-Config.plist" 30 | "${appName}/ios/${appName}/Info.plist" 31 | "${appName}/android/app/src/main/assets/appcenter-config.json" 32 | "${appName}/android/app/src/main/AndroidManifest.xml") 33 | 34 | # Print info about current job. 35 | echo "Insert secrets to ${appName} app." 36 | 37 | # Update files from array. 38 | for constant in "${platformConstants[@]}" 39 | do 40 | for file in "${targetFiles[@]}" 41 | do 42 | # Replace secret value from enviroment variables. 43 | sed -i '' "s/{$constant}/"${!constant}"/g" $file 44 | done 45 | done 46 | --------------------------------------------------------------------------------