Can I program a table to look like a table - objective-c

Can I create a table (TableView) and have it display values for three Columns:- Col1,Col2,Col3 with N values under these three columns?
Col1 Col2 Col3
Value1 Value1 Value1
Value2 Value2 value2
Value3 value3 value3
.... ... ...
.... ... ...
.... ... ...
Valuen Valuen Valuen
I cannot now see how I can code a MutableDictionary and/or a MutableArray to do anything like this.
I am new to cocoa programing and objective-c. Any sample to the point code that I can look at?
I would be grateful.

Matt B.'s answer is technically correct, but I would say that for someone who is "new to cocoa programming and objective-c" that bindings might be too much magic to take in at first. (Heck, I've been doing Cocoa stuff for 2 years and I'm just starting to get the hang of them)
I'd say the first thing to understand is the delegate pattern. This pattern is very frequently used in the Cocoa frameworks, and to manually populate an NSTableView with objects, you'll need to understand it.
The basic idea is that the NSTableView knows how to draw, but not what to draw. So what we do is we give the NSTableView a "delegate" object, and the tableview asks the delegate how many rows it has, what goes in each row, etc.
The delegate object itself is an object that knows what should go in the tableview, but not how to draw it. It conforms to NSTableViewDataSource protocol (the equivalent of a Java "interface"). That way the NSTableView has a standard set of methods it can use to query the delegate and ask for the information it needs.

I cannot now see how I can code a MutableDictionary and/or a MutableArray to do anything like this.
A dictionary is completely useless to you here.
You need to make an object that models what you want to list in the table. Each row corresponds to one of these objects, which you'll most probably keep in an array. The columns correspond to properties of the model objects.
The most common illustration is a list of people (e.g., employees). Each row in the table view displays one Person object. Each column displays one property of that object: First name, last name, perhaps a company title, phone number, etc. Both Bindings and the table view data source protocol are designed to work best (that is, most easily) this way.
You may be tempted to pass on implementing model objects and just write a parallel array or something. As long as you're using a data source, you can do this, but don't fall into this trap—it prevents you from switching to Bindings later, it makes exposing the property to AppleScript (you can't make three arrays look like one property) impossible, and it makes developing the UI beyond a single table view much harder.
Cocoa is designed around Model-View-Controller; work with it, by providing a model, and you'll find everything in Cocoa much easier.
(And no, a dictionary will not suffice as a model object. It won't help you with AppleScript or Bindings, and it'll also fail you any time you want to make the model objects smarter than just a box of simple key-value properties. Derived properties, behavior, and custom initializers are all ugly hacks at best when implemented on dictionaries.)

The keyword you're after here is bindings. Cocoa Bindings can seem a bit like voodoo at first, but it's the de-facto way of exposing the contents of an array to a table view. And it's absolutely marvelous once you get the hang of it.
A google search for NSTableView bindings tutorial brings up a good number of pages. This tutorial from CocoaDevCenter is really quite good (as is most of their stuff - bindings is an advanced topic, some of their earlier guides may be useful, too).
Apple's docs are a bit denser but may be of use, too.

Related

Is using protocol and delegate to create a Control like UITableView the optimized one?

The UITableView can be used to create a list view if the at least the UITableViewDataSource is adopted by the relevant class. I have the below questions:
Why is it designed in such a way that based on the section and row , the controls are created through data source methods and given back to the UITableView instance. Why not provide all these information in UITableView instance with out using the UITableViewDataSource. What difference is it going to make?
EDIT1:
#hermann and #JOhn: You have mentioned that it breaks the MVC pattern. Let us assume I am creating a custom UITableView like control myself. I design it in such a way that I do not pass the data directly to the UITableView but instead I pass the relevant subviews that needs to be added in the rows and section and their relavant headers alone. I think this will not break the MVC..Am I correct? But still it has the problem that the current UITableView implementation style solves..the ability to reuse controls and images instead of bloating the memory usage.
First, doing so allows to stick on the MVC pattern. A UI object, meaning a view, should never directly communitcate with the model, wich is the business data. Plus it should not perform any business logic, which belongs to the controller.
Second, it is more flexible without the need of subclassing the UITableView object.
Third, the full concept is quite efficient from a performance and memory management point of view. Instead of loading all data upfront, that may be displied within a table, it can be fetched or calculated or whatever on a just in time "need to know now" basis.
Plus data containers, especially memory consuming once like images, can be released as soon as the data has been provided using the delegate/data source methods.
Of course, a subclass of UITableView could do the same in principle. I just doubt this would result in more maintainable code or even save any time or work resprectively.
If you don't want to stick with MVC, then feel free to subclassing the table view and hand all its data over in its init method or enable the table view subclass to load all that data from webservices or data bases or wherever it comes from.
And when you run into problems and get back to us searching for guidance, then be prepared for some nasty replies like "Why don't you stick to the established best practices or the MVC pattern?" ect.
In the event that your very table just displays some rather static values, such as if it just acts as menu for further navigation drill down etc. then this concept may look a bit rediculous. But it does not hurt either. And when it comes to more complex tasks of data providing then it certainly has its advantages.
Give it a chance. Give it a try!
For MVC you want to try to clearly separate what the model, controller, and views are responsible for doing. By allowing the view (tableview) to ask for the data from a delegate, the view can be create extremely generalized.
Using the delegate pattern, the controller can "stage" the data in anyway that is wants and then give it to tableView as the tableView needs it. The tableView doesn't care where the data comes, how it was transformed, what ADT is used, nothing. It is complete ignorant to where or what the data is. All it knows it should show this string at this location for this section and row.

DataSource pattern versus setting Properties while Configuring Objects

I often get confused with when to use DataSource Pattern and when to use the Properties for providing configuration information to objects.
I have two ways to do this,
Generally I keep a lot of properties in the Object's class that has to be configured and a method that resets the object and continues with the new properties.
And the for the Object which is configuring the other object, I keep a method that with the name configureXYZ:WithValues: , which resets the properties and calls the reset method of the object to be configured.
This I have seen with MPMoviePlayerController, that we have to set properties.
and Other way is how tableView works, all the configuration information comes from datasource methods.
Can anyone throw more light on which way is preferred in which scenario.
Because Its often I feel tempted to use design patterns and make the code look stylish but I wanted to know when do we actually need these.
I am absolutely clear with delegate pattern and have to use it on regular basis.
DataSource was one thing I was never clear with.
When designing a class, the key factor you should consider when deciding between using a delegate or properties is how often the values can change. Properties work best if you will set the values one time and they should never change again. Delegates (of which datasource is just an example) work best if the values might change over time or change due to conditions.
For example, in UITableView, the number of rows is highly dynamic. It could change for many reasons outside of the control of the table view. What the rows even represent is highly dynamic. They might be data; they might be menu options; they might be pieces in a game. UITableView doesn't try to guess or control any of that. It moves it to a delegate (datasource) where potentially very complex decisions could be made.
MPMoviePlayerController has a few controls that mean very specific things and should almost never change (particularly once the movie starts playing). Basically you set the thing up, hit play and walk away. In that case, a delegate would likely be overkill.
There are many cases that are in the middle, and either way may be ok. I would encourage developers to consider delegation first, and then if it doesn't make sense go with properties. This isn't because delegation is always the right answer, but more because most C++- or Java-educated developers don't think in terms of delegation, so should make a conscious effort to do so.
Some other thoughts along these lines:
When using properties, it is ideal if they are configured at initialization time and are thereafter immutable. This solves a great number of problems.
If you find yourself needing a lot of properties, delegation is probably better and often simpler.
Delegate notification methods (somethingDidHappen:) are often better implemented as blocks. (Blocks are relatively new in ObjC. Many delegate-based Apple interfaces are moving to blocks, but you'll see a real mix out there for historical reasons.)
The difference between "delegate" and "datasource" is that a delegate manages behavior, while a datasource provides data. They are typically implemented identically.
It mostly depends on the dynamics of the class. UITableView is a very dynamic interface element. Its data comes and go. You can add/remove/edit/sort. You can interact with it. IF you assign properties to a tableView, it loses some of the properties that makes it as robust as it is. MPMoviePlayerController, on the other hand, has a different purpose. I have never used this class but by the looks of it, it reads one video file and provides playback. There is not many changes to it, so properties makes a lot of sense.
If you are writing a class, and you need that class to be as flexible as possible(UIPickerView, UITableView), having delegates allows you to do so. If your class only works with limited configuration after initialization, you could be better by taking the property approach.

Do I need to use a delegate to maintain the MVC pattern when accessing NSUserDefaults?

Still on assignment 4 of cs193p. - http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/assignments/Assignment%204_2.pdf
I've fully (ish) implemented the displaying photos from a list of places.
I'm adding the second tab of the application (required tasks 10 & 11) , which is to generate and display a list of the 20 most recent photos viewed in chronological order.
My question relates to the MVC pattern and setting/accesing NSUserdefaults.
Basically, anytime a photo is viewed, a property list stored in NSUserdefaults needs to be updated.
When selecting the "recent photos" tab, those values need to be read and displayed, so that the user can select a recently viewed photo, and then view it by selecting it.
I think I can implement this quite easily from a writing lines of code and it will probably work point of view.
I've seen this question: CS193P UITabBarController MVC Help on Assignment 4 which is kind of related, but doesn't really address my more theoretical question about the nature of the pattern.
My question is more about the MVC pattern.
In the lecture, when he demonstrated this with favourite graphs, from the previous calculator assignment he used a delegate to communicate between the favourites list view controller and the graphviewController (see diagram on slide 64 of lecture 9). http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/lectures/Lecture%209_1.pdf
I'm trying to work out if I need to do something similar to avoid breaking the MVC pattern, or if I can just use NSUserdefaults in both the viewWillLoad of my imageViewController to add a photo to the favourites and and then in my setter in RecentImagesViewController. I know NSUserdefaults is designed for persistence, it just feels a bit like I"m using a global variable.
I realise this question is worded in a way which makes it difficult to follow if you aren't familiar with the cs193p course - sorry.
Thanks for any advice!!
I don't think you have to transform something rather simple in something complex. You are storing the favorites using the NSUserDefaults and that's it. The place where you are using might not be the best (I am not saying the viewWillLoad is a bad place, I don't know your code), but I don't think you need a delegate to just update the NSUserDefaults. Botton line, don't forget the KISS principle. :)
Well, it probably feels like you're using a global variable because the user defaults themselves are a global concept. And they should be. You don't want different parts of the app operating on unsynchronized versions of user preferences.
But, if you use the term variable in the sense of an old C/C++ global static piece of data, then, no ... that's not what it is. NSUserDefaults was written by Apple to be a nice tidy class that encapsulates the user default data. The fact that you use [NSUserDefaults standardUserDefaults] to access something like a singleton instance (not sure if that's how Apple chose to implement it) still doesn't mean it's a true global variable.
I agree with Jacky Boy that keeping it simple is best, but your question is really asking whether doing it the way you are is a violation of the MVC pattern (and adhering slavishly to a pattern is not always going to make your code the best). That depends on what you consider the model to be. I could justify saying that Apple built NSUserDefaults to be a model layer encapsulation of the preferences data. So, there you have your model layer, and your controllers should be able to use it.
Or do you feel the need to write the entire model layer yourself, in which case your model layer would just have a wrapper for NSUserDefaults. That would seem like overkill for most situations.
Here is maybe one situation that could warrant it. If you have a lot of preference data that seems logically related, but some of it is not appropriate for NSUserDefaults. Perhaps it's a lot of binary data, stored in a hierarchy of objects, and you want to persist it with Core Data. But, it still seems logically related to what you're keeping in NSUserDefaults. Maybe then, you decide to write your own model layer, that encapsulates both the Core Data and NSUserDefaults data. Your view controllers could then use that directly.
But, generally, I think iOS is well designed to have whoever needs to just use the standardUserDefaults object directly.
If I understand the question correctly, it sounds like the setting/loading should be occurring from the appropriate view controller. Creating a delegate (which may or may not be a singleton) that you can call from each of the different tab's view controllers will help prevent you from duplicating code.

Core Data - Managed object question

I have 2 basic questions regarding Core Data;
What exactly is a managed object -- Is it equivalent to 1 instance of a class. For example, if there is an entity called Shape which has attributes like no of sides & color and if there are 5 entries displayed in a table, does it mean there are 5 managed objects each with attributes no. of sides & color. I am a bit confused about this basic concept.
What exactly is the relationship between Fetched Results Controller (FRC) and a table view? I know the delegate methods, but how exactly is the table view impacted/related to FRC ?
Any basic examples will be really useful. Thank you.
Q1. A managed object is a representation of some entity that has been persisted by an application. It is simply a generic abstraction away from the actual persisted type. So you are right in saying that the managed object will have the same keys/properties as the concrete type. As the NSManagedbject class implements the key-value coding pattern you can query its key/values at runtime...
- (id)valueForKey:(NSString *)key
For full documentation on NSManagedObject see here
Q2. The fetched results controller is what your UIViewController is to your UIView. It contains the logic that controls persistence for your table view. Its sole purpose in life is to keep database handling logic out of your UITableView. It does so by allowing you to define the behaviour you want to execute in the context of your UITableView. What I mean by this is that its delegate provides methods with signatures that explicitly imply an effect on a UITableView.
Q1. Yes, there are 5 managed objects out there and available to you. You could put all five in an array if you wanted to. Managed Object is simply a term that means you have code to manage the Insert, Change, and Delete actions into the database - in otherwords, some code manages it through its life cycle. You get at it through an FRC, the FRC ^fetches^ instances of the object from the database, and allows your code to ^control^ what happens to the ^result^. Hence the name.

Objective-C: Blocks vs. Selectors vs. Protocols

I frequently find myself writing "utility" classes that can be re-used throughout my projects.
For example, suppose I have an "Address Book" view. I might want to use my address book to select who gets sent an email, or maybe who gets added to a meeting request.
I'd develop this view controller so it can be used by both the email controller, and the meetings controller, with some sort of callback mechanism to let the caller know the user either finished selecting someone from the address book, or they canceled.
It seems there are basically four (reasonable) approaches one might take in this scenario;
Create an "AddressBookDelegate" protocol and a corresponding delegate property on the AddressBookController. Then use the messages defined in the protocol to communicate the result (similar to UIActionSheetDelegate).
Create an "informal" "AddressBookDelegate" protocol and a corresponding delegate property on the AddressBookController, but the type of the delegate property will be "id", and will check at runtime with "respondsToSelector:" to see if the delegate implements the methods we require (seems like most of the framework stuff has started going this way).
Pass the AddressBookController an id that represents a delegate, as well as two SELs which specify the methods to call when the user selects a user or cancels the request. The benefit I see with this is; suppose one controller supports BOTH sending emails AND setting up meetings (I know in this example that seems like bad design... but one can imagine a more generic situation where this would seem perfectly reasonable for a utility class) - In this case you could pass the AddressBookController different SELs depending on whether you're adding users to an email, or adding users to a meeting... a huge improvement over an iVar to indicate the controller's "state".
Pass the AddressBookController two blocks; one to run when the user selects someone from the address book, and one to run if the user cancels the request.
The blocks have been so tremendously useful to me, and SO much more elegant, I'm finding myself almost confused over when to NOT use them.
I'm hoping more experienced members of the StackOverflow community than I can help out with their thoughts on this topic.
The 'traditional' way to do this is with a protocol. Informal ones were used before #protocol was added to the language, but that was before my time and for at least the last few years informal protocols have been discouraged, especially given the #optional specifier. As for a 'delegate' which passes two SELs, this just seems more ugly than declaring a formal protocol, and generally doesn't seem right to me. Blocks are very new (esp. on iOS), as these things go, and while we have yet to see the tremendous volume of documentation/blogs on the best tried and true style, I like the idea, and this seems to be one of the things blocks are best for: neat new control flow structures.
Basically what I'm trying to say is that each of these methods vary in age, with none being better than the last except for style, which obviously counts for an awful lot, and is ultimately why each of these things was created. Basically, go with the newest thing you feel comfortable with, which should be either blocks or a formal protocol, and that your confusion is most likely coming from reading conflicting sources because they were written at different times, but with time in perspective, it is clear to see which supersedes the others.
[Controller askForSelection:^(id selection){
//blah blah blah
} canceled:^{
//blah blah blah
}];
is probably a hell of a lot more concise than defining two extra methods, and a protocol for them (formally or otherwise) or passing the SELs and storing them in ivars, etc.
I would just go with your first approach. It's a tried and true pattern in Cocoa, and seems to fit very well into what you're doing.
A few comments on the other approaches:
Informal protocol - I don't really see any advantage of doing this over a formal protocol. Every since formal protocols gained #optional methods, the utility of informal protocols is much less.
Passing SELs - I don't think this is an established pattern in Cocoa. I personally wouldn't consider it as better than the delegate approach, but if it fits your thinking better, then go for it. You're not really getting rid of state; you're just transforming into something else. Personally, I'd prefer to have an ivar that I can set and check without having to use selector types.
Passing blocks - This is sort of a new-age approach, and it has some merit. I think you need to be careful though because, in my opinion, it doesn't scale really well. For example, if NSTableView's delegate and data source methods were all blocks, I would personally find that somewhat annoying. Imagine if you wanted to set 10 different blocks, your -awakeFromNib (or whatever) method would be pretty big. Individual methods seem more appropriate in this case. However, if you're sure that you're never going to go beyond, say, two methods, then the block approach seems more reasonable.