iOS 6 breaks GeoLocation in webapps (apple-mobile-

2019-01-16 07:23发布

I have an app that does a simple textbook navigator.geoLocation.watchPosition(...) that works great in iOS 5.x both in Safari and as a web app (using apple-mobile-web-app-capable meta tag).

However, in iOS6, GeoLocation does not work in the webapp. It still works in safari as expected, but when I run the webapp, it prompts me for location permission, then silently fails. I see the location icon, but no events are thrown from watchLocation. I get no error events or any location events.

Has anyone run into this? Any workarounds? It's definitely iOS6 specific and also specific to the apple-mobile-web-app-capable/webapp.

11条回答
混吃等死
2楼-- · 2019-01-16 08:00

I'm having the same problem. Looks like watchPosition is simply failing out after the first position is received. I haven't found a work around yet, but I wanted to confirm that I was experiencing issues.

Using these samples: http://www.w3schools.com/html/html5_geolocation.asp

I get expected results on ios5 but ios6 drops the ball with watchPosition.

查看更多
Ridiculous、
3楼-- · 2019-01-16 08:01

This appears to be fixed under iOS 6.1! It wasn't in the recent betas, but today's final 6.1 release seems to be good with my testing.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-16 08:03

This is FINALLY fixed in iOS7 beta (beta 2 is all I've tested)!

查看更多
欢心
5楼-- · 2019-01-16 08:12

The good news is: I've done it... I've figured it out. The bad news is: somebody smarter than me is going to have to tell you why this works, whereas any other variation of this solution or any of the other solutions offered don't work. This was a hard-fought victory but I'm too embarrassed to say how many hours (days) it took me to figure this out. Without further ado:

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.");
        }

Note: for some reason, this doesn't seem to work as consistently if the execution of this code it delayed at some point after initially launching the app. So, this is the FIRST thing I execute in my initialization method.

Note: The only other thing I've added to my app is, when I need to use the geolocation data (which, for me, takes place after the initialization of several other Classes/Object Literals), is to check for the latitude/longitude values. If they exist, continue; If not, run the above geolocation method again, then continue.

Note: One of the things that threw me for a long time was that I only needed to get the current position of the user. I didn't need to track the users' movements. I kept trying different iterations of this with the getCurrentPosition() method. For whatever reason, it doesn't work. So, this is the solution I came up with. Run it like you're going to track the users location (to get their location in the first place), then once you've gotten their location, clear the watchPosition ID to prevent it from tracking them. If you need to track their location as it changes over time, you can of course... not clear the watchPosition ID.

HTH. From everything I've been reading, there are a lot of developers who need this functionality to work for their mission-critical apps. If this solution doesn't work for you, I'm not sure what other direction I can give. Having said that, I've tested this several hundred times and this successfully retrieves the users' location in a WebApp (navigator.standalone) on iOS 6.

查看更多
淡お忘
6楼-- · 2019-01-16 08:12

here is a video of me replicating the bug and demonstrating a work around. This bug appears to exist weather you use the web app meta tag or not.

http://youtu.be/ygprgHh6LxA

Update: 121212 - IOS 6.1 Beta 3 testing shows the bug is still not resolved...

Update: 122012 - IOS 6.1 Beta 4 testing shows the bug is still not resolved...


Update: 031113 - Replication Example

Okay, it is a simple issue to replicate in just a few seconds. I feel it is not a safari, but an IOS issue. It’s almost as if Google wrote the bios for the IOS to meet the WC3 html geo location spec and took it with them when IOS6 kicked them off the bus. Using an IOS device go here:

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

Click start, watch should return result almost every second. Then click the Google link to leave this page. Then user browser back button to return Click start. Watch will return 1 to 3 records and hang. Minimize safari (home button) and then restore (safari icon); stops hanging

That's it. until it does not hang, the issue remains.

Mark

UPDATE:

IOS 7.1 fixed the issue...

查看更多
戒情不戒烟
7楼-- · 2019-01-16 08:12

seems to be fixed in iOS 6.1, finally! See my site www.slople.com where it works again under 6.1

查看更多
登录 后发表回答