Global variables and objects in Objective C. What is the best way? - iphone

I want to use global variables and objects for the iphone project.
I have created NSobject class and defined like below:
.h File:
#import <Foundation/Foundation.h>
#interface GlobelClass : NSObject
extern NSString *mystr;
extern NSMutableArray *Arrdata;
#end
.m File:
#import "GlobelClass.h"
#implementation GlobelClass
NSString *mystr;
NSMutableArray *Arrdata;
#end
What is the best way Or should I use singleton pattern like below link answer:
Using global variables in Objective-C
Please share thoughts?

One of the way to use global variable in the application is:
You can use App Delegate class itself :
.h file:
AppDelegate: UIResponder <UIApplicationDelegate> {
}
#property(nonatomic,strong) NSString* strUserID;
.m file:
#synthesize strUserID;
Now you can access strUserID as global variable in your UIViewController as:
ABCProjectAppDelegate *appDelegate = (ABCProjectAppDelegate*) [[UIApplication sharedApplication] delegate];
You can set value:
appDelegate.strUserID = #"Test";
Get Value:
NSString *strId = appDelegate.strUserID;
:)

Related

Passing multiple strings from one class to another class

I am new to iPhone. I have small doubt. I have three strings in class BiblePlayerViewController and I want to pass those 3 strings to appdelegate from this class. How to do that?
create a property NSDictionary in BiblePlayerViewController and add your three strings to the dictionary,so you can read that dictionary where ever you want
NSDictionary *FileDict = [[NSDictionary alloc] initWithObjectsAndKeys:str1,#"key1",str2,#"key2",str3,#"key3",nil];
Create a static reference of Appdelegate and declare NSStrings as class variables in Appdelegate
Put this is appdelegate
+(Appdelegate*)getAppdelegate{
return self
}
and then in your viewcontroller
do appdelegate.string1 = string1 and so on ..
you can also encapsulate these objects in an Array and pass them to appdelegate .
The idea is to get a static reference of Appdelegate.
Create a variable of type NSString in appdelegate.h
NSString *test;
import appdelegate.h in BiblePlayerViewController.m
Now get a reference to appdelegate class using
Appdelegate *ad; //init with some object
//now access the NSString var u just created
ad.test=#"your string";
I think you can use the shared object of the appdelegate class for the similar cases.
in the appdelegate class declare global object as
#define UIAppDelegate ((MyAppDelegateClass *)[UIApplication sharedApplication].delegate)
By declaring this, from any class that imports your AppDelegate class can use this shared object of AppDelegate class.
Then is you have three property declared in AppDelegate as
#interface MyAppDelegateClass : NSObject <UIApplicationDelegate>
{
NSString *string1;
NSString *string2;
NSString *string3;
}
#property (nonatomic,retain) NSString string1;
#property (nonatomic,retain) NSString string2;
#property (nonatomic,retain) NSString string3;
#end
Then in the AppDelegate Implementation
#implementation MyAppDelegateClass
#synthesize string1;
#synthesize string2;
#synthesize string3;
#end
In the class from where you need to send the strings to AppDelegate use like below
You need to import AppDelegate class first
#import "MyAppDelegateClass.h"
#interface MyCustomSenderClass : UIViewController
#end
And in the implementation
#implementation MyCustomSenderClass
- (void) sendStringsToAppDelegate
{
UIAppDelegate.string1 = myString1;
UIAppDelegate.string2 = myString2;
UIAppDelegate.string3 = myString3;
}
#end
Thus you can directly set a value to the AppDelegate from any class imports your AppDelegate class.
I think this helps you.

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;

Accessing member variable of AppDelegate

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.

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.

need to define a "modifiable" global variable in objective-c

I have the following issue. I have two classes that manipulate information but they are completely disconnected, i.e. I can't reach the other class.
I need both classes to use a certain value. For example, class A sets the value foo = A and class B needs to be able to read that value and rest foo to nil.
I thought about creating the variable in the main app delegate, but can't figure out how.
Ideas?!!
Global variables are generally bad idea. Based on your description i think you can use KVO to inform class B about the changes in 'foo'.
But if you relly need a global variable you can do this:
#interface YourAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic) NSString *foo;
#end
#implementation YourAppDelegate
#synthesize foo;
...
#end
#implementation ClassA
...
- (void)someMethod {
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.foo = #"NewValueOfFoo";
}
...
#end
#implementation ClassB
...
- (void)otherMethod {
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"Value of foo: %#", appDelegate.foo); //This will print: "Value of foo: NewValueOfFoo"
}
...
#end
I'm not sure what you mean by "completely disconnected". Depending on what you're trying to do, you could use NSUserDefaults
http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
or NSNotifications
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNotification_Class/Reference/Reference.html
If class A doesn't need to know about class B, you could consider delegation as well.
Why can't he just do this?
A. Add 2 new files to your project: GlobalValues.h and GloblaValues.m.
B. Open GlobalValues.h, and declare all your needed variables.
extern NSString *MyServiceName; // name of the 'service':
C. Open GlobalValues.m, and start the new file by importing GlobalValues.h, and assign values to the variables you declared in the header file:
#import "GlobalValues.h"
NSString *MyServiceName = #"MyService is called THIS";
D. In the implementation files of the classes that need to use these variables, you would put - at the very beginning:
#import "GlobalValues.h"