245 lines
9.5 KiB
Objective-C
245 lines
9.5 KiB
Objective-C
//
|
||
// NTESNotificationCenter.m
|
||
// NIM
|
||
//
|
||
// Created by Xuhui on 15/3/25.
|
||
// Copyright (c) 2015年 Netease. All rights reserved.
|
||
//
|
||
|
||
#import "NTESNotificationCenter.h"
|
||
#import "NTESVideoChatViewController.h"
|
||
#import "NTESAudioChatViewController.h"
|
||
//#import "NTESMainTabController.h"
|
||
//#import "NTESSessionViewController.h"
|
||
|
||
#import "IfishSessionViewController.h"
|
||
#import "IfishMianTabViewController.h"
|
||
#import "NSDictionary+NTESJson.h"
|
||
#import "NTESCustomNotificationDB.h"
|
||
#import "NTESCustomNotificationObject.h"
|
||
#import "Toast+UIView.h"
|
||
#import "NTESWhiteboardViewController.h"
|
||
#import "NTESCustomSysNotificationSender.h"
|
||
#import "NTESGlobalMacro.h"
|
||
#import <AVFoundation/AVFoundation.h>
|
||
#import "NTESLiveViewController.h"
|
||
#import "NTESSessionMsgConverter.h"
|
||
#import "NTESSessionUtil.h"
|
||
|
||
NSString *NTESCustomNotificationCountChanged = @"NTESCustomNotificationCountChanged";
|
||
|
||
@interface NTESNotificationCenter () <NIMSystemNotificationManagerDelegate,NIMNetCallManagerDelegate,NIMRTSManagerDelegate,NIMChatManagerDelegate>
|
||
|
||
@property (nonatomic,strong) AVAudioPlayer *player; //播放提示音
|
||
|
||
@end
|
||
|
||
@implementation NTESNotificationCenter
|
||
|
||
+ (instancetype)sharedCenter
|
||
{
|
||
static NTESNotificationCenter *instance = nil;
|
||
static dispatch_once_t onceToken;
|
||
dispatch_once(&onceToken, ^{
|
||
instance = [[NTESNotificationCenter alloc] init];
|
||
});
|
||
return instance;
|
||
}
|
||
|
||
- (void)start
|
||
{
|
||
|
||
}
|
||
|
||
- (instancetype)init {
|
||
self = [super init];
|
||
if(self) {
|
||
NSURL *url = [[NSBundle mainBundle] URLForResource:@"message" withExtension:@"wav"];
|
||
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
|
||
|
||
[[NIMSDK sharedSDK].systemNotificationManager addDelegate:self];
|
||
[[NIMAVChatSDK sharedSDK].netCallManager addDelegate:self];
|
||
[[NIMAVChatSDK sharedSDK].rtsManager addDelegate:self];
|
||
[[NIMSDK sharedSDK].chatManager addDelegate:self];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
|
||
- (void)dealloc{
|
||
[[NIMSDK sharedSDK].systemNotificationManager removeDelegate:self];
|
||
[[NIMAVChatSDK sharedSDK].netCallManager removeDelegate:self];
|
||
[[NIMAVChatSDK sharedSDK].rtsManager removeDelegate:self];
|
||
[[NIMSDK sharedSDK].chatManager removeDelegate:self];
|
||
}
|
||
|
||
#pragma mark - NIMChatManagerDelegate
|
||
- (void)onRecvMessages:(NSArray *)messages
|
||
{
|
||
static BOOL isPlaying = NO;
|
||
if (isPlaying) {
|
||
return;
|
||
}
|
||
isPlaying = YES;
|
||
[self playMessageAudioTip];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
isPlaying = NO;
|
||
});
|
||
}
|
||
|
||
- (void)playMessageAudioTip
|
||
{
|
||
UINavigationController *nav = [IfishMianTabViewController instance].selectedViewController;
|
||
BOOL needPlay = YES;
|
||
for (UIViewController *vc in nav.viewControllers) {
|
||
if ([vc isKindOfClass:[NIMSessionViewController class]] || [vc isKindOfClass:[NTESLiveViewController class]])
|
||
{
|
||
needPlay = NO;
|
||
break;
|
||
}
|
||
}
|
||
if (needPlay) {
|
||
[self.player stop];
|
||
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error:nil];
|
||
[self.player play];
|
||
}
|
||
}
|
||
|
||
- (void)onMessageRevoked:(NIMMessage *)message
|
||
{
|
||
NIMMessage *tip = [NTESSessionMsgConverter msgWithTip:[NTESSessionUtil tipOnMessageRevoked:message]];
|
||
NIMMessageSetting *setting = [[NIMMessageSetting alloc] init];
|
||
setting.shouldBeCounted = NO;
|
||
tip.setting = setting;
|
||
|
||
IfishMianTabViewController *tabVC = [IfishMianTabViewController instance];
|
||
UINavigationController *nav = tabVC.selectedViewController;
|
||
|
||
for (IfishSessionViewController *vc in nav.viewControllers) {
|
||
if ([vc isKindOfClass:[IfishSessionViewController class]]
|
||
&& [vc.session.sessionId isEqualToString:message.session.sessionId]) {
|
||
NIMMessageModel *model = [vc uiDeleteMessage:message];
|
||
tip.timestamp = model.messageTime;
|
||
[vc uiAddMessages:@[tip]];
|
||
break;
|
||
}
|
||
}
|
||
|
||
tip.timestamp = message.timestamp;
|
||
// saveMessage 方法执行成功后会触发 onRecvMessages: 回调,但是这个回调上来的 NIMMessage 时间为服务器时间,和界面上的时间有一定出入,所以要提前先在界面上插入一个和被删消息的界面时间相符的 Tip, 当触发 onRecvMessages: 回调时,组件判断这条消息已经被插入过了,就会忽略掉。
|
||
[[NIMSDK sharedSDK].conversationManager saveMessage:tip forSession:message.session completion:nil];
|
||
}
|
||
|
||
|
||
#pragma mark - NIMSystemNotificationManagerDelegate
|
||
- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification{
|
||
|
||
NSString *content = notification.content;
|
||
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
|
||
if (data)
|
||
{
|
||
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
|
||
options:0
|
||
error:nil];
|
||
if ([dict isKindOfClass:[NSDictionary class]])
|
||
{
|
||
if ([dict jsonInteger:NTESNotifyID] == NTESCustom)
|
||
{
|
||
//SDK并不会存储自定义的系统通知,需要上层结合业务逻辑考虑是否做存储。这里给出一个存储的例子。
|
||
NTESCustomNotificationObject *object = [[NTESCustomNotificationObject alloc] initWithNotification:notification];
|
||
//这里只负责存储可离线的自定义通知,推荐上层应用也这么处理,需要持久化的通知都走可离线通知
|
||
if (!notification.sendToOnlineUsersOnly) {
|
||
[[NTESCustomNotificationDB sharedInstance] saveNotification:object];
|
||
}
|
||
if (notification.setting.shouldBeCounted) {
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:NTESCustomNotificationCountChanged object:nil];
|
||
}
|
||
NSString *content = [dict jsonString:NTESCustomContent];
|
||
[[IfishMianTabViewController instance].selectedViewController.view makeToast:content];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#pragma mark - NIMNetCallManagerDelegate
|
||
- (void)onReceive:(UInt64)callID from:(NSString *)caller type:(NIMNetCallType)type message:(NSString *)extendMessage{
|
||
|
||
IfishMianTabViewController *tabVC = [IfishMianTabViewController instance];
|
||
[tabVC.view endEditing:YES];
|
||
UINavigationController *nav = tabVC.selectedViewController;
|
||
|
||
if ([self shouldResponseBusy]){
|
||
[[NIMAVChatSDK sharedSDK].netCallManager control:callID type:NIMNetCallControlTypeBusyLine];
|
||
}
|
||
else {
|
||
UIViewController *vc;
|
||
switch (type) {
|
||
case NIMNetCallTypeVideo:{
|
||
vc = [[NTESVideoChatViewController alloc] initWithCaller:caller callId:callID];
|
||
}
|
||
break;
|
||
case NIMNetCallTypeAudio:{
|
||
vc = [[NTESAudioChatViewController alloc] initWithCaller:caller callId:callID];
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if (!vc) {
|
||
return;
|
||
}
|
||
|
||
//由于音视频聊天里头有音频和视频聊天界面的切换,直接用present的话页面过渡会不太自然,这里还是用push,然后做出present的效果
|
||
CATransition *transition = [CATransition animation];
|
||
transition.duration = 0.25;
|
||
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
|
||
transition.type = kCATransitionPush;
|
||
transition.subtype = kCATransitionFromTop;
|
||
transition.delegate = self;
|
||
[nav.view.layer addAnimation:transition forKey:nil];
|
||
nav.navigationBarHidden = YES;
|
||
[nav pushViewController:vc animated:NO];
|
||
}
|
||
|
||
}
|
||
|
||
- (void)onRTSRequest:(NSString *)sessionID
|
||
from:(NSString *)caller
|
||
services:(NSUInteger)types
|
||
message:(NSString *)info
|
||
{
|
||
IfishMianTabViewController *tabVC = [IfishMianTabViewController instance];
|
||
|
||
[tabVC.view endEditing:YES];
|
||
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
if ([self shouldResponseBusy]) {
|
||
[[NIMAVChatSDK sharedSDK].rtsManager responseRTS:sessionID accept:NO option:nil completion:nil];
|
||
}
|
||
else {
|
||
NTESWhiteboardViewController *vc = [[NTESWhiteboardViewController alloc] initWithSessionID:sessionID
|
||
peerID:caller
|
||
types:types
|
||
info:info];
|
||
if (tabVC.presentedViewController) {
|
||
__weak IfishMianTabViewController *wtabVC = (IfishMianTabViewController *)tabVC;
|
||
[tabVC.presentedViewController dismissViewControllerAnimated:NO completion:^{
|
||
[wtabVC presentViewController:vc animated:NO completion:nil];
|
||
}];
|
||
}else{
|
||
[tabVC presentViewController:vc animated:NO completion:nil];
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
- (BOOL)shouldResponseBusy
|
||
{
|
||
IfishMianTabViewController *tabVC = [IfishMianTabViewController instance];
|
||
UINavigationController *nav = tabVC.selectedViewController;
|
||
return [nav.topViewController isKindOfClass:[NTESNetChatViewController class]] || [tabVC.presentedViewController isKindOfClass:[NTESWhiteboardViewController class]];
|
||
}
|
||
|
||
|
||
@end
|