首页 » React Native » React Native技术文章 » 正文

【React Native开发】React Native模块之Linking详解以及实例-Android/iOS双平台通用(55)

尊重版权,未经授权不得转载

本文来自:江清清的技术专栏(http://www.lcode.org)

(一)前言

今天我们来看一下Linking模块的使用详解,现在在Android和iOS平台上面之前IntentAndroid和LinkingiOS这两个模块已经废弃了,现在全部转移使用Linking模块,所以之前的两个模块我这边就不进行讲解了,直接给大家讲解Linking模块的具体介绍以及使用方法。

刚创建的React Native技术交流4群(458982758),欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!

Linking模块给我们提供了Android和iOS双平台通用的接口进行处理App进入和传出的链接。

(二)处理链接

如果你的应用被其他任何注册过的外部URL进行唤起,那么你可以在任何组件中进行获取并且处理。具体代码如下:

componentDidMount() {
  var url = Linking.getInitialURL().then((url) => {
    if (url) {
      console.log('Initial url is: ' + url);
    }
  }).catch(err => console.error('An error occurred', err));
}

如上代码,当组件被挂载之后,就可以进行去获取外部的URL并且进行处理它了。

[注意].对于Android平台上面,如何进行支持深度链接的更多信息可以点击查询:Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links.  该篇文章是Android官网的,后面这边会着重讲解一下该文章的内容以及深度链接的知识点。

[注意].对iOS平台,如果你需要在应用中监听传入的应用的链接,那么你需要在*AppDelegate.m文件中添加如下的代码:

#import "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];
}

// Only if your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
 return [RCTLinkingManager application:application
                  continueUserActivity:userActivity
                    restorationHandler:restorationHandler];
}

然后你的React组件就可以监听Linking的相关事件:

componentDidMount() {
  Linking.addEventListener('url', this._handleOpenURL);
},
componentWillUnmount() {
  Linking.removeEventListener('url', this._handleOpenURL);
},
_handleOpenURL(event) {
  console.log(event.url);
}

[注意].如上的方法仅支持iOS平台

(三)打开外部链接

为了启用链接对应的行为或者应用(Web URL,邮箱,联系人等),只需要如下进行调用:

Linking.openURL(url).catch(err => console.error('An error occurred', err));

如果你需要检查一下打开的链接的应用是否被安装,你可以调用如下的代码:

Linking.canOpenURL(url).then(supported => {
  if (!supported) {
    console.log('Can\'t handle url: ' + url);
  } else {
    return Linking.openURL(url);
  }
}).catch(err => console.error('An error occurred', err));
(四)属性方法

4.1. addEventLinstener(type,handler )  static 静态方法,适合iOS平台 。添加监听Linking事件变化的方法,第一个参数是事件类型url,第二个参数为事件处理方法。

4.2.removeEventListener(type,handler)  static 静态方法,适合iOS平台。移除监听Linking事件变化,第一个参数是事件类型url,第二个参数为事件处理方法。

4.3.openURL()  static静态方法, 进行使用设备中已经安装的应用打开指定的URL。当然你还可以使用其他类型的URLs,例如地址信息位置(举例:"geo:37.484847,-122.148386"),联系人或者其他可以被安装的应用打开的URL都可以。

[注意].如果系统不能处理打开传入的URL,那么该方法会返回失败。如果你传入的不是一个http(s)URL,最好的方法就是使用 {@code canOpenURL} 进行检查一下。

[注意].对于Web  URL,连接协议头("http://","https://")不能省略

4.4.canOpenURL(url)  static静态方法,该用来检查判断传入的URL是否可以被已经安装的应用打开。

[注意].对于Web  URL,连接协议头("http://","https://")不能省略

[注意].在iOS 9开始的系统中,你需要在Info.plist中添加LSApplicationQueriesSchemes字段。

4.5.getInitialURL()  static方法,如果当前的应用是被一个外部传入的URL调起打开的,那么该方法返回一个链接地址,否则会返回null

[注意].如果需要在Android平台中支持深度链接,可以查阅官方文档:http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents

(五)使用实例

上面我以及基本介绍了Linking的内容以及基本使用方法,下面我们分别从Android,iOS两种平台分别进行讲解一下实例使用。

5.1首先看一下Android平台的使用方式,

/**
 * React Native For Android端进行根据URL打开系统的应用
 * https://github.com/facebook/react-native
 */
import React, {
  AppRegistry,
  Component,
  StyleSheet,
  Text,
  View,
  Linking,
  TouchableHighlight,
} from 'react-native';
class CustomButton extends React.Component {
  constructor(props){
    super(props);
  }
  propTypes: {
    url: React.PropTypes.string,
  }
  render() {
    return (
      <TouchableHighlight
        style={styles.button}
        underlayColor="#a5a5a5"
        onPress={()=>Linking.canOpenURL(this.props.url).then(supported => {
           if (supported) {
               Linking.openURL(this.props.url);
           } else {
              console.log('无法打开该URI: ' + this.props.url);
           }
        })}>
        <Text style={styles.buttonText}>{this.props.text}</Text>
      </TouchableHighlight>
    );
  }
}
class LinkingDemo extends Component {
  componentDidMount() {
   var url = Linking.getInitialURL().then((url) => {
    if (url) {
      console.log('捕捉的URL地址为: ' + url);
    }
   }).catch(err => console.error('错误信息为:', err));
 }
  render() {
    return (
      <View>
         <CustomButton url={'http://www.lcode.org'}  text="点击打开http网页"/>
         <CustomButton url={'https://www.baidu.com'} text="点击打开https网页"/>
         <CustomButton url={'smsto:18352402477'}  text="点击进行发送短信"/> 
         <CustomButton url={'tel:18352402477'} text="点击进行打电话"/>
         <CustomButton url={'mailto:jiangqqlmj@163.com'} text="点击进行发邮件"/>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  button: {
    margin:5,
    backgroundColor: 'white',
    padding: 15,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: '#cdcdcd',
  },
});
AppRegistry.registerComponent('LinkingDemo', () => LinkingDemo);

Android版本运行效果如下:

5.2.下面来看一下iOS平台的相关用法

首先我们需要在AppDelegate.m文件中引入RCTLinkingManager.h头文件,那么就需要我们引入相关配置了,关于库的引入默认项目都默认已经配置好的,但是我们需要配置一个库头文件搜索路径,具体如下:

AppDelegate.m中的部分代码如下:

#import "AppDelegate.h"
#import "RCTRootView.h"
#import "RCTLinkingManager.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}

// Only if your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
  return [RCTLinkingManager application:application
                   continueUserActivity:userActivity
                     restorationHandler:restorationHandler];
}

以上只是部分.m文件中的代码,另外就是didFinishLaunchingWithOptions方法了,该方法中不需要添加什么代码

前端js文件代码如下:

/**
 * React Native For Android端进行根据URL打开系统的应用
 * https://github.com/facebook/react-native
 */
import React, {
  AppRegistry,
  Component,
  StyleSheet,
  Text,
  View,
  Linking,
  TouchableHighlight,
} from 'react-native';
class CustomButton extends React.Component {
  constructor(props){
    super(props);
  }
  propTypes: {
    url: React.PropTypes.string,
  }
  render() {
    return (
      <TouchableHighlight
        style={styles.button}
        underlayColor="#a5a5a5"
        onPress={()=>Linking.canOpenURL(this.props.url).then(supported => {
           if (supported) {
               Linking.openURL(this.props.url);
           } else {
              console.log('无法打开该URI: ' + this.props.url);
           }
        })}>
        <Text style={styles.buttonText}>{this.props.text}</Text>
      </TouchableHighlight>
    );
  }
}
class LinkingDemo extends Component {
  render() {
    return (
      <View style={{marginTop:20}}>
         <Text text="iOS平台,Linking演示"/>
         <CustomButton url={'http://www.lcode.org'}  text="点击打开http网页(http://www.lcode.org)"/>
         <CustomButton url={'https://www.baidu.com'} text="点击打开https网页(https://www.baidu.com)"/>
         <CustomButton url={'smsto:18352402477'}  text="点击进行发送短信(smsto:18352402477)"/> 
      </View>
    );
  }
}
const styles = StyleSheet.create({
  button: {
    margin:5,
    backgroundColor: 'white',
    padding: 15,
    borderBottomColor: '#cdcdcd',
  },
});
AppRegistry.registerComponent('LinkingDemo', () => LinkingDemo);

具体运行效果如下:

 

看上面日志运行截图发现,当进行处理短信的URL的时候,是处理失败的,原因是当前的应用是不允许进行查询短信的scheme的,权限不够。

(六)最后总结

今天我们主要学习一下Linking模块详解。当前所讲解内容同时适配Android、iOS双平台。大家有问题可以加一下群React Native技术交流4群(458982758).或者底下进行回复一下。

尊重原创,未经授权不得转载:From Sky丶清(http://www.lcode.org/) 侵权必究!

关注我的订阅号(codedev123),每天分享移动开发技术(Android/IOS),项目管理以及博客文章!(欢迎关注,第一时间推送精彩文章)

关注我的微博,可以获得更多精彩内容