Detecting when phone call present iphone objective c - ios

Is there a way to detect if a phone call is going on on a phone in objective c? You'll notice many views move downwards under this situation and as such I want to know when.

You should not be detecting calls with the status bar frame. Instead you can detect phone calls with NSNotification like this
Put this in you viewDidLoad:
#import <CoreTelephony/CTCall.h>
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callReceived:) name:CTCallStateIncoming object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callEnded:) name:CTCallStateDisconnected object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callConnected:) name:CTCallStateConnected object:nil];
And don't forget to add CoreTelephony.framework

As explained by rmaddy, if you're trying to catch status bar frame changes, detecting phone calls is not the best way.
What you can do is implement the methods - (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame and - (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame of your app delegate or listen for the UIApplicationWillChangeStatusBarFrameNotification and UIApplicationDidChangeStatusBarFrameNotification notifications.

Related

pushNotification to another viewController only show when view is active

Notification only called the function when observer_ViewController is active
AppDelegate.m
[[NSNotificationCenter defaultCenter] postNotificationName:kNewShipNotifaction object:ship];
observer_ViewController.m
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newShipCome:) name:kNewShipNotifaction object:nil];
}
- (void)newShipCome:(NSNotification *)notifacation{
[self updateNotifyWithShip:notifacation.object];
}
Notification didn't call the newShipCome:(NSNotification *)notification method when I'm in another viewController. When I switched to the observer_ViewController, the method still didn't get called.
So...how can I get notification update correctly when I'm not in the observer_ViewController ?
remove de-register code form viewWillDisappear it will work

How to use UIApplicationDidBecomeActiveNotification

How to use UIApplicationDidBecomeActiveNotification?
Should I declare it in viewDidLoad or viewWillAppear to reload data when coming from background to foreground.
Does UIApplicationDidBecomeActiveNotification gets called only when app comes from background to foreground?
Please help.
Thanks.
Sometimes it is useful to have a listener of UIApplicationDidBecomeActiveNotification when you need to make some action in your view controller on wake up from background (in case you entered to background with this view controller on-screen). In such wake up viewWillAppear will not be triggered!
Example of use:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(someMethod) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)someMethod
{
<YOUR CODE AT WAKE UP FROM BACKGROUND>
}
Of course, you can also implement all you need at your app delegate class life cycle.
You get this notification if your app was interrupted by a phone call or push notification. Generally, if your application is getting active on screen after interruption.
You can register any class, that is loaded in memory by the moment application will become active as observer to this notification.
Use following code in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(someMethod:)
name:UIApplicationDidBecomeActiveNotification object:nil];
Use someMethod to handle this notification. And don't forget to remove this class as observer in dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
The OP asked about system notifications fired when the app is backgrounded and then foregrounded again. The Notification designed to handle this situation is the UIApplicationDidEnterBackgroundNotification and UIApplicationWillEnterForegroundNotification. If you want a notification that fires for a wider range of situations, such as when you have a system notification, take a phone call, a SMS comes in, or you slide up the control pane, as well as being backgrounded then you will want the UIApplicationWillResignActiveNotification and UIApplicationDidBecomeActiveNotification. It's important to recognize that these are different, since you might only need to react if your app is backgrounded, and not for other scenarios.

How do I call multiple methods in #selector for notification?

Currently I'm only calling one method when application will enter foreground. How do I call various methods in #selector?
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(displayHappyFace)
name:UIApplicationWillEnterForegroundNotification
object:nil];
Just create a separate function for all your other function.
[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(AllFunction)
name:UIApplicationWillEnterForegroundNotification
object:nil];
All functions.
-(void) AllFunction
{
[self displayHappyFace];
[self otherFunction];
}
Add another observer to UIApplicationWillEnterForegroundNotification if you wish to keep the methods' logic separate:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(displayHappyFace)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(callOtherMethod)
name:UIApplicationWillEnterForegroundNotification
object:nil];
#selector supports only one method. Remember to remove self as the observer before releasing its memory, to avoid messages being passed to a nil object.
You can only put one selector there.
Best practice is to create a new method called handleNotificationName: for each notification.
Example:
- (void)handleUIApplicationWillEnterForegroundNotification:(NSNotification *)aUIApplicationWillEnterForegroundNotification { }
This makes it really easy to figure out where your app handles each notification and makes code maintenance easy.
Inside the handler method you can call whatever methods you need to. You can have conditional logic also based on state you have or based the userInfo dictionary of the Notification ( if it has one ).
Don't forget to remove your notification observer in you object's dealloc method (at least, if not somewhere else because you might not want to always receive the notification depending on the use case)

Knowing the app. launc in Objective C

The app. delegate has the method that gets invoked when the app launches. Pain is my app is not following MVC and I have to reset many text fields to empty when the app. launches(not concerned about first launch). These txt fields are not created in app delegate so i cannot set them in app delegate (as the txt fields are not accessible). how can i know the app has launched in the new class to reset the fields . Is there any condition like
if(application.HasAppLaunced)
{
}
KIndly help
You could register your view controller as an observer of event
UIApplicationDidEnterBackgroundNotification
or
UIApplicationWillEnterForegroundNotification
in your view controller somewhere in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(appEnteredBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
and add this method to reset your fields, you can reset all fields here:
- (void)appEnteredBackground{
[textField setText:#""];
}
don't forget to unregister your view controller, put this in some appropriate location:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
I don't completely understand what are you asking for, but if the question is how to detect whather app is active you may use following condition:
[[UIAppication sharedApplication] applicationState] == UIAppicationStateActive
Try This
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Reset your text fields here
}
Try this one.. You can call a method to empty thetextfields using NSNotificationCenter
You can write the following line in AppDelegate.
[[NSNotificationCenter defaultCenter]postNotificationName:#"EmptyFields" object:nil];
You can write the following line in viewDidLoad method.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(setEmpty) name:#"EmptyFields" object:nil];
You can do textfields empty in the following method. You can write it in your ViewController.
- (void) setEmpty{
NSLog(#"Empty....");
}

NSNotificationCenter can lead to bugs. Do you know more elegant solutions?

I can add observer twice (by accident) to the notification center and I will get notifications twice.
Is it possible to get only one notification? Do you know more elegant solutions?
I show you this example because this may lead to bugs.
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)keyboardDidShow:(NSNotification *)ntf
{
}
If you're not sure if you added the observer somewhere else, you can use the following code everytime you're adding an Observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
This way you are removing the old one (if it existed) and adding a new one.
It's not 100% fail proof but it's a start. This could fail in Multi-Threaded apps where the calls are being made async or other unique situations.
You can also set an object to nil and then later use that object as if was still valid.
Not everything can be made fail safe.

Resources