整合之前Mac系統下必須先要能運行ReactNative的項目,否則不適用,例如我建立了一個項目名稱為'RN如下圖,結構位置需要一致,下面的所有指令都是根據這個路徑來配置,如果需要更改自己根據結構修改
(1)CodePush環境安裝與註冊
1.終端輸入 sudo npm install -g code-push-cli,就可以安裝了。
安裝完畢後,輸入 code-push -v查看版本,如看到版本代表成功
2.終端輸入 code-push register,註冊成功後有一個access key
3.終端輸入 code-push login 輸入剛才的key,就登入成功了,session檔案將會寫在 /Users/你的使用者名稱/.code-push.config,後面直接預設是登入狀態
(2)在CodePush伺服器註冊app
4.終端輸入code-push app add 項目名稱,實際輸入 code-push app add RN
5.會產生一個Production和Staging 兩個Key,第一個是產生環境,第二個是開發環境
(3)整合CodePush SDK----IOS
6.終端cd 到RN目錄下,然後安裝COdePush的SDK,終端輸入 npm install --save react-native-code-push
7.將react-native-code-push檔案夾中RN.xcodeproj直接拉入項目中Libraries中如下圖
8.加入libz.tbd
9.在Build Settings的Header Search Paths那一項中加入$(SRCROOT)/../node_modules/react-native-code-push
10.在AppDelegate中例如下圖
11.在命令列下使用code-push deployment ls --displayKeys查出Staging的值,在info.plist檔案中添加CodePushDeploymentKey並且把Staging的值填入
(3)ReactNative代碼
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */import React, {Component} from 'react';import { AppRegistry, StyleSheet, Text, View, ListView, ScrollView, Image, TouchableOpacity, AlertIOS, TextInput, Dimensions,} from 'react-native';//匯入的第三方import CodePush from "react-native-code-push";import {createStore} from 'redux'import BaseComponent from '../Base/BaseComponent';import Modal from 'react-native-root-modal';import Toast from 'react-native-root-toast';// var {width} = require('Dimensions').get('window');// var {width,heigtht} = require('Dimensions').get('window');var width = require('Dimensions').get('window').width;//自訂工具類var Global = require('../App/Global')var Utils = require('../App/Utils')// CodePush({checkFrequency: CodePush.CheckFrequency.MANUAL})export default class CodePushDemo extends BaseComponent { constructor() { super(); this.state = {restartAllowed: true}; } codePushStatusDidChange(syncStatus) { switch (syncStatus) { case CodePush.SyncStatus.CHECKING_FOR_UPDATE: this.setState({syncMessage: "Checking for update."}); //檢查是否需要更新 break; case CodePush.SyncStatus.DOWNLOADING_PACKAGE: this.setState({syncMessage: "Downloading package."}); break; case CodePush.SyncStatus.AWAITING_USER_ACTION: this.setState({syncMessage: "Awaiting user action."}); break; case CodePush.SyncStatus.INSTALLING_UPDATE: this.setState({syncMessage: "Installing update."}); break; case CodePush.SyncStatus.UP_TO_DATE: this.getUpdateMetadata() this.setState({syncMessage: "App up to date.", progress: false}); break; case CodePush.SyncStatus.UPDATE_IGNORED: this.setState({syncMessage: "Update cancelled by user.", progress: false}); break; case CodePush.SyncStatus.UPDATE_INSTALLED: this.setState({syncMessage: "Update installed and will be applied on restart.", progress: false}); break; case CodePush.SyncStatus.UNKNOWN_ERROR: this.setState({syncMessage: "An unknown error occurred.", progress: false}); break; } } //是否重啟更新 toggleAllowRestart() { this.state.restartAllowed ? CodePush.disallowRestart() : CodePush.allowRestart(); this.setState({restartAllowed: !this.state.restartAllowed}); } //下載資源套件 codePushDownloadDidProgress(progress) { this.setState({progress}); } /** Update is downloaded silently, and applied on restart (recommended) */ //後台更新 sync() { CodePush.sync( { installMode: CodePush.InstallMode.IMMEDIATE, }, this.codePushStatusDidChange.bind(this), this.codePushDownloadDidProgress.bind(this), ); //CodePush.notifyApplicationReady();//APP重啟後,防止資料復原 } /** Update pops a confirmation dialog, and then immediately reboots the app */ //對話方塊更新 syncImmediate() { CodePush.sync( { installMode: CodePush.InstallMode.IMMEDIATE, updateDialog: { appendReleaseDescription: true, descriptionPrefix: '描述', title: '標題', mandatoryUpdateMessage: '發現新版本', mandatoryUpdateMessage: '更新', optionalUpdateMessage: '發現新版本,是否更新', optionalInstallButtonLabel: "更新", optionalIgnoreButtonLabel: '不更新', } }, this.codePushStatusDidChange.bind(this), this.codePushDownloadDidProgress.bind(this) ); //CodePush.notifyApplicationReady();//APP重啟後,防止資料復原 } render() { let progressView; if (this.state.progress) { progressView = ( <Text style={styles.messages}>{this.state.progress.receivedBytes} of {this.state.progress.totalBytes} bytes received</Text> ); } return ( <View style={styles.container}> <Text style={styles.welcome}> Welcome to CodePush! </Text> <TouchableOpacity onPress={this.sync.bind(this)}> <Text style={styles.syncButton}>點擊後台更新</Text> </TouchableOpacity> <TouchableOpacity onPress={this.syncImmediate.bind(this)}> <Text style={styles.syncButton}>點擊對話方塊更新</Text> </TouchableOpacity> {progressView} <TouchableOpacity onPress={this.getUpdateMetadata.bind(this)}> <Text style={styles.syncButton}>Press for Update Metadata</Text> </TouchableOpacity> <Text style={styles.messages}>{this.state.syncMessage || ""}</Text> </View> ); } //將要顯示 componentWillMount() { CodePush.checkForUpdate() .then((update) => { if (!update) { Utils.Toast("app是最新版了"); } else { Utils.Toast("有更新哦"); } } ); }}const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", backgroundColor: "#F5FCFF", paddingTop: 50 }, image: { margin: 30, width: Dimensions.get("window").width - 100, height: 365 * (Dimensions.get("window").width - 100) / 651, }, messages: { marginTop: 30, textAlign: "center", }, restartToggleButton: { color: "blue", fontSize: 17 }, syncButton: { color: "green", fontSize: 17 }, welcome: { fontSize: 20, textAlign: "center", margin: 20 },});//輸入類module.exports = CodePushDemo
(4)CodePush資源打包 14.要運行項目首先要吧js打包到Xcode上,終端cd 到RN目錄下(我直接放到./ios/RN/index.jsbundle)
然後終端輸入 react-native bundle --entry-file index.ios.js --platform ios --bundle-output ./ios/RN/index.jsbundle
15.複製進去
16,打包CodePush資源套件終端cd 到RN目錄下,然後終端輸入react-native bundle --platform ios --entry-file index.ios.js --bundle-output codepush.js --dev false
17.然後在終端輸入 code-push release RN codepush.js 1.0.0 (這裡有有坑,info.plist裡面的版本要和這個版本一直才能更新,不是比原來的大)
18.在每個js建立的時候構造器加入
CodePush.notifyApplicationReady();,防止復原,我是寫了一個基類,然後每次調用檔案的時候自動調用