How do I manage models & views in an iPhone app? - iphone

I have a bunch of model objects that inherit from NSObject (Result). And I have a bunch of view objects that inherit from UIView (ResultView). They exist in a 1:1 relationship (one model for one view). In my controller I have an two arrays: one for Result objects and one for ResultView objects. The controller displays many of these result views and they can be added/deleted/reordered. Trying to keep 2 arrays in sync (results & resultViews) isn't working out. How should I approach this problem?
I'm considering initializing a view object with a model object (eg: an initWithResult: in my ResultView class and then retain a pointer to the Result object in the ResultView). Then I could do something like ResultView.result to access model data. Is there a better solution? This would break MVC, wouldn't it?

Unless you're trying to persist these model objects in a DB or something similar, I would put a view property on the model objects. If you don't have to create the view for any reason, then just nil it out to save on memory.
Does it break MVC? I guess. But if your model objects will always have a view associated with them, it starts to go into the blurry line area. No programming god will send you to hell for breaking the standard a little bit.
Do what's clean, optimal, and easiest for another programmer to understand when looking at your code.

Ok, if I understand your question correctly, the model objects are persistent while the views are dynamically created/deleted. You are relying implicitly on the index of the two arrays to achieve the mapping of two parts. One simple way is to add a "model object id" in your view class. Then you can easily reference to the correct model object in the view.

Related

Data models using structs (value types in general) - How to keep everything in sync?

I hope this question is not too generalized or broad. But I've been trying to grasp this concept for the past week and I don't make any progress. I've read dozens of articles and answers on StackOverflow but nobody seems to address this properly. Everyone is always using the most basic models that don't intertwine at all (see example). It might just be me being stupid.
I'm really struggling with understanding how a good data model works and how to implement it into an app. I want a method that is consistent and convenient throughout the app. I have an example.
Let's say I want to create a data model like this:
struct Person {
var name: String
}
struct Car {
var name: String
var owner: Person // Link to a car struct
}
struct Garage {
cars: [Car] // Array of car structs. Usage: Maybe a list view that shows all cars
}
This covers some of my big problems using structs as data models:
References between models - Structs are value types, referencing another model simply creates a copy of that model. Thus, I end up with multiple copies of the same data. What if that data changes? Or what if the reference itself changes (i.e. the owner of a car)? Observing a Car struct using, for instance, Apple's Combine framework doesn't really work because of this owner reference and the fact that it just is a copy of the original Person.
Arrays of models - This seems to be even more tricky. I have to decide whether I want to use the array as a whole (i.e. for a list view) or if I need to use individual elements (i.e. passing a car to a detail view). When trying to keep everything synced it seems like I have to choose one of the two. Doing both at the same time looks impossible. I could create two separate models, each for its own use case but again, I end up having multiple copies of the same data. It just doesn't work.
(To make it more clear: What I mean is I always have to decide between Observe([cars]) and [Observe(car)]. Doing both doesn't seem to work.)
How would I use this data model inside a project with multiple views like a "CarListView", "CarDetailView", "PersonDetailView", etc. without ending up with dozens different copies of my data that are all different?
I really want to use structs because the code becomes so simple and beautiful. But it just seems to be really annoying and partially impossible. However, wherever I go people advice using structs over classes in most cases. The example looks like a fairly basic and normal use case. Is it not suitable for struct usage? Am I just stupid?
I'd be extremely grateful for any insight on this topic. This is driving me crazy.

MVVM viewmodel and model questions

I'm trying to learn MVVM, and i'm struggling a little on differentiating between a model and viewmodel.
If someone could answer these 2 questions it would help clear a lot up for me:
Say I have an Objects class, which is a viewmodel that contains multiple ObservableCollections of Object.
The Object class contains an ObservableCollection of strings that are displayed on the GUI.
Is the Object class a model or viewmodel?
What if the Object class contains just a string and a integer (name and value), is it a model or viewmodel?
The Model is the class that holds your data. The data can be strings /integers or whatever.
The Model can also be a list / collection of those objects. For example a List of Person objects can still be your Model.
The ViewModel is the tier between your Model and the View. It should be used to perform whatever tasks you need on the data (for instance, if your Model is a list of Person objects but you only want to show in your view people that are aged older then 18, this logic is done in the ViewModel)
So to answer your question:
If you have an object which contains the data (in your example a list of strings) it is the Model.
Even if the object is a little more complex (with relation to the number of properties it holds) it's probably still the Model.
Business Logic should be kept separate from the model. On the other hand Validation can be added to the Model (for instance to make sure the Age property of a person is non-negative) since this is still rules on how your data should behave

Referencing nsmutablearray to Data Model

I have a design issue which I am trying to analyze in my current project and thought maybe someone could help me figure this out. I have an nsarray object which I filter through predicate, and I want to set that object as my data model through view controller. First, is this a good practice of doing so? Since, I want to have an access of that object through out my transaction. I am not dealing with any database, plist, or core data model at current, these are just custom data model class I have created.
Thanks.
It's very common for a view of some sort to be backed by an NSArray, or an NSMutableArray. (Particularly, a UITableView, which can provide a single cell for each object in your array.)
Depending on the scope of your project, you can either investigate using Core Data for binding your model to your data:
CocoaDevCentral Core Data Overview
Or, for something a bit easier but less robust, you can look into implementing the methods defined in the UITableViewDelegate and UITableViewDataSource protocols, if you want to populate the cells of your table on a per-request basis.

fetchedresultscontroller with two entities - predicate to target each entity?

My iPhone app has a summary page (UITableView) where I would like to show a quick overview and therefore I need to get info from several entities. It was suggested to create an abstract parent entity and have my two entities as children of this one. This do allow me to fetch the two entities using the one fetchedresultscontroller.
This works but I find that I need to filter the return a small bit. Because of the 'hack' above these entities have nothing in common so I need completely separate predicates.so from EntityA I would need "color = blue" and from EntityB "length >= 10". Because the entity I'm actually querying have none of these this doesn't work at all.
Is there a way to do this or what's the best approach here?
Niether the UITableView or the NSFetchedResultsController is designed to deal with more than one entity at a time. Moreover, it seldom makes any sense to try to do so. If you find yourself in such a situation, you probably need to rethink your data model design.
If entities are logically associated with each other then they should be linked by a relationship. If data from any two objects is to be displayed in the same tableviewCell without being gibberish then they must have some logical association and therefore should be linked by a relationship of some kind. To display in the table, you fetch one side of the relationship and then walk the relationship/s to find the other related objects.
If the logical association is strong, it should be defined as a formal relationship in the data model e.g.:
EntityA{
//... some attributes
b<-->B.a
}
EntityB{
//...some attributes
a<-->A.b
}
However, if the relationship is weak or transient, then you should use a fetched property to relate them. The fetched property dynamically searches for other entities based on a preprogrammed fetch.
EntityA{
creationDate:date
someBs--(creationDate=$FETCH_SOURCE.creationDate)-->B
}
EntityB{
creationDate:date
}
A key concept here is that Core Data is providing the entire model layer of your Model-View-Controller design. It is not just a dumb database but an active object graph that models both the data itself and its behavior. Once you have a properly designed data model, problems with the controllers and views resolve themselves automatically.
If i understand correctly, you can use notifications and send a dictionary of required information to the UITableView view controller class.

Best approach to control access/handle objects/models data passed to View in Zend Framework

I want to pass data to views, and I've two options in my mind (if you know a better approach, please mention).
I am using Zend_Based ORM system, and coded in a way that if I add a new field in database, its automatically available within the model.
1st: I convert the model's data into array and pass the array to the view. This way I will have all the data available within the view, but model's function/operations will not be available. And incase I need specific functionality, i will be coding view helpers while there are chances that the same functionality is already coded within model. e.g. a getting a date in specific format.
2nd: Or I pass the complete model object to the view, this way I will have all the model's functions available, but view will be able to access model's save function which is a bad thing. I can add some more functionality within model to make it read-only, but it will be extra work.
any suggestions which approach is better.
According to the MVC principle it's perfectly fine to let the View allow access to the Model. So, pass the complete Model to the View.
By the way, passing arrays around will copy your data (by value), while passing objects around will not (by reference). (Assuming PHP5). Large arrays might affect your performance.