做遠(yuǎn)程推送,首先在蘋果的開發(fā)者中心配置兩個(gè)證書吸耿,下載到本地祠锣,在鑰匙串中點(diǎn)擊對(duì)應(yīng)證書,選擇導(dǎo)出證書即可得到激光所需要的p12文件咽安,這個(gè)過程中會(huì)用密碼填寫锤岸,需要記住。
這里主要介紹本地推送板乙,本地進(jìn)行推送重點(diǎn)在于構(gòu)建出firedate和間timerinter是偷,來達(dá)到某個(gè)時(shí)間點(diǎn)的推送。iOS系統(tǒng)的升級(jí)系統(tǒng)的推送系統(tǒng)也進(jìn)行了比較大的更新募逞,尤其在iOS10以及以后推出了一套新的API來管理推送蛋铆。還有就是對(duì)于iOS8的系統(tǒng),必須注冊(cè)并用戶點(diǎn)擊了同意才能進(jìn)行推送放接,當(dāng)然都需要在info里面添加需要進(jìn)行推送的字段刺啦。
iOS8:注冊(cè)推送通過UIUserNotificationSettings這個(gè)對(duì)象來設(shè)置推送類型,通過UIApplication 注冊(cè)通知纠脾。
UIUserNotificationSettings *localNot = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:localNot];
iOS10:通過UNUserNotificationCenter這個(gè)對(duì)象來獲取授權(quán)玛瘸,并且也把查詢用戶授權(quán)的接口也以及給出
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:UNAuthorizationOptionAlert|UNAuthorizationOptionSound|UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error&& granted) {
NSLog(@"用戶點(diǎn)擊允許");
} else {
NSLog(@"注冊(cè)失敗");
}
}];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
//
NSLog(@"未作出選擇");
} else if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
//
NSLog(@"未授權(quán)");
} else {
NSLog(@"已經(jīng)授權(quán)");
}
}];
遠(yuǎn)程推送
ios_8_to_ios 10
[[UIApplication sharedApplication] registerForRemoteNotifications];
iOS_10_later
[[UIApplication sharedApplication] registerForRemoteNotifications];
iOS_8_ before
[application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
發(fā)送通知:為了兼容iOS10以及大于:發(fā)送本地通知也有兩套不同的API。
iOS10er:發(fā)送本地通知主要依賴于application這個(gè)對(duì)象苟蹈,首先構(gòu)造出UILocalNotification這個(gè)發(fā)送本地通知的對(duì)象糊渊,再通過application這個(gè)對(duì)象發(fā)送UILocalNotification,UILocalNotification的firedate和@property(nonatomic) NSCalendarUnit repeatInterval; 決定了在那個(gè)時(shí)間發(fā)送通知和重復(fù)規(guī)律慧脱,不過需要注意的是,repeaterval是一個(gè)枚舉類型:
NSCalendarUnitEra = kCFCalendarUnitEra,
NSCalendarUnitYear = kCFCalendarUnitYear,
NSCalendarUnitMonth = kCFCalendarUnitMonth,
NSCalendarUnitDay = kCFCalendarUnitDay,
NSCalendarUnitHour = kCFCalendarUnitHour,
NSCalendarUnitMinute = kCFCalendarUnitMinute,
NSCalendarUnitSecond = kCFCalendarUnitSecond,
NSCalendarUnitWeekday = kCFCalendarUnitWeekday,
NSCalendarUnitWeekdayOrdinal = kCFCalendarUnitWeekdayOrdinal,
我在開發(fā)中需要在某一天按照周重復(fù)來提醒用戶渺绒,選擇的是NSCalendarUnitWeekdayOrdinal(不知道為什么不是選擇NSCalendarUnitWeekday這個(gè)枚舉值)。userinfo這個(gè)字典屬性:可以用來放這個(gè)通知的id(自己生成),在取消通知的時(shí)候根據(jù)該id值判斷是否為需求取消的宗兼。
iOS10later:iOS發(fā)送通知?jiǎng)t簡(jiǎn)單很多躏鱼,通過UNNotificationTrigger的子類UNTimeIntervalNotificationTrigger;UNCalendarNotificationTrigger殷绍;UNLocationNotificationTrigger三個(gè)類染苛,根據(jù)需求來構(gòu)造出本地通知。
UNTimeIntervalNotificationTrigger:+ (instancetype)triggerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats;
這個(gè)方法構(gòu)造主到,不過只有timeintercal茶行,而沒有firedate,猜想應(yīng)該是當(dāng)前時(shí)間(還沒有驗(yàn)證)镰烧;我在開發(fā)中用到的是UNCalendarNotificationTrigger:它需要一個(gè)NSDateComponents對(duì)象,來指定起飛時(shí)間楞陷,這個(gè)可以借助NSCalendar怔鳖,這個(gè)對(duì)象根據(jù)發(fā)送通知的時(shí)間來構(gòu)造出NSDateComponents:
static dispatch_once_t onceToken;
static NSCalendar *calender;
dispatch_once(&onceToken, ^{
calender = [NSCalendar currentCalendar];
});
NSDateComponents *compen = [calender components:NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitMonth fromDate:alertDate];
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:compen repeats:YES];//repeats決定是否重復(fù)
到這里是否有疑問間隔如何設(shè)置,其實(shí)也是借助datecompent這個(gè)對(duì)象固蛾,比如你想要設(shè)置每天八點(diǎn)结执,只需要trigger.dateComponents.houre = 8;就可以達(dá)到天重復(fù),對(duì)于周重復(fù)艾凯,設(shè)置weekday這個(gè)屬性即可(這也是對(duì)于iOS10以后通知間隔不是選擇NSCalendarUnitWeekday疑惑所在献幔,注意NSDateComponents是一個(gè)深拷貝對(duì)象,需要trigger.dateComponents.weekday = x;)趾诗。很重要一點(diǎn)對(duì)于iOS10可以查看nextfiredate來檢查是否正確蜡感,對(duì)iOS10er可以輸出locationnotifation這個(gè)對(duì)象,也可以查看下個(gè)觸發(fā)點(diǎn)恃泪。
UNMutableNotificationContent:決定了通知如何顯示:到這里我們就可以構(gòu)造出一個(gè)請(qǐng)求對(duì)象了:
UNNotificationRequest [UNNotificationRequest requestWithIdentifier:remindArray[i] content:content trigger:trigger];//得到request就可以拿UNUserNotificationCenter這個(gè)對(duì)象來發(fā)送了
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"week:%ld hour:%ld minute:%ld remindid:%@",(long)trigger.dateComponents.weekday, (long)trigger.dateComponents.hour,(long)trigger.dateComponents.minute,remindArray[i]);
NSLog(@"通知已經(jīng)成功添加");
}
}];
取消通知:iOS10later:
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removePendingNotificationRequestsWithIdentifiers:identArray];
iOS10er:
NSArray *array = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *local in array) {
NSString *notiString = local.userInfo[kidentifier];
BOOL find = NO;
for (NSString *identfil in identArray) {
if ([identfil isEqualToString:notiString]) {
find = YES;
break;
} else
continue;
}
if (find) {
[findArray addObject:local];
}
}
for (UILocalNotification *local in findArray) {
[[UIApplication sharedApplication] cancelLocalNotification:local];
NSLog(@"取消本地通知...%@",local.userInfo[kidentifier]);
}
在收到通知不同系統(tǒng)版本處理
<iOS10:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
NSLog(@"接收到本地通知");
// 通過UI控件來測(cè)試.當(dāng)App徹底退出時(shí), 用戶點(diǎn)擊通知, 打開APP , 會(huì)不會(huì)調(diào)用這個(gè)方法
// UISwitch *sw = [[UISwitch alloc] init];
// [self.window.rootViewController.view addSubview:sw];
// 查看當(dāng)前的狀態(tài)出于(前臺(tái): 0)/(后臺(tái): 2)/(從后臺(tái)進(jìn)入前臺(tái): 1)
NSLog(@"applicationState.rawValue: %zd", application.applicationState);
// 執(zhí)行響應(yīng)操作
// 如果當(dāng)前App在前臺(tái),執(zhí)行操作
if (application.applicationState == UIApplicationStateActive) {
UIAlertView *alerview = [[UIAlertView alloc] initWithTitle:notification.alertTitle message:notification.alertBody delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alerview show];
// [MBProgressHUD showSuccess:notification.alertBody];
NSLog(@"執(zhí)行前臺(tái)對(duì)應(yīng)的操作");
} else if (application.applicationState == UIApplicationStateInactive) {
// 后臺(tái)進(jìn)入前臺(tái)
NSLog(@"執(zhí)行后臺(tái)進(jìn)入前臺(tái)對(duì)應(yīng)的操作");
//NSLog(@"%@", notification.userInfo);
} else {
// 當(dāng)前App在后臺(tái)
NSLog(@"執(zhí)行后臺(tái)對(duì)應(yīng)的操作");
}
}
>=iOS10:iOS10以后通知管理更加方便郑兴,不管遠(yuǎn)程還是本地都通過走兩個(gè)方法,一個(gè)是在前臺(tái)收到通知贝乎,以及在后臺(tái)收到通知情连,方法如下
//前臺(tái)接收通知時(shí)
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
UNNotificationRequest *requst = notification.request;
UNNotificationContent *content = requst.content;
NSDictionary *userInfo = content.userInfo;
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"iOS 10 收到遠(yuǎn)端通知");
} else {
NSLog(@"iOS 收到本地通知");
}
//執(zhí)行這個(gè)方法,處于前臺(tái)的app才可以顯示通知览效,類型可以選擇
completionHandler(UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
completionHandler();
}