Is it possible that NSNotificationCenter doesn't work on certain devices? - ios

Am using NSNotificationCenter in my iPhone App to post a notification
// I add an observer in didFinishLanchingWithOptions() in the AppDelegate
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(getData:) name:kNotif_GetData object:nil];
....
....
// then in another method, I post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:kNotif_GetData object:nil];
....
One user says that this functionality (which is executed by getData()) is not working. so that might mean that the notification hasn't gotten fired. Any idea why this might happen? When I test it with different devices, it works perfect. The user uses iPhone5 and iOS7. Is there any more setting or any explicit user setting which is needed or which could turn this on/off?

No, notification centre is reliable.
"Not working" is not enough information to diagnose the problem. Get more information from the user or add more logging so that you know what is actually going on.

Related

Method in viewWillAppear and viewDidLoad didn't loaded

I have created a method to check the status of a server in my viewcontroller, I need to check this, everytime I will open the app.
I call [self checkStatus]; from viewWillAppear and viewDidLoad, but when I open the app, by clicking home button, and I try to open the app again (clicking the app icon in applications) this method is not called. I have a NSLog to view when it is launched or not.
I'm frustrated. Thanks for your help.
You can react to app changes using NotificationCenter:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doSomething:) name:UIApplicationDidBecomeActiveNotification object:nil];
BTW: don't forget to removeObserver when you don't need it!
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
You can also use UIApplicationWillEnterForegroundNotification etc, depending what do you need.
You should read about app lifecycle on Apple Developer pages :). Read:
AppleDeveloperLink Especially section: "Execution States for Apps" to know more about app lifecycle.
StackOverflowLink to know more about view lifecycle.
iOS is not calling those methods again, but the delegate methods in the AppDelegate. You have to propagate the message to your controllers then.
I hope this will help you: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/

How hide or close my app when i reveive a call?

I have a little bug. I'm developing an iOS App.
If i receive a call, my app stays open and the screen for my entering call appears on my app. I would like to close my app if i have a call.
How can i fix that?
Thanks,
J.
The green, in-call status bar is not a bug but a feature. You don't need to close the app when the call comes.
Instead, make sure your views are resized properly when the in-call status bar appears.
As Per Apple Human Interface guidelines
Never quit an iOS app programmatically because people tend to interpret this as a crash.
However, if external circumstances prevent your app from functioning as intended, you need
to tell your users about the situation and explain what they can do about it. Depending on
how severe the app malfunction is, you have two choices.
Display an attractive screen that describes the problem and suggests a correction. A
screen provides feedback that reassures users that there’s nothing wrong with your app. It
puts users in control, letting them decide whether they want to take corrective action and
continue using your app or press the Home button and open a different app
If only some of your app's features are unavailable, display either a screen or an alert
when people use the feature. Display the alert only when people try to access the feature
that isn’t functioning. `
But again you handle your app accordingly when call comes by using the following notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(incomingCall:) name:CTCallStateIncoming object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callEnded:) name:CTCallStateDisconnected object:nil];
Srinivasan N's answer has the incorrect observer, you'll want to add this observer which will account for all scenarios: phone calls, Personal Hotspot, GPS/navigation, etc.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(adjustViews:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
}
- (void)adjustViews:(NSNotification *)notification
{
NSValue *rectValue = [[notification userInfo] valueForKey:UIApplicationStatusBarFrameUserInfoKey];
CGRect newFrame;
[rectValue getValue:&newFrame];
NSLog(#"Changed frame to: Width: %f, Height: %f", newFrame.size.width, newFrame.size.height);
// Adjust your views here
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

iPad App Crashes on Orientation change

I am developing an iPad app. I allow both landscape and portrait mode. My UI is fine in portrait mode but when I change it to landscape mode, my UI gets messed up. I saw some SO posts related to this and I added following code in initWith... in my UIView.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(abc)
name:UIDeviceOrientationDidChangeNotification
object:nil];
My UI is working fine in portrait mode after doing this. When I change it to landscape mode, my UI is fine. But after I change it back into portrait mode, my app crashes. I read some posts on SO related to app crashing an got to know about instruments. I enabled zombies and found that a message is being sent to already released object and this message is coming from NSNotificationCenter.
Is there something else that I need to handle apart from registering my device ? Also, is there any way where in I can change the implementation from UIView to UIViewController and implement the methods that UIViewController has regarding device orientation ? Please let me know the steps I need to follow in order to get this done. Thanks!
Where are you registering for the notifications? You need to remove the observer when you are about to change orientations (either in prepForSegue or willAnimateRotationToInterfaceOrientation depending on however you've got your setup) in order prevent messaging a no longer valid object. You also don't want to pile up several notifications if your registering in viewDidAppear/viewWillAppear.
Remove the observer using:
[[NSNotificationCenter defaultCenter] removeObserver:self];//removes all notifications for that object (the way I've used it before)
or if you want to be specific, do something like:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice];//remove just that notification
The UIViewController class has several methods that deal with changes in orientation. See the docs for a discussion of those methods.
One method you should look into is viewWillLayoutSubviews. This is a common place to perform manual view layout. This is called anytime the view controller's orientation changes.
Using these methods is much more common than registering for device orientation change notifications. Based on your statements about the crash, a possible issue is that you never remove the observer that you add. For every call to addObserver there must be a corresponding call to removeObserver. Otherwise the observer is called even if it has long gone away. And this results in the crash you describe.

Application does not run in background simply does not work

I have read over many stack overflow questions where people ask to terminate their app oppose to let it run in the background.
The main answer I found was to set the application does not run in background BOOL to YES in my info.plist
I have done this and cleaned my project but still my application runs in the background when the user presses the home button. This solution simply does not work.
What can I do to make my application quit when a user presses the home button.
My app is currently running on iOS 6.
Any help is appreciated :)
This answer is for your first comment, not the original question. Have your iPod view controller register for the UIApplicationDidEnterBackgroundNotification notification. The implementation should stop the music. This is a much better user experience than choosing to have your app terminate on suspend.
// Put this in a good place like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(backgrounding) name:UIApplicationDidEnterBackgroundNotification object:nil];
// Handle the notification
- (void)backgrounding {
// app is leaving the foreground, stop the music
}
// In your dealloc method add:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];

If add an observer for a notification in the AppDelegate, do I need to bother removing it?

In the AppDelegate's didFinishLaunchingWithOptions:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(contextChanged:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
This is so I can merge changes to the data from other threads.
Question: Do I need to bother removing this listener in applicationWillResignActive or applicationWillTerminate? It doesn't seem like there's a point. I guess I'm asking if it's normal to have listeners like this in the main loop that never get removed.
You can never remove it, but if your app receive a notification (it won't happen in this case) while it is in background the notification will be queued and delivered to the application when it comes up again (if the app isn't killed ofc).
If don't want notifications that happen when your app is in background to be delivered once it comes up you can remove the listener in the methods you pointed out.
In this case, actually, it doesn't matter.

Resources