0

I have a home screen.

On button press. I either fetch information from the server and store it in an object or I create some default information using a class called "Defaults.h/m" - where I store all my variables. And "Function.h/m" where I manipulate my default values and call methods.

How can I pass this data globally to any of the future view controllers I create. So that I can access and use the information.

Here is my signin/notsignin code:

You can see that I call [Function fetchInformation]. This method checks if the user has internet connection, then proceeds to set values in the defaults class.

 - (IBAction)signIn:(UIButton *)sender {
 
     NSString * username = self.usernameTextField.text;
     NSString * password = self.passwordTextField.text;
 
     if([Function isInternetConnectionAvailable]){
        if([Function login:username :password]){
            [Function fetchInformation];
        }
        else{
            UIAlertView * error = [Function showErrorAlert:@"Login" :@"Username or Password is incorrect" : @"OK"];
            [error show];
        }
     }
     else{
         UIAlertView * error = [Function showErrorAlert:@"Connection" :@"Please connect to the internet" : @"OK"];
         [error show];
     }
}

- (IBAction)notSignedIn:(UIButton *)sender {
    [Function fetchInformation];
    
}

Here is my fetchInformation method:

+(void)fetchInformation
{
    //instantiate user defaults
    NSString * information = @"";
    
    if([Function isInternetConnectionAvailable]){
        //set learnfest data from the server using a url request and json response
        information = [self getAppInformation];
        [self updateStoredLearnfestInformation:information];
    }
    else{
        //set default information
        information = [self getLocalLearnfestInformation];
        [self updateStoredLearnfestInformation:information];
    }
    
    //[self debugOut:@"Information" :information];
    [self decodeAppInformation:information];
}

Here is my updateStoredLearnfestInformation method:

+(void)updateStoredLearnfestInformation:(NSString *)information
{
    //set default learnfest information
    [self updateSavedDataWithString:@"DEFAULT" :@"DEFAULT_INFORMATION" :information];
}

And my updateSavedDataWithString method:

+(void)updateSavedDataWithString:(NSString *)file :(NSString *)key :(NSString * )value
{
    [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

Update: I've added 3 methods that I use to store my default information about my app. Please review and consider what I have already done.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
cwiggo
  • 2,541
  • 9
  • 44
  • 87
  • I doubt the part of the code you've attached can be compiled. when you declare method as +(void) it means it is a static method, you can not use self pointer inside such method. – heximal May 08 '15 at 11:22
  • At first you should move this code to CodeReview.stackexchange.com I guess! Anyway I will update my answer! – Randika Vishman May 08 '15 at 11:46

2 Answers2

1

One of the options is to use a singleton object. You can import the module where your singleton is declared into all required controllers and access its properties and methods.

heximal
  • 10,327
  • 5
  • 46
  • 69
  • Thats why I have come here to ask this question. I'm trying simply NSLog a value in "Defaults" but i'm receiving a null value. – cwiggo May 08 '15 at 10:21
  • do you instantiate this object properly? there must be a static pointer to singleton which is requested like [UIApplication sharedApplication] - this is bright example of singleton pattern. sharedApplication is static method that is simultaneously a lazy initializer and getter for singleton pointer. – heximal May 08 '15 at 10:24
  • I can publish a short template for singleton here if you want – heximal May 08 '15 at 10:25
  • The problem is, I instantiate the Defaults class in every class.. so how can I pass this data through the view controllers? Using singleton? What other options are there? – cwiggo May 08 '15 at 10:33
  • if Defaults objects contain the same data I don't see any reason to instantiate them inside every class. A singleton object will be accessible for any other object in application, you don't have to 'pass it' anywhere, it stays always in the same place. any object can write and read it's properties. – heximal May 08 '15 at 11:03
1

I think you want something like this, which fetch and stores the some data, where you need to access throughout the entire app, which are defaults.

There are mainly 4 common ways which you can store data inside an iOS Application.

  1. user defaults
  2. property lists
  3. SQLite
  4. Core Data

And out of all the best fit for your requirement as I think I've understood is using User Defaults! There are plenty of good tutorials out there! Regarding these cases. Read this if you want a thorough guidance!

And in according to your question, I could give you a dummy implementation to your fetchInformation method.

-(void)fetchInformation {
// I hope you would put whatever implementation that you need to
// Fetch and decode the information where ever you want here.
// However after that specific implementation, to store the data to be
// accessible throughout the application following is the way I suggest...

   NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

   [userDefaults setBool:YES forKey:@"signedIn"];
   [userDefaults setObject:self.usernameTextField.text forKey:@"username"];
   [userDefaults setObject:self.passwordTextField.text forKey:@"password"];

   [userDefaults synchronize];   // Don't forget this line too
}

And in anywhere else in your application where you want to retrieve these data you can get those as follows.

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:@"signedIn"]) {
   NSString *username = [userDefaults objectForKey:@"username"];
   NSString *password = [userDefaults objectForKey:@"password"];
}

Hope this will help you to get your app completed successfully! Don't forget to follow that tutorial link if you are lacking some knowledge about "data persistence". And also it will give you the required simple guidance on how to store data into Plists(property lists) too.

Regarding to Chris question Code and Methods:

Make the following two methods merged:

+(void)updateStoredLearnfestInformation:(NSString *)information
+(void)updateSavedDataWithString:(NSString *)file :(NSString *)key :(NSString * )value

As follows:

+(void)updateStoredLearnfestInformation:(NSString *)information {
    [[NSUserDefaults standardUserDefaults] setValue:information forKey:@"DEFAULT_INFORMATION"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

Because of calling a method inside another method unless the method calling method does something important and specific. I meant +(void)updateStoredLearnfestInformation:(NSString *)information the only thing this do is calling another method. So you can directly put that second methods content in the above method itself.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Randika Vishman
  • 7,983
  • 3
  • 57
  • 80
  • hi! i'm very keen to use NSUserDefaults, but it's implementing across a complex (well i think) app. I'll have a go at implementing this technique as i've seen it before in a range of tutorials – cwiggo May 08 '15 at 10:49
  • :-) Okay, but for these kind of things going with NSUserDefaults is the first and best shot of mine. Because it's very hassle free way. And if you want you can create a new Class.h/m and keep it dedicated to NSUserDefaults and that way it becomes more easy. And using NSUserDefault like mechanism is not only in iOS, but also in Android and Java too.! If you want about Java here it is too: http://stackoverflow.com/a/11405851/1752988 Choice is up to you! :-) – Randika Vishman May 08 '15 at 10:55
  • please see my update question.. could you elaborate on what I've done and what I could do to make the variables accessible throughout my entire app? – cwiggo May 08 '15 at 11:02
  • 1
    @Chris I updated my answer too, and finally as you have decided to use the NSUserDefaults I guess I deserve an upvote at least! ;-) Cheers! – Randika Vishman May 08 '15 at 11:53
  • 1
    Great to see that you have responded. I'm in the process of updating my code to use NSUserdefaults :) – cwiggo May 08 '15 at 13:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77331/discussion-between-randika-and-chris). – Randika Vishman May 08 '15 at 15:27