- 首先开发一款app,算是一个中级的app,有考虑使用现在比较火热的flutter,但是考虑到后面需要集成的东西比较多,比如微信,whatsapp,Facebook,twitter等外国的一些主流app,另外一方面是任务比较着急,需要快速开发,所以综合考虑下来还是选择使用之前使用过的react-native进行开发。
- 另外一个原因就是react-native经过这么长时间的沉淀,轮子和工具肯定是不会少的,
- 对于ts支持友好
react-navigation简单解析
首先在开发过程中,对于路由的选择的就是现在比较流行的react-navigation。
React Navigation的诞生,源于React Native社区对基于Javascript的可扩展且使用简单的导航解决方案的需求。
React Navigation是Facebook,Expo和React社区的开发者们合作的结果:它取代并改进了React Native生态系统中的多个导航库,其中包括Ex-Navigation,React Native的Navigator和NavigationExperimental组件。
- StackNavigator 一次只渲染一个页面,并提供页面之间跳转的方法。 当打开一个新的页面时,它被放置在堆栈的顶部
- TabNavigator - 渲染一个选项卡,让用户可以在几个页面之间切换
- DrawerNavigator - 提供一个从屏幕左侧滑入的抽屉
举一个🌰
当前应用有三个tab,分别为home,order,main三个页面,代码如下
const HomeStack = createStackNavigator(
{
[EHomeRoutes.Home]: Home,
},
{
navigationOptions({ navigation }) {
return {
tabBarLabel: i18n.t(LANGUAGE_KEYS.HOME),
tabBarIcon: options => <Ionicon name="ios-home" size={23} {...getTabIconStyles(options)} />
}
}
}
)
const OrderStack = createStackNavigator(
{
[EOrderRoutes.Order]: Order,
},
{
navigationOptions({ navigation }) {
return {
tabBarLabel: i18n.t(LANGUAGE_KEYS.ORDER),
tabBarIcon: options => <Ionicon name="ios-order" size={23} {...getTabIconStyles(options)} />
}
}
}
)
const MainStack = createStackNavigator(
{
[EMainRoutes.Main]: Main,
[EMainRouter.Login]: Login
},
{
navigationOptions({ navigation }) {
return {
tabBarLabel: i18n.t(LANGUAGE_KEYS.Main),
tabBarIcon: options => <Ionicon name="ios-main" size={23} {...getTabIconStyles(options)} />
}
}
}
)
在上面的代码可以看到我将登陆页面login挡在MainStack里面,运行应用会发现一个问题,应用启动,当前显示为home页面,我们通过tab跳转到main页面,然后通过main在跳转到login页面,在login页面逻辑处理正确后我们应该跳回到home页面,但是当我们点击tab再次跳转到main页面我们会发现没有去main页面,而是直接去到了login页面,回头再去看代码,会发现我们将login页面放在了MainStack里面,这样会导致我们当前页面的stack还在login里面,所以出现了这个bug,那么如何解决这个问题呢,最简单的方法就是我们使用dispatch重写了reset或者直接使用reset方法
const resetAction = StackAction.reset({
index: 0,
actions: [NAvigationActions.navigate({ routeName: EMainRouter.Login})],
});
//使用
this.props.navigation.dispatch(resetaction)
// 或者直接使用reset
navigation.reset([NavigationActions.navigate({ routeName: EMainRouter.Login })], 0)
这个bug产生的主要原因是在mainstack里面login-view在当前stack的顶层,当我们选择跳转到mainstack的时候,stack返回给我们的login-view所以会显示在login页面
关于在react-native中集成微信授权登陆分享等功能
- 我们需要去微信开发平台去申请移动应用,一般审核时间在两天左右。审核通过后我们可以拿到一个appid和一个appsecret
- 然后我们在工程里面按住按钮react-native-wechat并且link这个包
- 安卓中需要添加一个WechatEntryActivity.java类,方便获取微信授权以及分享权限
package your.package.wxapi;
import android.app.Activity;
import android.os.Bundle;
import com.theweflex.react.WeChatModule;
public class WXEntryActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeChatModule.handleIntent(getIntent());
finish();
}
};
在AndroidManifest.xml中添加
<!-- 微信Activity -->
<activity android:name=".wxapi.WXEntryActivity" android:label="@string/app_name" android:exported="true" />
- 使用
// 分享朋友圈
private async shartLine() {
let result = await Wechat.shareToTimeline({
type: 'text',
description: 'hello, Wechat'
});
console.log('share text message to time line successful:', result);
}
// 分享图片
private async shareImage() {
Wechat.shareToSession({
thumbImage: 'https://static.jinhaidi.cn/form.jpeg',
type: 'imageUrl',
imageUrl: 'https://static.jinhaidi.cn/abc4e5422cd7297d3806989ed33cc6b3.png'
})
}
// 分享链接
private async shareArticle() {
Wechat.shareToSession({
title: '微信好友测试链接',
description: '我是来自app文章的分享',
thumbImage: 'https://static.jinhaidi.cn/abc4e5422cd7297d3806989ed33cc6b3.png',
type: 'news',
webpageUrl: 'https://jinhaidi.cn/article/5cbc2fa3f1e4e1318d24c3e7'
})
}
// 授权
// scope 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo
// state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击)
// 建议第三方带上该参数,可设置为简单的随机数加session进行校验
const codeData = await wechat.sendAuthRequest('snsapi_userinfo', 'test')
// 获取accessToken
// 开放平台申请的appid 和 appSecret 加上上一步获取的code
const resToken = await getAccessToken({
appid: WxAppId,
secret: WxAppSecret,
grant_type: 'authorization_code',
code: codeData.code
})
const userInfo = await getUnionId({
access_token: resToken.access_token,
openid: resToken.openid
})
参数正确无误的情况下可以获取到微信用户信息
关于ios方面的微信授权需要添加权限
- 用xcode打开你的项目, 右键点击左侧项目目录Libraries文件夹 ➜ Add Files to <...>
- b.去node_modules ➜ react-native-wechat ➜ ios ➜ 选择 RCTWeChat.xcodeproj
- c.在工程Build Phases ➜ Link Binary With Libraries中添加libRCTWeChat.a(直接拖拽过去)
- 在工程target的Build Phases->Link Binary with Libraries中加入以下库文件:
SystemConfiguration.framework CoreTelephony.framework libsqlite3.0 libc++ libz
- 点击TARGETS 下的项目名 -> info ,添加你的 申请的 微信 AppID到 "URL type"的"URL Schema"处
- iOS9 以上,添加 微信白名单
- 编辑info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
<string>wechat</string>
</array>
- 在你项目的AppDelegate.m添加以下代码,启动[LinkingIOS]
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}