bundle setting in Iphone:::inform or reload data from other class

Discussion in 'iOS Programming' started by tranvutuan, Jan 26, 2012.

  1. tranvutuan macrumors member

    Joined:
    Dec 19, 2011
    #1
    I went over the article about the bundle setting at here. They have 2 class m. One is AppDelegate.m and the other is MyViewController.m ( this is a UITableViewController).
    If a user makes a change to Settings, the change will be notified by
    Code:
    [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(defaultsChanged:)
                                               name:NSUserDefaultsDidChangeNotification
                                             object:nil];
    then an update to UI will be handle by
    Code:
    - (void)defaultsChanged:(NSNotification *)notif
    {
            NSLog(@"CHANGE CHANGE CHANGE");
        [self setupByPreferences];
        UITableView *tableView = ((UITableViewController *)self.navigationController.visibleViewController).tableView; 
        [tableView reloadData];
    }
    In this example, they are updating the UI by using
    Code:
    UITableView *tableView = ((UITableViewController *)self.navigationController.visibleViewController).tableView; 
    [tableView reloadData];
    What if we do have another class which is not UITablewViewController, how can we make a call to update what have been changed in Settings.
    Please advice me on this issue, all hints are welcomed.
     
  2. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #2
    I had trouble understanding your question which I'm interpreting as such; How do you observe changes to UserDefaults from another object.

    The type of object observing isn't important. So add the same line that adds the observer like in your first code block. You'd likely do that at the end of your init method. When the selector is called in that object, you'll have to use the default of interest for your purpose.

    Remember to remove the observing object in your dealloc method or other appropriate time.
     
  3. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #3
    Sorry to make you confused...in updateSettings method, the article does
    Code:
    UITableView *tableView = ((UITableViewController *)self.navigationController.visibleViewController).tableView; 
    [tableView reloadData];
    to update the UI right away. What I meant is after exiting the app by pressing Home button, when the app is launched again. You can see the change.
    If I dont have these above codes in updateSettings... you can not see the change until hitting Run from Xcode.....
    Another thing is adding an observer at my block init method, it is not being called if I press home button and relaunch the app again...
     
  4. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    What do you think is happening, programmatically, when you press the home button and relaunch the app?

    Have you read the App States and Multitasking section of the iOS App Programming Guide?
     
  5. tranvutuan, Jan 30, 2012
    Last edited: Jan 30, 2012

    tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #5
    After pressing the home button and relaunch the app, the method
    Code:
    applicationDidBecomeActive:
    applicationWillEnterForeground:
    
    I tried to reload data of other classes by doing :
    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        NSLog(@"APPLICATION WILL ENTER BACKGROUND");
        [myOtherClass vewDidLoad];
    }
    
    myOtherClass came from :
    AppDelegate.h
    Code:
    @property (nonatomic, strong) IBOutlet MyOtherController         *myOtherController;
    
    AppDelegate.m
    Code:
    - (void)applicationDidFinishLaunching:(UIApplication *)application
    {
        
       myOtherClass    =  [MyOtherClass alloc] init];
    }
     
  6. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    First, that NSLog looks pretty inaccurate for what it's supposed to be reporting. Second, does myOtherClass have a vewDidLoad method? You sure you didn't spell that incorrectly and you meant viewDidLoad? Third, if you meant viewDidLoad, you don't call that directly. That's the viewController's responsibility.

    Is myOtherController different than myOtherClass?
     
  7. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #7
    Sorry to lost you. the log should be
    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        /*
         Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
         */
        
        NSLog(@"APPLICATION WILL ENTER FOREGROUND");
    
       }
    
    Moreover, myOtherClass is myOtherController (once again. this is my typo). what we should have is
    Code:
    
    myOtherClass came from :
    AppDelegate.h
    
    @property (nonatomic, strong) IBOutlet MyOtherController         *myOtherController;
    
    AppDelegate.m
    
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application
    {
        
       myOtherController    =  [myOtherController alloc] init];
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        NSLog(@"APPLICATION WILL ENTER BACKGROUND");
        [myOtherClass refreshing];
    }
    
    
    In myOtherClass.m
    Code:
    -(void) refreshing {
     [self viewDidLoad]
    }
    
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
  9. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #9
    The viewDidLoad will watch if the app has just finished launching so that it can manage the change and apply to the UI
    Code:
    -(void) viewDidLoad {
    NSLog(@"VIEW DID LOAD IN MY VIEW CONTROLLER");
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings:) name:UIApplicationDidFinishLaunchingNotification object:nil];                           
    }
    After changing the default settings,I press home button and relaunch the app again. My goal is app will change the UI right away. However, it wasn't successful.
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    And what debugging have you done to determine why it's not working? For example, are you sure viewDidLoad is being called? Or are you sure updateSettings: is being called?
     
  11. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #11
    viewDidLoad is called but unfortunately, updateSettings is not called at all..Still working on at why it is not called though
     
  12. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #12
    And what leads you to believe that the UIApplicationDidFinishLaunchingNotification is being triggered when your app enters the foreground (or as you call it, relaunches)?
     
  13. tranvutuan, Jan 30, 2012
    Last edited: Jan 30, 2012

    tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #13
    Yeah I also thought about it because we do have other options such that
    Code:
        UIApplicationWillEnterForegroundNotification
        UIApplicationWillResignActiveNotification
        UIApplicationDidBecomeActiveNotification
        UIApplicationDidEnterBackgroundNotification
    I did try with UIApplicationWillEnterForegroundNotification...but still does not work then....
    Do you have any ideas about it.
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #14
    How are you certain of this?

    So, I just threw together a quick test project and was able to get my updateSettings: to be called. Here is the relevant code:

    ViewController.m
    Code:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// Do any additional setup after loading the view, typically from a nib.
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings:) name:UIApplicationWillEnterForegroundNotification object:nil];
    }
    
    - (void)updateSettings:(NSNotification *)notification
    {
        NSLog(@"Entering %s...", __FUNCTION__);
        self.view.backgroundColor = [UIColor redColor];
    }
    
    
    I launch the app. View background is grey. I press the home button and then return to the app (so it enters the foreground again). NSLog message is printed and view background is red.
     
  15. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #15
    How your AppDeletegate looks like... What does method addObserver belongs to. What I have is
    In my AppDelegate.m
    Code:
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        /*
         Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
         */
    
        
        NSLog(@"APPLICATION WILL ENTER FOREGROUND");
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                      selector:@selector(defaultsChanged:)
                                                          name:NSUserDefaultsDidChangeNotification
                                                        object:nil]; 
    }
    
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #16
    I didn't make any changes to my AppDelegate because I thought we were trying to solve the problem of having your updateSettings: method called when the app became active. Upon further review of this thread, I realize that's not the case. You're trying to have updateSettings: called when NSUserDefaultsDidChangeNotification is triggered. In that case, you already have your defaultsChanged: method getting called, correct? So, now it's just a matter of having that method call MyOtherController's updateSettings: method, right? Well, you already have a reference to your MyOtherController instance in your AppDelegate. Now you just need to make sure that updateSettings: is made public so that other classes can call it.
     
  17. tranvutuan thread starter macrumors member

    Joined:
    Dec 19, 2011
    #17
    sorry I am back... I was so busy recently. Anyway thanks for your help....
     

Share This Page