From 6b07ae2b6c91a29c3af8590b03c7ff133c2bdacc Mon Sep 17 00:00:00 2001 From: adamsfliu Date: Thu, 15 Aug 2024 16:34:09 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90TUILiveKit=E3=80=91=E3=80=90iOS?= =?UTF-8?q?=E3=80=91update=202.4.0=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS/CHANGELOG.md | 4 ++ .../Source/Common/Log/LiveKitLog.swift | 66 ++++++++----------- .../LiveList/View/LiveListRootView.swift | 5 +- .../Source/Service/EngineServiceCenter.swift | 10 ++- .../Source/Store/Room/RoomEffects.swift | 14 +++- .../TUILiveRoomAnchorViewController.swift | 3 +- .../View/TUILivePreviewViewController.swift | 2 +- .../TUIVoiceRoomViewController.swift | 4 +- .../VoiceRoom/View/Panel/AlertPanel.swift | 6 +- .../View/Prepare/VoiceRoomPrepareView.swift | 7 ++ .../Root/VoiceRoomRootMenuDataCreator.swift | 12 ++-- .../View/Root/VoiceRoomRootView.swift | 6 +- iOS/TUILiveKit/TUILiveKit.podspec | 4 +- 13 files changed, 80 insertions(+), 63 deletions(-) diff --git a/iOS/CHANGELOG.md b/iOS/CHANGELOG.md index d4bb8277..26a3e115 100644 --- a/iOS/CHANGELOG.md +++ b/iOS/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.0 +### New Features +- Android&iOS: Add new feature for room owners change room background in voice rooms +- Android&iOS: Optimize some known issues ## 2.3.0 ### New Features - Android&iOS: Add new feature for room owners to invite audience members to speak in voice rooms diff --git a/iOS/TUILiveKit/Source/Common/Log/LiveKitLog.swift b/iOS/TUILiveKit/Source/Common/Log/LiveKitLog.swift index c2073918..345219ff 100644 --- a/iOS/TUILiveKit/Source/Common/Log/LiveKitLog.swift +++ b/iOS/TUILiveKit/Source/Common/Log/LiveKitLog.swift @@ -13,56 +13,48 @@ import Foundation #endif class LiveKitLog { + private static let API = "TuikitLog" + private static let LOG_KEY_API = "api" + private static let LOG_KEY_PARAMS = "params" + private static let LOG_KEY_PARAMS_LEVEL = "level" + private static let LOG_KEY_PARAMS_MESSAGE = "message" + private static let LOG_KEY_PARAMS_FILE = "file" + private static let LOG_KEY_PARAMS_LINE = "line" + private static let LOG_KEY_PARAMS_MODULE = "module" + private static let LOG_KEY_PARAMS_MODULE_VALUE = "TUILiveKit" + private func `init`() {} - enum LiveKitLogLevel { - case error - case warn - case info - case debug - func getString() -> String { - switch self { - case .error: - return "LiveKitLog Error" - case .warn: - return "LiveKitLog Warn" - case .info: - return "LiveKitLog Info" - case .debug: - return "LiveKitLog Debug" - } - } + enum LiveKitLogLevel: Int { + case error = 2 + case warn = 1 + case info = 0 } static func error(_ file: String, _ line: String, _ messages: String...) { log(level: .error, file: file, line: line, messages) } - static func warn(_ file: String,_ line: String , _ messages: String...) { + static func warn(_ file: String, _ line: String, _ messages: String...) { log(level: .warn, file: file, line: line, messages) } - static func info(_ file: String,_ line: String, _ messages: String...) { + static func info(_ file: String, _ line: String, _ messages: String...) { log(level: .info, file: file, line: line, messages) } - static func debug(_ file: String,_ line: String, _ messages: String...) { - log(level: .debug, file: file, line: line, messages) - } - private static func log(level: LiveKitLogLevel = .info, file: String, line: String, _ messages: [String]) { - var logs = level.getString() - logs.append(" [\(URL(fileURLWithPath: file).lastPathComponent),\(line)] ") - for message in messages { - logs.append(message) - } - if level == .debug { - debugPrint(logs) - } else { - let cloud = TRTCCloud.sharedInstance() - let selector = NSSelectorFromString("apiLog:") - if cloud.responds(to: selector) { - cloud.perform(selector, with: logs) - } - } + let apiParams: [String: Any] = [ + LOG_KEY_API: API, + LOG_KEY_PARAMS: [ + LOG_KEY_PARAMS_LEVEL: level.rawValue, + LOG_KEY_PARAMS_MESSAGE: messages.joined(), + LOG_KEY_PARAMS_MODULE: LOG_KEY_PARAMS_MODULE_VALUE, + LOG_KEY_PARAMS_FILE: file, + LOG_KEY_PARAMS_LINE: Int(line) ?? 0, + ], + ] + let jsonData = try? JSONSerialization.data(withJSONObject: apiParams, options: .prettyPrinted) + guard let jsonData = jsonData, let jsonString = String(data: jsonData, encoding: .utf8) else { return } + TRTCCloud.sharedInstance().callExperimentalAPI(jsonString) } } diff --git a/iOS/TUILiveKit/Source/Common/UIComponent/LiveList/View/LiveListRootView.swift b/iOS/TUILiveKit/Source/Common/UIComponent/LiveList/View/LiveListRootView.swift index bbcc2856..7f8102e7 100644 --- a/iOS/TUILiveKit/Source/Common/UIComponent/LiveList/View/LiveListRootView.swift +++ b/iOS/TUILiveKit/Source/Common/UIComponent/LiveList/View/LiveListRootView.swift @@ -118,13 +118,10 @@ extension LiveListRootView { guard let self = self else { return } if result.cursor == "" { self.liveListCollectionView.es.noticeNoMoreData() - if self.liveListDataSource.isEmpty { - self.liveListDataSource.append(contentsOf: result.liveInfoList) - } } else { self.liveListCollectionView.es.resetNoMoreData() - self.liveListDataSource.append(contentsOf: result.liveInfoList) } + self.liveListDataSource.append(contentsOf: result.liveInfoList) self.liveListCollectionView.reloadData() } .store(in: &cancellableSet) diff --git a/iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift b/iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift index 23d28d71..44fb5447 100644 --- a/iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift +++ b/iOS/TUILiveKit/Source/Service/EngineServiceCenter.swift @@ -239,18 +239,22 @@ extension ServiceCenter: TUILiveListManagerObserver { func onLiveInfoChanged(liveInfo: TUILiveInfo, modifyFlag: TUILiveModifyFlag) { guard let store = self.store else { return } if store.selectCurrent(UserSelectors.isOwner) { return } - if modifyFlag == .category { + if modifyFlag.contains(.category) { if let categoryValue = liveInfo.categoryList.first?.intValue, let category = LiveStreamCategory(rawValue: categoryValue) { store.dispatch(action: RoomActions.updateRoomCategory(payload: category)) } } - if modifyFlag == .coverUrl { + if modifyFlag.contains(.backgroundUrl) { + store.dispatch(action: RoomActions.updateRoomBackgroundUrl(payload: liveInfo.backgroundUrl)) + } + + if modifyFlag.contains(.coverUrl) { store.dispatch(action: RoomActions.updateRoomCoverUrl(payload: liveInfo.coverUrl)) } - if modifyFlag == .publish { + if modifyFlag.contains(.publish) { store.dispatch(action: RoomActions.updateRoomMode(payload: liveInfo.isPublicVisible ? .public : .privacy)) } } diff --git a/iOS/TUILiveKit/Source/Store/Room/RoomEffects.swift b/iOS/TUILiveKit/Source/Store/Room/RoomEffects.swift index 97dd169e..aa78a45b 100644 --- a/iOS/TUILiveKit/Source/Store/Room/RoomEffects.swift +++ b/iOS/TUILiveKit/Source/Store/Room/RoomEffects.swift @@ -31,6 +31,7 @@ class RoomEffects: Effects { return action.payload.nextActions + [ RoomActions.updateRoomInfo(payload: roomInfo), RoomActions.setRoomCoverUrl(payload: roomState.coverURL), + RoomActions.setRoomBackgroundUrl(payload: roomState.backgroundURL), RoomActions.setRoomCategory(payload: roomState.liveExtraInfo.category), RoomActions.setRoomMode(payload: roomState.liveExtraInfo.liveMode), ] @@ -159,6 +160,7 @@ class RoomEffects: Effects { } return [RoomActions.updateRoomCoverUrl(payload: liveInfo.coverUrl), RoomActions.updateRoomMode(payload: liveInfo.isPublicVisible ? .public : .privacy), + RoomActions.updateRoomBackgroundUrl(payload: liveInfo.backgroundUrl), ] } .catch { error -> Just<[Action]> in @@ -241,7 +243,17 @@ class RoomEffects: Effects { let setRoomBackgroundUrl = Effect.dispatchingOne { actions, environment in actions.wasCreated(from: RoomActions.setRoomBackgroundUrl) .flatMap { action in - return Just(RoomActions.updateRoomBackgroundUrl(payload: action.payload)) + var liveInfo = TUILiveInfo() + liveInfo.roomInfo.roomId = environment.store?.selectCurrent(RoomSelectors.getRoomId) ?? "" + liveInfo.backgroundUrl = action.payload + return environment.roomService.setLiveInfo(liveInfo: liveInfo, modifyFlag: .backgroundUrl) + .map { _ in + RoomActions.updateRoomBackgroundUrl(payload: action.payload) + } + .catch { error -> Just in + let action = ViewActions.toastEvent(payload: ToastInfo(message: error.message)) + return Just(action) + } } .eraseToAnyPublisher() } diff --git a/iOS/TUILiveKit/Source/View/LiveRoom/TUILiveRoomAnchorViewController.swift b/iOS/TUILiveKit/Source/View/LiveRoom/TUILiveRoomAnchorViewController.swift index d85d36ba..7a968f1b 100644 --- a/iOS/TUILiveKit/Source/View/LiveRoom/TUILiveRoomAnchorViewController.swift +++ b/iOS/TUILiveKit/Source/View/LiveRoom/TUILiveRoomAnchorViewController.swift @@ -56,6 +56,7 @@ public class TUILiveRoomAnchorViewController: UIViewController { constructViewHierarchy() activateConstraints() subscribeToast() + enableSubscribeRouter(enable: true) } public override func touchesBegan(_ touches: Set, with event: UIEvent?) { @@ -99,7 +100,7 @@ extension TUILiveRoomAnchorViewController { }) } - func enableSubscribeRouter(enable: Bool) { + public func enableSubscribeRouter(enable: Bool) { enable ? routerCenter.subscribeRouter() : routerCenter.unSubscribeRouter() } diff --git a/iOS/TUILiveKit/Source/View/TUILivePreviewViewController.swift b/iOS/TUILiveKit/Source/View/TUILivePreviewViewController.swift index a4f6ec21..dfab1785 100644 --- a/iOS/TUILiveKit/Source/View/TUILivePreviewViewController.swift +++ b/iOS/TUILiveKit/Source/View/TUILivePreviewViewController.swift @@ -83,7 +83,7 @@ extension TUILivePreviewViewController { self.listController.remove(at: 1) } - var roomParams = RoomParams() + let roomParams = RoomParams() roomParams.maxSeatCount = 0 roomParams.seatMode = .applyToTake let voiceLiveController = TUIVoiceRoomViewController(roomId: voiceRoomId, behavior: .prepareCreate, roomParams: roomParams) diff --git a/iOS/TUILiveKit/Source/View/VoiceRoom/TUIVoiceRoomViewController.swift b/iOS/TUILiveKit/Source/View/VoiceRoom/TUIVoiceRoomViewController.swift index 030169c4..3862d944 100644 --- a/iOS/TUILiveKit/Source/View/VoiceRoom/TUIVoiceRoomViewController.swift +++ b/iOS/TUILiveKit/Source/View/VoiceRoom/TUIVoiceRoomViewController.swift @@ -120,10 +120,10 @@ public class TUIVoiceRoomViewController: UIViewController { case .join, .autoCreate: showVoiceRoot() subscribeViewState() - enableSubscribeRouter(enable: true) case .prepareCreate: showVoicePrepare() } + enableSubscribeRouter(enable: true) } private func initRoomState(roomParams: RoomParams) { @@ -162,7 +162,7 @@ public class TUIVoiceRoomViewController: UIViewController { // MARK: - Store extension TUIVoiceRoomViewController { - func enableSubscribeRouter(enable: Bool) { + public func enableSubscribeRouter(enable: Bool) { enable ? routerCenter.subscribeRouter() : routerCenter.unSubscribeRouter() } } diff --git a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Panel/AlertPanel.swift b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Panel/AlertPanel.swift index fcfb39d2..33b3304d 100644 --- a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Panel/AlertPanel.swift +++ b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Panel/AlertPanel.swift @@ -8,7 +8,7 @@ import UIKit import RTCCommon -typealias AlertButtonClickClosure = () -> Void +typealias AlertButtonClickClosure = (AlertPanel) -> Void struct AlertInfo { let description: String @@ -232,13 +232,13 @@ extension AlertPanel { @objc private func cancelButtonClick(sender: UIButton) { if let cancelClosure = alertInfo.cancelClosure { - cancelClosure() + cancelClosure(self) } } @objc private func defaultButtonClick(sender: UIButton) { - alertInfo.defaultClosure() + alertInfo.defaultClosure(self) } } diff --git a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Prepare/VoiceRoomPrepareView.swift b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Prepare/VoiceRoomPrepareView.swift index baa8ac8d..eec7405a 100644 --- a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Prepare/VoiceRoomPrepareView.swift +++ b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Prepare/VoiceRoomPrepareView.swift @@ -63,6 +63,13 @@ class VoiceRoomPrepareView: RTCBaseView { let model = FeatureClickPanelModel() model.itemSize = CGSize(width: 63.scale375(), height: 56.scale375Height()) model.itemDiff = 25.scale375() + model.items.append(FeatureItem(normalTitle: .backgroundText, + normalImage: .liveBundleImage("live_prepare_background_icon"), + designConfig: designConfig, + actionClosure: { [weak self] _ in + guard let self = self else { return } + self.routerStore.router(action: .present(.systemImageSelection(.background))) + })) model.items.append(FeatureItem(normalTitle: .musicText, normalImage: .liveBundleImage("live_prepare_music_icon"), designConfig: designConfig, diff --git a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootMenuDataCreator.swift b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootMenuDataCreator.swift index 532ef89f..0f518c15 100644 --- a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootMenuDataCreator.swift +++ b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootMenuDataCreator.swift @@ -109,12 +109,6 @@ extension VoiceRoomRootMenuDataCreator { } menus.append(setting) - var musicList = ButtonMenuInfo(normalIcon: "live_gift_icon") - musicList.tapAction = { sender in - routerStore.router(action: .present(.giftView)) - } - menus.append(musicList) - var linkMic = ButtonMenuInfo(normalIcon: "live_link_voice_room", normalTitle: "") linkMic.tapAction = { sender in routerStore.router(action: .present(.voiceLinkControl)) @@ -142,6 +136,12 @@ extension VoiceRoomRootMenuDataCreator { designConfig.cornerRadius = 10 designConfig.titleFont = .customFont(ofSize: 12) designConfig.type = .imageAboveTitleBottom + model.items.append(FeatureItem(normalTitle: .backgroundText, + normalImage: .liveBundleImage("live_setting_background_icon"), + designConfig: designConfig, + actionClosure: { _ in + routerStore.router(action: .present(.systemImageSelection(.background))) + })) model.items.append(FeatureItem(normalTitle: .musicText, normalImage: .liveBundleImage("live_setting_music_icon"), designConfig: designConfig, diff --git a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootView.swift b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootView.swift index 8ca8fda5..f18cab7e 100644 --- a/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootView.swift +++ b/iOS/TUILiveKit/Source/View/VoiceRoom/View/Root/VoiceRoomRootView.swift @@ -22,7 +22,7 @@ class VoiceRoomRootView: RTCBaseView { private lazy var isOwner: Bool = store.selectCurrent(UserSelectors.isOwner) private let giftCacheService = TUIGiftStore.shared.giftCacheService private var cancellableSet = Set() - private var alertPanel: AlertPanel? + private weak var alertPanel: AlertPanel? let backgroundImageView: UIImageView = { let backgroundImageView = UIImageView(frame: .zero) @@ -368,11 +368,11 @@ extension VoiceRoomRootView { let alertInfo = AlertInfo(description: String.localizedReplace(.inviteLinkText, replace: "\(seatInvitation.userName)"), imagePath: seatInvitation.avatarUrl, cancelButtonInfo: (String.rejectText, .g3), - defaultButtonInfo: (String.acceptText, .b1)) { [weak self] in + defaultButtonInfo: (String.acceptText, .b1)) { [weak self] _ in guard let self = self else { return } self.store.dispatch(action: SeatActions.responseSeatInvitation(payload: (false, seatInvitation.id))) self.store.dispatch(action: SeatActions.updateReceivedSeatInvitation(payload: SeatInvitation())) - } defaultClosure: { [weak self] in + } defaultClosure: { [weak self] _ in guard let self = self else { return } self.store.dispatch(action: SeatActions.responseSeatInvitation(payload: (true, seatInvitation.id))) self.store.dispatch(action: SeatActions.updateReceivedSeatInvitation(payload: SeatInvitation())) diff --git a/iOS/TUILiveKit/TUILiveKit.podspec b/iOS/TUILiveKit/TUILiveKit.podspec index fe625a97..69069d6e 100644 --- a/iOS/TUILiveKit/TUILiveKit.podspec +++ b/iOS/TUILiveKit/TUILiveKit.podspec @@ -29,7 +29,7 @@ Pod::Spec.new do |spec| spec.default_subspec = 'TRTC' spec.subspec 'Professional' do |professional| - professional.dependency 'RTCRoomEngine/Professional', '>= 2.5.0' + professional.dependency 'RTCRoomEngine/Professional', '>= 2.5.1' professional.source_files = 'Source/**/*' professional.resource_bundles = { 'TUILiveKitBundle' => ['Resources/*.xcassets', 'Resources/Localized/**/*.strings'] @@ -37,7 +37,7 @@ Pod::Spec.new do |spec| end spec.subspec 'TRTC' do |trtc| - trtc.dependency 'RTCRoomEngine/TRTC', '>= 2.5.0' + trtc.dependency 'RTCRoomEngine/TRTC', '>= 2.5.1' trtc.source_files = 'Source/**/*' trtc.resource_bundles = { 'TUILiveKitBundle' => ['Resources/*.xcassets', 'Resources/Localized/**/*.strings']