iOS 5 | How-To Use Global Variables with the AppDelegate for iPhone and IPad Apps

How-to define a global variable in iOS 5 with ARC enabled. With the introduction of Automatic Reference Counting with iOS 5, which forces certain programming rules and restrictions, certain programming constructs and accepted practices are no longer possible. The use of the extern is one of the C based directives that is frowned on by the linker. Actually you will get linkage errors if you try to use with ARC enabled.

However, it is still very possible to use global variables with iOS 5, you just can use the #define directive to do so. This tutorial demonstrates one possible solution for using global variables. Of course you always opt out of ARC, but Automatic Reference Counting makes Objective-C much cleaner and forces you to write better code.

Follow these steps to create global variables

  • Create a new Single View project
  • Once the project is created, open the storyboard and add a second view controller
  • On the first view controller, add two UITextFields, an UIButton and a couple of UILabels for the UITextFields. Your scene should look like figure 1.
  • Before working on the second view controller, add IBOutlets for the two UITextFields.
  • Also select the first UITextField and uncheck the “enabled” attribute in the Attribute Inspector.
  • Select the Button and add an IBAction. If you are not familiar with the procedure to create IBActions and IBOutlets, read the following tutorial on creating IBActions, IBOutlets and Delegates
  • Next select the UIButton and create a segue to the second view controller. Again the previously mentioned tutorial on how to do this.
  • Next select the first view controller and embed a navigation view controller by selecting the Navigation Controller from the Editor menu -> Embed-> Navigator...
  • Once the navigator is created, add a delegate for the UIButton by control + dragging a connection from the button to the view controller proxy (yellow globe at the bottom).
  • For the second view controller, add two UITextFields and two labels. Create a second view controller class for the view controller. Once created, create IBOutlets for the two UITextFields. The UI for the second view controller should also look like figure 1. Since the UITextFields are editable, a keyboard will appear when you place the cursor in either of those fields. Follow this tutorial on dismissing the keyboard to move the keyboard to the background when you press the return button.
  • To create the global variable which we will use to pass data in both directions between the two view controllers, add a NSString variable named, gvar in the header file of the AppDelegate above the @interface directive as in listing 1.

Figure 01 - App Scene Layout
Figure 01 - App Scene Layout

Listing 1 - Declaring a Global Variable

#import <UIKit/UIKit.h>
NSString * gvar;
@interface klAppDelegate : UIResponder <UIApplicationDelegate>
  • Next open the implementation file and initialize the variable in the didFinishLaunchingWithOptions method as in listing 2.
  • Now open the view controller, klCViewController implementation file and in the viewDidLoad method, add the following as in listing 3 to assign the value from the gvar the first UITextField.

Listing 2 - Initializing the Global Variable

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    gvar = [[NSString alloc] initWithString:@"Hello "];
    // Override point for customization after application launch.
    return YES;
}

Listing 3 - Assigning gvar to UITextField

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.ShowGVARData.text = gvar;
}
  • In the IBAction method, addToGVAR, add the code as in listing 4 to add the value from the second UITextField before transitioning to the second view controller since we configure a push segue above

Listing 4- addToGVAR Method

- (IBAction)addToGVAR:(id)sender {
    gvar = [self GVarInput].text;
   
}
  • If you did everything as in the above instructions, the gvar variable which displayed the initial value when the scene was loaded, now contains the content of the second UITextField so that when we click on the button and transition to the next scene the gvar variable will get updated.
  • The two method of importance in the listing 5 code that we will need are the viewDidLoad and the viewWillDisappear. The first will display the value of the gvar when the view is loaded. Assuming that you a have added an #import for the klAppDelegate as you must do in the first view controller. The second will grab the any input from the UITextField from the second view controller before it is removed from the stack.

Listing 5 Adding Code for the viewDidLoad and viewWillUnload

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self GVAROutput].text = gvar;
}
-(void)viewWillDisappear:(BOOL)animated{
    gvar = [self GVAROutput].text;
}
  • The viewWillUnload will update the gvar when the view is unloaded when the user clicks on the back button.
  • The output is displayed in the three following screenshots, Figure 2, 3 & 4
  • The downfall is to not lose control over the gvar between scenes and to know which value is in the variable. But this solution does provide an effective counter solution to the #define macro.

Figure 02 - Initial Load and Initial Variable Assignment
Figure 02 - Initial Load and Initial Variable Assignment
Figure 03 - Add Value to Global Variable
Figure 03 - Add Value to Global Variable
Figure 04 - Pass Value to Second View Controller
Figure 04 - Pass Value to Second View Controller
Figure 05 - Enter Value in Second View Controller and Return to First View Controller
Figure 05 - Enter Value in Second View Controller and Return to First View Controller

More by this Author


Comments 10 comments

korutech profile image

korutech 4 years ago from Canberra, Australia

This article brings about an interesting concept that caused me to lose an entire weekend and several tuffs of hair.

Within a great many reference books and tutorials on iOS, far too many put data inside the view. IMO all data should belong to the app and views should merely present it. It's my impression this is actually how things should be/Apple's intent. It seems people have short circuited that intent to illustrate the basics of how various views work. It's a completely unscalable model.

On the other hand, if data was contained in the app no matter what you're doing, the app would always be scalable as you add new views, to manipulate/manage the data in different ways.

Something else that occurs to me from sorting out a KVO nightmare, is that the view model has changed in iOS5.

KVO examples I've seen add key observers in ViewDidLoad and remove them in ViewDidUnload. In table detail view applications, with a navigation controller, ViewDidUnload doesn't get called when the user navigates away from the view. ViewDidLoad is always called when the view comes into view however.

In listing 5 above, the code uses viewWillDisappear, but the remark below refers to viewWillUnload. This makes me think the way things work has changed and people are still adjusting to it?


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Thanks for your comments and thoughts. They are very refreshing. But I hope my tutorial wasn't the reason for your bad weekend or lost of hair.

You offer some very interesting points and you are stating a blaring point about application development: data should never be part of the views. There should be a clear separation between the Model and the View. iOS 5 has introduced many changes to the way we are supposed to write code and create apps, for instance ARC. I am sure that Apple, like many other software companies, has good reason to force us into a new direction, but it should never be to the point of breaking our code.

A case in point is IBM. they are so strong on backwards compatibility that some developers find it maddening but at the same time, you are always sure that your apps from previous code versions will be keep on working. Apple and others should keep this in mind when introducing changes when developers have invested several thousand hours developing apps and helping Apple make billions.

You are write about the viewWillDisappear. I was a little shocked during testing that the viewDidUnload never gets called, which then makes someone take pause because if you follow their architecture, the view controller adds a view to the stack (or places it on top of the stack) when called and it is removed (supposedly) when a new one is called. So this point about viewWillDisappear and views brings into focus a new reality and maybe this is because the view are managed in part by the storyboard: When a view is placed at the top of the hierarchy, or the stack, the other is not removed but only gets pushed to the back, thus, it merely disappears.


korutech profile image

korutech 4 years ago from Canberra, Australia

My bad weekend wasn't due to your article :) I rewrote the data model for my app moving data from the views to the app which made your article very relevant. Most of my KVO broke in the process. It was somewhat painful to fix, but now memory management and caching is twice as efficient, so worth the effort.

I think your point about backwards compatibility is an important one, though I've never believed it should be at the expense of progress. I used to develop MS apps using C++ and MFC. MS were terrible at breaking apps with new frameworks so I can relate to iOS developers grief.

I was under the impression you could opt not to use ARC. The project I'm working on ATM uses some JSON classes that don't support ARC, even though my project does. The mixture seems fine; just opting not to compile the JSON classes with ARC.

The change of view behaviour is alarming. That said, once you understand the new model it's quite good. My current app allows endless reclusion of views to deep dive into data. A very helpful function available within ViewWillDisappear, is determining which way your view is travelling. EG: if([self isMovingFromParentViewController]) == TRUE the view is popping off the stack. This in turn allows you to pop your active data member off your own stack.

I might start a hub about it to explain the model as I'm sure others would fine it very useful.

Just to touch on one other point worth noting about the new viewModel. When the app loses focus, viewWillAppear is how you can kick off new actions that need to happen when your app gets focus again. On the whole, it's worth considering moving what you would have had in ViewDidLoad to ViewWillAppear.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Good point about the event triggers. I will keep in mind. As for ARC, yes can opt out of it as needed. I didn't know you could selectively opt in and out on the same project, good to know.


korutech profile image

korutech 4 years ago from Canberra, Australia

I've written a hub illustrating how to add non-ARC code to an ARC project here: http://hubpages.com/technology/Adding-non-ARC-sour...

It was a little long to post in a comment :)


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Cool, I will check it out.


rheerholtz 4 years ago

Kevin,

Thanks for this Tut. It is helping me somewhat. One thing I confused about. Why is gvar value "Hello" again after returning from the 2nd VC, while gvar was set to a new value in 1st VC.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

You can change the value of gvar as needed, you just don't need to create a new instance.


supra1994 3 years ago

Hi,

I created a counter on a single VC. Do you think this method will work if I wanted to use this counter to work across 5 VC with segues?

Example: VC 1 has a UIAction button of plus 1 (no text fields) and when clicked adds it to a UILabel-outlet on VC5. I've been searching for a way to make this work by capturing all clicked buttons from 4VCs to last VC. Works fine on one VC.

Thanks Jeff


klanguedoc profile image

klanguedoc 3 years ago from Canada Author

Hi Jeff,

Sorry for the late reply. If you still need my two cents, I would say that yes this technique would work any number of VCs. If not (since I haven't tried it), maybe you could consider using a plist to maintain the values between VCs since this is another technique for data persistence. Here is a tutorial:

http://hubpages.com/technology/iOS-How-to-Use-Prop...

Hope this helps

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working