UniAPPH5页面解决ios系统无法弹出定位提示

649 阅读2分钟

最近在写一个功能,要求实现在h5页面上navigator.geolocation实现定位功能。在移动端测试时,安卓手机都能正常弹出定位提示,提示用户是否开启定位权限。

但是,苹果不可以!!

当时无论怎么测试,苹果都无法打开定位弹窗,在网上找了许久,都没法解决。只能自己搞了。

测试发现,纯粹的HTMl页面是可以让苹果弹出定位开启权限的,但相关代码一旦放入vue文件中就会失灵(到现在我也不知道为什么╮(╯▽╰)╭)。

那没办法喽,只能试试在vue文件中混入HTML文件,并且让他们之间进行相互通讯。

[查阅uniapp文档](web-view | uni-app官网),发现其支持以web-view的形式将html文件混入vue文件中。(我还以为ifame可以,测试发现移动端不行┑( ̄Д  ̄)┍)。

以下是具体实现方法。

HTML部分

uniapp推荐是在根目录下新建一个文件夹放置html文件

image.png

下面是内容。文件命名随便起,对的上就行,我这里用的是locate.html。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        let pos = ''
        // 浏览器定位
        function locate() {
            navigator.geolocation.getCurrentPosition(success, error, {
                enableHighAccuracy: true,
                timeout: 5000,
                maximumAge: 0
            })
        }
        function success(position) {
            pos = [position.coords.longitude, position.coords.latitude]
        }
        function error(error) {
            switch (error.code) {
                case error.PERMISSION_DENIED:
                    alert('用户拒绝对获取地理位置的请求。')
                    break;
                case error.POSITION_UNAVAILABLE:
                    alert('位置信息是不可用的。')
                    break;
                case error.TIMEOUT:
                    alert('请求用户地理位置超时。')
                    break;
                case error.UNKNOWN_ERROR:
                    alert('未知错误。')
                    break;
            }
        }

//获取实时定位需要持续监听
        setInterval(() => {
            locate()
            window.parent.postMessage({
                params: JSON.stringify(pos),
            }, '*');
        }, 2000)

    </script>
</body>

</html>

当然,高德的也可以,只是我懒。

Vue部分

vue页面需要引入并监听传来的信息。

引入文件时候注意要将页面大小设置为0,不然web-view会铺满整个页面。

<template>
	<view>
		<web-view style="width: 0; height: 0;" src="/hybrid/html/locate.html"></web-view>
	</view>
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
//创建函数处理监听消息
function handleMessage(event: any) {
	let params = JSON.parse(event.data.params);
	return params
}
onLoad((e) => {
//创建监听来接受消息
	window.addEventListener("message", handleMessage);

})
</script>

这样就可以持续获取苹果的定位。但是这样会导致进入该vue页面就会直接触发。所以可以加上一个判断,当机型是ios时才会触发开启定位。

<template>
	<view>
	<web-view v-if="isIOS" style="width: 0; height: 0;" src="/hybrid/html/locate.html"></web-view>
	</view>
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
//创建函数处理监听消息
function handleMessage(event) {
	let params = JSON.parse(event.data.params);
	return params
}

const isIOS = ref(false)
function modelJudgment() {
	let ran = navigator.userAgent
	let ios = !!ran.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
	let android = ran.indexOf('Android') > -1 || ran.indexOf('Linux') > -1
	if (ios) {
		isIOS.value = true
		window.addEventListener("message", handleMessage);
	}
	if (android) {
		isIOS.value = false
                //安卓的定位可以在vue页面实现,这里不过多赘述。
                //安卓的定位函数
	}
}

onLoad((e) => {
  modelJudgment()

})
</script>

这样就可以实现在用uniapp写的h5页面中触发ios的定位弹窗提示了。