24

我有一个应用程序,它执行一个简单的教科书 navigator.geoLocation.watchPosition(...) ,它在 iOS 5.x 中运行良好,无论是在 Safari 还是作为网络应用程序(使用 apple-mobile-web-app-capable 元标记)。

但是,在 iOS6 中,GeoLocation 在 webapp 中不起作用。它仍然可以按预期在 safari 中运行,但是当我运行 webapp 时,它会提示我提供位置许可,然后静默失败。我看到了位置图标,但 watchLocation 没有引发任何事件。我没有收到错误事件或任何位置事件。

有没有人遇到过这个?任何解决方法?它绝对是特定于 iOS6 的,也特定于 apple-mobile-web-app-capable/webapp。

4

11 回答 11

14

这绝对是一个错误,但我找到了解决方法。你不会喜欢这个,但至少它会让你的网络应用程序再次运行。您需要检查 User Agent 标头,如果它包含“iPhone OS 6”,则不要使用:

<meta content="yes" name="apple-mobile-web-app-capable" />

是的,这意味着它不是一个真正的 Web 应用程序,您将获得 Safari 页眉和​​页脚栏。但至少它会让你的应用在主屏幕上再次运行。您可以访问我的网站www.nextbus.com来了解它是如何工作的。

请注意,谷歌似乎遇到了这个问题。尝试转到maps.google.com然后将 Web 应用程序添加到您的主屏幕。地理位置将适用于它,但您确实会看到丑陋的 Safari 页眉和​​页脚栏。

请向苹果大声抱怨!

于 2012-09-20T06:07:56.120 回答
3

好消息是:我已经做到了……我已经弄清楚了。坏消息是:比我更聪明的人将不得不告诉你为什么这有效,而此解决方案的任何其他变体或提供的任何其他解决方案都不起作用。这是一场艰苦卓绝的胜利,但我不好意思说我花了多少小时(天)才弄清楚这一点。无需再费周折:

if (window.navigator.geolocation) {

            var accuracyThreshold = 100,
            timeout = 10 * 1000,
            watchID = navigator.geolocation.watchPosition(function(position) {
                $('#latitude').val(position.coords.latitude); // set your latitude value here
                $('#longitude').val(position.coords.longitude); // set your longitude value here

                // if the returned distance accuracy is less than your pre-defined accuracy threshold,
                // then clear the timeout below and also clear the watchPosition to prevent it from running continuously
                position.coords.accuracy < accuracyThreshold && (clearTimeout(delayClear), navigator.geolocation.clearWatch(watchID))
            }, function(error) {

                // if it fails to get the return object (position), clear the timeout
                // and cancel the watchPosition() to prevent it from running continuously
                clearTimeout(delayClear);

                navigator.geolocation.clearWatch(watchID);

                // make the error message more human-readable friendly
                var errMsg;

                switch (error.code) {
                    case '0':
                        errMsg = 'Unknown Error';
                        break;
                    case '1':
                        errMsg = 'Location permission denied by user.';
                        break;
                    case '2':
                        errMsg = 'Position is not available';
                        break;
                    case '3':
                        errMsg = 'Request timeout';
                        break;
                }
            }, {
                enableHighAccuracy: true,
                timeout: timeout,
                maximumAge: 0
            }),
            delayClear = setTimeout(function() {
                navigator.geolocation.clearWatch(watchID);
            }, timeout + 1E3); // make this setTimeout delay one second longer than your watchPosition() timeout
        }
        else {
            throw new Error("Geolocation is not supported.");
        }

注意:由于某种原因,如果此代码的执行在最初启动应用程序后的某个时间点延迟,这似乎并不能始终如一地工作。所以,这是我在初始化方法中执行的第一件事。

注意:我添加到我的应用程序中的唯一另一件事是,当我需要使用地理位置数据时(对我来说,这发生在其他几个类/对象文字的初始化之后),是检查纬度/经度值。如果存在,继续;如果没有,请再次运行上述地理定位方法,然后继续。

注意:让我很长时间的一件事是我只需要获取用户的当前位置。我不需要跟踪用户的动作。我一直在用 getCurrentPosition() 方法尝试不同的迭代。无论出于何种原因,它都不起作用。所以,这就是我想出的解决方案。像要跟踪用户位置一样运行它(首先获取他们的位置),然后在获得他们的位置后,清除 watchPosition ID 以防止它跟踪他们。如果您需要随着时间的推移跟踪他们的位置,您当然可以......不清除 watchPosition ID。

HTH。从我所阅读的所有内容来看,有很多开发人员需要此功能才能为他们的任务关键型应用程序工作。如果此解决方案对您不起作用,我不确定我还能给出什么其他方向。话虽如此,我已经对此进行了数百次测试,并且成功地在 iOS 6 上的 WebApp (navigator.standalone) 中检索了用户的位置。

于 2013-01-19T01:11:36.560 回答
2

这是我复制错误并演示解决方法的视频。这个错误似乎存在于您是否使用网络应用元标记的天气。

http://youtu.be/ygprgHh6LxA

更新:121212 - IOS 6.1 Beta 3 测试显示该错误仍未解决...

更新:122012 - IOS 6.1 Beta 4 测试显示该错误仍未解决...


更新:031113 - 复制示例

好的,只需几秒钟即可复制一个简单的问题。我觉得这不是野生动物园,而是IOS问题。这几乎就像 Google 为 IOS 编写了 bios 以满足 WC3 html 地理位置规范,并在 IOS6 将它们踢下巴士时随身携带。使用 IOS 设备去这里:

http://uc.myaesc.com/geoloctestorig.htm

点击开始,手表几乎每秒都会返回结果。然后单击 Google 链接离开此页面。然后用户浏览器返回按钮返回点击开始。Watch 将返回 1 到 3 条记录并挂起。最小化 safari(主页按钮)然后恢复(safari 图标);停止悬挂

而已。直到它没有挂起,问题仍然存在。

标记

更新:

IOS 7.1 解决了这个问题...

于 2012-11-17T23:30:19.513 回答
1

这并不完全是一个答案,因为 ios6 中的主屏幕应用程序似乎有一些与 GeoLocation 相关的错误,但我发现以下链接非常有帮助。它解释说,由于主屏幕应用程序现在像本地应用程序一样存储,它们有自己的存储/缓存。

地理位置在第一次迭代时有效,但从那时起无法更新。解决方法是删除以下元标记,以便主屏幕应用程序在浏览器模式下运行(我不确定它是否完全称为浏览器模式)。不幸的是,该应用程序将使用浏览器的页眉和页脚呈现,但 GeoLocation 将再次工作。

<meta content="yes" name="apple-mobile-web-app-capable" />

iOS 6 地理位置和本地数据存储

“主屏幕应用程序中的数据现在像原生应用程序一样存储。每个原生应用程序都有自己的沙箱,用于存储、备份和恢复数据。在 iOS 6 之前,主屏幕应用程序与在浏览器中运行的同一个应用程序共享数据. 如果用户清除浏览器中的缓存,主屏幕版本的应用程序也会丢失数据。在 iOS 6 中,主屏幕应用程序的数据会像原生应用程序一样保存到沙箱中。备份和恢复可以正确处理数据,并且清除浏览器中的缓存不会影响它们。”

于 2012-10-04T15:21:58.597 回答
1

看来它只工作一次,然后任何辅助调用都会失败。一种替代方法是缓存结果并使用缓存的结果(如果有),尽管这意味着您不能拥有一个跟随某人位置的应用程序。

于 2012-09-28T19:56:08.160 回答
0

这最终在 iOS7 beta 中得到修复(我测试过的只有 beta 2)!

于 2013-07-04T23:17:54.013 回答
0

终于在 iOS 6.1 中修复了!请参阅我的网站 www.slople.com,它在 6.1 下再次运行

于 2013-01-30T12:08:45.997 回答
0

我有同样的问题。看起来 watchPosition 在收到第一个位置后只是失败了。我还没有找到解决方法,但我想确认我遇到了问题。

使用这些示例: http ://www.w3schools.com/html/html5_geolocation.asp

我在 ios5 上得到了预期的结果,但 ios6 用 watchPosition 丢球了。

于 2012-09-19T22:44:30.210 回答
0

我可以确认在全屏运行我的网络应用程序时遇到了同样的问题。

有趣的是,当全屏 Safari 请求允许使用我的位置时,网站标题是“网络”而不是网站的标题,就像以前的 iOS 版本一样。

删除“apple-mobile-web-app-capable”元标记很好,它可以工作,但前提是您再次“添加到主屏幕”。我们每天有大约 7000 名用户已经将我们的图标添加到他们的主屏幕。让他们再次这样做,然后在实施修复时可能再次这样做并不是很好。

于 2012-09-28T10:59:00.480 回答
0

这似乎在 iOS 6.1 下已修复!它不在最近的测试版中,但今天的最终 6.1 版本似乎对我的测试很好。

于 2013-01-29T05:26:48.643 回答
0

您必须注意加载的非安全内容。对我来说,从安全上下文加载所有 javascript、图像和 css 解决了 safari 的问题。

于 2017-09-13T11:01:16.560 回答