iOS开发-本地通知与远程通知

App开发中经常会使用到推送,苹果和安卓区别是苹果用自己的APNS推送服务器,不论我们是集成第三方推送 

还是用苹果系统的推送都要经过APNS推送服务器。

目前市场上比较流行的几个第三方推送:

1.极光推送 (使用较多,但是偶尔会出现crash,crash定位在jPush SDK没法解决,会出现推送延迟的情况)

2.阿里云推送(推出时间较短,目前可能会出现一些问题,支持全量推送、设备号推送、账号推送,注意阿里云推送推送消息和推送通知走的是两个不同的接口,

同时支持通知和应用内消息推送,api多语言,接口灵活)

3.腾讯推送(性能上还是可以的,因为项目是选择用的极光,腾讯推送没有经过实际大批量的验证,以后用到了会进行补充)

4.百度云推送(免费、不稳定,设备绑定时常失效,后台界面不易调用)

5.个推(10000台在线连接数(约为DAV的70%)以上收费、偶尔会不稳定)

6.友盟推送(免费、相对稳定的到达率,后台界面医用,可统计打开率(部分功能待优化)、可设置发送速度)

以上的厂商提供的推送服务,如果是中小型的项目免费的就可以,但是如果用户量比较大,还是建议使用

收费的推送,相对来说收费开通的通道和资源比较多,减少了很多不必要的问题 


推送和通知NSNotification 的区别 

1.NSNotification是系统内部发出的通知,一般用于内部事件的监听,或者状态的改变等、是不可见的(建议不要滥用NSNotification,因为是在主线程中执行,使用不当会发生线程阻塞)

2.本地通知与远程通知是可见的,主要用户告知用户或者发送一些App的内容更新,推送一些消息,让App知道App内部发生了什么事情。

iOS 常用的通知

1.本地推送通知:(Local Notification)

2.远程推送通知:(Remote Notification)

iOS中通知显示的效果

1.设置音效

2.设置横幅

3.设置弹窗 

4.锁屏下也可以呈现 

5.App图标的数字 (注意:显示弹窗或者横幅效果是取决于用户设置:通知中心-选择应用-选择下载的通知模式)

通知的注意点:

1.App在前台运行的时候,通知不会展示出来

2.点击通知,默认会自动打开推送通知的App 

3.不管App是否打开,通知都可以如期发出 

1、本地推送通知:

一.关于通知注册:

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进行区分

六:关于覆盖安装:

如果我们的应用程序给系统发送的本地通知是周期性的,那么即使把程序删了重装,之前的本地通知在重装时依然存在,没有从系统中移除


通知的一些属性:

// 枚举值-发出通知的时间(有局限性)
@property(nonatomic) NSCalendarUnit repeatInterval;
// 自定义-发出通知的时间(可以自由设定时间)
@property(nonatomic,copy) NSCalendar *repeatCalendar;
// 区域-创建只需要创建一个中心点与半径就可以了
@property(nonatomic,copy) CLRegion *region
// 进入区域发出一个通知,设置yes,只会发出一个通知,设置NO就会每次进入这个区域都发送
@property(nonatomic,assign) BOOL regionTriggersOnce NO
// 设置通知的内容
@property(nonatomic,copy) NSString *alertBody;      
 // 决定alertAction是否生效
@property(nonatomic) BOOL hasAction;
// 设置滑块的文字
@property(nonatomic,copy) NSString *alertAction;    
// 设置点击通知的启动图片(一般设置App启动图片后,这里可以随便写)
@property(nonatomic,copy) NSString *alertLaunchImage;
// 设置alertTitle,就是通知内容上面的文字
@property(nonatomic,copy) NSString *alertTitle
 // 设置弹出的声音
@property(nonatomic,copy) NSString *soundName;
 // 设置App的消息条数
@property(nonatomic) NSInteger applicationIconBadgeNumber;
 // 设置通知一些额外数据
 @property(nonatomic,copy) NSDictionary *userInfo;

如何发出本地通知:

 // 1.创建本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];

    // 2.设置本地通知的内容
    // 2.1.设置通知发出的时间
    localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
    // 2.2.设置通知的内容
    localNote.alertBody = @"Good Morning?";
    // 2.3.设置滑块的文字(锁屏状态下:滑动来“解锁”)
    localNote.alertAction = @"解锁";
    // 2.4.决定alertAction是否生效
    localNote.hasAction = NO;
    // 2.5.设置点击通知的启动图片
    localNote.alertLaunchImage = @"$$$$";
    // 2.6.设置alertTitle
    localNote.alertTitle = @"您有一条新通知";
    // 2.7.设置有通知时的音效
    localNote.soundName = @"buyao.wav";
    // 2.8.设置应用程序图标右上角的数字
    localNote.applicationIconBadgeNumber = 99;

    // 2.9.设置额外信息
    localNote.userInfo = @{@"type" : @1};

    // 3.调用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
}
使用注意:
iOS7,不需要用户授权就可发出通知,而iOS8以后,必须用户授权才可以发出通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 设置应用程序的图标右上角的数字
    [application setApplicationIconBadgeNumber:0];

    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
    }

    // 界面的跳转(针对应用程序被杀死的状态下的跳转)
    // 杀死状态下的,界面跳转并不会执行下面的方法- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification,
    // 所以我们在写本地通知的时候,要在这个与下面方法中写,但要判断,是通过哪种类型通知来打开的
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        // 跳转代码
        UILabel *redView = [[UILabel alloc] init];
        redView.frame = CGRectMake(0, 0, 200, 300);
        redView.numberOfLines = 0;
        redView.font = [UIFont systemFontOfSize:12.0];
        redView.backgroundColor = [UIColor redColor];
        redView.text = [NSString stringWithFormat:@"%@", launchOptions];
        [self.window.rootViewController.view addSubview:redView];
    }

    return YES;
}
监听通知,如果用户打开通知,可以让用户进入一些特定的界面
/*
 应用程序在进入前台,或者在前台的时候都会执行该方法
 */
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    // 必须要监听--应用程序在后台的时候进行的跳转
    if (application.applicationState == UIApplicationStateInactive) {
        NSLog(@"进行界面的跳转");
      // 如果在上面的通知方法中设置了一些,可以在这里打印额外信息的内容,就做到监听,也就可以根据额外信息,做出相应的判断
        NSLog(@"%@", notification.userInfo);

// 
        UIView *redView = [[UIView alloc] init];
        redView.frame = CGRectMake(0, 0, 100, 100);
        redView.backgroundColor = [UIColor redColor];
        [self.window.rootViewController.view addSubview:redView];
    }
}

2、远程推送通知:

远程推送服务APNS(Apple Push Notification Servers)
所有苹果设备在联网的情况下都会与苹果建立长连接
长连接:
1.只要联网就一直建立连接
2.长连接作用:1.时间校准2.系统升级3.查找我的iPhone等 
长连接的好处
1.数据传输速度快 
2.数据保持最新状态 
远程推送的基本过程
1.客户端app需要将用户的UUID和app的bundleID发送给apps服务器,进行注册,apps服务器将加密后的Device Token返回给app 
2.app获得Device Token后,上传到公司的服务器 
3.当需要推送通知时,公司的服务器会将推送内容和Device Token一起发给apns服务器 
4.apns 再将推送的内容推送给客户端 
客户端要做的事情
1.注册苹果获得Device Token 
2.得到苹果返回的Device Token 
3.发送Device Token给公司服务器 
4.监听用户通知的点击 
调试远程推送功能时,需要真机调试,模拟器接受不到远程通知
真机测试相关内容
1.创建apeid(不带*)
2.创建appid ssl 证书(获得一个调试证书,一个发布证书)
3.生成相应的描述文件 
4.安装相关证书 

为什么使用远程推送?
解决传统获取数据的局限性,让数据实时更新 
使用场景
聊天功能(非及时聊天)、推送版本下载、app活动、app内部新功能等 
iOS开发-本地通知与远程通知_第1张图片
iOS开发-本地通知与远程通知_第2张图片
iOS开发-本地通知与远程通知_第3张图片
如何推送
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { //iOS8
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];
    } else { // iOS7
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert];
    }

// 根据远程通知通过UIApplicationLaunchOptionsRemoteNotificationKey打开的情况来进行
    if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
        // 跳转
        // 添加一个红色的View
    }

    return YES;
}
// 获取DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // 将DeviceToken传给服务器
    NSLog(@"%@", deviceToken.description);
}
// 正常接到远程通知的时候会调用这个方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"%@", userInfo);
    // 正常打开推送后,
}
// 后台操作(根据收到推送,让程序自己执行一些操作,不管用户是否点击推送)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"---------");
    UIView *redV = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    redView.frame = CGRectMake(100, 100, 100, 100);
    [self.window.rootViewController.view addSubview:redV];

    // 1.打开后台模式 2.告诉系统是否有新内容的更新 3.发送的通知有固定的格式("content-available":"1")
    // 2.告诉系统有新内容
    completionHandler(UIBackgroundFetchResultNewData);
}
1、打开后台模式
在Capabilities中找到Background Modes 设置YES 
2、告诉系统有新内容
completionHandler(UIBackgroundFetchResultNewData);
3、发送通知有固定格式
("content-available":"1")

你可能感兴趣的:(iOS)