做爲一個跨平臺應用開發框架,React Native雖然在動態更新方面提供了動態更新的基礎,可是動態更新技術並無想象的那麼完善。好在微軟開發了CodePush,填補了React Native應用在動態更新方面的空白。node
CodePush是微軟提供的一套用於React Native和Cordova的熱更新服務,藉助CodePush,開發者能夠直接部署移動應用更新並快速實現代碼的熱更新,CodePush的官方地址爲https://microsoft.github.io/code-push/。react
CodePush做爲一箇中央倉庫,開發者能夠實時推送更新,而後客戶端應用能夠在應用啓動時查詢更新。藉助CodePush,不須要從新審覈和安裝應用,就能夠解決應用的缺陷和添加新特性。CodePush支持的功能以下: • 支持直接對用戶部署代碼更新; • 管理Alpha、Beta和生產環境應用; • 支持React Native和Cordova跨平臺技術的熱更新; • 支持JavaScript文件與圖片資源的更新;android
使用CodePush以前,須要先安裝CodePush命令行工具,並註冊CodePush帳號和應用,安裝命令以下:ios
npm install -g code-push-cli
複製代碼
安裝完成後能夠經過code-push -v命令進行驗證。而後,在終端輸入命令 code-push register,會打開註冊頁面讓開發者選擇受權帳號,如圖11-11所示。 git
受權經過以後,CodePush會生成一個access key,複製此key到終端便可完成註冊,如圖11-12所示。 除了code-push register命令外,CodePush經常使用的命令還有: • code-push login:登陸CodePush • code-push logout: 註銷CodePush • code-push access-key ls:列出access-key • code-push access-key rm :刪除某個access-key 爲了讓CodePush服務器知道建立的應用,還須要向服務器進行註冊,註冊的命令以下:code-push app add <appName> <platform> react-native
複製代碼
其中,appName表示應用的名稱,platform表示應用的平臺。在終端輸入命令後便可完成應用的註冊,如圖11-13所示。github
向CodePush添加應用時須要指明應用的平臺,成功註冊CodePush應用後,每一個應用都會生成兩個deployment key。其中,Production是用於生產環境的deployment key,Staging則是用於模擬環境的deployment key。 註冊成功後,能夠經過https://appcenter.ms/apps來查看註冊的CodePush應用的信息,如圖11-14所示。 須要說明的是,若是須要同時發佈Android和iOS兩個平臺的熱更新,那麼在註冊CodePush應用時須要註冊兩個應用,並獲取兩套deployment key。 除了code-push app add命令外,CodePush用於應用管理的命令還有: • code-push app add:在登陸帳號中添加一個新的應用。 • code-push app remove :在登陸帳號中刪除一個存在的應用。 • code-push app rename:重命名一個存在的應用。 • code-push app list:列出登陸帳號下全部的應用。 • code-push app transfer:把應用的全部權轉移到另一個帳號。完成CodePush帳號的建立和應用的註冊操做以後,接下來還須要集成CodePush SDK到React Native應用中。 首先,使用react-native init命令新建一個React Native項目,以下所示:npm
react-native init codepush
複製代碼
而後,安裝react-native-code-push插件,安裝命令以下:json
npm install --save react-native-code-push
複製代碼
而後,運行link命令將react-native-code-push插件添加到原生工程中,以下所示:react-native
react-native link react-native-code-push
複製代碼
此時,系統會提示輸入iOS和Android應用的deployment key,此時輸入應用的Staging便可,若是不輸入則能夠直接點擊【Enter】鍵跳過,以下所示:xcode
? What is your CodePush deployment key for Android (hit <ENTER> to ignore)
? What is your CodePush deployment key for iOS (hit <ENTER> to ignore)
複製代碼
若是忘記deployment key的話,能夠經過以下命令進行查看,如圖11-14所示。
須要說明的是,使用react-native link命令連接原生庫時,若是直接跳過輸入deployment key,也能夠在原生端手動配置。 成功添加react-native-code-push到CodePush項目後,還須要對原生工程作一些修改。使用react-native link連接原生庫時,若是跳過輸入deployment key,也能夠在原生端手動進行配置。 對於iOS來講,使用Xcode打開ios/codepush.xcodeproj目錄下的iOS工程,而後Xcode的導航視圖的PROJECT下選中項目,而後依次選擇【Info】→【Configurations】→【添加】→【Duplicate Release Configuration】,而後輸入Staging的key,如圖11-15所示。
而後,在Build Settings面板選擇【add User-Defined Setting】添加自定義編譯環境配置,如圖11-17所示。 而後,在User-Defined中添加CodePush的deployment key,如圖11-18所示。 打開Info.plist文件,並在CodePushDeploymentKey列的Value選項中輸入$(CODEPUSH_KEY),如圖11-19所示。 對於Android來講,使用Android Studio打開android工程,而後在工程的android/settings.gradle文件中引入react-native-code-push庫,以下所示:include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
複製代碼
而後,在app/build.gradle文件中關聯react-native-code-push庫的依賴,以下所示:
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
dependencies {
compile project(':react-native-code-push')
}
複製代碼
接下來,在MainApplication類的getPackages()方法中註冊CodePush,以下所示:
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePush(BuildConfig.codepushkey,getApplicationContext(), BuildConfig.DEBUG)
);
}
複製代碼
因爲CodePush的deployment-key分爲生產環境與測試環境兩種,因此能夠在build.gradle文件中進行設置,以下所示:
android {
releaseStaging {
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'
}
release {
buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
}
}
}
複製代碼
到此,CodePush熱更新所須要的原生配置就完成了,接下來只須要修改React Native的邏輯便可。
使用Xcode打開ios/codepush.xcodeproj文件,而後打開AppDelegate.m文件,能夠看到此時jsCodeLocation相關代碼以下:
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [CodePush bundleURL];
#endif
}
複製代碼
從上面的代碼能夠看出,在非Debug狀態下,系統默認加載的資源地址爲CodePush的bundleURL,爲了加載CodePush的Bundle資源,須要手動修改編譯選項爲Release。具體來講,打開Xcode的菜單,而後依次選擇【Product】→【Scheme】→【Edit Scheme】,如圖11-19所示。
完成上述原生配置以後,接着打開React Native的入口文件index.js,並對index.js文件進行以下的修改。import React, {Component} from 'react';
import {AppRegistry, Platform, StyleSheet, Text, View} from 'react-native';
import {name as appName} from './app.json';
import codePush from 'react-native-code-push'
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
message: ''
};
}
componentDidMount() {
codePush.checkForUpdate().then((update) => {
if (update) {
this.setState({message: '有新的更新!'})
} else {
this.setState({message: '已經是最新,不須要更新!'})
}
})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>版本號 1.0</Text>
<Text style={styles.instructions}>{this.state.message}</Text>
</View>
);
}
}
//省略樣式文件
AppRegistry.registerComponent(appName, () => codePush(App));
複製代碼
如上所示,能夠componentDidMount生命週期函數會檢查CodePush應用是否須要更新,若是檢測須要更新則下載CodePush應用的更新。從新編譯和運行應用,效果如圖11-21所示。
而後,將index.js文件顯示的版本號升級爲1.1,修改內容以下:render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>版本號 1.1</Text>
<Text style={styles.instructions}>{this.state.message}</Text>
</View>
);
}
複製代碼
接下來,使用CodePush的code-push release命令行工具發佈iOS的更新,以下所示:
code-push release-react codepush ios
複製代碼
等待系統打包併發布熱更新的bundle文件,發佈成功後關閉並從新打開應用,就能夠看到應用啓動時會提示更新,如圖11-22所示。
在檢測到更新後,系統會下載最新的資源並更新,當再次關閉並從新打開應用時,能夠看到應用更新成功後的效果。而且,還可使用CodePush提供的code-push deployment命令來查看更新狀況,如圖11-23所示。 和iOS的應用熱更新相似,Android應用的熱更新也可使用這一步驟。