x2on
x2on

Reputation: 2297

AppDelegate: Get value from ViewController?

I would like to get at

- (void)applicationWillTerminate:(UIApplication *)application

a variable from a view controller class. I have build an tabbar application and only added the tabbar controller to the appdelegate.

[window addSubview:tabBarController.view];

How can i get an variable from the TestViewController:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface TestViewController : UIViewController {
    IBOutlet UILabel *testLabel;
    NSString *currentString; //Value that i want to save at applicationWillTerminate
}

@property (nonatomic, retain) UILabel* testLabel;
@property (nonatomic, retain) NSString* currentString;

@end

Upvotes: 1

Views: 4969

Answers (3)

Eld
Eld

Reputation: 984

Not 100% sure what you are asking for but here is a guess:
UITabBarController's have a property called viewControllers which return all view controllers associated with the tabbar.

Assuming that the TestViewController was the first tab you could get to it by:

- (void)applicationWillTerminate:(UIApplication *)application {
    TestViewController* test_view_controller = [tabBarController.viewControllers objectAtIndex:0] ;
    NSString* value = test_view_controller.currentString ;
}

Note this would break if you decided to later move the TestViewController to a different position in the tabbar.

-- Edit -- Check all controllers and get the string from the controller that is of type TestViewController.

NSString* value = nil ;
for ( id unknownController in tabBarController.viewControllers ) {
  if ( [unknownController isKindOfClass:[TestViewController class]] ) {
     value = ((TestViewController*)unknownController).currentString ; 
  }
}
// value should be the value of the string.

Upvotes: 0

TechZen
TechZen

Reputation: 64428

Expanding on dbarker's answer, it sounds like what you really need is to save the currentString value in your data model. The proper place to do that is in the viewController itself.

If your data model is just that one string, you can create a property in the app delegate to hold it. Then the viewController writes to the app delegate property whenever the value of currentString changes in a view and/or its value when the view closes.

This way, the data (which is the entire point of the app anyway) is always in place when the app closes regardless of how many views you open.

It is the proper role of controllers to move information from the interface to the data model. Strictly speaking, the viewController shouldn't store any data at all beyond that needed by the interface itself. That should be a property of the data model which the viewControllers set by sending a message to the data model object with the values taken from the interface.

In this case, you would not have a currentString property in your view controllers. Instead they would have a property that is just a reference to the data model's currentString property. The view controllers would continuously update that property but would store nothing themselves.

The advantage of this design is obvious. If you need the value anywhere in your app, you have one location and one call to get it. No single part of the app needs to even know of the existence of any other part of the app save for the data model.

Upvotes: 1

dstnbrkr
dstnbrkr

Reputation: 4335

It's somewhat incidental that TestViewController hasn't been dealloc'd by the time you reach applicationWillTerminate - it might make sense to store that value a level higher in your application. That approach would be to always store currentString in the UIApplicationDelegate so that you don't have to fetch it later:

@implementation TestViewController
- (void)setCurrentString:(NSString *)currentString {
    ((MyAppDelegate *)[[UIApplication sharedApplication] delegate]).currentString = currentString;
} 
@end

Upvotes: 2

Related Questions