A brief discussion on React native APP updates

A brief discussion on React native APP updates

App Update Process

1. Request an interface or file when the App is opened to obtain reuse information such as remote version/version update instructions/address, etc.

2. Get the current version of the App through the library or native solution

3. Compare the differences between the remote version and the current version (you can use a library or write a comparison solution yourself)

4. Operate through the obtained link (you can jump to the corresponding website to download, similar to Dandelion, which can be an apk link, downloaded through the Android native method, or an App Store link)

Rough flow chart

Detailed description:

1. These remote information can be interfaces, so that there can be a middle platform to control it, or of course it can be a file, so that the operation and maintenance can control the relevant information, not only the remote version, but also other attributes can be added in the project, such as: versionCode, versionCodeSwitch, notUpdate, deleteApp

  • 1.1 versionCode Upgrade the version by code, which is usually a number (necessary when submitting to the App Store in iOS). In this way, versionName will not increase. However, if versionCode is added, if versionName is to be upgraded, versionCode also needs to be increased.
  • 1.2 versionCodeSwitch is used to control whether to update according to versionCode. Generally, I turn it on in testing and other environments and turn it off in production environment.
  • 1.3 notUpdate Whether to update based on remote information, usually turned on
  • 1.4 deleteApp Android app needs to be uninstalled and reinstalled, because direct installation may have some problems. This information will be used to delete the app first and then download it again

2. There are many ways to get the information of the current mobile phone. I use the react-native-device-info library, which provides more complete information. Of course, you can also use native methods to get the information of the APP.

3. You can use a library or write your own library to compare the local version number with the native version number. Here are two libraries recommended, both with over a million downloads: semver-compare and compare-versions. Here is my versionName comparison solution, which is relatively simple:

/**
 * Compare two version numbers * @param currentVersion 
 * @return boolean 
 * true=need to update false=not needed*/
compareVersion = (currentVersion: string): boolean => {
    const {versionName: remoteVersion} = this.remoteInfo || {}
    if (!remoteVersion) {
        return false
    }
    if (currentVersion === remoteVersion) {
        return false
    }
    const currentVersionArr = currentVersion.split('.')
    const remoteVersionArr = remoteVersion.split('.')
    for (let i = 0; i < 3; i++) {
        if (Number(currentVersionArr[i]) < Number(remoteVersionArr[i])) {
            return true
        }
    } 
    return false
}

There are many ways to download apps. The simplest one is to jump to a third-party platform, such as Dandelion, and use the Linking method provided by RN to jump directly. Of course, Android can be downloaded directly through the address provided by itself. Here is a method (this method comes from the Internet):

@ReactMethod
public void installApk(String filePath, String fileProviderAuthority) {
    File file = new File(filePath);
    if (!file.exists()) {
        Log.e("RNUpdater", "installApk: file does not exist '" + filePath + "'");
        // FIXME this should take a promise and fail it
 return;
    }
    if (Build.VERSION.SDK_INT >= 24) {
        // API24 and up has a package installer that can handle FileProvider content:// URIs
 Uri contentUri;
        try {
            contentUri = FileProvider.getUriForFile(getReactApplicationContext(), fileProviderAuthority, file);
        } catch (Exception e) {
            // FIXME should be a Promise.reject really
 Log.e("RNUpdater", "installApk exception with authority name '" + fileProviderAuthority + "'", e);
            throw e;
        }
        Intent installApp = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        installApp.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        installApp.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        installApp.setData(contentUri);
        installApp.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, reactContext.getApplicationInfo().packageName);
        reactContext.startActivity(installApp);
    } else {
        // Old APIs do not handle content:// URIs, so use an old file:// style
 String cmd = "chmod 777 " + file;
        try {
            Runtime.getRuntime().exec(cmd);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.parse("file://" + file), "application/vnd.android.package-archive");
        reactContext.startActivity(intent);
    }
}

If we provide download services ourselves, we need to pay attention to bandwidth. If the network speed is too slow, the user experience will be too poor, and it will also lead to more traffic consumption. The trade-offs need to be decided by developers.

Update APP information

When packaging, update the interface or file information through the script. Of course, this depends on the specific packaging solution. For example, my current solution is to use Jenkins for packaging, and use shell scripts to update the corresponding information when packaging (other language scripts can also be used if necessary):

1. First define the file address you need to obtain

androidVersionFilePath="$WORKSPACE/android/app/build.gradle" // Get Android version information through this fileiosVersionFilePath="$WORKSPACE/ios/veronica/Info.plist" // Get iOS version information through this filechangeLogPath="$WORKSPACE/change.log" // Store version update information in this file

2. Obtain the version information after packaging through the file address

getAndroidVersion(){
  androidVersion=$(cat $androidVersionFilePath | grep "versionName" | awk '{print $2}' | sed 's/\"//g')
  androidCode=$(cat $androidVersionFilePath | grep "versionCode " | awk '{print $2}' | sed 's/\"//g')
  androidDelete=$(cat $androidVersionFilePath | grep "deleteApp" | awk '{print $4}' | sed 's/\"//g')
  return 0
}

getIOSVersion(){
  rows=$(awk '/CFBundleShortVersionString/ {getline; print}' $iosVersionFilePath)
  iosVersion=$(echo "$rows" | sed -ne 's/<string>\(.*\)<\/string>/\1/p')
  iosVersion=$(echo "$iosVersion" | sed 's/^[[:space:]]*//')

  rows2=$(awk '/VersionCode/ {getline; print}' $iosVersionFilePath)
  iosCode=$(echo "$rows2" | sed -ne 's/<string>\(.*\)<\/string>/\1/p')
  iosCode=$(echo "$iosCode" | sed 's/^[[:space:]]*//')
  return 0
}

desc=$(cat $changeLogPath | tr "\n" "#")

3. Replace the information in the existing file

sed -i '' "s/\"releaseInfo\":.*$/\"releaseInfo\": \"$desc\"/" $JsonPath/$fileName
sed -i '' "s/\"versionName\":.*$/\"versionName\": \"$versionName\",/" $JsonPath/$fileName
sed -i '' "s/\"versionCode\":.*$/\"versionCode\": \"$versionCode\",/" $JsonPath/$fileName
sed -i '' "s/\"deleteApp\":.*$/\"deleteApp\": \"$deleteApp\",/" $JsonPath/$fileName

My file is in json format, and the description text can be filled in arbitrarily, which will trigger some parsing problems:

  • Symbols that will cause JSON.parse to fail are not allowed, such as \, ````, \n, \r, \" etc.
  • Because I use # to break the description text, this symbol is not allowed.

Rough flow chart

Summarize

This is basically the update process for the native version of the APP. Of course, this process is not only applicable to APP, but also to PC software updates. In addition to the native version update, there is also a hot update, which is also very important.

The above is a brief discussion of the details of React native APP updates. For more information about React native APP updates, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of React setState data update mechanism
  • React Native implements hot update and automatic signature packaging function
  • Principle in-depth analysis Vue's responsive updates are faster than React
  • React component rendering and updating implementation code example
  • Detailed explanation of several implementation methods for updating components in React when props passed into the component change
  • How to implement differential incremental updates on React Native on iOS
  • A brief discussion on the problems encountered in react-native hot update react-native-pushy integration

<<:  Tutorial on building file sharing service Samba under CentOS6.5

>>:  Docker container operation instructions summary and detailed explanation

Recommend

CSS to achieve compatible text alignment in different browsers

In the front-end layout of the form, we often nee...

mysql query data for today, this week, this month, and last month

today select * from table name where to_days(time...

MariaDB-server installation of MySQL series

Table of contents Tutorial Series 1. Install Mari...

How to build nfs service in ubuntu16.04

Introduction to NFS NFS (Network File System) is ...

HTML 5.1 learning: 14 new features and application examples

Preface As we all know, HTML5 belongs to the Worl...

Introduction to the functions and usage of value and name attributes in Html

1. The value used in the button refers to the text...

Tutorial on installing MySQL under Linux

Table of contents 1. Delete the old version 2. Ch...

Vue Beginner's Guide: Environment Building and Getting Started

Table of contents Initial Vue Building a Vue deve...

Mysql date formatting and complex date range query

Table of contents Preface Query usage scenario ca...

Detailed explanation of MySQL master-slave replication and read-write separation

Article mind map Why use master-slave replication...

MySQL series 15 MySQL common configuration and performance stress test

1. Common MySQL configuration All the following c...

Deep understanding of JavaScript syntax and code structure

Table of contents Overview Functionality and read...

How to import SQL files in Navicat Premium

I started working on my final project today, but ...

Ubuntu16.04 installation mysql5.7.22 graphic tutorial

VMware12.0+Ubuntu16.04+MySQL5.7.22 installation t...