I have a data controller class used within my app that handles parsing xml and a few other operations vital to my app. What I want to be able to do is have the data that it parses store in an array that can be accessed in multiple views of my app. Right now, each view creates its own instance of the data controller class and so the array that the data is stored in is specific to that view controller. Is there a way to still create individual instances of the data controller class for each view controller, but the data is stored in the array where all views can access it? I have tried to store in NSUserDefaults but that doesn't seem the most effective way. Each view controller needs to have its own instance of the data controller class because I utilize delegate methods that are used in each of the view controllers. I hope this makes sense.
You have two ways to implement this (ok, maybe more than two but those are most common):
Store array in application delegate and acces it as property.
Create singleton object who gonna hold array (and other possible data/methods).
Related
I have a UIPageViewController containing multiple view controllers each with questions for the user to respond to. Once these questions are answered I want to save the values somewhere locally so I can later create a PDF populated with these values. What is the best way to do this? Would I use NSUserDefaults?
It depends on how you want the data to persist. If you want the data to persist the life of the user, even if the app is deleted from the device, you would obviously need to store it away from the client such as in a database (i.e. Realm, CoreData). If you want the data to persist the life of the app itself, data that you would continue to use to shape the user's experience, you could use UserDefaults but that doesn't seem like what you're trying to do. And if you just want the data to persist the life of that instance of the app, store it in regular properties.
I suspect, for whatever reason, the third option would be your choice. If so, I would suggest creating a model object that's as an instance property of the parent view controller (that all page view controllers can reference)...
class SurveyAnswers {
var userName: String?
var userAge: Int?
var favoriteSauce: PizzaSauce?
var livesWithCats: Bool?
}
...and simply use the protocol/delegate pattern to pass data from the child to the parent which would update properties in that object (so long as they are updating the same instance of that object). Then, when you're ready to prepare the PDF file, simply ask the parent for that object, whose properties have been set by the child view controllers.
And if you're OK with it, you could use the shared AppDelegate as a way to store and retrieve this data. I would just caution against making this a habit but depending on your application as a whole, this may be a perfectly acceptable option.
General rule of thumb: set properties in destination objects to pass data forward and use delegates to pass data backward.
I wonder 4 questions about the data model when creating iOS apps:
Do you create a class called DataModel and inside there we find arrays and objects that belong to the data model that is instantiated by every model? Or do you create a data model that is a singleton and has the app state? I guess singleton is not a good idea because is difficult to test.
Where do you write your networking code and mapping code (converting json files into data model objects)? I guess it should be an object inside the data model.
I understand the model encapsulates app state, for that reasonI I guess if we have a table in controller A and the detail in controller B (using a navigation controller), maybe we have to create an instance of the data model that holds ‘selectedStudent’ and then once the B controller is pushed, it uses the model to know what student was selected.
That’s what I understand from this image:
http://naikom.ru/img/2012/ios2/8.jpg
However from this image;
https://littlehales.files.wordpress.com/2012/01/mvc2.jpg
I see that there are several models and controllers communicate each other, so in my example, using prepareForSegue I could pass the selectedStudent to the other controller. If we do that, then the controller is encapsulating state, rather than the model.
Can you explain to me how I should do that? Or how do large apps do this?
According to this diagram:
http://i.stack.imgur.com/Psi8i.png
In order to send information from the data model to the controller we have to use NSNotificationCenter or KVO.
I know the problem of delegates is that they are just a 1-to-1 relationship, so probably not good idea. What about blocks or creating your own observer using a protocol and addObserver/removeObserver (using an array or a set)? Do you really use for this NSNotificationCenter or KVO in the data model?
There are different levels I'm asking this question at.
Case 1: Let's think about the typical drill-down design. Say a table view controller has an array of custom objects, and tapping a cell will push a view controller that allows the user to modify the object represented by the cell. In this case, should the pushed view controller have the custom object as a property of its own, or use a data source/delegate protocol to edit the custom object but not own it.
Case 2: A similar but slightly different situation is this. I'm using a singleton store to handle an array of bank accounts in my app. A view controller will show a list of the accounts, and I'm wondering if I should have the array of accounts as a property in my view controller or get the array via the store. (The array of accounts is accessed quite often.) I guess the only difference is a single object vs. an array of objects. I'm curious about how heavy these arrays can be, so whether it's faster to load the array from the store each time or have it as a property in the view controller.
Case 3: When should the local file system be used? In my app's example, bank accounts are accessed quite often, so I have them unarchived and set as properties upon launching the app, but for much bigger data, I only load them from the file system when they should be displayed or edited. I'm still not sure what the right way is.
I am using sqlite to store the array of data and I have more than one view controller in my application and my question is Is it right to create a singleton class to control that array of information coz I don't want to recreate the array from sqlite file every time loading a new view controller into the memory?
A singleton will work. You can also just pass the array from the current view controller to the new view controller when it gets created and displayed.
In my app an NSArray is created to store various results from a library search. The idea is that each NSArray of results should also be stored locally so that if the search is made again in the future the local results are retrieved.
Now, I've been thinking about two different approaches. The first is to simply make an array in the second view controller that stores the different results arrays. The second is to instead make a class called Search (for example) that has an NSArray attribute to store the results. This object would be initiated in the second view controller (which would then add it to its own array).
Does this make sense? In terms of memory management is one better than the other? Also, I'll need to use the delegate function to get the data across to the second view controller, right?
Thanks
I personally don't see a big difference. To clarify on the second option, create a singleton object that your Search class makes available to any client class (the view controllers). That singleton provides a store function and a retrieve last result function.
You can make this even simpler by just using the class itself - class methods to store and retrieve, and the class then uses a static NSMutableArray (or NSArray) to keep save the objects.
If you want to make this array available across restarts, then use NSUserDefaults. If things in your array cannot be saved in defaults (some objects cannot) you can possibly turn the array into a NSData object and store that (if all objects comply with NSCoding you are in good shape.