AdamM
AdamM

Reputation: 4440

iPhone refresh a view from another class

I want to be able to refresh a view from another class, but nothing I have tried is working. My application is a tabbed application with several tabs set up. I have a method called refresh in my ViewController1 class that looks like this

-(void)TestMe{


     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"widgjson" ofType:@"json"];  
     NSData *myData = [NSData dataWithContentsOfFile:filePath];  

     NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *docDir = [paths objectAtIndex: 0];
     NSString *docFile = [docDir stringByAppendingPathComponent: @"json.txt"];
     [responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding error:Nil];

     [self loadView];
     [self viewDidLoad];
}

This works fine. When the application first loads up, it loads a different json, then when I click this button it loads a new JSON and then updates the view. This is just temporary to test out refreshing. However if I try to call this method from another class, or from the AppDelegates ApplicationDidEnterForeground methods, nothing happens. I tried calling it like this

 -(void)TestMe{


    ViewController1 *vc = [[ViewController1 alloc] init];


    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"widgjson" ofType:@"json"];  
    NSData *myData = [NSData dataWithContentsOfFile:filePath];  

    NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex: 0];
    NSString *docFile = [docDir stringByAppendingPathComponent: @"json.txt"];
    [responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding error:Nil];

    [vc loadView];
    [vc viewDidLoad];

}

So why does this method not work from any other classes. All I want to is to be able to refresh a view from another class or when the application loads up, but just can't seem to find anything that works.

Would be very grateful if someone could point me in right direction!

EDIT: UPDATING TO CLARIFY

Okay, what I have done for the time being which I don't like is put this

exit(0);

Inside AppDelegates ApplicationDidEnterBackground. This works to an extent, but is not an ideal solution.

What I would like to have happen is that when application is opened again, the AppDelegate gets run again which sets up the tabs. The JSON pulled from the server can affect the order of the tabs which is why I need the AppDelegates ApplicationDidFinishLaunching method to reload itself again.

Also I would like to know can I do this from another class in the application. The first time my application is loaded it asks for the users phone number, which is sent to the server which then generates an PIN. After this is done, then I want the AppDelegate method to load up and begin setting up the tabs and the order etc.

Upvotes: 1

Views: 2514

Answers (2)

jrturton
jrturton

Reputation: 119242

To prevent your application running in the background (and so to force reloading when you exit and re-enter) you can set the UIApplicationExitsOnSuspend key to YES in your info.plist.

However, this is probably a bit drastic.

Your current code for refreshing from the application delegate is a non-starter because you are creating a new instance of the view controller rather than talking to one that is on the screen.

For this reason it is best not to involve your application delegate at all in the process.

Instead, your view controller can register itself as an observer for the UIApplicationDidBecomeActive notification, and do whatever it needs to itself. You would typically register for this notification on viewDidLoad, and unregister on viewDidUnload (since, by definition, if you have unloaded the view, you don't need to refresh it when the app comes back up!).

You would register as follows (using blocks here as they are the future):

Declare an ivar of type id to hold the observer object, let's call it becomeActiveObserver in this case. So, wherever you are declaring your ivars, add id becomeActiveObserver. Then, in viewDidLoad:

becomeActiveObserver = [[NSNotificationCenter defaultCenter] 
addObserverForName:UIApplicationDidBecomeActive 
object:nil 
queue: nil 
usingBlock:^(NSNotification *note){ 
    //put your reloading code in here
    [self TestMe];
}];

And remove like so in viewDidUnload:

[[NSNotificationCenter defaultCenter] removeObserver:becomeActiveObserver;

You can follow a similar pattern to pick up notifications (your own, or system ones) from anywhere else in your app. This is a better design than passing everything through the app delegate as it involves much looser coupling.

Upvotes: 3

Abhishek Singh
Abhishek Singh

Reputation: 6166

I guess clickMe is an action to a button.if you want to refresh the viewcontroller at startup then add a function in viewcontroller similar to clickme or any function that refreshes the view and call it from applicationWillEnterForeground method or you may try this :-

- (void)applicationWillEnterForeground:(UIApplication *)application 
{     
NSLog(@"app will enter foreground");     
[viewController clickMe:NULL]; 
} 

and you may change the file in the applicationWillEnterForeground method of appDelegate if your application requires.

Upvotes: 2

Related Questions