iOS本地通知:UILocalNotification

來源:互聯網
上載者:User

在去年做過一個小App,其中使用的關鍵功能就是向使用者發送本地通知,可惜當時沒有寫部落格的習慣,所以沒有將對應的知識記錄下來。最近又遇到了該功能的使用,這一次果斷寫個部落格做下有關UILocalNotification的筆記。


首先是添加一個本地通知到系統中,代碼如下:

    // 初始化本地通知對象    UILocalNotification *notification = [[UILocalNotification alloc] init];    if (notification) {        // 設定通知的提醒時間        NSDate *currentDate   = [NSDate date];        notification.timeZone = [NSTimeZone defaultTimeZone]; // 使用本地時區        notification.fireDate = [currentDate dateByAddingTimeInterval:5.0];                // 設定重複間隔        notification.repeatInterval = kCFCalendarUnitDay;                // 設定提醒的文字內容        notification.alertBody   = @"Wake up, man";        notification.alertAction = NSLocalizedString(@"起床了", nil);                // 通知提示音 使用預設的        notification.soundName= UILocalNotificationDefaultSoundName;                // 設定應用程式右上方的提醒個數        notification.applicationIconBadgeNumber++;                // 設定通知的userInfo,用來標識該通知        NSMutableDictionary *aUserInfo = [[NSMutableDictionary alloc] init];        aUserInfo[kLocalNotificationID] = @"LocalNotificationID";        notification.userInfo = aUserInfo;                // 將通知添加到系統中        [[UIApplication sharedApplication] scheduleLocalNotification:notification];    }

上面的alertBody是裝置收到本地通知時橫額或鎖屏時的主要文字內容,alertActions是鎖屏時顯示的slide to後面的文字內容。例如:



repeatInterval表示通知的重複間隔,在SDK中定義如下:

<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHByZSBjbGFzcz0="brush:java;">@property(nonatomic) NSCalendarUnit repeatInterval; // 0 means don't repeat
其取值主要有:

        NSCalendarUnitEra                = kCFCalendarUnitEra,        NSCalendarUnitYear               = kCFCalendarUnitYear,        NSCalendarUnitMonth              = kCFCalendarUnitMonth,        NSCalendarUnitDay                = kCFCalendarUnitDay,        NSCalendarUnitHour               = kCFCalendarUnitHour,        NSCalendarUnitMinute             = kCFCalendarUnitMinute,        NSCalendarUnitSecond             = kCFCalendarUnitSecond,        NSCalendarUnitWeekday            = kCFCalendarUnitWeekday,        NSCalendarUnitWeekdayOrdinal     = kCFCalendarUnitWeekdayOrdinal,

分別表示一個世紀、一年、一個月等等,0表示不重複。具體可以查看CFCalendar Reference

repeatInterval的下限應該是NSCalendarUnitMinute,即每分鐘重複發送一次通知。

如果設定為NSCalendarUnitSecond,那麼訊息不會重複,每秒發送一次通知,iOS系統當然不會容許這樣的存在了。

這裡比較不好的一點是該值不能自訂(很遺憾,NSCalendarUnit是個枚舉類型),例如你不能塞個10.0給它從而希望它每十秒重複一次。所以如果你想每20分鐘發送一次通知,一小時內發送3次,那麼只能同時設定三個通知了。



上面的代碼運行後,5秒鐘之後就可以收到一個本地通知。

在收到通知後,調用程式委託中的下列方法處理:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{    NSLog(@"Application did receive local notifications");        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];    [alert show];}

注意這個方法只有在程式啟動之後才會執行,因此當程式處於後台時,該方法不會執行。


有一點需要注意,如果我們的應用程式給系統發送的本地通知是周期性的,那麼即使把程式刪了重裝,之前的本地通知在重裝時依然存在(沒有從系統中移除)。例如,我們在viewDidLoad方法中啟動添加本地通知的方法,多跑幾次,然後把程式在模擬器中刪除,再重新跑,並用下列方法輸出所有的本地通知:

    NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];    NSLog(@"%@", localNotifications);

控制台輸出:

2014-03-14 15:46:37.145 LocalNotificationDemo[4419:60b] (    "{fire date = Friday, March 14, 2014 at 3:38:16 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:38:16 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}",    "{fire date = Friday, March 14, 2014 at 3:44:45 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:44:45 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}",    "{fire date = Friday, March 14, 2014 at 3:44:55 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:44:55 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}",    "{fire date = Friday, March 14, 2014 at 3:45:13 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:45:13 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}",    "{fire date = Friday, March 14, 2014 at 3:45:29 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:45:29 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}",    "{fire date = Friday, March 14, 2014 at 3:46:28 PM China Standard Time, time zone = Asia/Chongqing (GMT+8) offset 28800, repeat interval = NSDayCalendarUnit, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, March 15, 2014 at 3:46:28 PM China Standard Time, user info = {\n    ClockID = LocalNotificationID;\n}}")

可以看到之前發送的本地通知一直滯留在系統中。

不只是模擬器,在iOS裝置上也是這樣,博主之前的App在裝置上重裝時以前的本地通知會繼續發送。

因此我們需要取消通知的方法,當然該對象也會在scheduledLocalNotifications數組中移除。

取消方法分為兩種。

第一種比較暴力,直接取消所有的本地通知:

[[UIApplication sharedApplication] cancelAllLocalNotifications];

這個適合在App重裝時第一次啟動的時候,或還原程式預設設定等場合下使用。

第二種方法是針對某個特定通知的:

- (void)cancelLocalNotification:(UILocalNotification *)notification NS_AVAILABLE_IOS(4_0);

這時就需要通知有一個標識,這樣我們才能定位是哪一個通知。可以在notification的userInfo(一個字典)中指定。

例如:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{    NSLog(@"Application did receive local notifications");        // 取消某個特定的本地通知    for (UILocalNotification *noti in [[UIApplication sharedApplication] scheduledLocalNotifications]) {        NSString *notiID = noti.userInfo[kLocalNotificationID];        NSString *receiveNotiID = notification.userInfo[kLocalNotificationID];        if ([notiID isEqualToString:receiveNotiID]) {            [[UIApplication sharedApplication] cancelLocalNotification:notification];            return;        }    }        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];    [alert show];}


最後建議本地通知不要發得太頻繁,不然使用者會覺得非常的煩。



參考的文章和資料:

IOS本地通知

CFCalendar Reference

iOS: 枚舉類型 enum,NS_ENUM,NS_OPTIONS







聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.