UNPKG

update-react-native-app

Version:

Uses Github releases to update apk in React Native

106 lines (79 loc) 2.48 kB
import { NativeModules, Platform } from 'react-native' import RNFS from 'react-native-fs' import semverMax from 'semver-max' export default class Updater { static UpdateRNApp = NativeModules.UpdateRNApp options jobId = -1 releasesUri = 'https://api.github.com/repos/{ownerAndRepo}/releases' constructor(options) { this.options = options } get = (url, success, error) => { fetch(url) .then((response) => response.json()) .then(success) .catch(error) } getApkVersion = () => { if (this.jobId !== -1) { return } if (!this.options.repo) { return } this.get( this.releasesUri.replace('{ownerAndRepo}', this.options.repo), this.getApkVersionSuccess, this.getVersionError, ) } getApkVersionSuccess = (releases) => { const latestRelease = releases.length > 0 ? releases[0] : null const latestVersion = latestRelease.tag_name.replace('v', '') // Only if we have a latest release and it's higher then the current one if (latestRelease && semverMax(latestVersion, Updater.UpdateRNApp.versionName) !== Updater.UpdateRNApp.versionName) { const apkAsset = latestRelease.assets.find(asset => asset.browser_download_url.indexOf('.apk') > -1) if (apkAsset) { this.fire('onUpdateAvailable', latestRelease, () => { this.downloadApk(apkAsset) }) } } } downloadApk = (apkAsset) => { const progress = (data) => { const percentage = ((100 * data.bytesWritten) / data.contentLength) | 0 this.fire('onProgress', percentage) } const downloadDest = `${RNFS.ExternalCachesDirectoryPath}/${apkAsset.name}` const downloadFile = RNFS.downloadFile({ fromUrl: apkAsset.browser_download_url, toFile: downloadDest, begin: (response) => this.fire('onDownloadStart'), progress, background: true, progressDivider: 1, }) this.jobId = downloadFile.jobId downloadFile.promise.then((response) => { this.fire('onDownloadEnd') Updater.UpdateRNApp.installApk(downloadDest) this.jobId = -1 }).catch((error) => { this.fire('onDownloadError', error) this.jobId = -1 }) } getVersionError = (err) => {} checkUpdate = () => { if (Platform.OS === 'android') { this.getApkVersion() } } fire = (func, ...args) => { if (this.options[func]) { this.options[func].apply(null, args) } } }