A quick question i hope.
I'm new to xcode and IOS apps, and have made a bunch of tutorials but i still don't get one thing. If i make a new file (StaticData.h, StaticData.m) and in the .h I declare a public property NSMutableArray. And in the .m file i fill it statically.
#implementation StaticData
-(NSMutableArray *)staticArray
{
NSString *value0 = #"test)";
return [NSMutableArray arrayWithObjects:value0, nil];
}
#end
Now i import the .h file in a viewcontroller and try to load the data in the table. the array is empty. So i set a breakpoint but it is never hit.
So how do i init a file without a view?
You need to use your file by creating an instance of your class StaticData like this:
StaticData *data = [[StaticData alloc] init];
Don't forget to delete data when you are ready!
Related
Now I am developing an iOS application which works like this:
User scans QR code,
App searches for a specific key - > value,
it gives out a value to the user.
Currently I have two ViewControllers - the main and "value" ViewController, which is inherited from main. The problem is that if I create NSDictionary in main VC it is not visible in "value" VC. Main VC gives only the string (QR code, the key) through the segue. So, the value VC has to search for key and display the value.
What I ask is some kind of global variable or one DataSource visible across the whole app. Of course, I can implement NSDictionary initialisation inside value ViewDidLoad method and it will work, but this is not the point. New modules are to be added there and the variable has to be global. I googled a lot and got the idea that singleton pattern can be helpful here. I tried to implement it, but no idea how to do. Do I need it, or it is too complex for this kind of DataSource?
Thank you!
The basic idea is, you will still need to #include the header file of the place where this dictionary will be. The solution that Naveen proposes means that you will be including the header for the app delegate wherever you want to access it. Whether to use the app delegate for this purpose or not is kinda grayish. Some people often do this, some say its a bad use of it.
The singleton approach means that you will create a class, that will always contain the same information since the init method will return object that was previously created.
For the singleton aproach, imagine I have a database manager class. So in the header of this class (the DatabaseManagerSingleton.h) ill have this:
#interface DatabaseManager : NSObject
+ (DatabaseManager*)sharedInstance;
// Your dictionary
#property (nonatomic,strong) NSMutableDictionary* someDictionary;
The implementation will look like this: (check how "sharedInstance" initializes the object)
#implementation DatabaseManager
#pragma mark - Singleton Methods
+ (DatabaseManager*)sharedInstance {
static DatabaseManager *_sharedInstance;
if(!_sharedInstance) {
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[super allocWithZone:nil] init];
});
}
return _sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)init
{
self = [super init];
if (self != nil)
{
// Custom initialization
_someDictionary = [[NSMutableDictionary alloc] init];
}
return self;
}
Now, a VERY important thing is that, any place you want to use this object should first include the header:
EDIT: To use it in your code:
1) add the header
#import "DatabaseManager.h"
2) initialize the object
DatabaseManager *databaseManager = [DatabaseManager sharedInstance];
3) do whatever you need
// Initialize the dictionary
databaseManager.someDictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"OBJECT",#"someKey", nil]; // In this case the object is just a NSString.
// Access
[databaseManager.someDictionary objectForKey:#"someKey"];
Put as a property on Appdelegate
#property (nonatomic,strong) NSDictionary * sharedData;
Access anywhere like
NSDictionary *sharedData= ((APPDelegate *) [UIApplication sharedApplication].delegate).sharedData;
Ive been reading a lot of links on how to pass variables from SO on how to do this including this link.
Accessing variables of another class in xcode
however, i have already imported the FirstViewController.h file in my SecondViewController.m file in my FirstViewController.h file I have a variable defined as
.h
#property (nonatomic,retain) int test;
.m
#synthesized test;
and in view did load SecondViewController.h i try to do
FirstViewContoller.test=10;
but the variable is not recognized.
Would like if anyone could help please
You can't set properties on classes. You can only set properties of objects, i. e. instances of a class. You have to write
FirstViewController *vc = [[FirstViewController alloc] init];
vc.test = 10;
// use then vc for whatever it should be used.
Oh, and by the way: this is not in any way related to Xcode.
I'm trying to create a structure, which should be used as an array.
Then at the same time I need to access it from a different view, so I'm guessing I need to make it global for now, until I learn a better way (have tried many suggestions from google searches)
But how do I declare a variable twice?
I mean both as my structure, and as an array?
Sometimes "global variables" can be appropriate, but not simply as "global variables". The proper way to do it in Objective C is with singletons.
Here is part of the .h implementation below:
#interface MySingleton : NSObject
#property (nonatomic, strong) NSMutableArray *myArray;
+ (MySingleton *)sharedSingleton
#end
And here is what the .m implementation would look like:
#implementation MySingletion
#synthesize myArray;
static MySingleton *shared = nil;
- (id)init
{
self = [super init];
if(self)
{
myArray = [[NSMutableArray alloc] init];
}
return self;
}
+ (MySingleton *)sharedSingleton
{
if(shared == nil)
{
shared = [[MySingleton alloc] init];
}
return shared;
}
Then, whenever you wanted to access this from a given class, you would #import "MySingleton.h" and access your array like so:
[MySingleton sharedSingleton].myArray
Edit: However, this does not mean that every time you need to pass data it should be done with a singleton. Singletons are correct in certain situations, but as others have mentioned, you should pass the data to the next class yourself in most situations.
Well i just created a new h and m fil, where i put a lot of varibales
using extend in the.h file
and alloc init in the .m file
Then i just include this file where i need the variables. Probably there is a much better way, but this was the only one i could figure out.
I have a class which contains a method to download data from my server. This is in the form of JSON, but is parsed and put into an array. As this is a 'model' file, what would be the best way to make it so that multiple 'controllers' can access this data?
Hang it off the app delegate, stick it in a global variable, or declare a class method in appropriate spot that returns it.
Better yet, start thinking now about having a proper model layer that, among other things, can manage this data. That will make refactoring easier in the future as your application evolves.
You can create singleton object of class with array object. and by using class method you can get that array any where in app.
e.g.
in Cardnames.h file
#import <Foundation/Foundation.h>
#interface CardNames : NSObject
#property (nonatomic, retain) NSMutableArray *CardNamesArray;
+(CardNames*) getCardsList;
#end
in Cardnames.m file
#import "CardNames.h"
#implementation CardNames
#synthesize CardNamesArray;
static CardNames *cards = nil;
+(CardNames*) getCardsList
{
#synchronized(self)
{
if(cards == nil)
{
cards = [[self alloc] init];
cards.CardNamesArray = [[NSMutableArray alloc] init];
/// code to fill array
}
return cards;
}
}
#end
and in other classes u can use like this
#import "CardNames.h"
.
.
.
NSMutableArray *CardsArray = [[CardNames getCardsList] CardNamesArray];
I am creating ios app in xcode 4.2.
I have outside file with database. I dont wanna download data in every view. How should i create one global variable for tabbar application? And when should i upload this database before closing of application?
In iOS applications the model data is often kept in a singleton, rather than in a global variable. Here is an article briefly describing singletons in Objective-C.
You can load your data in the class method that initializes your shared singleton. Uploading the data back is a bit trickier, because the singleton itself does not know when to do it. Therefore you should make an instance method -(void)uploadData in your singleton class, and call that method when your application is about to close. applicationWillResignActive: method of your application delegate is a good place to initiate the upload.
I use singletones like this: in class DataBase with some arrays of data i implement share method:
+(id)share
{
static id share = nil;
if (share == nil) {
share = [[self alloc] init];
}
return share;
}
and then in some classes: self.dataBase = [DataBase share];
You can create global variables by doing this
extern NSString *someString;
#interface ......
#property (strong, nonatomic) NSString *someString;
#end
#implementation ......
#systhesize someString;
NSString *someString;
#end