iOS 推送通知

一、 本地推送

1-1 本地推送逻辑

UNNotificationContent//推送内容
    推送内容
    标题/副标题/提醒/声音...

UNNotificationTrigger //推送触发者
    UNPushNotificationTrigger
    UNTimeIntervalNotificationTrigger //时间间隔触发器
    UNCalendarNotificationTrigger //日历触发器
    UNLocationNOtificationTrigger //位置触发器

UNNotificationRequest 
    封装Content 和 Trigger为统一格式
    交给NotificationCenter处理

UNUserNotificationCenter
    处理推送权限
    接收和移除NotificationRequest

UNUserNotificationCenterDelegate
    即将展示推送的处理
    用户进行交互行为的处理

1-2 实现本地推送

#import "GTNotifation.h"
#import <UserNotifications/UserNotifications.h>
@interface GTNotifation()<UNUserNotificationCenterDelegate>
@end
  
@implementation GTNotifation
  
+ (GTNotifation *)notificationManager{ //设置单例
  static GTNotifation *manager;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    manager = [[GTNotifation alloc] init];
  });
  return manager;
}

/// 检查申请用户通知权限
- (void)checkNotificationAuthorization{
  
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:UNAuthorizationOptionBadge|UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if(granted){
            [self _pushLocalNotification];//触发一次推送
        }
    }];
}

/// 发送推送消息
-(void)_pushLocalNotification{
  
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.badge = @(1);
    content.title = @"标题";
    content.body = @"内容";
  
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval: 30.f repeats:NO];//30秒后;不重复触发
  
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"_pushLocalNotification" content: content trigger: trigger];
  
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError *_Nullable error){
    
  }];
}

#pragma mark - UNUserNotificationCenterDelegate
/// 将要展示通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
    
    completionHandler(UNNotificationPresentationOptionAlert); //调用本地需要把Alert展示出来
}

/// 收到了通知--用户点击通知来到这里
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{
    
    //处理业务逻辑: 比如跳转页面
    completionHandler();//调用系统的完成方法
}

@end

二、远程推送

1-1、APNs

APNs : Apple Push Notification services
 
 APNs的作用:
    防止每个App都要维持连接
    保证连接带来安全性和性能的挑战
 
 推送的流程
    App 发送 UDID和BundleID 给APNs, 生成deviceToken
    App 发送deviceToken 给服务器
    服务器将信息和设备 deviceToken 发送给APNs
    APNs 根据 deviceToken 进行推送
 
 与本地推送不同:
    推送数据不是由本地代码生成
        代码中只需要接收和处理通知--UNUserNotificationCenterDelegate
 
    需要服务器与APNs配合进行推送
        证书的配置/Capabilities配置--后续的证书课程详细讲解
        注册DeviceToken
            注册获得DeviceToken
            registerForRemoteNotifications
            UIApplicationDelete 回调注册结果
 
 推送服务基本流程:
    本地: 权限申请--> 生成Content、选择Trigger、生成Request-->接收处理-->业务层回调
    远程: 权限申请--> 远程推送注册-->APNs + 系统-->接收处理-->业务层回调
 
 第三方的推送平台
    极光推送/信鸽推送
    无须自己维护后台/全平台(Android)

1-2 实现远程推送

✅在自定义的GTNotifation.m中:
#import "GTNotifation.h"
#import <UserNotifications/UserNotifications.h>
@interface GTNotifation()<UNUserNotificationCenterDelegate>
@end
  
@implementation GTNotifation
  
+ (GTNotifation *)notificationManager{ //设置单例
  static GTNotifation *manager;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    manager = [[GTNotifation alloc] init];
  });
  return manager;
}

/// 检查申请用户通知权限
- (void)checkNotificationAuthorization{
      UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:UNAuthorizationOptionBadge|UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if(granted){
            //必须要在主线程执行, 获取deviceToken
            dispatch_async(dispatch_get_main_queue(), ^{
                //(向远程推送注册deviceToken)向苹果的远程服务器APNs进行请求deviceToken
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            });
            //我把deviceToken传给我们服务器, 我们服务器需要用这个deviceToken来告诉 苹果的APNs具体有哪些设备需要接收这条远程推送.
        }
    }];
}
/*可以用开源软件"Pusher"来模拟远程push:
    在项目"Capabilities"-->开启"Push Notification"
    注意:远程推送的内容需要Json的格式
        选择推送证书
        deviceToken
        {"aps":{"alert:"推送标题","badge":1,"sound":"default"}}
*/
#pragma mark - UNUserNotificationCenterDelegate
/// 将要展示通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{

    completionHandler(UNNotificationPresentationOptionAlert); //调用本地需要把Alert展示出来
}

/// 收到了通知--用户点击通知来到这里
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{

    //处理业务逻辑: 比如跳转页面
    completionHandler();//调用系统的完成方法
}

✅在AppDelegate.m中:
#pragma mark - UIApplicationDelegate

/// 远程推送服务器注册成功的回调, 并返回deviceToken
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    
    //GTNotifation中实现
}
/// 远程推送服务器注册失败的回调
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    
}

/*总结:
远程推送证书&代码实现:
    注册Token/自定义发送
    接收推送消息进行业务处理
    
远程推送内容:
    Json数据格式
    https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingNotificationPayload.html
    
远程推送调试工具:
    Pusher
    搭建自己的服务器平台
*/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 人有生死。我有,我父母也有。 很快,我就要30了,我将要步入中年,担负起赡养的重担。在那之后,我讲不仅仅是我自己。...
    木槿无声阅读 431评论 0 0
  • 今晨,送走了令人瑟瑟发抖的严寒冻雨,迎来了阳光明媚风正好。欣喜上天的赐予,早早提前出门上班,途经的公园林荫...
    枫林醉晚阅读 334评论 0 3
  • 每个人的战争之抗癌食物 1. 橄榄油、菜籽油和亚麻籽油。 2. 绿茶可阻止组织入侵和血管生成。 3. 姜黄。由姜黄...
    风清扬大侠阅读 839评论 0 0
  • 最近跟老公讨论过一个问题:假如你知道一家商店的服务很差劲,但是你必须买的东西只能从这家店购买,你是去这家店买呢,还...
    静斋看雪阅读 173评论 0 1