AGSGDBFeatureServiceTable load in background thread

4413
11
03-28-2015 02:44 PM
SimonFox
New Contributor II

Hi folks,

I'm tearing my hair out trying to load a feature service table in a background thread, as below. This works fine on the main iOS thread. But in a background thread no network activity occurs. I confirmed using Charles proxy server.

Hard to understand why, as it appears to block the main thread. My app locks up while these calls are occurring. Have I missed something?


Thanks,
Simon

dispatch_queue_t backgroundLoadThread = dispatch_queue_create("com.xxx.loadservicethread", NULL);

dispatch_async(backgroundLoadThread, ^(void) {

     AGSGDBFeatureServiceTable* fst = [[AGSGDBFeatureServiceTable alloc]initWithServiceURL:url

                                                                                       credential:myCredentials

                                                                                 spatialReference:mapView.spatialReference];

...

0 Kudos
11 Replies
SimonFox
New Contributor II

using loadCompleted(...) doesn't help either.

0 Kudos
DiveshGoyal
Esri Regular Contributor

The feature service table, like other classes in the SDK that connect to web services, already performs its loading on a background thread, even if you instantiate it on the main thread. Is there a reason why you still want to create it on a background thread?

0 Kudos
SimonFox
New Contributor II

Hi Divesh, thanks for your reply.

It appeared to me that the call was being made on the main thread. With the debugger it can take some seconds to proceed across the initWithServiceURL call.

It's possible that the lag is occurring somewhere else I guess. It's not apparent in my own code though, so at some point there are long delays occurring on the main thread and my UI is freezing for 15 seconds or so.

Which operation exactly is freezing, I guess I can't be sure. Perhaps it is the post-processing of loaded data after the call is complete. But there doesn't seem to be any way to keep the main thread free during this loading.

Regards,

Simon.

0 Kudos
SimonFox
New Contributor II

This is the code block that causes the app to freeze up. Maybe will help see where my problem lies.

Thanks for any help, much appreciated.

self.geodatabaseTask.loadCompletion = ^(NSError* error) {

       

               for (AGSMapServiceLayerInfo* info in self.geodatabaseTask.featureServiceInfo.layerInfos) {

      

                     NSURL* url = [self.geodatabaseTask.URL URLByAppendingPathComponent:[NSString stringWithFormat:@"%lu",(unsigned long)info.layerId]];

              

                     AGSGDBFeatureServiceTable* fst = [[AGSGDBFeatureServiceTable alloc]initWithServiceURL:url

                                                                                          credential:self.credentials

                                                                                    spatialReference:mapView.spatialReference];

          

                     AGSFeatureTableLayer *f = [[AGSFeatureTableLayer alloc]initWithFeatureTable:fst];

                     f.delegate = self;

           

                     fst.loadCompletion = ^(NSError* error) {

                         [mapView addMapLayer:f];

                     };

             }

        }

    };

0 Kudos
DiveshGoyal
Esri Regular Contributor

If you can send me a project I can try to look into it.

On the surface, the code snippet you provided looks Ok. It is similar to what the OfflineFeatureEditingSample also does. I don't expect any of it to block the main thread and freeze your app.

0 Kudos
SimonFox
New Contributor II

Thanks Divesh, very kind of you to help. Yes, I used that example project to work from

I'll simplify the code and check with my client then send a project. Really appreciate your help.

Thanks, Simon.

0 Kudos
SimonFox
New Contributor II

I tested the OfflineFeatureEditingSample project using my web service and the same problem occurs. There are 37 layers, and not a huge amount of data.


With the simulator it isn't so bad as it's running on the faster Mac processor. But on my iPhone 5s the UI locks up until all layers have completed loading.

I also find the actual polygons don't load in any predictable time period. Some of them don't load at all even though the map location is right in the middle of them. Maybe they load later, maybe they don't.

When I used the method from the GeometryServiceSampleViewController project I didn't have any of these problems. But I thought I would need to have a local database to improve app performance. Will have to make my own caching system for polygons I guess. My client won't accept a frozen app on startup.

Thanks for your help.

0 Kudos
DiveshGoyal
Esri Regular Contributor

Are you loading 37 AGSGDBFeatureServiceTable objects at startup? If so, do things get better if you load only a subset (say 5, or 10)? I'm not suggesting that as a workaround (yet), I'm trying to narrow down the cause of the problem.

0 Kudos
SimonFox
New Contributor II

Yes, load 37 requests at once is a bad idea. I'm surprised it works no problem when just loading FeatureLayers directly (as in GeometryServiceSampleViewController). There's absolutely no UI lag at all.

I tried spreading the requests out with the OfflineFeatureEditingSample approach and the UI is more responsive. A little jerky though, unlike the above method.

I used Instruments to try and see something on the Main Thread, but it does appear that all network cals are triggering background thread dispatches. Maybe digging deeper with Instruments could learn more. Not the easiest tool to use though.

There must be some task occurring on the main thread though, to explain the jerky UI. If I had time I'd work more with Instruments to try and find it. I double checked that it's not blocking in my own code via delegates etc...

Wish I had a good profiling tool like for Java. Would get to the bottom of it in no time. Instruments is just awful

0 Kudos