Anyone else seeing AGSLocationDisplay less responsive at 100.5?

714
6
Jump to solution
05-24-2019 04:16 PM
ReedHunter
New Contributor III

The blue dot stopped moving with me when I'm in motion outside as of version 100.5.  I have a production vs beta version of my app, so I could make sure it was the SDK by using the same device at the same time based on the same code, tapping back and forth between the 100.4 vs 100.5 builds as I walked outside testing.  I use the standard location feed from my iPads, and had consistent results from two devices. The blue dot steadily updated location in 100.4, following me smoothly as I strolled.  The 100.5 build only showed my initial position at startup, and only a few times updated before being stuck, animating my travel direction smoothly but not budging from a previous location.   Changing map modes such as between navigation and manual pan reliably triggered a single update of the location, but nothing afterward.

This problem does not reproduce on the "Display device location" developer sample for 100.5 provided by Esri, so this unfortunately is not so simple as 100.5 bad, 100.4 good.  The only difference I see so far between my code that worked since 100.1 and the new 100.5 sample that works is that the Esri sample is in swift, and that module of my code is in objective-c.  My question then is anyone else seeing this behavior?  If so, how does your code compare to the Display device location sample?

I'll be tackling this regardless in a few weeks starting with a long delayed swift conversion for that module.  If nobody sheds light on this for me, I'll post whatever resolution I reach that solves this hurdle. 

Thanks and best regards.

Reed

0 Kudos
1 Solution

Accepted Solutions
ReedHunter
New Contributor III

It turns out that what changed at 100.5 is that you can no longer have AGSLocationDisplay started on a background thread.  Putting the mapView.locationDisplay startWithCompletion call onto the main thread fixed the problem.

            dispatch_async(dispatch_get_main_queue(), ^{

                [weakSelf.mapView.locationDisplay startWithCompletion:^(NSError * _Nullable error) {}];

                

                weakSelf.clLocationManager = [[CLLocationManager alloc]init];

                weakSelf.clLocationManager.delegate = weakSelf;

                [weakSelf.clLocationManager startUpdatingLocation];

            });

View solution in original post

6 Replies
Nicholas-Furness
Esri Regular Contributor

Hi Reed,

This may be a bug in 100.5 which we've fixed for 100.6.

I'll check with the team in case there's a specific workaround we can use, but in the meantime are you able to move the AGSMapView.LocationDisplay.start to happen once the AGSMap is loaded? From what I understand, that should work, but I'll be able to check more specifically in a couple of days.

Let me know whether that helps.

Nick.

0 Kudos
ReedHunter
New Contributor III

Thanks Nicholas Furness

My call to AGSMapView.LocationDisplay.start was already happening after the AGSMap was loaded, so that unfortunately wasn't it.

0 Kudos
ReedHunter
New Contributor III

It turns out that what changed at 100.5 is that you can no longer have AGSLocationDisplay started on a background thread.  Putting the mapView.locationDisplay startWithCompletion call onto the main thread fixed the problem.

            dispatch_async(dispatch_get_main_queue(), ^{

                [weakSelf.mapView.locationDisplay startWithCompletion:^(NSError * _Nullable error) {}];

                

                weakSelf.clLocationManager = [[CLLocationManager alloc]init];

                weakSelf.clLocationManager.delegate = weakSelf;

                [weakSelf.clLocationManager startUpdatingLocation];

            });

View solution in original post

Nicholas-Furness
Esri Regular Contributor

Hmm. Which queue were you starting the location display from? For most scenarios you'd have to explicitly move off the main queue yourself. I just wonder if it's the dispatch_async that's the solution here rather than dispatching to the main queue.

My hunch is that dispatch_async is incidental to the real cause (essentially under certain conditions if the location display is started too soon while the map is readied, the logic for tracking movement got stuck which affected auto-pan). This should be fixed in 100.6.

I also just noticed that in your code above your app will have two CLLocationManagers running. One is owned and managed by the mapView.locationDisplay and one is owned and managed by your app. Is there a reason for that?

0 Kudos
ReedHunter
New Contributor III

Nicholas, 

I think you're on the right track.  It turns out I was already using the main thread.  Assumptions in your questions above set me straight about completion blocks not being the same thing as putting code on a background thread. Right before the call to 

   dispatch_async(dispatch_get_main_queue(), ...

I set a debug breakpoint and called po [NSThread isMainThread];  This returned true, so this turns out to not be a background vs main thread problem.

To further test whether a call to any serial dispatch queue would work, I made a module level strong dispatch_queue_t property, assigned it a dispatch_queue of type DISPATCH_QUEUE_SERIAL, and used it in place of dispatch_get_main_queue. Unfortunately the bug returned - the blue dot stopped updating. I'm assuming then that my own custom serial dispatch block gets scheduled earlier than what happens with dispatch_get_main_queue.

Regarding clLocationManager, I use it to acquire its horizontalAccuracy property.  We use this to block/enable GPS vertex collection UI in our editing environment based on our business need of minimum precision quality, give numeric accuracy feedback in feet in part of the UI, and toggle one button icon between green and red to alert users to current satellite access.  If the Esri SDK were to expose that property through mapView.locationDisplay, I'd refactor the code to remove clLocationManager.

Btw, when I tried to respond to your private message my mail server said it was undeliverable.  I think that unfortunately means private messages through geonet won't work between us.

0 Kudos
Nicholas-Furness
Esri Regular Contributor

If you are just using the default location data source on mapView.locationDisplay.dataSource, it'll be an AGSCLLocationDataSource which exposes its CLLocationManager via its locationManager property.

Not sure how you created your dispatch queue, but I believe the current recommended approach is to use dispatch_get_global_queue(QOS_CLASS_UTILITY) to set the queue's priority. It shouldn't matter if it's serial or concurrent. Try an async dispatch to that.

Cheers,

Nick

P.S. Hmm. Yeah. Email replying to DMs doesn't seem to work. You need to reply to DMs via the browser. I'll see if that's something we can fix. Turns out that because I'm an admin, we can DM in the browser without me following you but the email gateway doesn't get that message. We're checking if GeoNet can be improved in that regard.

0 Kudos