├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── parryworld │ └── rnappupdate │ ├── RNAppUpdate.java │ └── RNAppUpdatePackage.java ├── index.js ├── ios ├── RNAppUpdate.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── RNAppUpdate │ ├── RNAppUpdate.h │ └── RNAppUpdate.m └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata 3 | build/ 4 | *.iml 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata 3 | build/ 4 | *.iml 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 parryworld 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Not Maintained] React Native AppUpdate 2 | 3 | Sorry, guys. I haven't developed React Native since a long time ago, so this repo is no longer maintained. 4 | 5 | If you still need this functionality, you can use [react-native-update-apk](https://github.com/mikehardy/react-native-update-apk) instead. 6 | 7 | --- 8 | 9 | Update apk and update from app store in React Native. 10 | 11 | ## Installation 12 | ```bash 13 | npm install react-native-appupdate --save 14 | ``` 15 | **Note: If your react-native version < 0.40** 16 | 17 | ```bash 18 | npm install react-native-appupdate@1.0.5 --save 19 | ``` 20 | 21 | adding automatically with react-native link 22 | 23 | ```bash 24 | react-native link react-native-appupdate 25 | react-native link react-native-fs 26 | ``` 27 | ## Usage 28 | ```javascript 29 | import { Alert } from 'react-native'; 30 | import AppUpdate from 'react-native-appupdate'; 31 | 32 | const appUpdate = new AppUpdate({ 33 | iosAppId: '123456', 34 | apkVersionUrl: 'https://github.com/version.json', 35 | needUpdateApp: (needUpdate) => { 36 | Alert.alert( 37 | 'Update tip', 38 | 'Finding new version, do you want to update?', 39 | [ 40 | {text: 'Cancel', onPress: () => {}}, 41 | {text: 'Update', onPress: () => needUpdate(true)} 42 | ] 43 | ); 44 | }, 45 | forceUpdateApp: () => { 46 | console.log("Force update will start") 47 | }, 48 | notNeedUpdateApp: () => { 49 | console.log("App is up to date") 50 | }, 51 | downloadApkStart: () => { console.log("Start") }, 52 | downloadApkProgress: (progress) => { console.log(`Downloading ${progress}%...`) }, 53 | downloadApkEnd: () => { console.log("End") }, 54 | onError: () => { console.log("downloadApkError") } 55 | }); 56 | appUpdate.checkUpdate(); 57 | ``` 58 | 59 | ```javascript 60 | // version.json 61 | { 62 | "versionName":"1.0.0", 63 | "apkUrl":"https://github.com/NewApp.apk", 64 | "forceUpdate": false 65 | } 66 | ``` 67 | ## Third Library 68 | * react-native-fs 69 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 22 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | compile 'com.android.support:appcompat-v7:23.0.1' 24 | compile "com.facebook.react:react-native:+" 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/com/parryworld/rnappupdate/RNAppUpdate.java: -------------------------------------------------------------------------------- 1 | package com.parryworld.rnappupdate; 2 | 3 | import android.content.Intent; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | import android.net.Uri; 7 | 8 | import com.facebook.react.bridge.ReactApplicationContext; 9 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 10 | import com.facebook.react.bridge.ReactMethod; 11 | 12 | import java.io.File; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created by parryworld on 2016/11/18. 18 | */ 19 | 20 | public class RNAppUpdate extends ReactContextBaseJavaModule { 21 | 22 | private String versionName = "1.0.0"; 23 | private int versionCode = 1; 24 | 25 | public RNAppUpdate(ReactApplicationContext reactContext) { 26 | super(reactContext); 27 | PackageInfo pInfo = null; 28 | try { 29 | pInfo = reactContext.getPackageManager().getPackageInfo(reactContext.getPackageName(), 0); 30 | versionName = pInfo.versionName; 31 | versionCode = pInfo.versionCode; 32 | } catch (PackageManager.NameNotFoundException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return "RNAppUpdate"; 40 | } 41 | 42 | @Override 43 | public Map getConstants() { 44 | final Map constants = new HashMap<>(); 45 | constants.put("versionName", versionName); 46 | constants.put("versionCode", versionCode); 47 | return constants; 48 | } 49 | 50 | @ReactMethod 51 | public void installApk(String file) { 52 | String cmd = "chmod 777 " + file; 53 | try { 54 | Runtime.getRuntime().exec(cmd); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | Intent intent = new Intent(Intent.ACTION_VIEW); 59 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 60 | intent.setDataAndType(Uri.parse("file://" + file), "application/vnd.android.package-archive"); 61 | getCurrentActivity().startActivity(intent); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /android/src/main/java/com/parryworld/rnappupdate/RNAppUpdatePackage.java: -------------------------------------------------------------------------------- 1 | package com.parryworld.rnappupdate; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.Arrays; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by parryworld on 2016/11/18. 15 | */ 16 | 17 | public class RNAppUpdatePackage implements ReactPackage { 18 | 19 | @Override 20 | public List createNativeModules(ReactApplicationContext reactContext) { 21 | return Arrays.asList(new NativeModule[]{ 22 | new RNAppUpdate(reactContext), 23 | }); 24 | } 25 | 26 | // Deprecated RN 0.47 27 | // @Override 28 | public List> createJSModules() { 29 | return Collections.emptyList(); 30 | } 31 | 32 | @Override 33 | public List createViewManagers(ReactApplicationContext reactContext) { 34 | return Collections.emptyList(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { 4 | NativeModules, 5 | Platform, 6 | } from 'react-native'; 7 | import RNFS from 'react-native-fs'; 8 | 9 | const RNAppUpdate = NativeModules.RNAppUpdate; 10 | 11 | const jobId = -1; 12 | 13 | class AppUpdate { 14 | constructor(options) { 15 | this.options = options; 16 | } 17 | 18 | GET(url, success, error) { 19 | fetch(url) 20 | .then((response) => response.json()) 21 | .then((json) => { 22 | success && success(json); 23 | }) 24 | .catch((err) => { 25 | error && error(err); 26 | }); 27 | } 28 | 29 | getApkVersion() { 30 | if (jobId !== -1) { 31 | return; 32 | } 33 | if (!this.options.apkVersionUrl) { 34 | console.log("apkVersionUrl doesn't exist."); 35 | return; 36 | } 37 | this.GET(this.options.apkVersionUrl, this.getApkVersionSuccess.bind(this), this.getVersionError.bind(this)); 38 | } 39 | 40 | getApkVersionSuccess(remote) { 41 | console.log("getApkVersionSuccess", remote); 42 | if (RNAppUpdate.versionName !== remote.versionName) { 43 | if (remote.forceUpdate) { 44 | if(this.options.forceUpdateApp) { 45 | this.options.forceUpdateApp(); 46 | } 47 | this.downloadApk(remote); 48 | } else if (this.options.needUpdateApp) { 49 | this.options.needUpdateApp((isUpdate) => { 50 | if (isUpdate) { 51 | this.downloadApk(remote); 52 | } 53 | }); 54 | } 55 | } else if(this.options.notNeedUpdateApp) { 56 | this.options.notNeedUpdateApp(); 57 | } 58 | } 59 | 60 | downloadApk(remote) { 61 | const progress = (data) => { 62 | const percentage = ((100 * data.bytesWritten) / data.contentLength) | 0; 63 | this.options.downloadApkProgress && this.options.downloadApkProgress(percentage); 64 | }; 65 | const begin = (res) => { 66 | console.log("downloadApkStart"); 67 | this.options.downloadApkStart && this.options.downloadApkStart(); 68 | }; 69 | const progressDivider = 1; 70 | const downloadDestPath = `${RNFS.DocumentDirectoryPath}/NewApp.apk`; 71 | 72 | const ret = RNFS.downloadFile({ 73 | fromUrl: remote.apkUrl, 74 | toFile: downloadDestPath, 75 | begin, 76 | progress, 77 | background: true, 78 | progressDivider 79 | }); 80 | 81 | jobId = ret.jobId; 82 | 83 | ret.promise.then((res) => { 84 | console.log("downloadApkEnd"); 85 | this.options.downloadApkEnd && this.options.downloadApkEnd(); 86 | RNAppUpdate.installApk(downloadDestPath); 87 | 88 | jobId = -1; 89 | }).catch((err) => { 90 | this.downloadApkError(err); 91 | 92 | jobId = -1; 93 | }); 94 | } 95 | 96 | getAppStoreVersion() { 97 | if (!this.options.iosAppId) { 98 | console.log("iosAppId doesn't exist."); 99 | return; 100 | } 101 | this.GET("https://itunes.apple.com/lookup?id=" + this.options.iosAppId, this.getAppStoreVersionSuccess.bind(this), this.getVersionError.bind(this)); 102 | } 103 | 104 | getAppStoreVersionSuccess(data) { 105 | if (data.resultCount < 1) { 106 | console.log("iosAppId is wrong."); 107 | return; 108 | } 109 | const result = data.results[0]; 110 | const version = result.version; 111 | const trackViewUrl = result.trackViewUrl; 112 | if (version !== RNAppUpdate.versionName) { 113 | if (this.options.needUpdateApp) { 114 | this.options.needUpdateApp((isUpdate) => { 115 | if (isUpdate) { 116 | RNAppUpdate.installFromAppStore(trackViewUrl); 117 | } 118 | }); 119 | } 120 | } 121 | } 122 | 123 | getVersionError(err) { 124 | console.log("getVersionError", err); 125 | } 126 | 127 | downloadApkError(err) { 128 | console.log("downloadApkError", err); 129 | this.options.onError && this.options.onError(); 130 | } 131 | 132 | checkUpdate() { 133 | if (Platform.OS === 'android') { 134 | this.getApkVersion(); 135 | } else { 136 | this.getAppStoreVersion(); 137 | } 138 | } 139 | } 140 | 141 | export default AppUpdate; 142 | -------------------------------------------------------------------------------- /ios/RNAppUpdate.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0EA4DC2B1DDEC30100B4B05F /* RNAppUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EA4DC2A1DDEC30100B4B05F /* RNAppUpdate.m */; }; 11 | 0EA4DC2C1DDEC30100B4B05F /* RNAppUpdate.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0EA4DC291DDEC30100B4B05F /* RNAppUpdate.h */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 0EA4DC241DDEC30100B4B05F /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | 0EA4DC2C1DDEC30100B4B05F /* RNAppUpdate.h in CopyFiles */, 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 0EA4DC261DDEC30100B4B05F /* libRNAppUpdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNAppUpdate.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 0EA4DC291DDEC30100B4B05F /* RNAppUpdate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNAppUpdate.h; sourceTree = ""; }; 30 | 0EA4DC2A1DDEC30100B4B05F /* RNAppUpdate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNAppUpdate.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 0EA4DC231DDEC30100B4B05F /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 0EA4DC1D1DDEC30100B4B05F = { 45 | isa = PBXGroup; 46 | children = ( 47 | 0EA4DC281DDEC30100B4B05F /* RNAppUpdate */, 48 | 0EA4DC271DDEC30100B4B05F /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 0EA4DC271DDEC30100B4B05F /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 0EA4DC261DDEC30100B4B05F /* libRNAppUpdate.a */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 0EA4DC281DDEC30100B4B05F /* RNAppUpdate */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 0EA4DC291DDEC30100B4B05F /* RNAppUpdate.h */, 64 | 0EA4DC2A1DDEC30100B4B05F /* RNAppUpdate.m */, 65 | ); 66 | path = RNAppUpdate; 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | 0EA4DC251DDEC30100B4B05F /* RNAppUpdate */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = 0EA4DC2F1DDEC30100B4B05F /* Build configuration list for PBXNativeTarget "RNAppUpdate" */; 75 | buildPhases = ( 76 | 0EA4DC221DDEC30100B4B05F /* Sources */, 77 | 0EA4DC231DDEC30100B4B05F /* Frameworks */, 78 | 0EA4DC241DDEC30100B4B05F /* CopyFiles */, 79 | ); 80 | buildRules = ( 81 | ); 82 | dependencies = ( 83 | ); 84 | name = RNAppUpdate; 85 | productName = RNAppUpdate; 86 | productReference = 0EA4DC261DDEC30100B4B05F /* libRNAppUpdate.a */; 87 | productType = "com.apple.product-type.library.static"; 88 | }; 89 | /* End PBXNativeTarget section */ 90 | 91 | /* Begin PBXProject section */ 92 | 0EA4DC1E1DDEC30100B4B05F /* Project object */ = { 93 | isa = PBXProject; 94 | attributes = { 95 | LastUpgradeCheck = 0810; 96 | ORGANIZATIONNAME = parryworld; 97 | TargetAttributes = { 98 | 0EA4DC251DDEC30100B4B05F = { 99 | CreatedOnToolsVersion = 8.1; 100 | ProvisioningStyle = Automatic; 101 | }; 102 | }; 103 | }; 104 | buildConfigurationList = 0EA4DC211DDEC30100B4B05F /* Build configuration list for PBXProject "RNAppUpdate" */; 105 | compatibilityVersion = "Xcode 3.2"; 106 | developmentRegion = English; 107 | hasScannedForEncodings = 0; 108 | knownRegions = ( 109 | en, 110 | ); 111 | mainGroup = 0EA4DC1D1DDEC30100B4B05F; 112 | productRefGroup = 0EA4DC271DDEC30100B4B05F /* Products */; 113 | projectDirPath = ""; 114 | projectRoot = ""; 115 | targets = ( 116 | 0EA4DC251DDEC30100B4B05F /* RNAppUpdate */, 117 | ); 118 | }; 119 | /* End PBXProject section */ 120 | 121 | /* Begin PBXSourcesBuildPhase section */ 122 | 0EA4DC221DDEC30100B4B05F /* Sources */ = { 123 | isa = PBXSourcesBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 0EA4DC2B1DDEC30100B4B05F /* RNAppUpdate.m in Sources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXSourcesBuildPhase section */ 131 | 132 | /* Begin XCBuildConfiguration section */ 133 | 0EA4DC2D1DDEC30100B4B05F /* Debug */ = { 134 | isa = XCBuildConfiguration; 135 | buildSettings = { 136 | ALWAYS_SEARCH_USER_PATHS = NO; 137 | CLANG_ANALYZER_NONNULL = YES; 138 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 139 | CLANG_CXX_LIBRARY = "libc++"; 140 | CLANG_ENABLE_MODULES = YES; 141 | CLANG_ENABLE_OBJC_ARC = YES; 142 | CLANG_WARN_BOOL_CONVERSION = YES; 143 | CLANG_WARN_CONSTANT_CONVERSION = YES; 144 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 145 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 146 | CLANG_WARN_EMPTY_BODY = YES; 147 | CLANG_WARN_ENUM_CONVERSION = YES; 148 | CLANG_WARN_INFINITE_RECURSION = YES; 149 | CLANG_WARN_INT_CONVERSION = YES; 150 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 151 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 152 | CLANG_WARN_UNREACHABLE_CODE = YES; 153 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 154 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 155 | COPY_PHASE_STRIP = NO; 156 | DEBUG_INFORMATION_FORMAT = dwarf; 157 | ENABLE_STRICT_OBJC_MSGSEND = YES; 158 | ENABLE_TESTABILITY = YES; 159 | GCC_C_LANGUAGE_STANDARD = gnu99; 160 | GCC_DYNAMIC_NO_PIC = NO; 161 | GCC_NO_COMMON_BLOCKS = YES; 162 | GCC_OPTIMIZATION_LEVEL = 0; 163 | GCC_PREPROCESSOR_DEFINITIONS = ( 164 | "DEBUG=1", 165 | "$(inherited)", 166 | ); 167 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 168 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 169 | GCC_WARN_UNDECLARED_SELECTOR = YES; 170 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 171 | GCC_WARN_UNUSED_FUNCTION = YES; 172 | GCC_WARN_UNUSED_VARIABLE = YES; 173 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 174 | MTL_ENABLE_DEBUG_INFO = YES; 175 | ONLY_ACTIVE_ARCH = YES; 176 | SDKROOT = iphoneos; 177 | }; 178 | name = Debug; 179 | }; 180 | 0EA4DC2E1DDEC30100B4B05F /* Release */ = { 181 | isa = XCBuildConfiguration; 182 | buildSettings = { 183 | ALWAYS_SEARCH_USER_PATHS = NO; 184 | CLANG_ANALYZER_NONNULL = YES; 185 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 186 | CLANG_CXX_LIBRARY = "libc++"; 187 | CLANG_ENABLE_MODULES = YES; 188 | CLANG_ENABLE_OBJC_ARC = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_CONSTANT_CONVERSION = YES; 191 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 192 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 193 | CLANG_WARN_EMPTY_BODY = YES; 194 | CLANG_WARN_ENUM_CONVERSION = YES; 195 | CLANG_WARN_INFINITE_RECURSION = YES; 196 | CLANG_WARN_INT_CONVERSION = YES; 197 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 198 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 199 | CLANG_WARN_UNREACHABLE_CODE = YES; 200 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 201 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 202 | COPY_PHASE_STRIP = NO; 203 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 204 | ENABLE_NS_ASSERTIONS = NO; 205 | ENABLE_STRICT_OBJC_MSGSEND = YES; 206 | GCC_C_LANGUAGE_STANDARD = gnu99; 207 | GCC_NO_COMMON_BLOCKS = YES; 208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 210 | GCC_WARN_UNDECLARED_SELECTOR = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 212 | GCC_WARN_UNUSED_FUNCTION = YES; 213 | GCC_WARN_UNUSED_VARIABLE = YES; 214 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 215 | MTL_ENABLE_DEBUG_INFO = NO; 216 | SDKROOT = iphoneos; 217 | VALIDATE_PRODUCT = YES; 218 | }; 219 | name = Release; 220 | }; 221 | 0EA4DC301DDEC30100B4B05F /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | HEADER_SEARCH_PATHS = "$(SRCROOT)/../../react-native/React/**"; 225 | OTHER_LDFLAGS = "-ObjC"; 226 | PRODUCT_NAME = "$(TARGET_NAME)"; 227 | SKIP_INSTALL = YES; 228 | }; 229 | name = Debug; 230 | }; 231 | 0EA4DC311DDEC30100B4B05F /* Release */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | HEADER_SEARCH_PATHS = "$(SRCROOT)/../../react-native/React/**"; 235 | OTHER_LDFLAGS = "-ObjC"; 236 | PRODUCT_NAME = "$(TARGET_NAME)"; 237 | SKIP_INSTALL = YES; 238 | }; 239 | name = Release; 240 | }; 241 | /* End XCBuildConfiguration section */ 242 | 243 | /* Begin XCConfigurationList section */ 244 | 0EA4DC211DDEC30100B4B05F /* Build configuration list for PBXProject "RNAppUpdate" */ = { 245 | isa = XCConfigurationList; 246 | buildConfigurations = ( 247 | 0EA4DC2D1DDEC30100B4B05F /* Debug */, 248 | 0EA4DC2E1DDEC30100B4B05F /* Release */, 249 | ); 250 | defaultConfigurationIsVisible = 0; 251 | defaultConfigurationName = Release; 252 | }; 253 | 0EA4DC2F1DDEC30100B4B05F /* Build configuration list for PBXNativeTarget "RNAppUpdate" */ = { 254 | isa = XCConfigurationList; 255 | buildConfigurations = ( 256 | 0EA4DC301DDEC30100B4B05F /* Debug */, 257 | 0EA4DC311DDEC30100B4B05F /* Release */, 258 | ); 259 | defaultConfigurationIsVisible = 0; 260 | defaultConfigurationName = Release; 261 | }; 262 | /* End XCConfigurationList section */ 263 | }; 264 | rootObject = 0EA4DC1E1DDEC30100B4B05F /* Project object */; 265 | } 266 | -------------------------------------------------------------------------------- /ios/RNAppUpdate.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/RNAppUpdate/RNAppUpdate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNAppUpdate.h 3 | // RNAppUpdate 4 | // 5 | // Created by parryworld on 2016/11/18. 6 | // Copyright © 2016年 parryworld. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RNAppUpdate : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/RNAppUpdate/RNAppUpdate.m: -------------------------------------------------------------------------------- 1 | // 2 | // RNAppUpdate.m 3 | // RNAppUpdate 4 | // 5 | // Created by parryworld on 2016/11/18. 6 | // Copyright © 2016年 parryworld. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RNAppUpdate.h" 11 | 12 | @interface RNAppUpdate() { 13 | NSString *versionName; 14 | NSString *versionCode; 15 | } 16 | @end 17 | 18 | @implementation RNAppUpdate 19 | 20 | RCT_EXPORT_MODULE(); 21 | 22 | - (id)init { 23 | self = [super init]; 24 | if (self) { 25 | versionName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 26 | versionCode = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSDictionary *)constantsToExport { 32 | return @{ 33 | @"versionName":versionName, 34 | @"versionCode":versionCode, 35 | }; 36 | } 37 | 38 | RCT_EXPORT_METHOD(installFromAppStore:(nonnull NSString *)trackViewURL) { 39 | UIApplication *application = [UIApplication sharedApplication]; 40 | NSURL *URL = [NSURL URLWithString:trackViewURL]; 41 | 42 | if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) { 43 | [application openURL:URL options:@{} completionHandler:nil]; 44 | } else { 45 | [application openURL:URL]; 46 | } 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-appupdate", 3 | "version": "1.1.2", 4 | "description": "Update apk and update from app store in React Native", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/parryworld/react-native-appupdate.git" 9 | }, 10 | "keywords": [ 11 | "react-native", 12 | "react-component", 13 | "ios", 14 | "android", 15 | "update", 16 | "app", 17 | "apk" 18 | ], 19 | "author": "parryworld", 20 | "license": "MIT", 21 | "dependencies": { 22 | "react-native-fs": "^2.3.3" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/parryworld/react-native-appupdate/issues" 26 | }, 27 | "homepage": "https://github.com/parryworld/react-native-appupdate" 28 | } 29 | --------------------------------------------------------------------------------