saitoxu.io

AboutTwitterGitHub

ATSで許可されていないhttpなURLへの対処方法

August 06, 2017

前置き

iOS では ATS(App Transport Security)で許可されていない http リソースにはアクセスできない仕組みになっており、 React Native でもそれは変わりません。

自身が管理しているドメインであれば https にする、または 特定の限られた http リソース(かつ信頼できる)であれば ATS を許可する、 などやり方はありますが、 今回不特定の http リソースにアクセスする方法を実現したかったのでちょっと調べました。

環境は React Native 0.44、iOS での利用を想定してます。

方法

WebViewonErrorという props を渡すことで、 ネットワークに繋がっていないなどのエラー時に任意の関数を呼べます。

関数の引数としてエラー情報が入ったProxyオブジェクトが返ってくるので、 それを使って外部ブラウザで開いたりすると良さそうです。

// 外部ブラウザで開く例
import React, { Component } from 'react'
import { Alert, Linking, WebView } from 'react-native'
const ATS_ERROR_CODE = -1022
export default class WebViewSample extends Component {
constructor(props) {
super(props)
this.handleError = this.handleError.bind(this)
this.openUrl = this.openUrl.bind(this)
}
handleError(proxy) {
const { code } = proxy.nativeEvent
const { url } = this.props
if (code === ATS_ERROR_CODE) {
this.openUrl(url)
}
}
openUrl(url) {
Linking.canOpenURL(url).then(supported => {
if (supported) {
Linking.openURL(url)
} else {
Alert.alert('URLを開けませんでした。')
}
})
}
render() {
const { url } = this.props
return <WebView source={{ uri: url }} startInLoadingState onError={this.handleError} />
}
}
view raw WebViewSample.js hosted with ❤ by GitHub

おわりに

外部ブラウザで開きたくないという場合は、 今回試してはいないですが naoufal/react-native-safari-view も使えそうです(しばらく更新されていないのは気がかりですが)。