增加换肤功能

This commit is contained in:
启星
2025-08-14 10:07:49 +08:00
parent f6964c1e89
commit 4f9318d98e
8789 changed files with 978530 additions and 2 deletions

View File

@@ -0,0 +1,86 @@
//
// InviteToJoinRoomManager.swift
// TUIRoomKit
//
// Created by janejntang on 2023/7/3.
// You can choose to invite members and send invitations.
import Foundation
import RTCRoomEngine
import TUICore
class InviteToJoinRoomManager {
class func startInviteToJoinRoom(message: RoomMessageModel, inviter: TUILoginUserInfo) {
let inviteJoinModel = InviteJoinModel(message: message, inviter: inviter)
pushSelectGroupMemberViewController(groupId: message.groupId) { responseData in
guard let modelList =
responseData[TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_ResultUserList] as? [TUIUserModel]
else { return }
var invitedList: [String] = []
for userModel in modelList {
invitedList.append(userModel.userId)
}
inviteToJoinRoom(inviteJoinModel: inviteJoinModel, invitedList: invitedList)
}
}
class func pushSelectGroupMemberViewController(groupId: String, callback: @escaping TUIValueResultCallback) {
let param = [TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_GroupID: groupId]
if let navigateController = RoomMessageManager.shared.navigateController {
navigateController.push(TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Classic, param: param) { responseData in
callback(responseData)
}
} else {
let nav = UINavigationController()
let currentViewController = getCurrentWindowViewController()
currentViewController?.present(TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Classic,
param: param, embbedIn: nav,
forResult: { responseData in
callback(responseData)
})
}
}
class func inviteToJoinRoom(inviteJoinModel: InviteJoinModel, invitedList: [String]) {
guard invitedList.count > 0 else { return }
let dataDict = inviteJoinModel.getDicFromInviteJoinModel(inviteJoinModel: inviteJoinModel)
guard let dataString = dataDict.convertToString() else { return }
let pushInfo = V2TIMOfflinePushInfo()
invitedList.forEach { userId in
V2TIMManager.sharedInstance().invite(userId,
data: dataString,
onlineUserOnly: true,
offlinePushInfo: pushInfo,
timeout: 60) {
debugPrint("invite,success")
} fail: { code, message in
debugPrint("invite,code:\(code),message:\(String(describing: message))")
}
}
}
class private func getCurrentWindowViewController() -> UIViewController? {
var keyWindow: UIWindow?
for window in UIApplication.shared.windows {
if window.isMember(of: UIWindow.self), window.isKeyWindow {
keyWindow = window
break
}
}
guard let rootController = keyWindow?.rootViewController else {
return nil
}
func findCurrentController(from vc: UIViewController?) -> UIViewController? {
if let nav = vc as? UINavigationController {
return findCurrentController(from: nav.topViewController)
} else if let tabBar = vc as? UITabBarController {
return findCurrentController(from: tabBar.selectedViewController)
} else if let presented = vc?.presentedViewController {
return findCurrentController(from: presented)
}
return vc
}
let viewController = findCurrentController(from: rootController)
return viewController
}
}

View File

@@ -0,0 +1,125 @@
//
// RoomManager.swift
// TUIRoomKit
//
// Created by janejntang on 2023/7/3.
// Manage rooms, including room creation, entry, exit, destruction and conversion operations of the host
import Foundation
import RTCRoomEngine
import TUICore
class RoomManager {
static let shared = RoomManager()
private var engineManager: EngineManager {
EngineManager.shared
}
private var roomInfo: TUIRoomInfo {
engineManager.store.roomInfo
}
private lazy var userId: String = {
return TUILogin.getUserID() ?? engineManager.store.currentUser.userId
}()
private let messageManager = RoomMessageManager.shared
let roomObserver: RoomObserver = RoomObserver()
var roomId: String?
deinit {
debugPrint("deinit \(self)")
}
func isEnteredOtherRoom(roomId: String) -> Bool {
return roomInfo.roomId != roomId && roomInfo.roomId != ""
}
func createRoom(roomInfo: TUIRoomInfo) {
roomId = roomInfo.roomId
roomObserver.registerObserver()
engineManager.createRoom(roomInfo: roomInfo) { [weak self] in
guard let self = self else { return }
self.roomObserver.createdRoom()
self.enterRoom(roomId: roomInfo.roomId, isShownConferenceViewController: false)
} onError: { _, message in
RoomRouter.makeToast(toast: message)
}
}
func enterRoom(roomId: String, isShownConferenceViewController: Bool = true) {
roomObserver.registerObserver()
engineManager.store.isImAccess = true
self.roomId = roomId
engineManager.enterRoom(roomId: roomId, enableAudio: engineManager.store.isOpenMicrophone, enableVideo: engineManager.store.isOpenCamera, isSoundOnSpeaker: true) { [weak self] roomInfo in
guard let self = self else { return }
self.roomObserver.enteredRoom()
guard isShownConferenceViewController else { return }
let vc = ConferenceMainViewController()
RoomRouter.shared.push(viewController: vc)
} onError: { _, message in
RoomRouter.makeToast(toast: message)
}
}
func exitRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
engineManager.exitRoom { [weak self] in
guard let self = self else { return }
self.refreshSource()
self.messageManager.isReadyToSendMessage = true
onSuccess()
} onError: { [weak self] code, message in
guard let self = self else { return }
self.refreshSource()
if code.rawValue == -2_102 {
self.destroyRoom(onSuccess: onSuccess, onError: onError)
} else {
onError(code, message)
}
}
}
func destroyRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
engineManager.destroyRoom { [weak self] in
guard let self = self else { return }
self.roomObserver.messageModel.roomState = .destroyed
self.refreshSource()
self.messageManager.isReadyToSendMessage = true
onSuccess()
} onError: { [weak self] code, message in
guard let self = self else { return }
self.refreshSource()
onError(code, message)
}
}
private func refreshSource() {
roomId = nil
TUILogin.setCurrentBusinessScene(.None)
roomObserver.userList = []
roomObserver.unregisterObserver()
}
private func changeUserRole(userId: String, role: TUIRole, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
engineManager.changeUserRole(userId: userId, role: .roomOwner) {
onSuccess()
} onError: { code, message in
onError(code, message)
}
}
func exitOrDestroyPreviousRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
if roomInfo.ownerId == userId {
if let userModel = engineManager.store.attendeeList.first(where: { $0.userId != userId }) {
changeUserRole(userId: userModel.userId, role: .roomOwner) { [weak self] in
guard let self = self else { return }
self.exitRoom(onSuccess: onSuccess, onError: onError)
} onError: { [weak self] code, message in
guard let self = self else { return }
self.destroyRoom(onSuccess: onSuccess, onError: onError)
}
} else {
destroyRoom(onSuccess: onSuccess, onError: onError)
}
} else {
exitRoom(onSuccess: onSuccess, onError: onError)
}
}
}

View File

@@ -0,0 +1,138 @@
//
// RoomMessageManager.swift
// TUIRoomKit
//
// Created by janejntang on 2023/5/8.
// Copyright © 2023 Tencent. All rights reserved.
// Manage messages, including sending messages and modifying messages
//
import Foundation
import TUICore
import RTCRoomEngine
class RoomMessageManager: NSObject {
static let shared = RoomMessageManager()
private var engineManager: EngineManager {
EngineManager.shared
}
private lazy var userId: String = {
return TUILogin.getUserID() ?? engineManager.store.currentUser.userId
}()
weak var navigateController: UINavigationController?
var isReadyToSendMessage: Bool = true
var groupId: String = ""
private override init() {
super.init()
TUICore.registerEvent(TUICore_TUIChatNotify, subKey: TUICore_TUIChatNotify_SendMessageSubKey, object: self)
}
func sendRoomMessageToGroup() {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
guard BusinessSceneUtil.canJoinRoom() else { return }
if self.engineManager.store.isEnteredRoom {
RoomManager.shared.exitOrDestroyPreviousRoom() { [weak self] in
guard let self = self else { return }
self.sendMessage()
} onError: { [weak self] code, message in
guard let self = self else { return }
self.sendMessage()
debugPrint("exitRoom,code:\(code),message:\(message)")
}
} else {
self.sendMessage()
}
}
}
private func sendMessage() {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
guard self.isReadyToSendMessage else {
self.changeReadyToSendMessage()
return
}
self.isReadyToSendMessage = false
FetchRoomId.getRoomId { [weak self] roomId in
guard let self = self else { return }
let messageModel = RoomMessageModel()
messageModel.groupId = self.groupId
messageModel.roomId = roomId
messageModel.ownerName = TUILogin.getNickName() ?? ""
messageModel.owner = self.userId
let messageDic = messageModel.getDictFromMessageModel()
guard let jsonString = messageDic.convertToString() else { return }
let jsonData = jsonString.data(using: String.Encoding.utf8)
let message = V2TIMManager.sharedInstance().createCustomMessage(jsonData)
message?.supportMessageExtension = true
let param = [TUICore_TUIChatService_SendMessageMethod_MsgKey: message]
TUICore.callService(TUICore_TUIChatService, method: TUICore_TUIChatService_SendMessageMethod, param: param as [AnyHashable : Any])
RoomManager.shared.roomId = roomId
}
}
}
func resendRoomMessage(message: RoomMessageModel,dic:[String: Any]) {
if message.messageId == "" {
self.modifyMessage(message: message, dic: dic)
return
}
V2TIMManager.sharedInstance().findMessages([message.messageId]) { [weak self] messageArray in
guard let self = self else { return }
guard let array = messageArray else { return }
for previousMessage in array where previousMessage.msgID == message.messageId {
self.modifyMessage(message: message, dic: dic)
}
} fail: { [weak self] code, messageString in
guard let self = self else { return }
self.modifyMessage(message: message, dic: dic)
}
}
private func modifyMessage(message: RoomMessageModel, dic:[String: Any]) {
guard let message = message.getMessage() else { return }
guard var customElemDic = TUITool.jsonData2Dictionary(message.customElem.data) as? [String: Any] else { return }
for (key, value) in dic {
customElemDic[key] = value
}
guard let jsonString = customElemDic.convertToString() else { return }
let jsonData = jsonString.data(using: String.Encoding.utf8)
message.customElem.data = jsonData
V2TIMManager.sharedInstance().modifyMessage(message) { code, desc, msg in
if code == 0 {
debugPrint("modifyMessage,success")
} else {
debugPrint("modifyMessage,code:\(code),message:\(String(describing: desc))")
}
}
}
deinit {
debugPrint("deinit \(self)")
}
}
extension RoomMessageManager {
private func changeReadyToSendMessage() {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 20) { [weak self] in
guard let self = self else { return }
self.isReadyToSendMessage = true
}
}
}
extension RoomMessageManager: TUINotificationProtocol {
func onNotifyEvent(_ key: String, subKey: String, object anObject: Any?, param: [AnyHashable : Any]?) {
guard key == TUICore_TUIChatNotify, subKey == TUICore_TUIChatNotify_SendMessageSubKey else { return }
guard let code = param?[TUICore_TUIChatNotify_SendMessageSubKey_Code] as? Int, code == 0 else { return }
guard let message = param?[TUICore_TUIChatNotify_SendMessageSubKey_Message] as? V2TIMMessage else { return }
let messageModel = RoomMessageModel()
messageModel.updateMessage(message: message)
guard messageModel.messageId.count > 0, messageModel.roomState == .creating, messageModel.roomId == RoomManager.shared.roomId else { return }
let roomInfo = TUIRoomInfo()
roomInfo.roomId = messageModel.roomId
RoomManager.shared.createRoom(roomInfo: roomInfo)
}
}