Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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.
 

xStep

macrumors 68020
Jan 28, 2003
2,031
143
Less lost in L.A.
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.
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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.
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...
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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?

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];
}
 
Last edited:

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
I tried to reload data of other classes by doing :
Code:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"APPLICATION WILL ENTER BACKGROUND");
    [myOtherClass vewDidLoad];
}
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.

myOtherClass came from :
AppDelegate.h
Code:
@property (nonatomic, strong) IBOutlet MyOtherController         *myOtherController;
AppDelegate.m
Code:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    
   myOtherClass    =  [MyOtherClass alloc] init];
}

Is myOtherController different than myOtherClass?
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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?

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]
}
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
What happens in viewDidLoad?
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.
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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?

viewDidLoad is called but unfortunately, updateSettings is not called at all..Still working on at why it is not called though
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
And what leads you to believe that the UIApplicationDidFinishLaunchingNotification is being triggered when your app enters the foreground (or as you call it, relaunches)?
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
And what leads you to believe that the UIApplicationDidFinishLaunchingNotification is being triggered when your app enters the foreground (or as you call it, relaunches)?
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.
 
Last edited:

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
updateSettings is not called at all..

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.
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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.

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]; 
}
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
How your AppDeletegate looks like... What does method addObserver belongs to.
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.
 

tranvutuan

macrumors member
Original poster
Dec 19, 2011
74
0
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.

sorry I am back... I was so busy recently. Anyway thanks for your help....
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.