1. 開發應用程序時, 如果要在接受到本地通知或者遠程通知裏進行事件處理, 則可以直接在didReceiveLocalNotification和didReceivedRemoteNotification方法中直接進行調用。
應用程序啓動時的main.m文件, 直接指定appDelegate
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([DemoAppDelegate class]));
}
}
2. 如果是捕獲的是
applicationWillResignActive,
applicationWillEnterForeground,
applicationDidBecomeActive,
didFinishLaunchingWithOptions
根據UIApplication.h中的通知列表中, 表示上述的事件都可以通過通知獲取, 通知事件列表如下:
// These notifications are sent out after the equivalent delegate message is called
UIKIT_EXTERN NSString *const UIApplicationDidEnterBackgroundNotification NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationWillEnterForegroundNotification NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationDidFinishLaunchingNotification;
UIKIT_EXTERN NSString *const UIApplicationDidBecomeActiveNotification;
UIKIT_EXTERN NSString *const UIApplicationWillResignActiveNotification;
UIKIT_EXTERN NSString *const UIApplicationDidReceiveMemoryWarningNotification;
UIKIT_EXTERN NSString *const UIApplicationWillTerminateNotification;
UIKIT_EXTERN NSString *const UIApplicationSignificantTimeChangeNotification;
UIKIT_EXTERN NSString *const UIApplicationWillChangeStatusBarOrientationNotification; // userInfo contains NSNumber with new orientation
UIKIT_EXTERN NSString *const UIApplicationDidChangeStatusBarOrientationNotification; // userInfo contains NSNumber with old orientation
UIKIT_EXTERN NSString *const UIApplicationStatusBarOrientationUserInfoKey; // userInfo dictionary key for status bar orientation
UIKIT_EXTERN NSString *const UIApplicationWillChangeStatusBarFrameNotification; // userInfo contains NSValue with new frame
UIKIT_EXTERN NSString *const UIApplicationDidChangeStatusBarFrameNotification; // userInfo contains NSValue with old frame
UIKIT_EXTERN NSString *const UIApplicationStatusBarFrameUserInfoKey; // userInfo dictionary key for status bar frame
UIKIT_EXTERN NSString *const UIApplicationBackgroundRefreshStatusDidChangeNotificationNS_AVAILABLE_IOS(7_0);
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsURLKey NS_AVAILABLE_IOS(3_0); // userInfo contains NSURL with launch URL
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsSourceApplicationKey NS_AVAILABLE_IOS(3_0); // userInfo contains NSString with launch app bundle ID
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsRemoteNotificationKey NS_AVAILABLE_IOS(3_0); // userInfo contains NSDictionary with payload
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsLocalNotificationKey NS_AVAILABLE_IOS(4_0); // userInfo contains a UILocalNotification
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsAnnotationKey NS_AVAILABLE_IOS(3_2); // userInfo contains object with annotation property list
UIKIT_EXTERN NSString *const UIApplicationProtectedDataWillBecomeUnavailable NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationProtectedDataDidBecomeAvailable NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsLocationKey NS_AVAILABLE_IOS(4_0); // app was launched in response to a CoreLocation event.
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsNewsstandDownloadsKey NS_AVAILABLE_IOS(5_0); // userInfo contains an NSArray of NKAssetDownload identifiers
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsBluetoothCentralsKey NS_AVAILABLE_IOS(7_0); // userInfo contains an NSArray of CBCentralManager restore identifiers
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsBluetoothPeripheralsKey NS_AVAILABLE_IOS(7_0); // userInfo contains an NSArray of CBPeripheralManager restore identifiers
3. 對於本地通知調起事件,以及遠程通知事件上,你可能會想通過註冊上述的通知來進行捕獲。 但是, 你在查詢了上面這個列表後發現, 沒有這兩個通知事件。所以你抓狂了, 別急。 下面就是解決這個問題的方法。 開發SDK時,不能像上面第一部分代碼中main.m中那樣在應用程序啓動時能掛上AppDelegate, 所以不能通過appDelgate獲取到本地通知和遠程通知的調用時機。
3.1分析發現我們可以在程序中獲取到
[UIApplication sharedApplication].delegate, 這個delegate默認是指向DemoAppDelegate, 現在我們可以把[UIApplication sharedApplication].delegate指向一個變量proxy, 那麼這個變量將會獲取到所有原來應用AppDelegate的回調方法, 其中包括appDidFinishLaunchedWithOption, appWillResignActive, appWillEnterForeground等回調用, 同樣也包括本地通知以及遠程通知調用時的回調。
等等, 你似乎想到什麼。。。
沒錯, 你這樣寫會有問題, 會導致原始的appDelegate將會再也獲取不到這些回調了, 這是有潛在問題的。 比如你在appDelegate中實現的appWillTerminate中可能會做一些保存數據的操作,上面這樣做的話,你的這個appDelegate中的回調就再也調用不了啦, 自然你的數據保存操作也不會被執行。
3.2 緊接着, 你就會想到,有沒有什麼辦法能捕獲appDelegate的回調, 但又不影響appDelegate自身的調用呢?
有! 上面這個方法是把這個[UIApplication sharedApplication].delegate指向一個變量proxy, 我們只需要在proxy這個變量中同時把appDelegate也進行調用就可以了。 也即在proxy中,我們可以先處理一下我們想處理的回調方法, 然後繼續讓這些回調方法繼續流轉, 如流轉到appDelegate即可。也即讓自己先處理完成後, 再進行消息的轉發。
所以,我們需要如下幾個類。
1.
.h
@interface NABAppDelegate : NSObject <UIApplicationDelegate>
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
@end
.m
#import "NABAppDelegate.h"
@implementation NABAppDelegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NBLog(@"%@, %@", application, notification);
// SDK在這裏,可以做自己想做的事
}
@end
2.
.h
@interface NABAppDelegateProxy : NSProxy <UIApplicationDelegate>
- (id)init;
@property (nonatomic, strong) NSObject<UIApplicationDelegate> *naAppDelegate;
@property (nonatomic, strong) NSObject<UIApplicationDelegate> *originalAppDelegate;
@end
.m
#import "NABAppDelegateProxy.h"
@implementation NABAppDelegateProxy
- (id)init
{
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *sig;
sig = [self.originalAppDelegate methodSignatureForSelector:aSelector];
if (sig) {
return sig;
} else {
sig = [self.naAppDelegate methodSignatureForSelector:aSelector];
return sig;
}
return nil;
}
// Invoke the invocation on whichever real object had a signature for it.
- (void)forwardInvocation:(NSInvocation *)invocation
{
if ([self naDelegateRespondsToSelector:[invocation selector]]) {
[invocation invokeWithTarget:self.naAppDelegate];
}
if ([self.originalAppDelegate methodSignatureForSelector:[invocation selector]]) {
[invocation invokeWithTarget:self.originalAppDelegate];
}
}
// Override some of NSProxy's implementations to forward them...
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ([self.naAppDelegate respondsToSelector:aSelector])
return YES;
if ([self.originalAppDelegate respondsToSelector:aSelector])
return YES;
return NO;
}
- (BOOL)naDelegateRespondsToSelector:(SEL)selector
{
return [self.naAppDelegate respondsToSelector:selector] && ![[NSObject class] instancesRespondToSelector:selector];
}
@end
- (void)addAppDelegateProxy
{
_proxy = [[NABAppDelegateProxy alloc] init];
@synchronized ([UIApplication sharedApplication]) {
_proxy.naAppDelegate = [[NABAppDelegate alloc] init];
_proxy.originalAppDelegate = [UIApplication sharedApplication].delegate;
[UIApplication sharedApplication].delegate = _proxy;// 這句最爲重要
}
}
- (BOOL)naDelegateRespondsToSelector:(SEL)selector
{
return [self.naAppDelegate respondsToSelector:selector] && ![[NSObject class]instancesRespondToSelector:selector];
}
- (void)setCustomAppDelegateProxy:(id<UIApplicationDelegate>)delegate
{
if (delegate) {
self.proxy.naAppDelegate = delegate;
}
}
NABAppDelegateDemo *demoAppDelegate = [[NABAppDelegateDemo alloc] init];
[[XXXSDK shared] setCustomAppDelegateProxy:demoAppDelegate];
@interface NABAppDelegateDemo : NABAppDelegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
@end
@implementation NABAppDelegateDemo
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"did receive local notification, notification=%@", notification);
[application cancelLocalNotification:notification]; //(這裏可以根據需要決定是否進行cancelNotification)
}
@end
原文:http://blog.csdn.net/smking/article/details/39010067