mandy b
mandy b

Reputation: 61

Make variable available to entire application using AppDelegate

I am extraordinarily confused by the concept of using the app delegate to make a variable be able to be set and used anywhere in my application. Here's my code:

appdelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    NSMutableString *globalUsername;
}
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, retain) NSMutableString *globalUsername;

appdelegate.m

@synthesize globalUsername;

and another view scene (called "Forum.h" where I am trying to set the value)

AppDelegate *appDelegate = (MyAppDelegate *)[[[UIApplication sharedApplication] delegate]];
[appDelegate globalUsername appendString;

the last line is incomplete of course, but xcode automatically pickets up globalUsername variable, I just cannot call the "appendString" function to actually change it.

Upvotes: 4

Views: 15245

Answers (6)

Zhang
Zhang

Reputation: 11607

Erm, if you're trying to store a username, why not just use NSUserDefaults ?

// set the username
[[NSUserDefaults standardUserDefaults] setValue:@"johnsmith" forKey:@"username"];
[[NSUserDefaults standardUserDefaults] synchronize];

// retrieve the user name
NSString *username = [[NSUserDefaults standardUserDefaults] valueForKey:@"username"];

Upvotes: 11

TheEnigma2112
TheEnigma2112

Reputation: 173

I think you've got the relationship between the delegate and its view controllers mixed up. The AppDelegate gets created when you launch the app. Rather than create the AppDelegate in Forum.h, you create the ViewController, Forum, in the AppDelegate. Also the *globalUserName in the curly braces is unnecessary.

So AppDelegate.h would read:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, retain) NSMutableString *globalUsername;
@property (nonatomic, retain) Forum *forum;

Also, in the current version of Xcode and Objective-C, synthesize is also unnecessary. It gets set up and initialized automatically. In AppDelegate.m, you can refer to *globalUsername using:

self.globalUsername

Your AppDelegate.m should also include the following in applicationDidLaunch:

[[self.forum alloc] init];  //Allocate and initialize the forum ViewController
self.forum.delegate = self; //Set the forum ViewController's delegate variable to be the AppDelegate itself

But the Forum ViewController currently doesn't have a variable named delegate, so we'll have to create that. So in Forum.h you should add:

@property (nonatomic) id delegate;

So now in Forum.m, since AppDelegate.m took care of setting the delegate, we can now refer to the data in AppDelegate using Forum's delegate variable.

So finally, in order to access globalUsername from Forum.m, we can use self.delegate.globalUsername. So to append to the string from Forum.m, we can use:

[self.delegate.globalUsername appendString:myNewString];

Where "myNewString" is the string you want to add to globalUsername.

Hope this helps.

Upvotes: 2

Cocoanetics
Cocoanetics

Reputation: 8247

You are missing one set of [], those are actually two statements in one. first the method globalUsername is called on appDelegate and the result of that is then send the message appendString (which is missing parameters)

So this should look like this instead:

[[appDelegate globalUsername] appendString:@"foobar"];

But for a game you should not abuse the app delegate like this. Rather I recommend that if you want a global place to store game state you should look into having a Singleton, like I described here: http://www.cocoanetics.com/2009/05/the-death-of-global-variables/

PS: you probably don't want to work with a mutable string there because of several reasons. Better to have the property/ivar a normal NSString and then just set it. I don't see any good reason why you would want to append characters to a user's name. Even though NSStrings are immutable you can simply replace them with other ones.

[[appDelegate setGlobalUsername:@"foobar"];

or with same effect:

appDelegate.globalUsername = @"foobar";

Upvotes: 6

iKambad
iKambad

Reputation: 371

I think you forgot to alloc it. Just alloc it once in application did finish launching method.

Upvotes: 0

Anoop Vaidya
Anoop Vaidya

Reputation: 46543

@interface AppDelegate : UIResponder <UIApplicationDelegate> { NSMutableString *globalUsername; }

This doesnot create a global variable. Infact it is a protected member for AppDelegate Class.

From all the classes you cant access it. You need to create yet another instance of AppDelegate and then you will wise that ivar.

The term global refers that you will be having same value througout the application in all the classes. And you not need to alloc+init everytime.

For Global Variable you need to create a static variable. A shared class / Singleton class will work for you.

Upvotes: 0

Manann Sseth
Manann Sseth

Reputation: 2745

If it is NSMutableString, Then you have alloc - init in 'Delegate' class.

Because if it is Mutable Object, then you have to alloc & init.

First, In Delegate.m class

globalUserName = [[NSMutableString alloc] init];

Then,

In ViewController, you can use,

appDelegate.globalUsername appendString ....(What you want)

Thanks.

Upvotes: 4

Related Questions