环信实现本地及远程推送

图片来源环信开发者文档

  • 上图我们清晰的看到,推送的原理及流程:

    当App在前台:
    程序正在运行中,环信SDK处于活跃状态,
    此时客户端是通过长连接接收消息;

    当App进入后台,且在两分钟之内:
    此时程序仍处于活跃状态,SDK也处于活跃状态,
    客户端通过SDK长连接接收消息,
    此时根据需要实现本地通知,如果不实现,则不会出现通知消息提示;

    当App进入后台超过两分钟,会被系统挂起,或者主动杀死App:
    此时App都是处于不活跃状态,环信SDK长连接断开,
    客户端无法通过长连接接收消息,
    此时,新消息是通过苹果的 APNs 服务进行提醒的,
    并且在App再次启动时,环信SDK主动拉取不活跃期间的消息.

  • 注册环信通知

      ///注册APNS 支持iOS 8.0 及以上
      - (void)registerRemoteNotification {
      	//UNUserNotificationCenter 10.0以上API
      	if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
      		UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
      		center.delegate = self;
      		[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
          		if (!error) {
              		NSLog(@"request authorization succeeded!");
              		NSLog(@"通知注册成功");
              		dispatch_async(dispatch_get_main_queue(), ^{
                  		[[UIApplication sharedApplication] registerForRemoteNotifications];
              		});
          		}
      		}];
      	} else {
      		if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
      			//注册推送, 用于iOS8以及iOS8之后的系统
      			UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
      			[application registerUserNotificationSettings:settings];
      		} 
      	}
     }
     //iOS8需要实现方法	
     - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
     	[application registerForRemoteNotifications];
     }
    
  • 注册deviceToken

      //将得到的deviceToken传给SDK
      - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
      	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      		[[EMClient sharedClient] bindDeviceToken:deviceToken];
      	});
      }
    
      // 注册deviceToken失败,此处失败,与环信SDK无关,一般是您的环境配置或者证书配置有误
      - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
      }
    
  • App进入前后台

      // APP进入后台
      - (void)applicationDidEnterBackground:(UIApplication*)application{
      	[[EMClient sharedClient] applicationDidEnterBackground:application];
      }
      // APP将要从后台返回
      - (void)applicationWillEnterForeground:(UIApplication*)application{
      	[[EMClient sharedClient]applicationWillEnterForeground:application];
      }
    
  • 发送本地通知

      //环信接收到消息的回调
      - (void)messagesDidReceive:(NSArray *)aMessages {//环信SDK收到消息的回调
      	for (EMMessage *msg in aMessages) {
          UIApplicationState state = [[UIApplication sharedApplication] applicationState];
          // App在后台
          if (state == UIApplicationStateBackground) {
              //发送本地推送
              if (NSClassFromString(@"UNUserNotificationCenter")) { 
              	// ios 10
              	// 设置触发时间
              	UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
              	UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
              	content.sound = [UNNotificationSound defaultSound];
              	// 提醒,可以根据需要进行弹出,比如显示消息详情,或者是显示“您有一条新消息”
              	content.body = @"提醒内容";
              	UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:msg.messageId content:content trigger:trigger];
              	[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
              } else {
              	UILocalNotification *notification = [[UILocalNotification alloc] init];
              	notification.fireDate = [NSDate date]; //触发通知的时间
              	notification.alertBody = @"提醒内容";
              	notification.alertAction = @"Open";
              	notification.timeZone = [NSTimeZone defaultTimeZone];
              	notification.soundName = UILocalNotificationDefaultSoundName;
              	[[UIApplication sharedApplication] scheduleLocalNotification:notification];
              }
           }
      	}
      }
    
  • 本地及远程通知处理

    • 1.iOS10.0以下

        #pragma mark --- //iOS 7 及以上10以下 收到推送及点击处理
        //此时为本地推送,App处于后台切活跃状态
        - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
        	[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
        	// 处于后台的点击,此时活跃状态
        	[self PushHandleBackgroundNotification:userInfo];
        	completionHandler(UIBackgroundFetchResultNewData);
        }
      
        /// MARK: 处理后台通知 (10以下)
        - (void)PushHandleBackgroundNotification:(NSDictionary *)userInfo {
        	[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
        }
        
        //当App处于不活跃状态或者杀死状态
        //此时iOS是不允许直接得到APNs内容的,
        //但是当用户点击推送的提示栏,此时是可以在didFinishLaunchingWithOptions:方法中获取
        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        	if (launchOptions !=nil) {// 不是空 就是推送点击 否则是图标启动
        		NSDictionary* remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        		if (remoteNotification) {
        			if ([[UIDevice currentDevice].systemVersion floatValue] < 10.0) {
            			// iOS 10 不必走此方法
            		}
            	}
           }
        }
      
    • 2.iOS10.0及以上

        //iOS 10.0及以上:
        //App处于后台活跃
        //或者App处于后台不活跃
        //或者App被杀死时,调用此方法
        -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
      
        	NSDictionary * userInfo = response.notification.request.content.userInfo;
        	if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        		//远程推送处理
        	} else {
        		// 判断为本地通知
        	}
        	completionHandler();  // 系统要求执行这个方法
        }
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值