Skip to content

Commit

Permalink
Merge pull request #275 from boostcampwm-2024/task/change_make_channe…
Browse files Browse the repository at this point in the history
…l_logic

task #273 채널 생성 및 삭제 시점 변경
  • Loading branch information
INYEKIM authored Nov 30, 2024
2 parents 4678f74 + b42c404 commit 8510dcc
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 49 deletions.
9 changes: 3 additions & 6 deletions Projects/App/Sources/Splash/SplashViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,25 @@ public final class SplashViewController: BaseViewController<EmptyViewModel> {
extension SplashViewController {
private func moveToMainView() {
let fetchChannelListUsecase = DIContainer.shared.resolve(FetchChannelListUsecase.self)
let createChannelUsecase = DIContainer.shared.resolve(CreateChannelUsecase.self)
let deleteChannelUsecase = DIContainer.shared.resolve(DeleteChannelUsecase.self)
let fetchChannelInfoUsecase = DIContainer.shared.resolve(FetchChannelInfoUsecase.self)
let makeBroadcastUsecase = DIContainer.shared.resolve(MakeBroadcastUsecase.self)
let fetchAllBroadcastUsecase = DIContainer.shared.resolve(FetchAllBroadcastUsecase.self)
let deleteBroadCastUsecase = DIContainer.shared.resolve(DeleteBroadcastUsecase.self)
let factory = DIContainer.shared.resolve(LiveStreamViewControllerFactory.self)
let viewModel = BroadcastCollectionViewModel(
fetchChannelListUsecase: fetchChannelListUsecase,
createChannelUsecase: createChannelUsecase,
deleteChannelUsecase: deleteChannelUsecase,
fetchChannelInfoUsecase: fetchChannelInfoUsecase,
makeBroadcastUsecase: makeBroadcastUsecase,
fetchAllBroadcastUsecase: fetchAllBroadcastUsecase,
deleteBroadCastUsecase: deleteBroadCastUsecase
)
let viewController = BroadcastCollectionViewController(viewModel: viewModel, factory: factory)
let navigationController = UINavigationController(rootViewController: viewController)

let createChannelUsecase = DIContainer.shared.resolve(CreateChannelUsecase.self)

/// 유저의 이름이 저장되어 있지 않으면 유저 등록 뷰를 Navigation에 올림
if UserDefaults.standard.string(forKey: "USER_NAME") == nil {
let singUpViewModel = SignUpViewModel()
let singUpViewModel = SignUpViewModel(createChannelUsecase: createChannelUsecase)
navigationController.viewControllers.append(SignUpViewController(viewModel: singUpViewModel))
}

Expand Down
3 changes: 2 additions & 1 deletion Projects/Features/AuthFeature/Demo/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let viewModel = SignUpViewModel()
let mockCreateChannelUsecase = MockCreateChannelUsecaseImpl()
let viewModel = SignUpViewModel(createChannelUsecase: mockCreateChannelUsecase)
let viewController = SignUpViewController(viewModel: viewModel)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Combine

import LiveStationDomainInterface

final class MockCreateChannelUsecaseImpl: CreateChannelUsecase {
func execute(name: String) -> AnyPublisher<ChannelEntity, any Error> {
Future { promise in
promise(.success(ChannelEntity(id: "", name: name)))
}.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SignUpViewController: BaseViewController<SignUpViewModel> {

private let confettiAnimationView = LottieAnimationView(name: "confetti", bundle: Bundle(for: DesignSystemResources.self))
private let shookAnimationView = LottieAnimationView(name: "shook", bundle: Bundle(for: DesignSystemResources.self))
private lazy var loadingView = SHLoadingView(message: "아이디 등록 중")
private lazy var loadingView = SHLoadingView(message: "닉네임 등록 중")

public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Expand Down Expand Up @@ -62,6 +62,7 @@ public class SignUpViewController: BaseViewController<SignUpViewModel> {
.store(in: &cancellables)

output.isSaved
.receive(on: DispatchQueue.main)
.sink { [weak self] isSaved in
if isSaved {
self?.textField.resignFirstResponder()
Expand Down
18 changes: 16 additions & 2 deletions Projects/Features/AuthFeature/Sources/SignUpViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Combine
import Foundation

import BaseFeatureInterface
import LiveStationDomainInterface

public class SignUpViewModel: ViewModel {
public struct Input {
Expand All @@ -16,6 +17,8 @@ public class SignUpViewModel: ViewModel {
private let output = Output()
private var cancellables = Set<AnyCancellable>()

private let createChannelUsecase: any CreateChannelUsecase

public func transform(input: Input) -> Output {
input.didWriteUserName
.sink { [weak self] name in
Expand All @@ -35,7 +38,9 @@ public class SignUpViewModel: ViewModel {
return output
}

public init() { }
public init(createChannelUsecase: CreateChannelUsecase) {
self.createChannelUsecase = createChannelUsecase
}

private func validate(with name: String?) -> Bool {
guard let name else { return false }
Expand All @@ -47,6 +52,15 @@ public class SignUpViewModel: ViewModel {
UserDefaults.standard.set(name, forKey: "USER_NAME")

let savedName = UserDefaults.standard.string(forKey: "USER_NAME")
output.isSaved.send(savedName == name)

createChannelUsecase.execute(name: "Guest")
.sink { _ in
} receiveValue: { [weak self] channelEntity in
UserDefaults.standard.set(channelEntity.id, forKey: "CHANNEL_ID")
let savedID = UserDefaults.standard.string(forKey: "CHANNEL_ID")

self?.output.isSaved.send(savedName == name && savedID != nil)
}
.store(in: &cancellables)
}
}
6 changes: 0 additions & 6 deletions Projects/Features/MainFeature/Demo/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let mockFetchChannelListUsecase = MockFetchChannelListUsecaseImpl()
let mockCreateChannelUsecase = MockCreateChannelUsecaseImpl()
let mockDeleteChannelUsecase = MockDeleteChannelUsecaseImpl()
let mockFetchChannelInfoUsecase = MockFetchChannelInfoUsecaseImpl()
let mockmakeBroadcastUsecase = MockMakeBroadcastUsecaseImpl()
let mockFetchAllBroadcastUsecase = MockFetchAllBroadcastUsecaseImpl()
let mockDeleteBroadcastUsecase = MockDeleteBroadcastUsecaseImpl()
let viewModel = BroadcastCollectionViewModel(
fetchChannelListUsecase: mockFetchChannelListUsecase,
createChannelUsecase: mockCreateChannelUsecase,
deleteChannelUsecase: mockDeleteChannelUsecase,
fetchChannelInfoUsecase: mockFetchChannelInfoUsecase,
makeBroadcastUsecase: mockmakeBroadcastUsecase,
fetchAllBroadcastUsecase: mockFetchAllBroadcastUsecase,
Expand All @@ -37,5 +33,3 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
return true
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public final class BroadcastUIViewController: BaseViewController<BroadcastCollec
}

private func didFinishBroadCast() {
dismiss(animated: false)
viewModelInput.didTapFinishStreamingButton.send()
dismiss(animated: false) { [weak self] in
self?.viewModelInput.didTapFinishStreamingButton.send()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public final class SettingUIViewController: BaseViewController<BroadcastCollecti
private let streamingDescriptionCell = SettingTableViewCell(style: .default, reuseIdentifier: nil)
private let streamingNameCell = SettingTableViewCell(style: .default, reuseIdentifier: nil)
private let placeholderStringOfCells = ["어떤 방송인지 알려주세요!", "방송 내용을 알려주세요!"]
private lazy var loadingView = SHLoadingView(message: "채널 생성 중")
private lazy var loadingView = SHLoadingView(message: "방송 생성 중")

private var broadcastPicker = RPSystemBroadcastPickerView()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public class BroadcastCollectionViewModel: ViewModel {
private let output = Output()

private let fetchChannelListUsecase: any FetchChannelListUsecase
private let createChannelUsecase: any CreateChannelUsecase
private let deleteChannelUsecase: any DeleteChannelUsecase
private let fetchChannelInfoUsecase: any FetchChannelInfoUsecase
private let makeBroadcastUsecase: any MakeBroadcastUsecase
private let fetchAllBroadcastUsecase: any FetchAllBroadcastUsecase
Expand All @@ -68,22 +66,18 @@ public class BroadcastCollectionViewModel: ViewModel {
let extensionBundleID = "kr.codesquad.boostcamp9.Shook.BroadcastUploadExtension"

private let userName = UserDefaults.standard.string(forKey: "USER_NAME") ?? ""
private var channelName: String = ""
private var broadcastName: String = ""
private var channelDescription: String = ""
private var channel: ChannelEntity?
private var channelID = UserDefaults.standard.string(forKey: "CHANNEL_ID")

public init(
fetchChannelListUsecase: FetchChannelListUsecase,
createChannelUsecase: CreateChannelUsecase,
deleteChannelUsecase: DeleteChannelUsecase,
fetchChannelInfoUsecase: FetchChannelInfoUsecase,
makeBroadcastUsecase: MakeBroadcastUsecase,
fetchAllBroadcastUsecase: FetchAllBroadcastUsecase,
deleteBroadCastUsecase: DeleteBroadcastUsecase
) {
self.fetchChannelListUsecase = fetchChannelListUsecase
self.createChannelUsecase = createChannelUsecase
self.deleteChannelUsecase = deleteChannelUsecase
self.fetchChannelInfoUsecase = fetchChannelInfoUsecase
self.makeBroadcastUsecase = makeBroadcastUsecase
self.fetchAllBroadcastUsecase = fetchAllBroadcastUsecase
Expand All @@ -104,7 +98,7 @@ public class BroadcastCollectionViewModel: ViewModel {
self.output.streamingStartButtonIsActive.send(validness.isValid)
self.output.errorMessage.send(validness.errorMessage)
if validness.isValid {
channelName = name
broadcastName = name
}
}
.store(in: &cancellables)
Expand All @@ -123,9 +117,9 @@ public class BroadcastCollectionViewModel: ViewModel {

input.didTapFinishStreamingButton
.flatMap { [weak self] _ in
guard let self, let channel else { return Empty<(Void, Void), Error>().eraseToAnyPublisher() }
return deleteChannelUsecase.execute(channelID: channel.id)
.zip(deleteBroadCastUsecase.execute(id: channel.id))
guard let self,
let channelID else { return Empty<Void, Error>().eraseToAnyPublisher() }
return deleteBroadCastUsecase.execute(id: channelID)
.eraseToAnyPublisher()
}
.sink { _ in
Expand All @@ -135,16 +129,12 @@ public class BroadcastCollectionViewModel: ViewModel {
.store(in: &cancellables)

input.didTapStartBroadcastButton
.flatMap { [weak self] _ in
guard let self else { return Empty<ChannelEntity, Error>().eraseToAnyPublisher() }
output.isReadyToStream.send(false)
return createChannelUsecase.execute(name: channelName)
}
.flatMap { [weak self] in
guard let self else { return Empty<ChannelInfoEntity, Error>().eraseToAnyPublisher() }
channel = $0
return fetchChannelInfoUsecase.execute(channelID: $0.id)
.zip(makeBroadcastUsecase.execute(id: $0.id, title: $0.name, owner: userName, description: channelDescription))
guard let self,
let channelID else { return Empty<ChannelInfoEntity, Error>().eraseToAnyPublisher() }
output.isReadyToStream.send(false)
return fetchChannelInfoUsecase.execute(channelID: channelID)
.zip(makeBroadcastUsecase.execute(id: channelID, title: broadcastName, owner: userName, description: channelDescription))
.map { channelInfo, _ in channelInfo }
.eraseToAnyPublisher()
}
Expand All @@ -168,7 +158,7 @@ public class BroadcastCollectionViewModel: ViewModel {
let broadcast = broadcastInfoEntities.first { $0.id == channelEntity.id }
return Channel(
id: channelEntity.id,
title: channelEntity.name,
title: broadcast?.title ?? "Unknown",
thumbnailImageURLString: channelEntity.imageURLString,
owner: broadcast?.owner ?? "Unknown",
description: broadcast?.description ?? ""
Expand Down Expand Up @@ -210,15 +200,10 @@ public class BroadcastCollectionViewModel: ViewModel {
/// - Parameter _: 방송 이름
/// - Returns: (Bool, String?) - 유효 여부와 에러 메시지
private func valid(_ value: String) -> (isValid: Bool, errorMessage: String?) {
let isLengthValid = 3...20 ~= value.count
let isCharactersValid = value.allSatisfy { $0.isLetter || $0.isNumber || $0 == "_" }
let trimmedValue = value.trimmingCharacters(in: .whitespaces)

if !isLengthValid && !isCharactersValid {
return (false, "3글자 이상,20글자 이하로 입력해 주세요. 특수문자는 언더바(_)만 가능합니다.")
} else if !isLengthValid {
return (false, "최소 3글자 이상, 최대 20글자 이하로 입력해 주세요.")
} else if !isCharactersValid {
return (false, "특수문자는 언더바(_)만 가능합니다.")
if trimmedValue.isEmpty {
return (false, "공백을 제외하고 최소 1글자 이상 입력해주세요.")
} else {
return (true, nil)
}
Expand Down

0 comments on commit 8510dcc

Please sign in to comment.