I’m new to iOS & Cocoa. My question isn’t about how to make something work, but more about design to improve UX & performance.
I’m adding features to an existing app. Currently, the app has one class “RootViewController” (RVC) that is responsible for making server requests. RVC calls a server for a json response. This json response is parsed and the parsed response is referenced by an NSArray object called “array”. The data that the server gives to “array” must be updated regularly because it represents live inventory that other customers could buy.
I need to use the reference to “array” in other classes at different times during the lifetime of the app. I don’t want to call the server every time I want to use or update “array”. When testing this app on my own device, it seems like calling the server can be slow -> hurts performance of the app.
I’ve considered creating a class that could act as a delegate to keep a reference to an NSArray – sort of acting like a global variable. I’d make an asynchronous request to the server and keep up with the response in this delegate class. I’m not sure how to determine whether this approach is efficient or considers best practices (with MVC in mind).
I’m looking to find out the best place to store “array” so that other classes may use it quickly without depending too much on the network or memory usage. “array” must be able to be updated occasionally from the server (as the “model” may change from inventory changes) . Based on my research, iOS’s CoreData seems like the best place to start, but I’m not sure how to update CoreData regularly if the app is not active. In other words, I don’t want to present the user with stale data if the data in CoreData hasn’t been updated recently.
The json responses are about 20KB – 45KB.
Where is the best/alternate place to store light weight objects so that they can be updated regularly? I’m leaning toward the session style variable, but I don’t know if there is a better way to do this.
To look at this according to MVC, you have two parts:
This controller code is really the model-controller, not the view-controller. I wouldn’t put it in a view controller class. You could put it in your app delegate if the code is very simple, but I’d recommend putting it entirely in its own class.
In -applicationDidFinishLaunching:
InventoryController.h
InventoryController.m
Everywhere else:
In
-reloadContent, you should pull the content from the server. In-scheduleUpdates, you should set up a timer which acts on the controller, causing it to periodically reload data. If your view controller needs to adjust its behavior when the data is stale, store an NSDate alongside the array, add a method like-isStalewhich checks the dates, and invoke that first.Remember to load URLs in the background. You shouldn’t stop and reload data while you’re handling an event or action, so in essence, your view controller needs to return from the action method while it’s waiting for data, and adjust its display when you get the data back.
If a view controller needs to respond once the data is refreshed, have the view controllers register for a notification which you can post when your inventory controller finishes updating its content:
If you want to cache inventory data on the device so you can remove it from memory when the app goes into the background, you might do that by writing the array to a property list, but if stale data isn’t useful, you may not want to bother.
You could use Core Data in place of the array and the property list, but it doesn’t remove the need for a controller which loads the data from the server and loads it into the context. Instead of having an array, you’ll probably have have a managed object context and a fetched results controller. If you’re not editing that content in your app I doubt Core Data will provide any benefits over an array and property list.