IOS Bottleneck: global variable or master data or property lists

I am new to iOS and Cocoa. My question is not how to get something to work, but about design to improve UX and performance.

I am adding functions to an existing application. Currently, the application has one class "RootViewController" (RVC), which is responsible for executing server requests. RVC calls the server for a json response. This json response is parsed, and the processed response refers to an NSArray object called "array". The data that the server gives to the "array" should be updated regularly, as it is a live inventory that other customers can buy.

I need to use the reference to the "array" in other classes at different times throughout the life of the application. I do not want to call the server every time I want to use or update the "array". When testing this application on my own device, it seems that server call might be slow -> it hurts application performance.

I was thinking of creating a class that could act as a delegate to refer to NSArray - sort of acting like a global variable. I would make an asynchronous request to the server and keep up with the response in this delegate class. I am not sure how to determine if this approach is effective or considers best practices (taking into account MVC).

I am looking to find out the best place to store the "array" so that other classes can use it quickly, not depending too much on network or memory usage. The "array" should be able to be updated periodically from the server (since the "model" may change due to inventory changes). Based on my research, iOS CoreData seems like the best place to start, but I'm not sure how to regularly update CoreData if the application is inactive. In other words, I do not want to provide the user with outdated data if the data in CoreData has not been updated recently.

Json responses are around 20K - 45K.

Where is the best / alternative place to store lightweight items so they can be updated regularly? I am leaning towards a session style variable, but I don't know if there is a better way to do this.

+4
source share
3 answers

To look at this in accordance with MVC, you have two parts:

  • An array is a model
  • The code that retrieves the inventory from the server is the controller

This controller code is indeed a model controller, not a view controller. I would not put it in a view controller class. You can put it in your application delegate if the code is very simple, but I would recommend it completely in my class.

In -applicationDidFinishLaunching :

[[InventoryController sharedInstance] reloadContent]; [[InventoryController sharedInstance] scheduleUpdates]; 

InventoryController.h

 @interface InventoryController @property (retain) NSArray *inventory; @property (retain) NSTimer *reloadTimer; + (InventoryController *) sharedInstance; - (void) reloadContent; - (void) scheduleUpdates; @end 

InventoryController.m

 @implmentation InventoryController - (void) reloadContent { ... } + (InventoryController *) sharedInstance { static InventoryController * singleton; if (!singleton) singleton = [[self.class alloc] init]; return singleton; } - (void) scheduleUpdates { self.reloadTimer = ...; } @end 

Everywhere:

 NSArray *inventory = [[InventoryController sharedInstance] inventory]; 

In -reloadContent you have to pull the content from the server. In -scheduleUpdates you must configure a timer that acts on the controller, causing it to periodically reload data. If your view controller needs to adjust its behavior when the data is out of date, save the NSDate next to the array, add a method like -isStale , which checks the dates and is called first.

Remember to download the urls in the background. You should not stop and reload data during the processing of an event or action, so essentially your view controller should return from the action method while waiting for the data and configure its display when you return the data.

If the view manager should respond after updating the data, register the view controllers for a notification that you can post when the inventory controller completes updating its content:

  [[NSNotificationCenter defaultCenter] postNotificationName:InventoryControllerDidReloadContent object:self]; 

If you want to cache the inventory data on the device so that you can delete it from memory when the application goes into the background, you can do this by writing the array to the property list, but if the obsolete data is not useful, you can not worry.

You can use Core Data instead of an array and a list of properties, but it does not eliminate the need for a controller that downloads data from the server and loads it into context. Instead of having an array, you probably have the context of the managed entity and the resulting result controller. If you do not edit this content in your application, I doubt that Core Data will provide you any advantages over the list of arrays and properties.

+2
source

I would recommend storing this in the applicationโ€™s deletion. It works well for storing an array and can be accessed from any class in your application.

0
source

If this โ€œarrayโ€ has an interesting structure, then CoreData is an excellent choice. In this case, I assume that CoreData and plist will be about as fast as the others. Use what seems simple and if it is too slow, try another.

Try not to update the data while the application is not running. Save the latest update time with cached data. If it is "too old", display "please wait" and update it. If itโ€™s โ€œold but not too old,โ€ display what you have and update it in a non-main topic. Or try other options on this interface ("too old" == notification + read-only mode).

If you find a trick for updating in the background that gets a past review of applications, thinks long and hard about how much a custom battery it will have. Add a way to disable it. Or disable it by default and add a way to enable it. Or just don't do it. :-)

0
source

Source: https://habr.com/ru/post/1446561/


All Articles