Sample code illustrating MVC architecture in iOS - iphone

I'm trying to get the hang of MVC architecture. Say I have a plist in which there are a list of persons and each person has a few attributes like name, address and photograph. Suppose
I want to display these details in a table view. The cell title would be the name, description would be the address and the image towards the left would be the photograph of the person.
One approach I could take is to load the plist in an array-of-dictionaries in my viewDidLoad: and then display them.
However, I want to adopt an Object Oriented method by creating 'Person' class. How do I go about doing the same in this case? I believe I could start by creating a 'Person' class with three attributes:Name, Address, Photograph. What next? I would need many instances of this 'Person' class right? How would I 'load' each instance with a corresponding Person entry from the plist? Should I create another class that does this 'loading'? Do people use Singleton class to achieve his?
Could someone share some sample sample code to illustrate this? Or maybe guide me to blogs/resources that talk about this?

Hmmm, I think you are over thinking this a bit. I would just create a class that would handle my person, in this case your 'Person' class.
I would simply store each person using Core Data. Then, when it's time to display them, I would just make a fetch request and store all person managed objects into an NSMutableArray (which simply handles arrays of objects). Then you can simply use the index value to display the numerous persons in your array in a tableView.
In summary I would:
1. For every person, create instance of Person.
2. Verify if person exists in my Core Data Person Entity.
3. If not, then insert into Core Data (the object will become an
NSManagedObject).
4. For displaying, simply do a fetch request to pull all persons in your
entity. Here I prefer to store the
results into an NSMutableArray, but
that is completely up to you. Make
sure you release your fetch request
after the results are store in the
array.
5. Reference them to your table view using the index value for each
person NSManagedObject in the array.
For something that doesn't involve storing simply:
1. Create instance of Person for every entry.
2. Add Person object to array.
3. Reference each Person to table view using index value.
In the end the approach that you take will be dictated by what you want to do with the information.
As for reading the plist, I would opt for reading an XML for which all you need is an XML Parser class (there are several options for parsers). Since I don't do anything but parse the XML, I use NSXMLParser, but that choice is also up to you. Just create an NSXMLParser class (make sure that the different actions for when the parser finds a given element are in play inside that parser). So yes, you would need to make additions to the NSXMLParser for handling each element. It's really easier than it sounds.
Also, by storing in Core Data, you can always fetch the info without you using a Singleton.

I believe you are not looking for a design solution to the above mentioned question. If that is the case #A Salcedo 's version looks fine.
if you are looking for general guide lines for MVC and modeling , Martin Fowler's site offers some of the best (agile) design/modeling guidelines.
http://www.martinfowler.com/eaaDev/uiArchs.html (on MVC) and
http://martinfowler.com/design.html (many interesting design related posts).
Happy reading.

Related

classes and data presentation

I hope someone can give me some guidance in how to best approach this situation.
I am using dbcontext, wpf and sql server.
I am having situations were the presentation of the data requires other data than just what is coming from a single table. For example, if I had a person table but wanted to show also how many books they had read from related data, say fields would be name, address, NoOfBooks.
I currently create a new class, called say PersonBookPM, that I fill up with data from a linq query which combines the two tables which includes the above three fields.I create an observablecollection of that and make that the itemssource of the grid/listbox.
When I am then adding data to that I then need to use the selecteditem, convert that back to the single entity of person, and attach it back in to the context.
It seems like the classes have already been defined by the code gen and I am repeating the process only slightly differently.
Am I going round the houses here?
Thanks Scott

Core Data object graph design decision

I am designing an app which tracks data on Game objects. Each Game has a name, a date and other attributes. The problem I am having arises because I want the user to be able to add more names (for example) to pick from in the application. (in this case from a UITableView). So the user is presented with a list of names to choose from, and if the one they want is not in the list, they can add one to the list.
My solution is that I currently have a second entity called GameName so that I can show the user a list of those game names to pick from when they are adding a new Game. I just call an NSFetchRequest on all the GameName objects and display them in the UITableView. There doesn't have to be a Game object created yet to do this.
My dilemma is that I want to know if this is a good practice. It seems that if I do it this way, I will end up having a lot of entities with just one attribute, for the sake of allowing the user to pick from and add to a customizable list.
I hope this makes sense. I can clarify anything upon request.
Your approach is fine, and is commonly used in database design. The entity you want to add is called a "domain table" in databases. See this page, in particular this paragraph:
In a normalized data model, the reference domain is typically specified in a reference table. Following the previous example, a Gender reference table would have exactly two records, one per allowed value—excluding NULL. Reference tables are formally related to other tables in a database by the use of foreign keys.
Of course, you probably want to have an optional relationship between the GameName and Game entities.

How to best store object in a CoreData relationship property that may be of many different types?

I need to store an activity feed in an iOS application. Activity feed items will have a payload field which can be one of many (and I really mean many) types of entities in the system.
What is a good way to implement this payload relationship field on the Activity entity in my CoreData model?
Is it possible to use the id data type, or maybe use an NSManagedObject type?
One way to workaround this maybe to just store CoreData's entityId as a string in a special field, but I'd rather avoid that if there is a better way.
Example:
For simplicity let's say we have a not-so-standard blogging model: User, Blog, BlogPost, Comment and the following activities may happen:
User may create a new blog.
User may publish a new blog post.
A blog can be commented on.
A comment maybe liked.
etc.
Each of these generate a new Activity item on the website which in turns have a related payload relation to the item that was modified or being acted on.
Now I need to download, translate and store these activity feed items from the website in my iPhone application... so how do I mimic this payload field since it maybe pointing to any possible entity?
In my real code, though, there are about 10+ types of entities that could be put into this payload field so I'm looking for a good approach here.
If you don't need to search / query the fields of your objects of variable type, then I suggest to use NSCoder to convert them into a binary representation and store them in a BLOB field of your managed object. You might want to store some type information as well in an other field of the same managed object. On the other side if you need to search between these variable objects then you have to create a new managed object type (entity) for each object. See my answer also here: NSCoding VS Core data
Only thing that you can use is NSManagedObject. So you have to create your model and your relation and create new file for Activity and payload that will be subclasses of NSManagedObject.
Take a look at Core Data Programing Guide .
You will find your answers in there.

Modelling entity types using Core Data

I'm working on my first app using Core Data and I need to assign a type (with an associated name attribute) to a couple of entities.
Below is my object model so far.
The room and item types will be updated from time to time over the network.
Is this the best way to implement this using Core Data? Thanks :)
Edit: To try to explain better: for example, rooms may be Bedrooms, Kitchens etc. Items can be Aircon, Security Camera etc. The only difference between the different room and item types is the name text. The list of valid name texts will be updated so I don't want to hard code it in the app. Also, the user can create multiple rooms and items of the same type, which is why they are numbered (roomNumber,itemNumber)
improved Core Data Model Image http://img42.imageshack.us/img42/8458/picture6c.png
Nick, try and avoid the temptation of thinking of Core Data as a database. Design your model from the point of view looking at using the objects in your code.
i.e. your relationship properties are collections (or singluars) of the related thing.. you should rename the relationship JobLocation.JobLocationToRoom as just JobLocation.rooms
And yes, using Core Data will be quite straight forward, but it's hard to give you a definitive answer with such a vague question.
Perhaps my question wasn't clear, but I found the answer in the Apple iPhoneCoreDataRecipes demo code
The relationship I wanted to model is similar to Recipe -> RecipeType.
In addition to the other answers, you don't need to model separate ID attributes. Core Data managed objects automatically have managed object IDs that are handled for you entirely behind-the-scenes by the framework.

NSManagedObject for temporary use, how to switch between NSObject and NSManagedObject

Im using a Core Data model for my iPhone app. I have been looking for a way to instantiate or use an Entity outside the ManagedObjectContext. (This should not be done, I know, Im also more looking for a way to not do that, but get the benefits anyway).
My challenge is that I have a view where the user can search for "Persons", all the search results are parsed and put into a Person managedObject then displayed in a list.
If the user clicks a Person from the list, then and only then would I like the Person entity to be persisted to the store, however this requires me to delete all the other results so they don't get persisted along with the desired one. Also to the best of my knowledge, if the user decides to quite the app, the store is persisted, potentially with all current search results mixed in with real user data!
Is there some way I could have a TempPerson NSObject I could use for the search list? Without, however, me having to manually pull the 45 attributes from the temp object and manually set them on the managedObject!
Sort of like:
NSManagedObject aPersonCorrectlyReturnedFromTheStore = (NSManagedObject *)tempPersonOfJustTypeNSObject
I have seen example code from Apple where they build a temporary store to facilitate undo/redo and other stuff on an object that is not yet persisted. This I feel would be overkill in my situation. I just need to display search results until the user selects a Person to persist.
Hope it is clear what Im trying to do, feeling like my Core Data vocabulary isn't quite large enough yet:)
Thanks for any suggestions.
You could create each temporary person object as an NSDictionary or NSMutableDictionary. You can then create a new Person managed object and use the fact that NSManagedObject instances are KVC compliant and use setValuesForKeysWithDictionary:.
New managed objects that are inserted are not actually persisted until you send the managed object context a save: message.
Keep track of them in a collection (set or array) -- you are probably already doing this since you are presenting the search results somehow. Then, delete (deleteObject:) them all except for the one(s) that the user selects.
The deleted managed objects will never be stored.