集成之前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();,防止回滚,我是写了一个基类,然后每次调用文件的时候自动调用