I'm looking for a way to retrieve the UIApplicationLaunchOptionsLocalNotificationKey on iOS that doesn't involve using the application delegate, i.e. I don't want to have to implement the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification != nil)
{
// Process notification
}
}
I'm trying to create a helper library that needs information about the startup notification. Is there anyway of doing this? Can I retrieve the launch options via another method at a later point in the application process?
You can add yourself as an observer of the UIApplicationDidFinishLaunchingNotification notification which will be posed by the application and contains the information you are looking for.
As #Stavash suggests, there are limitations. For the first launch you won't be able to pick this notification up because the instance of your library won't be created (your class would need to be in the root XIB). But, this notification will also be sent when the app is re-opened for local / remote notifications.
Use a AppDelegate category and inside the +load method of your category add an observer for UIApplicationDidFinishLaunchingNotification. For the observer class you cannot use "self" but you will have to use a singleton object. Here are exact steps to get it done.
Add a category for your AppDelegate. Eg : #interface AppDelegate
(notification).
Implement the +load method in your category. When
the app is launched, it will start calling +load method of all the
classes that get loaded. This includes your categories also.
Create
a Singleton class with a method that will receive the
NSNotification. So implement a signature like this -
(void)appDidLaunch:(NSNotification *)notification; in your singleton
class.
Inside the +load method, add an observer for the notification
"UIApplicationDidFinishLaunchingNotification".
Make the singleton
object as your observer for this notification.
Add your breakpoints
in your +load and appDidLaunch methods to see the sequence of
methods being called. You will get the launchOptions also in your
observer callback method.
The other way to do it would be to Swizzle the AppDelegate's init method with a swizzle_init method. That way you can avoid the Singleton object and define your "appDidLaunch" observer method inside your AppDelegate's category. In that case you can set 'self' as your notification's observer.
Related
I would like to create a GCD element in a shared static object (say, called Manager) that will, every few seconds, fetch some data from an external repository (e.g. URL) and change a UIElement in the application ViewController.
My thinking is to:
initialize the Manager object in the AppDelegate initialization methods (as soon as the App gets lunched)
In the initialization method start an operation queue that fetches the data and, after every fetch, verifies if the new content is different than the previous one (that would be locally stored in a variable inside the Manager class.)
If the content is different change the UIElement (e.g. if it is a string then the UILabel would change, if it is an Image URL resource then the UIIMage will change).
I have no idea on how to access to the UILabel element from the Manager class. Am I going in the wrong direction or is there some other way/pattern to do this? (I suspect that I need to create a static Logic class that can be accessed by the callback methods function inside from the Manager class and that have reference to the ViewController that contains the UIElements)
Any simple but good tutorial would be of much help.
You can achieve this through delegation. Define a protocol for the Manager class called ManagerDelegate. Then when the manager does its work it can send the delegate information about what it has done or will do.
Some sample delegate methods could be:
- (void)managerBeganNewFetchRequest:(Manager *)manager;
- (void)manager:(Manager *)manager foundNewData:(id)data;
- (void)manager:(Manager *)manager didReceiveDuplicateData:(id)data;
Here's some info on delegation from the Apple's documentation: https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/Delegation.html
Post a notification.
In your ViewController with the UILabel you want to change, in viewDidLoad, do something like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateLabel) name:#"ManagerUpdated" object:nil];
Then in your manager class whenever you want to update the label:
[[NSNotificationCenter defaultCenter] postNotification:#"ManagerUpdated" object:nil];
You can den send data along with the object: parameter, instead of being nil it can be whatever you want.
I have a static method in a separate class to handle UIKeyboard.WillHideNotification & UIKeyboard.WillShowNotification so that it can be used across the app.
I am adding the observer in a ViewController in the following way :-
NSNotificationCenter.DefaultCenter.AddObserver (UIKeyboard.WillHideNotification, KeyboardAppearanceUtilities.OnKeyboardNotification);
How can I get the observer object in the notification Action method which is declared in KeyboardAppearanceUtilities class as follows :-
public static void OnKeyboardNotification (NSNotification notification)
{
}
notification.Object is always null for obvious reason that I am not setting the object parameter in the AddObserver method.
Can someone guide me how to rearrange the code so that this notification handler can be used across the app and also gives me access to the observer?
Your code would be a lot nicer if you used the strongly typed notifications:
http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIKeyboard%2bNotifications.ObserveWillHide
I have designed a web service application and fetch app's data from my server via some GET requests.. In my login class i enter userdefaults and save them to NSUSerDefaults, then in viewDidLoad of my login class i made a control, if the userdefaults are saved, i assing them to the text property of textfield. What i want is to call that method(login method) of my login class from the applicationDidFinishLaunchingWithOptionsdelegate method. Below is some peoudo code:
//LoginClass.m
#implementation LoginClass
....
//needed things...
-(ibaction)LoginMethod{
//the assingments&data fetchings ect
}
And i want to call this method in my appdelegate class like below
//....Appdelegate class
#import "LoginClass.h"
//.....other things....
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginClass *myObj= [[LoginClass alloc]init];
[myObj LoginMethod];
}
How can i do this? Shortly over all, how can i call a method of other classes from AppDelegate class?
Note: I use NSURLConnections and its delegate methods to fetch data, handle errors ect..
NOTE-2: I tagged with NSUserDefaults too because i use it too(in controlling i control its content)
EDIT After controlling defaults in my loginViewController's viewDidLoad, if there is a value in defaults i want to automatically call my login action, with no need to user's clicks.
Since the AppDelegate is usually the first class created this is where you can create the objects that you want to send messages. If this object creates them, then this objects knows about them and it can send it messages.
A word of caution, though:
Loading everything in your AppDelegate is going to take time. If you take too long then the Springboard will terminate your app.
I also think your design is a bit unsophisticated. If you are going to create everything in the AppDelegate then I suspect the control flow will be bouncing back to the AppDelegate to get references to other objects. Which doesn't make for modular code.
i have an NSNotificationCenter selector,
where to put it ? in the delegate (if yes then where?) in the controller?
where to put the method as well.
do i need to dealloc the NSNotificationCenter ?
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceNotificationReceived:) name:UIApplicationDidBecomeActiveNotification object:nil];
- (void)deviceNotificationReceived:(NSNotification *)notification
{
[self.soundMgr endInterruption];
}
The deviceNotificationReceived: method must be an instance method of the argument to addObserver:. It is self in this instance, so your method should go in the same class.
You should not release the NotificationCenter, as you did not create or retain it.
Your question was a little hard to understand, is this what you were asking?
Hi, i have an NSNotificationCenter selector,
okay, you mean you have a selector for a method in NSNotificationCenter.
In Objective-C, “selector” has two
meanings. It can be used to refer
simply to the name of a method when
it’s used in a source-code message to
an object. It also, though, refers to
the unique identifier that replaces
the name when the source code is
compiled.
http://developer.apple.com/mac/library/documentation/cocoa/....../ocSelectors.html
So you have created a selector that refer to a method.
where to put it ?
It's a variable, you can store it where ever you feel it fits in your design.
in the delegate
See above.
(if yes then where?)
It's a variable, it depends on your usage.
in the controller?
Do you have controller? Depends on your design.
where to put the method as well.
Which method?
do i need to dealloc the NSNotificationCenter ?
No, [NSNotificationCenter defaultCenter] returns a reference to the notification center, you don't dealloc it.
Since you are subscribing to the UIApplicationDidBecomeActiveNotification notification, the most logical place to put the notification is in the applicationdDidFinishLaunching method of your app delegate.
That's the first point your code gets called, so you cannot set it earlier.
where to put it ?
It depend on when you need to register for notification. One way is to add observer in 'init' method of the class and remove notification in 'dealloc'method of the class.
For example, when memory gets low, the System sends a UIApplicationDidReceiveMemoryWarningNotification notification. That's all Apple says in its docs at that point. But where does this notification come from, and to which method is it sent? Or where and how do I register what that I get notified?
From within the initialization code of the class you wish to receive the notification make the following method call:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleMemoryWarning:) name: UIApplicationDidReceiveMemoryWarningNotification object:nil];
This assumes that your class also implements a handleMemoryWarning method as follows:
- (void) handleMemoryWarning:(NSNotification *)notification
{
}
Much simpler to use the application delegate and implement the optional method
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
Most common notifications are also available translated into calls to a delegate, typically to optional methods in a formal protocol. Your delegate can be whatever object you like.
It is sent to the notification center, where all notifications are centralized. An object that wants to get informed about this notification registers itself to the notification center by telling which notification it wants to get informed and which method should be invoqued when the notification is raised.
For more information you can take a look to Notification programming topics for Cocoa and NSNotification class reference .
Be warned that your selector will need to take the notification as an argument.
If you use something like #selector(handleMemoryWarning) and - (void) handleMemoryWarning { } the object WILL NOT send the notification and you'll still be holding onto all of your memory.
I was just bitten by this.