參考資料:
https://blog.csdn.net/sinat_17775997/article/details/70473988
https://www.jianshu.com/p/8f2232da0956
http://www.cocoachina.com/ios/20161026/17855.html
本文主要介紹react-native應用如何處理APP被外部URL調起的事件,并解析URL攜帶的參數。
1、應用間互相跳轉簡介
在iOS開發的過程中,我們經常會遇到需要從一個應用程式A跳轉到另一個應用程式B的場景。這就需要我們掌握iOS應用程式之間的互相跳轉知識。
2、應用間互相跳轉實作原理
在iOS中打開一個應用程式隻需要拿到這個應用程式的協定頭即可,是以我們隻需配置應用程式的協定頭即可。
假設有應用A和應用B兩個應用,現在需要從應用A跳轉到應用B中。
原理:通過設定跳轉到應用B的URL Schemes(自定義的協定頭),應用B将其自身“綁定”到一個自定義URL Schemes上,就可以從應用A中利用應用B的URL Schemes啟動應用B了。
IOS應用在info.plist檔案中可以設定URL Schemes(URL types -> URL Schemes)。
(APP可以向手機作業系統注冊一個 URL scheme,該 scheme 用于從浏覽器或其他應用中啟動本應用。)
3、RN端使用Linking處理APP被其注冊過的外部 url 調起的情況
這一步,需要考慮兩種情況,即
(1)APP未在運作
當APP未在運作狀态時,可以使用Linking.getInitialURL()方法來處理外部URL調起的事件。
(2)APP在運作當中
當APP處在運作狀态時,Linking.getInitialURL()方法是不會響應外部URL調起事件的。需要執行以下操作:
首先,是在IOS原生端添加上述代碼,這段代碼的作用是當APP在運作當中被外部URL調起時,往RN端發送事件。這樣RN端的Linking子產品就能響應事件了。
然後,RN端就可以監聽LinKing的相關事件了。
樣例代碼如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Linking,
TouchableHighlight,
View,
ScrollView
} from 'react-native';
import PropTypes from 'prop-types';
class CustomButton extends Component {
constructor(props) {
super(props);
}
static propTypes = {
url: PropTypes.string,
text: PropTypes.string.isRequired,
};
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>
);
}
}
export default class IOSLinkingDemo extends Component {
constructor(props) {
super(props);
this.state = {
url: '',
params: ''
};
}
componentDidMount() {
//Linking.getInitialURL():APP在運作當中,這個方法是不能處理APP被外部URL調起的情況的。
Linking.getInitialURL().then((url) => {
this.handleUrl(url);
}).catch(err => {
console.error('錯誤資訊為:', err);
alert('錯誤資訊為:' + err);
});
//要在 App 啟動後也監聽傳入的 App 連結
Linking.addEventListener('url', this._handleOpenURL);
}
componentWillMount() {
Linking.removeEventListener('url', this._handleOpenURL);
}
_handleOpenURL = (event) => {
this.handleUrl(event.url);
};
// 取URL位址參數轉為對象
handleUrl = (url) => {
if (url) {
console.log('捕捉的URL位址為: ' + url);
alert('捕捉的URL位址為: ' + url);
let urlObj = this.getUrlParamsToJSON(url);
let params = '';
if (urlObj) {
for (let key in urlObj) {
params = params + `${key}=${urlObj[key]}\n`;
}
this.setState({
params: params
});
}
} else {
console.log('url為空');
alert('url為空');
}
};
getUrlParamsToJSON = (url) => {
var params = {};
//去除所有空格
url = url.replace(/\s/ig, '');
//正規表達式比對
url.replace(/([^?&=]+)=([^&]+)/g, (_, key, value) => {
params[key] = value;
});
return params;
};
/**
* 擷取URL的查詢參數
*/
getUrlParamsToMap = (url) => {
var params = new Map();
//去除所有空格
url = url.replace(/\s/ig, '');
//正規表達式比對
url.replace(/([^?&=]+)=([^&]+)/g, (_, key, value) => {
params.set(key, value);
});
return params;
};
render() {
return (
<ScrollView style={{flex: 1}}>
{/*<CustomButton url={'http://www.reactnative.vip'} text="點選打開http網頁"/>*/}
{/*<CustomButton url={'https://www.baidu.com'} text="點選打開https網頁"/>*/}
{/*<CustomButton url={'smsto:13667377378'} text="點選進行發送短信"/>*/}
{/*<CustomButton url={'tel:13667377378'} text="點選進行打電話"/>*/}
{/*<CustomButton url={'mailto:[email protected]'} text="點選進行發郵件"/>*/}
{/*<CustomButton url={'dfy:888999'} text="無法打開url"/>*/}
{/*<CustomButton url={'geo:37.484847,-122.148386'} text="點選打開一個地圖位置"/>*/}
{/*<CustomButton url={'myrnlinkdemo://'} text="自己打開自己"/>*/}
<CustomButton url={'myrnlinkdemo1://'} text="打開myrnlindemo1"/>
<Text>
url參數:{this.state.params}
</Text>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
button: {
margin: 5,
backgroundColor: 'white',
padding: 15,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#cdcdcd',
},
buttonText: {
fontSize: 20,
},
});
4、從 Safari 中調用自定義 URL Schemes
在 Xcode 中運作應用,一旦應用被安裝,自定義 URL scheme 就會被注冊,通過模拟器關閉應用,啟動 Safari 在浏覽器位址欄輸入之前定義的 URL scheme(如下):
圖中設定的URL Schemes為myrnlinkdemo,是以在浏覽器當中輸入:myrnlindemo://index?page=index。
5、在RN端可以利用URL傳遞進來的參數進行自定義處理。
當APP拿到參數對象後,就可以根據自己的業務需求進行自定義處理。比如傳遞過來page參數為index,就跳轉到首頁,如果page為其他參數,就跳轉到其他頁面,以此類推。