Accessing member variable of AppDelegate - iphone

I'm trying to wrap my head around singletons and I understand that the App Delegate is essentially a singleton object. I'm trying have some member variables in App Delegate that I can access from any other class. I did this in the App Delegate:
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
int screenwidth;
}
#property (nonatomic, retain) UIWindow *window;
#property (nonatomic) int screenwidth;
Then in the .m I did this:
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
...
screenwidth=400; //arbitrary test number
Now I have another class in the project, and it does this in the .h:
#import "AppDelegate.h"
In the .m I have this somewhere:
test=(AppDelegate*)[[[UIApplication sharedApplication] delegate] screenwidth];
However, it claims that "screenwidth" is an instance method that is not found. I also tried this:
test=(AppDelegate*)[[UIApplication sharedApplication] delegate].screenwidth;
This uses the dot syntax since screenwidth was synthesized, but it claims that property screenwidth not found
I'm sure these are basic issues that can be corrected simply. Any help appreciated.

Consider trying:
test=[(AppDelegate*)[[UIApplication sharedApplication] delegate] screenwidth];
I think your two tries are trying to cast the .screenwidth result to an AppDelegate*.

Make sure that you're either providing your own -screenwidth accessor or using the #synthesize directive to get the compiler to provide one:
#synthesize screenwidth
The #property directive is just a promise that accessors for the screenwidth property will be provided. You still have to provide them as described above.

If you want to avoid casting to your AppDelegate class every time, I recommend the following:
In MyAppDelegate.h:
#interface MyAppDelegate : NSObject <UIApplicationDelegate>
+ (MyAppDelegate *)sharedAppDelegate;
#property (nonatomic) int screenwidth;
/* ... */
#end
In MyAppDelegate.m:
#implementation LcAppDelegate
+ (MyAppDelegate *)sharedAppDelegate
{
return (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
}
/* ... */
#end
Of course, you still need to #import "MyAppDelegate.h" in the files where you want to access it:
#import "MyAppDelegate.h"
/* ... */
NSLog(#"the apps screen width: %d", [MyAppDelegate sharedAppDelegate].screenwidth);
BTW, note that you should not use int's and the like in Objective-C code. Instead, use NSInteger, NSUInteger, CGFloat and so on.

Related

It's possible create a custom delegate in AppDelegate?

i want know if it's possible create a custom delegate in the AppDelegate class, like in this way for instance:
#protocol AppDelegateDelegate <NSObject>
- (void)finishSync:(BOOL)success;
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
#property (nonatomic, weak) id <AppDelegateDelegate> delegate;
#end
it's possible create something like this? to notify the classes that are registered for this delegate?
EDIT
How i can use the Delegate? for example if i do this:
#import "AppDelegate.h"
#interface MasterViewController : UIViewController <AppDelegateDelegate>
#end
.m
#implementation MasterViewController
...
- (void)viewDidLoad {
AppDelegate *appController = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appController.customDelegate = self;
}
in i stay only in that view works, but for example if i switch in SecondViewController that have the same code to implement the delegate, the delegate don't works anymore neither in the MasterViewController...what i wrong?
Yes, That is fine. You can create delegates anywhere you want and use it anywhere by importing that class. There are no restrictions.

How to use appdelegate variable in view

i declared a variable NSString productname in appdelegate and assigned value appdelegate.productname = name from a view.Then i tried to get this value from another view.lbl.text=appdelegate.productname. Is this is wrong?
you can declare variables in appdelegate.h file, these variables are global you dont need to make appdelegate object to calling them.
like this -
#import <UIKit/UIKit.h>
#class ViewController;
// these are your variable, both are global.
int anyNumber;
NSString *productname;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#property (strong, nonatomic) UINavigationController *naviCon;
#end
Now you can use these variables at any where you want to use.
just import the appdelegate.h and use it freely.
#import "ViewController.h"
#import "AppDelegate.h"
this is your first view from where you are assigning the value to appdelegate string.
productname = name; //you can assign it directly, no need to make any object of appdelegate.
now you can use it any where. but remember little thing you have to import
#import "AppDelegate.h"
in your viewcontroller.
Thank you!
UIApplicationDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString * str = appDelegate.yourstr;
You can get it with this code:
UIApplicationDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *productName = appDelegate.productname;

change value of var in AppDelegate

In my AppDelegate, I have
#import <UIKit/UIKit.h>
#import "CustomerProfile.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) int x;
#end
At class B, I do
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.x = 5;
Then at Class C, I do
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.x = 4;
Eventually, at class D I print out the result of x and x = 5. Should x be 4.
It is confusing me. Please advice me on this issue.
Thanks
In your App delegate method your property x is set to strong (aka retain), you have to set to assign, a int var can't be retained because its not a object:
#property (assign, nonatomic, readwrite) int x; //then #synthesize in the implementation
Second, you have to import the header of your appDelegate (in your B,C,D Classes)
#import "yourAppDelegate.h"
set your appDelegate instance:
yourAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate]; // or [NSApplication sharedApplication] if your app it is for OS X
then set your x var to the desired value
appDelegate.x = 5 (or whatever)
I tested this in one of my projects and works.

How to pass a string from one view to another in tab based app

I have created a tab based application having 4 tabs and 4 views respective to these tabs.
I have a string in first view and when I printing this string in second view it printing null.
In first view.h
NSString *dateString;
#property(nonatomic,retain) NSString *dateString;
In first view.m
#synthesize dateString;
dateString=button6.titleLabel.text;
NSLog(#"dateString:%#",dateString);
In second view.h
NSString *dateString;
#property(nonatomic,retain) NSString *dateString;
In second view.m
#synthesize dateString;
- (void)viewDidLoad { [super viewDidLoad];
NSLog(#"dateString:%#",self.dateString);
}
Add your view controllers as properties for the application delegate (if the app is a relatively simple design).
Then you can reference the properties of the second view controller from the first view controller, by way of the app delegate. (One such property could be the string you want the second VC to copy or retain.)
Create NSString variable in Application delegate class and set the Property and make synthesize that variable.
And set the #"" (blank) value in applicationDidFinishLaunching method.
For Example - my variable name is str, then initialize str in applicationDidFinishLaunching like self.str = [NSString stringWithFormat:#""];
And now you can use it in any tab *view* and set the value as per your require.
More code
AppDelegate.h
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NSString *baseURL;
}
#property (nonatomic, retain) NSString *baseURL;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window;
#synthesize baseURL;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.baseURL = [NSString stringWithFormat:#""];
}
- (void)dealloc
{
[baseURL release];
[window release];
[super dealloc];
}
#end
ViewController1.h
#class AppDelegate;
#interface ViewController1 : UIViewController <UITextFieldDelegate>
{
AppDelegate *appDelegate;
}
#end
ViewController1.m
#import "AppDelegate.h"
#import "ViewController1.h"
#implementation ViewController1
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"value - %#",appDelegate.baseURL); // Here you can set or get the value.
}
it may not be the best answer.but creating a string variable in the appdelgate and passing the variable to this from the first view and fetching it from the second view works for me
Really, did we lose focus of MVC and the most awesome of abilities that is easy to do in iPhone Development?
How about a delegate?
#protocol ViewOneDelegate
- (void)getStringVariable;
#end
#interface ViewOneModel : NSObject
{
NSString* _stringVariable;
id<ViewOneDelegate> _theDelegate;
}
#property (nonatomic, retain) id<ViewOneDelegate> theDelegate;
#end
Assign a controller to be the delegate for the ViewOneModel.
Here is a simple solution, but not the best one, Create a global variable, and just use that.
Header
extern NSString *GlobalString;
#interface GlobalVariables : NSObject {
}
#end
implementation
#import "GlobalVariables.h"
#implementation GlobalVariables
NSString *GlobalString;
#end
And now to have access to the variable just import the header in the file you want to use.
You'll probably want to check if it's initiated before you use it.

Cannot find protocol declaration for 'MyObjectViewDelegate' when it is CLEARLY there ?1

I have a class like this..
#import "MyObjectAddView.h"
#import "MyAppDelegate.h"
#define myAppDelegate (MyAppDelegate *) [[UIApplication sharedApplication] delegate]
#class MyObjectAddView;
#interface AccountViewController : UIViewController <UIScrollViewDelegate, MyObjectAddViewDelegate, UIImagePickerControllerDelegate> {
MyObjectAddView *myAddView;
.....
}
#property (nonatomic, retain) IBOutlet MyObjectAddView *myAddView;
- (id) initWithSettings:(SettingsObject *)settings;
#end
WHY is it suddenly telling me that it Cannot find protocol declaration for 'MyObjectAddViewDelegate' when I'm clearly importing and including the #class for where the protocol is defined? Here how MyObjectAddView setup:
#import <UIKit/UIKit.h>
#import "MyAppDelegate.h"
#define myAppDelegate (MyAppDelegate *) [[UIApplication sharedApplication] delegate]
#protocol MyObjectAddViewDelegate;
#interface MyObjectAddView : UIView <UITextFieldDelegate> {
#private
id <MyObjectAddViewDelegate> delegate;
....
#public
.....
}
#property(nonatomic, assign) id <MyObjectAddViewDelegate> delegate;
.....
#end
#protocol MyObjectAddViewDelegate <NSObject>
// expense == nil on cancel
- (void)myObjectAddViewDidFinish:(MyObjectAddView *)addView;
#end
Everything seems perfectly setup and I don't see any circular imports ?! Any suggestions why it might not be seeing the protocol definition in MyObjectAddView?
Thanks.
You do not need a forward reference to a class after you have imported the header for that class. Only time you do a forward reference is if you plan on including the header inside of the implementation file. Remove #class MyObjectAddView and if that fixes it let me know if not I may have another solution for you.
Synthesizing the discussion: another solution is to check for cyclical imports between the delegate implementation and protocol declaration. This solved my issue.