您的位置:首页 > Web前端 > React

使用pushy进行React Native代码进行热部署(热更新)

2016-04-29 10:51 891 查看
在开讲前先介绍另外一种方法也可以进行代码的热更新,利用codepush大家可以参考这篇文章:

常用命令汇总:
//安装模块
npm install -g react-native-update-cli rnpm(一台机子执行一次)
npm install --save react-native-update
rnpm link react-native-update
//登录绑定
pushy login
pushy createApp --platform ios
pushy createApp --platform android
pushy selectApp --platform ios
//上传包
pushy uploadIpa <your-package.ipa>
pushy uploadApk android/app/build/outputs/apk/app-release.apk
//发布执更新
pushy bundle --platform <ios|android>

首先到pushy的网站(http://update.reactnative.cn/home)上面注册账号,并注册应用.

打开你的控制台,定位到你的项目根目录(有package.json文件就是根目录),输入以下命令

npm install -g react-native-update-cli rnpm

此项只要机子安装一次即可

npm install --save react-native-update

此项就是更新你的模块,注意确保你的package.json文件中react-native:版本大于0.18.0,如果小于此版本,需手动更改这个版本号,不知道react-native版本号有哪些可以执行nmp info react-native进行查询所有发布的版本号

rnpm link react-native-update

在你应用中各个平台裢接update的动态库

登录并绑定应用

$ pushy login
email: <输入你的注册邮箱>
password: <输入你的密码>


这会在项目文件夹下创建一个
.update
文件,注意不要把这个文件上传到Git等CVS系统上。你可以在
.gitignore
末尾增加一行
.update
来忽略这个文件。

登录之后可以创建应用。注意iOS平台和安卓平台需要分别创建:

$ pushy createApp --platform ios

App Name: <输入应用名字>

$ pushy createApp --platform android

App Name: <输入应用名字>

如果你已经在网页端或者其它地方创建过应用,也可以直接选择应用:

$ pushy selectApp --platform ios

1) 鱼多多(ios)

3) 招财旺(ios)

Total 2 ios apps

Enter appId: <输入应用前面的编号> 

接下来更改开发环境配置

在工程target的Build Phases->Link Binary with Libraries中加入libz.tbd、libbz2.1.0.tbd

在你的AppDelegate.m文件中增加如下代码:

IOS:

// ... 其它代码

#import "RCTHotUpdate.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

#if DEBUG

  // 原来的jsCodeLocation

  jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];

#else

  jsCodeLocation=[RCTHotUpdate bundleURL];

#endif

  // ... 其它代码

}

Android:

在你的ReactActivity中增加如下代码:

// ... 其它代码

import cn.reactnative.modules.update.UpdateContext;

public class MainActivity extends ReactActivity {

    @Override

    protected String getJSBundleFile() {

        return UpdateContext.getBundleUrl(this);

    }

    // ... 其它代码

}

开始代码前,几个问题介绍:


获取appKey

检查更新时必须提供你的
appKey
,这个值保存在
update.json
中,并且根据平台不同而不同。你可以用如下的代码获取:

import React, {
Platform,
} from 'react-native';

import _updateConfig from './update.json';
const {appKey} = _updateConfig[Platform.OS];


如果你不使用pushy命令行,你也可以从网页端查看到两个应用appKey,并根据平台的不同来选择。


检查更新、下载更新



异步函数checkUpdate可以检查当前版本是否需要更新:

checkUpdate(appKey)
.then(info => {
})


返回的info有三种情况:

{expired: true}
:该应用包(原生部分)已过期,需要前往应用市场下载新的版本。

{upToDate: true}
:当前已经更新到最新,无需进行更新。

{update: true}
:当前有新版本可以更新。info的
name
description
字段可
以用于提示用户,而
metaInfo
字段则可以根据你的需求自定义其它属性(如是否静默更新、 是否强制更新等等)。另外还有几个字段,包含了完整更新包或补丁包的下载地址, react-native-update会首先尝试耗费流量更少的更新方式。将info对象传递给downloadUpdate作为参数即可。


切换版本



downloadUpdate的返回值是一个hash字符串,它是当前版本的唯一标识。

你可以使用
switchVersion
函数立即切换版本(此时应用会立即重新加载),或者选择调用 
switchVersionLater
,让应用在下一次启动的时候再加载新的版本。


首次启动、回滚



在每次更新完毕后的首次启动时,
isFirstTime
常量会为
true

你必须在应用退出前合适的任何时机,调用
markSuccess
,否则应用下一次启动的时候将会进行回滚操作。 这一机制称作“反触发”,这样当你应用启动初期即遭遇问题的时候,也能在下一次启动时恢复运作。

你可以通过
isFirstTime
来获知这是当前版本的首次启动,也可以通过
isRolledBack
来获知应用刚刚经历了一次回滚操作。
你可以在此时给予用户合理的提示。


完整的示例



import React, {

  AppRegistry,

  Component,

  StyleSheet,

  Platform,

  Text,

  View,

  Alert,

  TouchableOpacity,

  Linking,

} from 'react-native';

import {

  isFirstTime,

  isRolledBack,

  packageVersion,

  currentVersion,

  checkUpdate,

  downloadUpdate,

  switchVersion,

  switchVersionLater,

  markSuccess,

} from 'react-native-update';

//检查更新时必须提供你的
appKey
,这个值保存在
update.json
中,并且根据平台不同而不同。你可以用如下的代码获取:
//如果你不使用pushy命令行,你也可以从网页端查看到两个应用appKey,并根据平台的不同来选择。
import _updateConfig from './update.json';
const {appKey} = _updateConfig[Platform.OS];

class MyProject extends Component {

  componentWillMount(){

    if (isFirstTime) {

      Alert.alert('提示', '这是当前版本第一次启动,是否要模拟启动失败?失败将回滚到上一版本', [

        {text: '是', onPress: ()=>{throw new Error('模拟启动失败,请重启应用')}},

        {text: '否', onPress: ()=>{markSuccess()}},

      ]);

    } else if (isRolledBack) {

      Alert.alert('提示', '刚刚更新失败了,版本被回滚.');

    }

  }

  doUpdate = info => {

    downloadUpdate(info).then(hash => {

      Alert.alert('提示', '下载完毕,是否重启应用?', [

        {text: '是', onPress: ()=>{switchVersion(hash);}},

        {text: '否',},

        {text: '下次启动时', onPress: ()=>{switchVersionLater(hash);}},

      ]);

    }).catch(err => { 

      Alert.alert('提示', '更新失败.');

    });

  };
 
checkUpdate = () => {
    //异步函数checkUpdate可以检查当前版本是否需要更新
   
checkUpdate(appKey).then(info => {

      if (info.expired) {

        Alert.alert('提示', '您的应用版本已更新,请前往应用商店下载新的版本', [

          {text: '确定', onPress: ()=>{info.downloadUrl && Linking.openURL(info.downloadUrl)}},

        ]);

      } else if (info.upToDate) {

        Alert.alert('提示', '您的应用版本已是最新.');

      } else {

        Alert.alert('提示', '检查到新的版本'+info.name+',是否下载?\n'+ info.description, [

          {text: '是', onPress: ()=>{this.doUpdate(info)}},

          {text: '否',},

        ]);

      }

    }).catch(err => { 

      Alert.alert('提示', '更新失败.');

    });

  };

  render() {

    return (

      <View style={styles.container}>

        <Text style={styles.welcome}>

          欢迎使用热更新服务

        </Text>

        <Text style={styles.instructions}>

          这是版本一 {'\n'}

          当前包版本号: {packageVersion}{'\n'}

          当前版本Hash: {currentVersion||'(空)'}{'\n'}

        </Text>

        <TouchableOpacity onPress={this.checkUpdate}>

          <Text style={styles.instructions}>

            点击这里检查更新

          </Text>

        </TouchableOpacity>

      </View>

    );

  }

}

const styles = StyleSheet.create({

  container: {

    flex: 1,

    justifyContent: 'center',

    alignItems: 'center',

    backgroundColor: '#F5FCFF',

  },

  welcome: {

    fontSize: 20,

    textAlign: 'center',

    margin: 10,

  },

  instructions: {

    textAlign: 'center',

    color: '#333333',

    marginBottom: 5,

  },

});

AppRegistry.registerComponent('MyProject', () => MyProject);



后期运营维护,更新升级操作:
打包上传:
把你的打出来的包上传到pushy平台,每一个版本都会平台记录相应的信息
iOS:

$ pushy uploadIpa <your-package.ipa>

android :

$ pushy uploadApk android/app/build/outputs/apk/app-release.apk

发布热更新版本:

$ pushy bundle --platform <ios|android>

Bundling with React Native version:  0.22.2
<各种进度输出>

Bundled saved to: build/output/android.1459850548545.ppk
Would you like to publish it?(Y/N) 

选择Y,是否要发布

Uploading [========================================================] 100% 0.0s

Enter version name: <输入版本名字,如1.0.0-rc>

Enter description: <输入版本描述>

Enter meta info: {"ok":1}

Ok.

Would you like to bind packages to this version?(Y/N)


这里的描述和名字都会在你的代码中获取到。
Alert.alert('提示', '检查到新的版本'+info.name+',是否下载?\n'+ info.description, [、
选择Y,是否要绑定绑本

Offset 0

1) FvXnROJ1 1.0.1 (no package)

2) FiWYm9lB 1.0 [1.0]

Enter versionId or page Up/page Down/Begin(U/D/B) <输入序号,U/D翻页,B回到开始,序号就是上面列表中)前面的数字>

1) 1.0(normal) - 3 FiWYm9lB (未命名)

Total 1 packages.

Enter packageId: <输入包版本序号,序号就是上面列表中)前面的数字>


OK结束。试试你的应用成功没。

本文选自pushy官方文档,更多官方信息文档:https://github.com/reactnativecn/react-native-pushy/blob/master/README.md
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息