Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 레포지토리 리펙토링 #175

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
32a280d
fix: 온보딩에서 로비뷰로 이동할 경우 로컬 데이터를 가져와서 push를 2번하는 이슈 해결
Sonny-Kor Dec 1, 2024
41a6054
refactor: Entity Custom StringConvertible 추가
Sonny-Kor Dec 1, 2024
84e91f4
refactor: Main Repository에서 Room 하나의 스트림만 가지도록 변경
Sonny-Kor Dec 1, 2024
5e7383b
feat: Network Helper 만드는 중
Sonny-Kor Dec 1, 2024
57be0b6
fix: 임시 network helper 삭제
Sonny-Kor Dec 2, 2024
e0e715c
merge: dev 와 머지
Sonny-Kor Dec 2, 2024
7ede47c
chore: myID 수정
Sonny-Kor Dec 2, 2024
82d36d6
feat: ASMusicKit에 randomSong() 함수 추가, search @MainActor 삭제
moral-life Dec 2, 2024
90036b9
feat: SelectMusic 화면에서, 타임 아웃 될 때까지 아무 노래도 고르지 않으면 랜덤 곡 제출 구현
moral-life Dec 2, 2024
37d7f55
fix: 치명적인 로직 수정
moral-life Dec 2, 2024
815e159
feat: onboarding 화면 키보드 오류 해결
moral-life Dec 2, 2024
a78b909
chore: UIViewController+Keyboard 없애고 OnboardingViewController extensi…
moral-life Dec 2, 2024
0cfda73
chore: 단순 print Log 삭제
moral-life Dec 3, 2024
e33ec15
fix: 노래 선택할 때 중지가 아니라 정지 버튼으로 수정
Sonny-Kor Dec 2, 2024
6219078
fix: 노래 선택할 때 선택한 노래가 없으면 재생버튼 막기
Sonny-Kor Dec 2, 2024
de592a0
fix: 노래 검색 중일때만 progress 동작
Sonny-Kor Dec 2, 2024
d169840
fix: 노래 선택, 키보드 안내려가는 문제 해결
Sonny-Kor Dec 2, 2024
4f1d357
chore: 완료버튼 없어져서 다시 수정
Sonny-Kor Dec 2, 2024
8b3098a
chore: 네비게이션 Toolbar topBarTrailing으로 수정
Sonny-Kor Dec 3, 2024
2275d32
feat: Network Helper 만드는 중
Sonny-Kor Dec 1, 2024
a53414e
rebase: dev
Sonny-Kor Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Answer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ extension Answer {
music: Music.musicStub4,
playlist: Playlist())
}

extension Answer: CustomStringConvertible {
public var description: String {
return """
player: \(player?.description ?? "nil")
music: \(music?.description ?? "nil")
"""
}
}
14 changes: 11 additions & 3 deletions alsongDalsong/ASEntity/ASEntity/GameState.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
public struct GameState {
public struct GameState: Equatable {
public let mode: Mode?
public let recordOrder: UInt8?
public let status: Status?
Expand Down Expand Up @@ -150,9 +150,17 @@ public enum GameViewType {
case .submitMusic:
(systemName: "music.note.list", color: "508DFD")
case .humming:
(systemName: "microphone", color: "FD5050")
if #available(iOS 18.0, *) {
(systemName: "microphone", color: "FD5050")
} else {
(systemName: "mic", color: "FD5050")
}
Comment on lines +153 to +157
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버전이 바뀌면서 Symbol 명이 바뀌었나 보군요 ㄷㄷㄷ

case .rehumming:
(systemName: "microphone", color: "FD5050")
if #available(iOS 18.0, *) {
(systemName: "microphone", color: "FD5050")
} else {
(systemName: "mic", color: "FD5050")
}
case .submitAnswer:
(systemName: "music.note.list", color: "508DFD")
case .result:
Expand Down
6 changes: 6 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Music.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ extension Music {
public static let musicStub3 = Music(title: "으아~", artist: "김흥국")
public static let musicStub4 = Music(title: "이브, 프시케 그리고 푸른 수염의 아내", artist: "르세라핌")
}

extension Music: CustomStringConvertible {
public var description: String {
return "\(title ?? "Unknown") - \(artist ?? "Unknown")"
}
}
6 changes: 6 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Player.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ extension Player {
public static let playerStub3: Player = Player(id: "2", avatarUrl: nil, nickname: "Moral-life", score: nil, order: 2)
public static let playerStub4: Player = Player(id: "3", avatarUrl: nil, nickname: "Sang₩", score: nil, order: 3)
}

extension Player: CustomStringConvertible {
public var description: String {
return "\(nickname ?? "Unknown")"
}
}
9 changes: 9 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Record.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,12 @@ extension Record {
public static let recordStub4_2 = Record(player: Player.playerStub4, recordOrder: 1, fileUrl: stubm4aData)
public static let recordStub4_3 = Record(player: Player.playerStub4, recordOrder: 2, fileUrl: stubm4aData)
}

extension Record: CustomStringConvertible {
public var description: String {
return """
player: \(player?.description ?? "nil")
recordOrder: \(String(describing: recordOrder))
"""
}
}
19 changes: 19 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Room.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,22 @@ public struct Room: Codable {
self.submits = submits
}
}

extension Room: CustomStringConvertible {
public var description: String {
return """
number: \(number ?? "nil")
host: \(host?.description ?? "nil")
players: \(players?.description ?? "nil")
mode: \(mode?.title ?? "nil")
round: \(round ?? 0)
status: \(status?.description ?? "nil")
recordOrder: \(recordOrder ?? 0)
records: \(records?.description ?? "nil")
answers: \(answers?.description ?? "nil")
dueTime: \(dueTime?.description ?? "nil")
selectedRecords: \(selectedRecords?.description ?? "nil")
submits: \(submits?.description ?? "nil")
"""
}
}
17 changes: 17 additions & 0 deletions alsongDalsong/ASEntity/ASEntity/Status.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,20 @@ public enum Status: String, Codable {
case hint
case result
}

extension Status: CustomStringConvertible {
public var description: String {
switch self {
case .humming:
return "humming"
case .rehumming:
return "rehumming"
case .waiting:
return "waiting"
case .hint:
return "hint"
case .result:
return "result"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import ASEntity
import ASLogKit
import Combine
@preconcurrency internal import FirebaseFirestore

public final class ASFirebaseDatabase: ASFirebaseDatabaseProtocol {
private let firestoreRef = Firestore.firestore()
private var roomListeners: ListenerRegistration?
private var roomPublisher = PassthroughSubject<Room, Error>()
private var roomPublisher = CurrentValueSubject<Room?, Error>(nil)

public func addRoomListener(roomNumber: String) -> AnyPublisher<Room, Error> {
let roomRef = firestoreRef.collection("rooms").document(roomNumber)
Expand All @@ -18,19 +19,28 @@ public final class ASFirebaseDatabase: ASFirebaseDatabaseProtocol {
return self.roomPublisher.send(completion: .failure(ASNetworkErrors.FirebaseListenerError))
}

if document.metadata.isFromCache {
Logger.debug("로컬 캐시에서 데이터를 가져온 경우")
return
}

do {
let room = try document.data(as: Room.self)
Logger.debug("방 정보를 가져왔습니다.\n\(room)")
return self.roomPublisher.send(room)
} catch {
return self.roomPublisher.send(completion: .failure(ASNetworkErrors.FirebaseListenerError))
}
}

roomListeners = listener
return roomPublisher.eraseToAnyPublisher()
return roomPublisher
.compactMap { $0 }
.eraseToAnyPublisher()
}

public func removeRoomListener() {
roomPublisher.send(nil)
roomListeners?.remove()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public struct FirebaseEndpoint: Endpoint, Equatable {
public init(path: Path, method: HTTPMethod) {
self.path = path
self.method = method
headers = [:]
self.headers = [:]
}

// TODO: - firebase api/cloud func에 맞는 path 넣기
Expand All @@ -29,7 +29,7 @@ public struct FirebaseEndpoint: Endpoint, Equatable {
case submitMusic
case submitAnswer
case resetGame

public var description: String {
switch self {
case .auth:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import Foundation

public protocol MainRepositoryProtocol {
var myId: String? { get }
var number: CurrentValueSubject<String?, Never> { get }
var host: CurrentValueSubject<Player?, Never> { get }
var players: CurrentValueSubject<[Player]?, Never> { get }
var mode: CurrentValueSubject<Mode?, Never> { get }
var round: CurrentValueSubject<UInt8?, Never> { get }
var status: CurrentValueSubject<Status?, Never> { get }
var recordOrder: CurrentValueSubject<UInt8?, Never> { get }
var records: CurrentValueSubject<[ASEntity.Record]?, Never> { get }
var answers: CurrentValueSubject<[Answer]?, Never> { get }
var dueTime: CurrentValueSubject<Date?, Never> { get }
var selectedRecords: CurrentValueSubject<[UInt8]?, Never> { get }
var submits: CurrentValueSubject<[Answer]?, Never> { get }
var room: CurrentValueSubject<Room?, Never> { get }

func connectRoom(roomNumber: String)
func disconnectRoom()


func createRoom(nickname: String, avatar: URL) async throws -> String
func joinRoom(nickname: String, avatar: URL, roomNumber: String) async throws -> Bool
func leaveRoom() async throws -> Bool
func startGame() async throws -> Bool
func changeMode(mode: Mode) async throws -> Bool
func changeRecordOrder() async throws -> Bool
func resetGame() async throws -> Bool
func submitAnswer(answer: Music) async throws -> Bool
func getAvatarUrls() async throws -> [URL]
func getResource(url: URL) async throws -> Data

func submitMusic(answer: ASEntity.Music) async throws -> Bool
func postRecording(_ record: Data) async throws -> Bool
func postResetGame() async throws -> Bool
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ public protocol RoomActionRepositoryProtocol: Sendable {
func createRoom(nickname: String, avatar: URL) async throws -> String
func joinRoom(nickname: String, avatar: URL, roomNumber: String) async throws -> Bool
func leaveRoom() async throws -> Bool
func startGame(roomNumber: String) async throws -> Bool
func changeMode(roomNumber: String, mode: Mode) async throws -> Bool
func changeRecordOrder(roomNumber: String) async throws -> Bool
func startGame() async throws -> Bool
func changeMode(mode: Mode) async throws -> Bool
func changeRecordOrder() async throws -> Bool
func resetGame() async throws -> Bool
}

public protocol MusicRepositoryProtocol {
func getMusicData(url: URL) async -> Data?
func getMusicData(url: URL) async throws -> Data?
}

public protocol GameStateRepositoryProtocol {
Expand All @@ -71,5 +71,5 @@ public protocol GameStateRepositoryProtocol {

public protocol HummingResultRepositoryProtocol {
func getResult() -> AnyPublisher<[(answer: Answer, records: [ASEntity.Record], submit: Answer, recordOrder: UInt8)], Never>
func getRecordData(url: URL) -> Future<Data?, Error>
func getRecordData(url: URL) async throws -> Data
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
import ASDecoder
import ASEncoder
import ASEntity
import ASNetworkKit
import ASRepositoryProtocol
import Combine
import Foundation
import ASRepositoryProtocol

public final class AnswersRepository: AnswersRepositoryProtocol {
private var mainRepository: MainRepositoryProtocol
private var networkManager: ASNetworkManagerProtocol
public init(mainRepository: MainRepositoryProtocol, networkManager: ASNetworkManagerProtocol) {

public init(mainRepository: MainRepositoryProtocol) {
self.mainRepository = mainRepository
self.networkManager = networkManager
}

public func getAnswers() -> AnyPublisher<[Answer], Never> {
mainRepository.answers
mainRepository.room
.receive(on: DispatchQueue.main)
.compactMap { $0 }
.compactMap { $0?.answers }
.removeDuplicates()
.eraseToAnyPublisher()
}

public func getAnswersCount() -> AnyPublisher<Int, Never> {
mainRepository.answers
mainRepository.room
.receive(on: DispatchQueue.main)
.compactMap { $0 }
.map { $0.count }
.compactMap { $0?.answers }
.map(\.count)
.removeDuplicates()
.eraseToAnyPublisher()
}

Expand All @@ -34,9 +32,10 @@ public final class AnswersRepository: AnswersRepositoryProtocol {
return Just(nil).eraseToAnyPublisher()
}

return mainRepository.answers
return mainRepository.room
.receive(on: DispatchQueue.main)
.compactMap(\.self)
.compactMap { $0?.answers }
.removeDuplicates()
.flatMap { answers in
Just(answers.first { $0.player?.id == myId })
.eraseToAnyPublisher()
Expand All @@ -45,14 +44,6 @@ public final class AnswersRepository: AnswersRepositoryProtocol {
}

public func submitMusic(answer: ASEntity.Music) async throws -> Bool {
let queryItems = [URLQueryItem(name: "userId", value: ASFirebaseAuth.myID),
URLQueryItem(name: "roomNumber", value: mainRepository.number.value)]
let endPoint = FirebaseEndpoint(path: .submitMusic, method: .post)
.update(\.queryItems, with: queryItems)

let body = try ASEncoder.encode(answer)
let response = try await networkManager.sendRequest(to: endPoint, type: .json, body: body, option: .none)
let responseDict = try ASDecoder.decode([String: String].self, from: response)
return !responseDict.isEmpty
try await mainRepository.submitMusic(answer: answer)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import ASNetworkKit
import ASRepositoryProtocol
import Combine
import Foundation
import ASRepositoryProtocol

public final class AvatarRepository: AvatarRepositoryProtocol {
// TODO: - Container로 주입
private let storageManager: ASFirebaseStorageProtocol
private let networkManager: ASNetworkManagerProtocol
private let mainRepository: MainRepositoryProtocol

public init (
storageManager: ASFirebaseStorageProtocol,
networkManager: ASNetworkManagerProtocol
public init(
mainRepository: MainRepositoryProtocol
) {
self.storageManager = storageManager
self.networkManager = networkManager
self.mainRepository = mainRepository
}

public func getAvatarUrls() async throws -> [URL] {
do {
let urls = try await self.storageManager.getAvatarUrls()
let urls = try await self.mainRepository.getAvatarUrls()
return urls
} catch {
throw error
Expand All @@ -27,9 +22,7 @@ public final class AvatarRepository: AvatarRepositoryProtocol {

public func getAvatarData(url: URL) async -> Data? {
do {
guard let endpoint = ResourceEndpoint(url: url) else { return nil }
let data = try await self.networkManager.sendRequest(to: endpoint, type: .none, body: nil, option: .both)
return data
return try await mainRepository.getResource(url: url)
} catch {
return nil
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ASEntity
import ASRepositoryProtocol
import Combine
import Foundation
import ASRepositoryProtocol

public final class GameStateRepository: GameStateRepositoryProtocol {
private var mainRepository: MainRepositoryProtocol
Expand All @@ -11,12 +11,13 @@ public final class GameStateRepository: GameStateRepositoryProtocol {
}

public func getGameState() -> AnyPublisher<ASEntity.GameState?, Never> {
Publishers.CombineLatest4(mainRepository.mode, mainRepository.recordOrder, mainRepository.status, mainRepository.round)
mainRepository.room
.receive(on: DispatchQueue.main)
.map { mode, recordOrder, status, round in
guard let mode, let round, let players = self.mainRepository.players.value else { return nil }
return ASEntity.GameState(mode: mode, recordOrder: recordOrder, status: status, round: round, players: players)
.compactMap { room in
guard let mode = room?.mode, let players = room?.players else { return nil }
return ASEntity.GameState(mode: mode, recordOrder: room?.recordOrder, status: room?.status, round: room?.round, players: players)
}
.removeDuplicates()
.eraseToAnyPublisher()
}
}
Loading