How to pass data between different UIViewControllers? - ios

What is the best way to pass data from one view controller to another?
Suppose I push another view controller onto the present view controller. If I have to give some data to the view being pushed from the present view controller how do I do it?
Also how do I pass data from the pushed view to the earlier view?
So far I have done this by declaring functions in each controller and calling them. I find it dirty and want a cleaner way to do this. I don't want to use plists or sqlite as the data isn't that significant.

Keeping the data in AppDelegate is not a good idea if the amount of data is quite large since the data will live throughout the application lifecycle.
Why not call the setter(s) of the newly created UIViewController object to pass the data so that you can release it if the view goes offscreen or gets deallocated.

Why can,t you try making the variable in AppDelegate.Give that data to the variable of the AppDelegate and fetch it wherever you want in your application or UIViewControllers you will get that data.That value will be assigned to the the variable of the app delegate upto the termination of the application.
Try taking help from already asked several times Pass Data Between Several Viewcontrollers in a App.
Hope you get my point .....Good luck!

Related

UIViewController - where to put init of instance variables (using Storyboards)

I'm using Storyboards. I need to init instance variables of UIViewController just once. viewDidLoad and awakeFromNib fire each time I open a viewController from menu (I'm using SWRevealViewController for sidebar menu as in Facebook app). Is it normal for awakeFromNib to fire many times or is it SWRevealViewController bug?
So is there some special init method or do I need to set instance variables from outside of viewController (in AppDelegate?)
EDIT:
I found this question
SWRevealViewControllerSegue, reusing Viewcontrollers
I didn't realize that each time you show a controller via segue it creates a new instance of controller. So what does it mean? Does it mean that if I have a table of data loaded from web API - it will be reloaded each time I go back and forth through segue?.. Doesn't seem very effective to me. Is it normal for iOS?
View controllers are either recreated or reused depending on the situation. When you push a view controller onto a navigation controller's stack, you almost always push a new instance. When using a tab bar controller, the view controllers it contains are often held in memory. To avoid excessive memory consumption, it makes sense that view controllers are cleaned up when possible, rather than held around.
In the case of your SWRevealViewController then yes, it sounds as though your view controller should be recreated every time. You ideally shouldn't be directly loading any data from a web API within your view controller; instead, extract your API calls and models into separate classes that you can reuse from any view controller. Then, rather than reloading the data over the network when your view controller loads, you just need to fetch the latest data from your model / store class.

passing data to a childViewController from the view controller that holds the container view controller

In my application I created a container view(called ContainerViewController) on the top of an another view(called GameViewController,where I keep the game logic and api callbacks).I also have other views and an api class.My container view contains 3 views and I am trying to pass some objects to one of my container view(VC1). Since GameViewController is only connected to ContainerViewController(meaning there is no segue directly, so I can't use prepareforsegue and I can't use presentViewController, since they childViewControllers), I can't pass data.
I also tried just getting the values from my deserializer class(inside vc1). The problem with that was the VC1 gets called before.
my question is, how can I set values of VC1 from my callback inside the GameViewController?
This is what my storyboard looks like:
Thank you.
You can do it many ways:
1st way : You can pass the data using Notification.
2nd way : You can create a separate singleton data model class to store your game data. Then you can access the object of that class among your view controllers to set the properties in view controllers.

Passing references to viewControllers to other viewControllers cocoa touch

The way I am designing my code, with several view controllers, that interact, I have the need to pass data between the view controllers. The way that I am doing it is to "pass a reference", make a pointer, to the target view controller in as a method argument like below:
-(void)aMethodToSetUpInterfaceElements:(UIViewController*)targetCV
Is there anything wrong with this, or do I need to watch out? It works well on a functional level, but what about the design?
There's nothing really wrong about this.
If it works for you, than it's ok. Just make sure to have a weak reference to the view controller, otherwise you could have a memory leak with retain cycle. Read this for more information: http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html
Speaking about design, it's really depends of each case. I could't say preciselly because you didn't give more informations about the funcionality that you are trying to achieve.
Maybe if you want to make your code more generic, to be used in other places or projects, you might consider to perform a delegate to your view controller, but this depends of your views hierarchy and its design. To see more information about passing data between viewControllers, please see this: Passing Data between View Controllers
I don't think it is a good idea to pass a view controller in order to transfer its data if you don't have enough reasons. I tend to exposing the minimal knowledge to another object.
For example, say you have two view controllers controllerA and controllerB.
If all you need is just to pass some data from controllerA to controllerB, you pass the data, which might be a NSData, a NSArray, a NSDictionary or your custom data structure. You should not pass the whole controllerA as an parameter to controllerB. Although you can access the data by using the controllerA.data getter, you have exposed too much knowledge about controllerA to controllerB, which may unconsciously ruin your design by increasing the coupling between controllerA and controllerB.
If you are aiming at handling the view transitions, that may be a good reason to pass a view controller as the parameter. So that you can make good use of its -presentViewController:animated:completion: to present a modal view, or push it into a navigation controller, or you probably want to get a reference to its view property and customize your own UI presentation.

Setting up UIViewController before pushing/presenting it

In my app, I use a UINavigationController to switch between many different UIViewControllers. The only problem is that with one of my views, upon it loading, I have to do lots of customization (both data access and graphics, both of which must be done in code). When the view controller is pushed, the animation is extremely choppy, because the phone is forced to both animate the transition and set up the view at the same time.
Setting up the view after it is loaded is not an option, so is it possible to set it up (there is a method called setupViewDidLoad that has all of the necessary code in it) during allocation before it is pushed/presented?
Edit:
Let me modify my question slightly. I have found that if I present the view controller using [self presentModalViewController:animated:] instead of pushing it with the navigation controller, there is no choppiness. What is the reason for this?
Your best bet is to do this. Set up any code you need in viewWillAppear in your views .m file. If you have to access data remotely you may want to think about creating a data storage class of its own to handle and store that so it can do it whenever - even if the view isn't loaded or hasn't been loaded yet.

Should my app use just one managed object context?

Is it appropriate for my app to have several managed object contexts? I was going this route, (passing along my MOC from one instance of a UIViewController subclass to the next,) but I'm starting to run into EXC_BAD_ACCESS errors and I'm wondering if it could be related.
So, when do I want to use multiple ManagedObjectContexts, and (when) should I only use one?
Edit:
In my UISplitViewController based app, when deleting a row on my Master view, only after presenting a second view inside the main detail view, my detail view controller crashes on respondsToSelector, which I don't call ever.
Edit 2:
Basically, I have a master view and a detail view. In the detail view, the user presses a button. The button brings up a "new transaction" view. Instead of presenting the view modally, I manually add it to the detail view. If the user makes a change to the managed object context in this new view and then tries to delete the row in the master view, it causes a crash. If I present the same view modally, everything works just fine.
Furthermore, NSZombieEnabled says that a respondsToSelector method is being called on the (parent) detail view. I don't call that anywhere in my app. Could this be a memory issue? A threading issue? I don't explicitly create any new threads, but I don't know if there are any threads being created behind the scenes.
What might be the problem?
EDIT3:
This problem seems to get better. In my detail view, I also have a table, which, like the master view, uses an NSFetchedResults controller. When I delete the cell, I also hide the detail view, which causes it to be released. Releasing the detail view causes the app to crash. If I don't delete the detail view, the transactions in the detail view's table are deleted. (This is because I have Core Data set to cascade when an account is deleted.)
So, perhaps I have too many NSFetchResultsController objects? I believe that what is happening is follows:
When I delete a row, the NSFetchResultsController value changes and so it tries to fire the delegate method. However, the detail view has been removed and it's view controller deallocated. So, the delegate system fires a controllerDidChange method and crashes when trying to deliver the notification to the detail view.
How can I fix this?
Generally speaking you should use just one, unless you need to access data from multiple threads, in which case you'll need one per thread.
You certainly shouldn't need to create one per UIViewController.
You might also want to re-think whether you should pass the whole managed object context to a UIViewController anyway - how about just passing it the model objects it needs to do it's job?

Resources