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/data layer (3) #86

Merged
merged 11 commits into from
Dec 6, 2022
126 changes: 126 additions & 0 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions DailyQuest/DailyQuest/Data/DataConfigure.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// DataConfigure.swift
// DailyQuest
//
// Created by ์ด์ „ํฌ on 2022/12/05.
//

import Foundation

enum DateFilter {
case today(_ date: Date)
case month(_ date: Date)
case year(_date: Date)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ struct QuestDTO: DTO {
self.currentCount = 0
self.totalCount = 0
}

init(groupId: UUID, uuid: String, date: String, title: String, currentCount: Int, totalCount: Int) {
self.groupId = groupId
self.uuid = uuid
self.date = date
self.title = title
self.currentCount = currentCount
self.totalCount = totalCount
}
}

extension QuestDTO {
Expand All @@ -35,3 +44,14 @@ extension QuestDTO {
totalCount: totalCount)
}
}

extension Quest {
func toDTO() -> QuestDTO {
return QuestDTO(groupId: groupId,
uuid: uuid.uuidString,
date: date.toString,
title: title,
currentCount: currentCount,
totalCount: totalCount)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,64 +9,59 @@ import Foundation
import RxSwift

final class DefaultBrowseRepository {

private let persistentStorage: BrowseQuestsStorage
private let networkService: NetworkService

init(persistentStorage: BrowseQuestsStorage, networkService: NetworkService = FirebaseService.shared) {

private let disposeBag: DisposeBag

init(persistentStorage: BrowseQuestsStorage,
networkService: NetworkService = FirebaseService.shared,
repositoryManager: RepositoryManager = RepositoryManager.shared) {
self.persistentStorage = persistentStorage
self.networkService = networkService
self.disposeBag = repositoryManager.disposeBag
}
}

extension DefaultBrowseRepository: BrowseRepository {

/// Fetch BrowseQuests
/// Firebase ์šฐ์„ , ์‹คํŒจ์‹œ persistentStorage, persistentStorage๋„ ์‹คํŒจ์‹œ Error๋ฐ˜ํ™˜
/// - Returns: Observable<[BrowseQuest]>
func fetch() -> Observable<[BrowseQuest]> {
return self.networkService.getAllowUsers(limit: 10)
.map { $0.toDomain() }
.flatMap { user in
self.networkService
.read(type: QuestDTO.self, userCase: .anotherUser(user.uuid), access: .quests, filter: .today(Date()))
.map { $0.toDomain() }
.toArray()
.asObservable()
.map { questList in
return BrowseQuest(user: user, quests: questList)
}
self.networkService
.read(type: QuestDTO.self, userCase: .anotherUser(user.uuid), access: .quests, filter: .today(Date()))
.map { $0.toDomain() }
.toArray()
.asObservable()
.map { questList in
return BrowseQuest(user: user, quests: questList)
}

}

.filter { !$0.quests.isEmpty }
.toArray()
.asObservable()
.do(afterNext: { browseQuests in
_ = self.persistentStorage.deleteBrowseQuests()
.asObservable()
.concatMap { _ in
Observable.from(browseQuests)
.flatMap { browseQuest in
self.persistentStorage.saveBrowseQuest(browseQuest: browseQuest)
.asObservable()
}
}
.subscribe(onError: { error in
print(error)
})
})
.catch { error in
return self.persistentStorage.fetchBrowseQuests()
self.persistentStorage.deleteBrowseQuests()
.asObservable()
.concatMap { _ in
Observable.from(browseQuests)
.flatMap { browseQuest in
self.persistentStorage.saveBrowseQuest(browseQuest: browseQuest)
.asObservable()
}
}
}
}

extension DefaultBrowseRepository {
static func test() {
let browseRepository = DefaultBrowseRepository(persistentStorage: RealmBrowseQuestsStorage(), networkService: FirebaseService.shared)
let fetchBrowseQuestsObserver = browseRepository.fetch()
_ = fetchBrowseQuestsObserver.subscribe { event in
print(event)
.subscribe(onError: { error in
print(error)
}).disposed(by: self.disposeBag)
})
.catch { error in
return self.persistentStorage.fetchBrowseQuests()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,80 +11,80 @@ import Foundation
final class DefaultQuestsRepository {

private let persistentStorage: QuestsStorage
private let networkService: NetworkService

init(persistentStorage: QuestsStorage) {
init(persistentStorage: QuestsStorage, networkService: NetworkService = FirebaseService.shared) {
self.persistentStorage = persistentStorage
self.networkService = networkService
}
}

extension DefaultQuestsRepository: QuestsRepository {
func save(with quest: [Quest]) -> Single<[Quest]> {
return persistentStorage.saveQuests(with: quest)
.flatMap { quests in
return Observable.from(quests)
.concatMap { quest in
return self.networkService.create(userCase: .currentUser,
access: .quests,
dto: quest.toDTO())
}
.map { $0.toDomain() }
.toArray()
}
}

func fetch(by date: Date) -> Observable<[Quest]> {
return persistentStorage.fetchQuests(by: date)
.catch { _ in
self.networkService.read(type: QuestDTO.self, userCase: .currentUser, access: .quests, filter: .today(date))
.map { $0.toDomain() }
.toArray()
.asObservable()
}
}

func update(with quest: Quest) -> Single<Quest> {
return persistentStorage.updateQuest(with: quest)
.flatMap { quest in
self.networkService.update(userCase: .currentUser, access: .quests, dto: quest.toDTO())
}
.map { $0.toDomain() }
.asObservable()
.asSingle()
}

func delete(with questId: UUID) -> Single<Quest> {
return persistentStorage.deleteQuest(with: questId)
.flatMap { quest in
self.networkService.delete(userCase: .currentUser, access: .quests, dto: quest.toDTO())
}
.map { $0.toDomain() }
.asObservable()
.asSingle()
}

func deleteAll(with groupId: UUID) -> Single<[Quest]> {
return persistentStorage.deleteQuestGroup(with: groupId)
}

func fetch(by uuid: String) -> Observable<[Quest]> {
return .just([])
}
}

extension DefaultQuestsRepository {
static func test() {
let persistentStorage = RealmQuestsStorage()
let repository = DefaultQuestsRepository(persistentStorage: persistentStorage)
let dummyDate = ["2022-11-17".toDate()!,
"2022-11-18".toDate()!,
"2022-11-19".toDate()!,
"2022-11-20".toDate()!,
"2022-11-21".toDate()!,
"2022-11-22".toDate()!,
"2022-11-23".toDate()!,
"2022-11-24".toDate()!]
let dummyData = (0...10).compactMap { i in
Quest(groupId: UUID(), uuid: UUID(), date: dummyDate[i % dummyDate.count], title: "\(i) dummyData", currentCount: 0, totalCount: i % 5)
}

print("๐Ÿ€save")
let _ = repository.save(with: dummyData)
.subscribe { event in
print(event)
}

print("๐Ÿ€fetch \(Date())")

let _ = repository.fetch(by: Date())
.subscribe { event in
print(event)
}

let temp = dummyData[0]
print("๐Ÿ€update \(temp.uuid)")
let quest = Quest(groupId: temp.groupId, uuid: temp.uuid, date: temp.date, title: "change", currentCount: temp.currentCount + 1, totalCount: temp.totalCount)
let _ = repository.update(with: quest)
.subscribe { event in
print(event)
}

print("๐Ÿ€delete \(dummyData[1].uuid)")
let _ = repository.delete(with: dummyData[1].uuid)
.subscribe { event in
print(event)
.flatMap { quests in
return Observable.from(quests)
.concatMap { quest in
self.networkService.delete(userCase: .currentUser,
access: .quests,
dto: quest.toDTO())
}
.map { $0.toDomain() }
.toArray()
}
}

func fetch(by uuid: String, date: Date) -> Observable<[Quest]> { // ๋ฐ›์„ ๋‚ ์งœ๊นŒ์ง€ ๋ฐ›์•„์™€์•ผํ•จ
return self.networkService.read(type: QuestDTO.self,
userCase: .anotherUser(uuid),
access: .quests,
filter: .today(date))
.map { $0.toDomain() }
.toArray()
.asObservable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ extension DefaultUserRepository: UserRepository {
}
}

func fetchUser(by uuid: String) -> Observable<User> {
return self.networkService.read(type: UserDTO.self,
userCase: .anotherUser(uuid),
access: .userInfo,
filter: nil)
.map { $0.toDomain() }
}
}

extension DefaultUserRepository: ProtectedUserRepository {
func deleteUser() -> Observable<Bool> {
return self.persistentStorage.deleteUserInfo()
.map { _ in true }
Expand All @@ -51,8 +61,4 @@ extension DefaultUserRepository: UserRepository {
.map { _ in true }
}
}

func fetchUser(by uuid: String) -> Observable<User> {
.just(User(uuid: "", nickName: "", profileURL: "", backgroundImageURL: "", description: "", allow: true))
}
}
15 changes: 15 additions & 0 deletions DailyQuest/DailyQuest/Data/Repositories/RepositoryManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// RepositoryManager.swift
// DailyQuest
//
// Created by ์ด์ „ํฌ on 2022/12/05.
//

import RxSwift

final class RepositoryManager {
static let shared = RepositoryManager()
private init() { }

var disposeBag: DisposeBag = DisposeBag()
}
Comment on lines +10 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

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

์ƒ๊ฐํ•ด๋ณด๋‹ˆ ์ด๋ฐฉ์‹์€ ์œ ์˜ํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ๋“ฏ ํ•ฉ๋‹ˆ๋‹ค. fetch()๋ฉ”์„œ๋“œ ๋“ฑ์ด ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ๊ธฐ์กด์˜ disposable์ด dispose๋˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด disposable์ด ์ƒ์„ฑ๋  ๊ฒƒ ๊ฐ™๋„ค์š”.

Copy link
Member Author

Choose a reason for hiding this comment

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

์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” ์ œ๊ฐ€ ์ง€์‹์ด ์กฐ๊ธˆ ๋ถ€์กฑํ•œ ๊ฒƒ ๊ฐ™๋„ค์š” ์กฐ๊ธˆ ๋” ๊ณต๋ถ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜Š ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// ProtectedUserRepository.swift
// DailyQuest
//
// Created by ์ด์ „ํฌ on 2022/12/05.
//

import RxSwift

protocol ProtectedUserRepository {
/// ์œ ์ €์ •๋ณด๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
/// - Returns: ์‚ญ์ œ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
func deleteUser() -> Observable<Bool>
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protocol QuestsRepository {
- Returns: ์„ฑ๊ณต์‹œ Quest๋ฅผ, ์‹คํŒจ์‹œ, error๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
*/
func save(with quest: [Quest]) -> Single<[Quest]>

/**
ํ•ด๋‹น ๋‚ ์งœ์˜ ํ€˜์ŠคํŠธ ๋ฐฐ์—ด์„ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.

Expand All @@ -27,7 +27,7 @@ protocol QuestsRepository {
- Returns: Quest์˜ ๋ฐฐ์—ด์„ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค. ๋น„์–ด์žˆ๋‹ค๋ฉด ๋น„์–ด์žˆ๋Š” ๋ฐฐ์—ด์„ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค.
*/
func fetch(by date: Date) -> Observable<[Quest]>

/**
ํ•ด๋‹น ๋‚ ์งœ์˜ ํ€˜์ŠคํŠธ ๊ฐ’(`currentCount`)์„ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.

Expand All @@ -36,7 +36,7 @@ protocol QuestsRepository {
- Returns: ์„ฑ๊ณต์‹œ Quest๋ฅผ, ์‹คํŒจ์‹œ error๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
*/
func update(with quest: Quest) -> Single<Quest>

/**
ํ•ด๋‹น ๋‚ ์งœ์— ํ•ด๋‹นํ•˜๋Š” ํ€˜์ŠคํŠธ์˜ ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.

Expand All @@ -45,7 +45,7 @@ protocol QuestsRepository {
- Returns: ์„ฑ๊ณต์‹œ ํ•ด๋‹น Quest๋ฅผ, ์‹คํŒจ์‹œ error๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
*/
func delete(with questId: UUID) -> Single<Quest>

/**
ํ•ด๋‹น group์˜ Quest๋ฅผ ๋ชจ๋‘ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

Expand All @@ -55,6 +55,6 @@ protocol QuestsRepository {
- Returns: ์„ฑ๊ณต์‹œ ํ•ด๋‹น Quest ๋ฐฐ์—ด์„, ์‹คํŒจ์‹œ error๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
*/
func deleteAll(with groupId: UUID) -> Single<[Quest]>
func fetch(by uuid: String) -> Observable<[Quest]>

func fetch(by uuid: String, date: Date) -> Observable<[Quest]>
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,5 @@ protocol UserRepository {
/// - Returns: ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ”๋€ ์œ ์ €์˜ ์ •๋ณด๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
func updateUser(by user: User) -> Observable<User>

/// ์œ ์ €์ •๋ณด๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
/// - Returns: ์‚ญ์ œ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์ž…๋‹ˆ๋‹ค.
func deleteUser() -> Observable<Bool>

func fetchUser(by uuid: String) -> Observable<User>
}
Loading