你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 本地通知使用總結

本地通知使用總結

編輯:IOS開發綜合

一.關於通知注冊:

ios8之前:registerForRemoteNotificationTypes:

ios8之後:registerUserNotificationSettings

 

二.關於提醒角標

1.本地推送UILocalNotification的applicationIconBadgeNumber屬性只會影響角標的顯示,不會影響通知欄的通知處理。

1)當applicationIconBadgeNumber>0時,角標會隨applicationIconBadgeNumber而變化。

2)當applicationIconBadgeNumber=0時,角標維持推送前狀態不變。

3)當applicationIconBadgeNumber<0時,角標置0不顯示。

2.遠程推送的badge字段,只會影響角標的顯示,不會影響通知欄的通知處理。

1)當badge>0時,角標會隨badge而變化。

2)當badge=0時,角標維持不變。

3)當badge<0時,角標維持不變。

3.UIApplication的applicationIconBadgeNumber屬性既會影響角標的顯示,又會影響通知欄通知的處理。

1)當applicationIconBadgeNumber>0時,角標會隨之變化,通知欄通知不變。

2)當applicationIconBadgeNumber=0時,角標變為0不顯示,通知欄通知清空。

3)當applicationIconBadgeNumber<0時,角標變為0不顯示,通知欄通知清空。

 

三.關於重復:

1. UILocalNotification.repeatInterval:repeatInterval的下限應該是NSCalendarUnitMinute,即每分鐘重復發送一次通知。如果設置為NSCalendarUnitSecond,那麼消息不會重復,每秒發送一次通知,iOS系統當然不會容許這樣的存在了。這裡比較不好的一點是NSCalendarUnit是個枚舉類型,該值不能自定義,例如你不能塞個10.0給它從而希望它每十秒重復一次。所以如果你想每20分鐘發送一次通知,一小時內發送3次,那麼只能同時設定三個通知了。

2.若想設置復雜的重復通知,比如只在每周的周一、周三重復,則只能設置兩個通知,分別進行周重復提醒。

 

四.關於userInfo:userInfo可以攜帶用戶自定義的關於通知的信息,通常可以用來作為不同通知的區分標志

 

五.關於接收通知:

1. 如果此時應用程序還在運行(無論是在前台還是在後台)則會調用-(void)application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification(如果是遠程通知則通過application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification)方法接收消息參數。參數中可以拿到notification對象,只要讀取userInfo屬性區分不同的通知即可。

2. 如果應用程序已經完全退出此時會調用- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法:

1)通過點擊通知欄通知進入:此時可以訪問launchOptions中鍵為UIApplicationLaunchOptionsLocalNotificationKey的對象,這個對象就是發送的通知,由此對象再去訪問userInfo。

2)通過點擊圖標進入:可以通過[[UIApplication sharedApplication] scheduledLocalNotifications]獲取全部的調度通知,並通過userinfo進行區分

 

六:關於覆蓋安裝:

如果我們的應用程序給系統發送的本地通知是周期性的,那麼即使把程序刪了重裝,之前的本地通知在重裝時依然存在,沒有從系統中移除

 

 

 

#import "AppDelegate.h"
#import "ViewController.h"
#import "HomeViewController.h"
#import "KCMainViewController.h"

#define NotificationID @"NotificationID"
NSString * const NotificationCategoryIdent  = @"ACTIONABLE";
NSString * const NotificationActionOneIdent = @"ACTION_ONE";
NSString * const NotificationActionTwoIdent = @"ACTION_TWO";


@implementation AppDelegate

#pragma mark 用戶打開app,分為點擊圖標打開與點擊通知欄通知打開方式
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
    //程序開啟時取消之前注冊的通知
    //1.通過點擊通知欄通知開啟app
//    UILocalNotification *notification=[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
//    if(notification!=nil){
//        NSDictionary *dic = [notification userInfo];
//        NSString *Identifer = [dic objectForKey:@"id"];
//        if ([Identifer isEqualToString:NotificationID]) {
//            [self cancelLocation:notification];
//        }
//
//    }
//    
//    //2.通過點擊圖標開啟app
//    else {
//        [self cancelLocationWithIdentifier:NotificationID];
//    }
    
    [self cancelLocationWithIdentifier:NotificationID];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    ViewController *vc = [[ViewController alloc] init];
    self.window.rootViewController = vc;
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    
   
    UIUserNotificationType types = (UIUserNotificationTypeAlert|
                                    UIUserNotificationTypeSound|
                                    UIUserNotificationTypeBadge);
    
    NSSet *categories = [self addNotiActionCategories];
    
    
    //注冊通知。ios8之後的方式
    if ([[UIApplication sharedApplication]currentUserNotificationSettings].types!=UIUserNotificationTypeNone) {
        
    }else{
        [[UIApplication sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types  categories:categories]];
        
    }
    return YES;
    
}

#pragma mark 調用過用戶注冊通知方法之後執行(也就是調用完registerUserNotificationSettings:方法之後執行)
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    if (notificationSettings.types!=UIUserNotificationTypeNone) {
        
        [self addLocalNotification];
    }
}



#pragma mark 當應用在前台,或者後台運行時收到通知後的處理接口
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    
    //獲取通知的userInfo
    NSString *receiveUseInfoID = notification.userInfo[@"id"];

        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"失敗" message:@"失敗" preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *actCancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
    
        }];
    
        UIAlertAction *actDetail = [UIAlertAction actionWithTitle:receiveUseInfoID style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
    
        }];
    
        [alertController addAction:actCancel];
        [alertController addAction:actDetail];
        [[self getCurrentVC] presentViewController:alertController animated:YES completion:nil];
}


#pragma mark 當應用未在前台,收到本地通知後,左劃通知,顯示按鈕對應的點擊動作處理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler {
    if ([identifier isEqualToString:NotificationActionOneIdent]) {
        
        NSLog(@"You chose action 1.");
    }
    else if ([identifier isEqualToString:NotificationActionTwoIdent]) {
        
        NSLog(@"You chose action 2.");
    }
    if (completionHandler) {
        
        completionHandler();
    }
}


#pragma mark 當應用未在前台,收到遠程通知後,左劃通知 通知滑動後的動作選項處理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
    
    if ([identifier isEqualToString:NotificationActionOneIdent]) {
        
        NSLog(@"You chose action 1.");
    }
    else if ([identifier isEqualToString:NotificationActionTwoIdent]) {
        
        NSLog(@"You chose action 2.");
    }
    if (completionHandler) {
        
        completionHandler();
    }
}


#pragma mark 進入前台後設置消息信息,只在由後台進入前台時調用,重新開啟app時不會調用
-(void)applicationWillEnterForeground:(UIApplication *)application{
//    NSInteger num =[UIApplication sharedApplication].applicationIconBadgeNumber;
//    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//進入前台取消應用消息圖標
}

#pragma mark 進入前台後設置消息信息,由後台進入前台以及重新開啟app時均會調用
- (void)applicationDidBecomeActive:(UIApplication *)application{

    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//進入前台取消應用消息圖標,同時清空通知欄通知

}

#pragma mark 程序即將退出時注冊通知
-(void)applicationWillTerminate:(UIApplication *)application{
    [self addLocalNotification];
}


#pragma mark - 私有方法
#pragma mark 添加本地通知

-(void)addLocalNotification{

    NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 7];
    [self addNormalLocationWithIdentifier:NotificationID WithFireDate:fireDate WithRepeatInterval:NSCalendarUnitWeekday];
}

//注冊通知
-(void)addNormalLocationWithIdentifier:(NSString *)Identifier  WithFireDate:(NSDate *)fireDate WithRepeatInterval:(NSCalendarUnit)repeatInterval{
    
    UILocalNotification *notification=[[UILocalNotification alloc]init];
    //設置調用時間
    notification.fireDate=fireDate;//通知觸發的時間,10s以後
    notification.repeatInterval=repeatInterval ;//通知重復次數,枚舉類型,除枚舉類型外的其它值不會引起重復通知,為0時亦不會重復
    [notification setCategory:NotificationCategoryIdent];
    //notification.repeatCalendar=[NSCalendar currentCalendar];//當前日歷,使用前最好設置時區等信息以便能夠自動同步時間
    
    //設置通知屬性
    notification.alertBody=@"你好你好,是否立即體驗?"; //通知主體
    notification.applicationIconBadgeNumber=4;//應用程序圖標右上角顯示的消息數
    notification.alertAction=@"打開應用"; //待機界面的滑動動作提示
    notification.alertLaunchImage=@"Default";//通過點擊通知打開應用時的啟動圖片,這裡使用程序啟動圖片
    //notification.soundName=UILocalNotificationDefaultSoundName;//收到通知時播放的聲音,默認消息聲音
    notification.soundName=@"msg.caf";//通知聲音(需要真機才能聽到聲音)
    
    //設置用戶信息
    NSMutableDictionary *aUserInfo = [[NSMutableDictionary alloc] init];
    aUserInfo[@"id"] = Identifier;
    aUserInfo[@"sequence"] = [NSNumber numberWithInt:-1];
    notification.userInfo = aUserInfo;
    
    //按調度調用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];

    //立即調用通知
    //[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}


//注冊只在某些日期按周重復的通知
-(void)addRepeatLocationWithWeekDate:(NSArray *)dateArray WithIdentifier:(NSString *)identifier{
    
    NSInteger todayWeekDay = [self weekdayWithDate:[NSDate date]];
    
    for (NSString * dateStr in dateArray) {
         NSInteger dateNum = [dateStr integerValue];
        NSInteger dateSeq;
        dateSeq = (dateNum + 7 -todayWeekDay)%7;
        if (!dateSeq) {
            dateSeq = 7;
        }
        
         NSDate *date = [[NSDate date] dateByAddingTimeInterval:(24*3600*dateSeq)];
        [self addNormalLocationWithIdentifier:identifier WithFireDate:date WithRepeatInterval:NSCalendarUnitWeekday];
    }
}

//注冊有小睡nap分鐘的通知
-(void)addNapLocationWithIdentifier:(NSString *)identifier  WithFireDate:(NSDate *)fireDate WithRepeatInterval:(NSCalendarUnit)repeatInterval WithNap:(NSInteger)nap{
    
    
    //若nap為0,則注冊一次通知,相當於不重復,否則重復三次
    NSInteger times;
    if (nap > 0) {
        times = 3;
    } else {
        times = 1;
    }
    
    for (int i = 0; i < times; i++) {
        [self addNormalLocationWithIdentifier:identifier WithFireDate:[fireDate dateByAddingTimeInterval:i * nap * 60] WithRepeatInterval:repeatInterval];
    }
}

#pragma mark 移除本地通知,在不需要此通知時記得移除


//移除指定通知
-(void)cancelLocation:(UILocalNotification *)noti{
    [[UIApplication sharedApplication] cancelLocalNotification:noti];
}


//移除特定id的通知
-(void)cancelLocationWithIdentifier:(NSString *)identifier{
    
    for (UILocalNotification *noti in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
        NSString *notiID = noti.userInfo[@"id"];
        if ([notiID isEqualToString:identifier]) {
            
            [[UIApplication sharedApplication] cancelLocalNotification:noti];
        }
    }
}

//移除全部通知
-(void)cancelAllLocation{
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

#pragma mark 添加通知動作action
-(NSSet *)addNotiActionCategories{
    UIMutableUserNotificationAction *action1;
    action1 = [[UIMutableUserNotificationAction alloc] init];
    [action1 setActivationMode:UIUserNotificationActivationModeBackground];
    [action1 setTitle:@"Action 1"];
    [action1 setIdentifier:NotificationActionOneIdent];
    [action1 setDestructive:NO];
    [action1 setAuthenticationRequired:NO];
    
    UIMutableUserNotificationAction *action2;
    action2 = [[UIMutableUserNotificationAction alloc] init];
    [action2 setActivationMode:UIUserNotificationActivationModeBackground];
    [action2 setTitle:@"Action 2"];
    [action2 setIdentifier:NotificationActionTwoIdent];
    [action2 setDestructive:NO];
    [action2 setAuthenticationRequired:NO];
    
    UIMutableUserNotificationCategory *actionCategory;
    actionCategory = [[UIMutableUserNotificationCategory alloc] init];
    [actionCategory setIdentifier:NotificationCategoryIdent];
    [actionCategory setActions:@[action1, action2]
                    forContext:UIUserNotificationActionContextDefault];
    
    NSSet *categories = [NSSet setWithObject:actionCategory];
    return categories;
}


#pragma mark 返回周幾
-(int)weekdayWithDate:(NSDate *)date{ //返回周幾
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorian components:NSCalendarUnitWeekday fromDate:date];
    int weekday = [components weekday];
    return weekday-1==0?7:weekday-1;
}

#pragma mark 獲取窗口當前展示VC
- (UIViewController *)getCurrentVC
{
    UIViewController *result = nil;

    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal)
    {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for(UIWindow * tmpWin in windows)
        {
            if (tmpWin.windowLevel == UIWindowLevelNormal)
            {
                window = tmpWin;
                break;
            }
        }
    }

    UIView *frontView = [[window subviews] objectAtIndex:0];
    id nextResponder = [frontView nextResponder];

    if ([nextResponder isKindOfClass:[UIViewController class]])
        result = nextResponder;
    else
        result = window.rootViewController;

    return result;
}

@end

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved