Prepareforsegue vs Storing in Dictionary. Using Swift, Xcode 6. Best practice? - ios7

I'd like to know why use prepareforsegue if you can just store the data in a Dictionary?
It seems easier if you just initialize the dictionary in the first view controller and add/edit/remove from it in the subsequent view controllers.
I'd like to know if this is a bad practice or will either work just fine?
I'm currently using a dictionary to pass data forward and backwards to view controllers.
Thanks in advance for your response.

Related

iOS: Create copy of UINavigationController

It is possible, to create an exact object copy of a UINavigationController? I have seen examples of copying objects using copyWithZone:, but I am confused as to how I would use this to copy my UINavigationController.
Any help?
UINavigationController doesn't conform to the NSCopying protocol, so you can't use copyWithZone: or copy on it.
If you are looking to have a customised UINavigationController that you can use throughout the app then you should subclass it and then create a new instance of that subclass every time you need a new one, such as when you create a new modal view controller.
EDIT: If you want to keep the view controllers from a previous navigation controller then you can do something like this (use subclassed navigation controller if needed):
UINavigationController *newNavigationController = [[UINavigationController alloc] init];
[newNavigationController setViewControllers:oldNavigationController.viewControllers animated:NO];
This will do a shallow copy of the viewControllers, i.e. you will have references to the original navigation controller's view controllers, not copies. If you want to do a deep copy on the view controllers then that will be far more complicated and will require specific copying code for each view controller. (See here for more info).
You can do this by creating a category (or a subclass), make the category NSCoding compliant, and add the necessary encoding and decoding functions. You then need to determine what properties you want to encode - the types of view controllers it currently has in its array, and perhaps you'll need to make those objects be NSCoding compliant. You can see that this is not going to be a trivial thing to do, but its not impossible. You may find the solution to your problem is best done using some other techniques.
EDIT: If you want to "duplicate" it, what you really need to know is what viewControllers are in the array. So suppose you want to replicate "state", which in some sense is the same as the original answer but less rigorous. Add a category or method to each object and ask to to give you current state as a dictionary. For the navigationController, that might be just the classes of the objects currently on the stack.
For each of these objects on the stack, you get them to give you a dictionary of their state. By state, its means what text is in UITextFields, views etc, anything that that object would need to go from a startup condition and get back to where it is now.
You package this all up - the nav dictionary and array of the state ones. You can save this as a plist. When you want to construct where you were later, the nav controller can tell what objects to create by knowing their class, then as each one is created it can be sent its dictionary and told "get back to where you were". Once done, then push another controller on the stack.

Objective-C: Creating a file purely for holding variables

I would like to add a file to my project, who's sole purpose would be to hold an array. I would then #import this file wherever I need to add/get from the array.
My problem is that when I create a new file (I'm using Xcode 4), I'm not sure what type of template to choose, and then what subclass to choose.
My reason for doing all of this is because I have a SplitView-Based app, and one of the views has a textfield, where I am trying to output data. My problem is that whenever I switch to a different view and then switch back, only the most recent entry is there. I am not 100% why that is but I suspect it is because when I switch to a different view, the current view is forgotten about, along with the variables in it.
This is not a good way to do it. There are many ways to do what you want: prepareForSegue: if you are using storyboards, delegation, instantiating your viewcontroller in code and setting a property in the header-file..those are just a few ways.
The way you are proposing is a slippery slope to bad Objective-C code and is only going to cause you more headaches in the future. Take the time to learn to do it right.
Check out this to get you thinking in the right direction.
How you save your data doesn't appear to be your problem. Take a look at the MVC design pattern and how view controllers implement it. They often rely on a dataSource protocol, which links the data from a "Model" to your "View" in a logical way to achieve your intended purpose.
The view controller should then be able to assign a delegate (usually itself (self) to keep the view populated with the correct data, whether the view gets unloaded or not.
If your view controller doesn't refer to a data source or a corresponding protocol, it would still be worth your time to see how you might take advantage of that design pattern. It will pay off in the long run to know this.
Instead of saving variables to a text file, you should consider using NSUserdefaults instead.
But I don't think that's the real solution to your problem, just wanted you know that there are other ways than saving stuff to a text file.

iOS: Uniquely identify ViewControllers from Storyboard

I have a custom ViewController that is meant to be reusable, and an arbitrary number of instances will be chained together in a NavigationController in Storyboard, all sharing the same model as a delegate.
The ViewControllers need to tell the model which instance they are. Currently, they have an int property that they get from the segue, but it doesn't seem very idiomatic and doesn't lend itself to having multiple instances onscreen (for iPad). I figure there's got to be a cleaner way to do this, so does anyone know what it is? Thanks.
RESULT: self.view.tag
A UIViewController's UIView has a tag property which you can set from anywhere you want. You could also simply identify the type of the controller by using [self class]. Or simply use the memory location by referencing the controller directly.
Update You could simply implement a unique identifier for a UIViewController using a category.
I guess the "cleanest" way in terms of design architecture would perhaps be an array of ViewControllers. (It could be managed in the app delegate.) However, there are memory considerations - on the iPhone you would likely want to create and the destroy the view controllers as needed. The array could contain the identifier and perhaps some other model-related information in order to recreated the controllers as needed.
Too bad there is no property storyboardIdentifier of UIViewController. They can be instantiated with this id but it would be helpful if the viewcontroller can query its id.
I recently ran into this. I figured out you can add a "Restoration ID" in the storyboard. Then you can access it perhaps like this (depending on your use case)
navigationController?.viewControllers.first?.restorationIdentifier

same class in different views

I have an App with 3 views, and 2 classes that each take care of parsing messages and connecting to a server.
The thing is, i would need to use the parser in all three views (and the connection too)
But i think that including and initializing an instance of both in all views may not be correct performance wise, am i right?
It it's not correct, how should i do it?
I am thinking about creating an instance of them in appDelegate, but i don't know how
to do it to use the methods of the instances.
Thanks in advance
Passing back to the AppDelegate is possible, but not really OOP is it? Pretty soon you'll be using it to pass data back and forward between view controllers in larger application.
The better way to do it, and similar to the way you pass the managed object context around in Core Data programs is to create a property in the view controllers to hold the parser. Create this parser in one place and after you create the new view controllers, set the property to point to your parser. That way you are just passing around one instance, and in in a more controlled manner.
It will be better in this case to create it in the appDelegate. The appDelegate can be reached anywhere in the code as follows:
MyAppDelegate *delegate=(MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate parse:data];

Adding data to a scrollview/table

I have an NSCrollView that contains an NSTableView. It has 3 columns and 4 rows. I have 4 NSStrings with content that I need to copy into the scrollview.
Using Xcode 4 I tried connecting the table or the NSTextFieldCell and then adding the text via
[_Cell1 setStringValue:MyString];
But nothing happens. It doesn't get updated.
Any way to do this?
Thank you.
EDIT:
I found the following answer to a similar question. I still am confused but after reading Apple's example about bindings I can only say that this does not make any sense, so much code to achieve something so simple. That's the problem with everything being an object and with OOP in general.
Any simple samples out there? I don't even know how to start setting this or connecting the gazillion things you need to connect to start working with this
You should use the NSTableViewDelegate. That's a set of methods the NSTableView calls to get the data that it should display. You just have to declare the delegate object of the tableview.
Delegate Protocol
NSTableView Tutorial
Unfortunately, you can't "add" or "set" the content of a table view. Like most view objects, a table view doesn't store content; it depends on a controller to provide content when it needs it.
There are two options:
Data source: simplest, easiest to understand
Binding to an array controller: harder to understand, but less work to implement
The best Apple resource on the subject: Populating Cell-Based Table Views from the Table View Programming Guide. If you're struggling, I suggest you start with the data source option. It'll be just a few lines of code, and you can adapt the simple samples from that document.
To populate the table, you need to implement these two methods:
– numberOfRowsInTableView:
– tableView:objectValueForTableColumn:row:
And to change the data, you'll need to implement one more:
- tableView:setObjectValue:forTableColumn:row:
You'll need to set your controller as the data source for the table view in interface builder. And the correct protocol for this is NSTableViewDataSource, not NSTableViewDelegate.
You could use an NSArrayController and bind the table columns' value bindings to the array controller's arranged objects. Then add the values you want to display to the array controller.