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
|