Files
peko-ios/YuMi/Modules/YMRoom/Manager/PublicRoomManager.m

348 lines
11 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// PublicRoomManager.m
// YUMI
//
// Created by YUMI on 2024/12/19.
//
#import "PublicRoomManager.h"
#import "UserInfoModel.h"
#import "ClientConfig.h"
#import "AccountInfoStorage.h"
#import "XPMessageRemoteExtModel.h"
@interface PublicRoomManager () <NIMChatManagerDelegate>
@property (nonatomic, assign) BOOL isInitialized;
@property (nonatomic, assign) BOOL isInPublicRoom;
@property (nonatomic, copy) NSString *currentPublicRoomId;
@property (nonatomic, copy) NSString *currentUserId;
@property (nonatomic, strong) UserInfoModel *userInfo;
@end
@implementation PublicRoomManager
#pragma mark - 单例方法
+ (instancetype)sharedManager {
static dispatch_once_t onceToken;
static PublicRoomManager *instance;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
[instance initialize];
});
return instance;
}
- (instancetype)init {
self = [super init];
if (self) {
_isInitialized = NO;
_isInPublicRoom = NO;
_currentPublicRoomId = nil;
_currentUserId = nil;
_userInfo = nil;
}
return self;
}
#pragma mark - 生命周期管理
- (void)initialize {
// 防止重复初始化
if (self.isInitialized) {
NSLog(@"PublicRoomManager: 已经初始化,跳过重复初始化");
return;
}
// 检查用户是否已登录
// NSString *uid = [AccountInfoStorage instance].getUid;
// if (uid.length == 0) {
// NSLog(@"PublicRoomManager: 用户未登录,无法初始化");
// return;
// }
// 检查是否已获取到用户信息
// UserInfoModel *userInfo = [AccountInfoStorage instance].getHomeUserInfo;
// if (!userInfo || !userInfo.partitionId) {
// NSLog(@"PublicRoomManager: 用户信息不完整,等待用户信息更新");
// return;
// }
// 检查配置信息是否已加载
// ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo;
// if (!configInfo || !configInfo.publicChatRoomIdMap) {
// NSLog(@"PublicRoomManager: 配置信息未加载,等待配置更新");
// return;
// }
// 保存用户信息
// self.userInfo = userInfo;
// self.currentUserId = uid;
// 注册云信代理
[[NIMSDK sharedSDK].chatManager addDelegate:self];
// 标记为已初始化
self.isInitialized = YES;
// NSLog(@"PublicRoomManager: 初始化成功用户ID: %@, 分区ID: %@", uid, userInfo.partitionId);
// 尝试进入公共房间
// [self tryEnterPublicRoom];
}
- (void)reset {
NSLog(@"PublicRoomManager: 开始重置");
// 退出公共房间
if (self.isInPublicRoom && self.currentPublicRoomId) {
[self exitPublicRoomWithCompletion:^(NSError * _Nullable error) {
if (error) {
NSLog(@"PublicRoomManager: 退出公共房间失败: %@", error);
} else {
NSLog(@"PublicRoomManager: 退出公共房间成功");
}
}];
}
// 移除云信代理
[[NIMSDK sharedSDK].chatManager removeDelegate:self];
// 重置状态
self.isInitialized = NO;
self.isInPublicRoom = NO;
self.currentPublicRoomId = nil;
self.currentUserId = nil;
self.userInfo = nil;
NSLog(@"PublicRoomManager: 重置完成");
}
#pragma mark - 状态查询
- (BOOL)isInitialized {
return _isInitialized;
}
- (BOOL)isInPublicRoom {
return _isInPublicRoom;
}
- (NSString *)currentPublicRoomId {
return _currentPublicRoomId;
}
#pragma mark - 私有方法
- (void)tryEnterPublicRoom {
if (!self.isInitialized || !self.userInfo) {
NSLog(@"PublicRoomManager: 未初始化或用户信息缺失,无法进入公共房间");
return;
}
// 获取公共房间ID
NSString *partitionId = self.userInfo.partitionId;
ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo;
NSDictionary *publicChatRoomIdMap = configInfo.publicChatRoomIdMap;
if (!publicChatRoomIdMap || !partitionId) {
NSLog(@"PublicRoomManager: 公共房间配置或分区ID缺失");
return;
}
NSNumber *roomId = publicChatRoomIdMap[partitionId];
if (!roomId) {
NSLog(@"PublicRoomManager: 未找到分区 %@ 对应的公共房间ID", partitionId);
return;
}
NSLog(@"PublicRoomManager: 尝试进入公共房间分区ID: %@, 房间ID: %@", partitionId, roomId);
// 进入公共房间
[self enterPublicRoomWithRoomId:roomId.stringValue completion:^(NSError * _Nullable error) {
if (error) {
NSLog(@"PublicRoomManager: 进入公共房间失败: %@", error);
} else {
NSLog(@"PublicRoomManager: 进入公共房间成功");
}
}];
}
- (void)enterPublicRoomWithRoomId:(NSString *)roomId completion:(void(^)(NSError * _Nullable error))completion {
if (!self.userInfo) {
NSError *error = [NSError errorWithDomain:@"PublicRoomManager"
code:-1
userInfo:@{NSLocalizedDescriptionKey: @"用户信息缺失"}];
if (completion) {
completion(error);
}
return;
}
// 创建进房请求
NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init];
request.roomId = roomId;
// 设置扩展信息
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
extModel.defUser = self.userInfo.defUser;
extModel.erbanNo = self.userInfo.erbanNo;
extModel.carName = self.userInfo.carName;
extModel.inRoomNameplatePic = self.userInfo.nameplatePic;
extModel.inRoomNameplateWord = self.userInfo.nameplateWord;
extModel.isCustomWord = self.userInfo.isCustomWord;
extModel.charmUrl = self.userInfo.userLevelVo.charmUrl;
extModel.experLevelSeq = self.userInfo.userLevelVo.experLevelSeq;
extModel.experUrl = self.userInfo.userLevelVo.experUrl;
extModel.newUser = self.userInfo.newUser;
extModel.vipIcon = self.userInfo.userVipInfoVO.nameplateUrl;
extModel.iosBubbleUrl = self.userInfo.iosBubbleUrl;
extModel.androidBubbleUrl = self.userInfo.androidBubbleUrl;
extModel.enterHide = self.userInfo.userVipInfoVO.enterHide;
extModel.preventKick = self.userInfo.userVipInfoVO.preventKick;
extModel.enterRoomEffects = self.userInfo.userVipInfoVO.enterRoomEffects;
extModel.gender = self.userInfo.gender;
extModel.fromSayHelloChannel = self.userInfo.fromSayHelloChannel;
extModel.platformRole = self.userInfo.platformRole;
extModel.nick = self.userInfo.nick;
NSMutableDictionary *ext = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary
forKey:[NSString stringWithFormat:@"%ld", self.userInfo.uid]];
request.roomExt = [ext toJSONString];
// 进入房间
@kWeakify(self);
[[NIMSDK sharedSDK].chatroomManager enterChatroom:request completion:^(NSError * _Nullable error, NIMChatroom * _Nullable chatroom, NIMChatroomMember * _Nullable me) {
@kStrongify(self);
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"PublicRoomManager: 进入公共房间失败: %@", error);
if (completion) {
completion(error);
}
} else {
NSLog(@"PublicRoomManager: 进入公共房间成功房间ID: %@", roomId);
self.isInPublicRoom = YES;
self.currentPublicRoomId = roomId;
if (completion) {
completion(nil);
}
}
});
}];
}
#pragma mark - 手动控制
- (void)enterPublicRoomWithCompletion:(void(^)(NSError * _Nullable error))completion {
if (!self.isInitialized) {
NSError *error = [NSError errorWithDomain:@"PublicRoomManager"
code:-2
userInfo:@{NSLocalizedDescriptionKey: @"管理器未初始化"}];
if (completion) {
completion(error);
}
return;
}
if (self.isInPublicRoom) {
NSLog(@"PublicRoomManager: 已在公共房间中");
if (completion) {
completion(nil);
}
return;
}
[self tryEnterPublicRoom];
}
- (void)exitPublicRoomWithCompletion:(void(^)(NSError * _Nullable error))completion {
if (!self.isInPublicRoom || !self.currentPublicRoomId) {
NSLog(@"PublicRoomManager: 未在公共房间中");
if (completion) {
completion(nil);
}
return;
}
@kWeakify(self);
[[NIMSDK sharedSDK].chatroomManager exitChatroom:self.currentPublicRoomId completion:^(NSError * _Nullable error) {
@kStrongify(self);
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"PublicRoomManager: 退出公共房间失败: %@", error);
} else {
NSLog(@"PublicRoomManager: 退出公共房间成功");
self.isInPublicRoom = NO;
self.currentPublicRoomId = nil;
}
if (completion) {
completion(error);
}
});
}];
}
#pragma mark - 用户信息更新处理
- (void)updateUserInfo:(UserInfoModel *)userInfo {
if (!userInfo || !userInfo.partitionId) {
NSLog(@"PublicRoomManager: 用户信息更新失败,信息不完整");
return;
}
// 检查用户是否切换
if (self.currentUserId && ![self.currentUserId isEqualToString:[NSString stringWithFormat:@"%ld", userInfo.uid]]) {
NSLog(@"PublicRoomManager: 检测到用户切换,重置管理器");
[self reset];
}
self.userInfo = userInfo;
self.currentUserId = [NSString stringWithFormat:@"%ld", userInfo.uid];
// 如果已初始化但未在公共房间,尝试进入
if (self.isInitialized && !self.isInPublicRoom) {
[self tryEnterPublicRoom];
}
}
#pragma mark - 配置更新处理
- (void)updateConfig {
if (!self.isInitialized) {
NSLog(@"PublicRoomManager: 未初始化,跳过配置更新");
return;
}
ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo;
if (!configInfo || !configInfo.publicChatRoomIdMap) {
NSLog(@"PublicRoomManager: 配置信息不完整,跳过配置更新");
return;
}
// 如果未在公共房间,尝试进入
if (!self.isInPublicRoom) {
[self tryEnterPublicRoom];
}
}
#pragma mark - NIMChatManagerDelegate
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
// 只处理公共房间的消息
for (NIMMessage *message in messages) {
if (message.session.sessionType == NIMSessionTypeChatroom) {
NSString *sessionId = message.session.sessionId;
if ([sessionId isEqualToString:self.currentPublicRoomId]) {
NSLog(@"PublicRoomManager: 收到公共房间消息: %@", message.text);
// 这里可以添加公共房间消息的处理逻辑
// TODO: 全服广播转移到此类
}
}
}
}
@end