Skip to content

Commit

Permalink
Merge pull request #102 from boostcampwm-2022/refactor/UserUseCase
Browse files Browse the repository at this point in the history
Refactor/user use case
  • Loading branch information
jinwoong16 committed Dec 7, 2022
2 parents 05a5570 + b9fdf85 commit 14c4342
Show file tree
Hide file tree
Showing 25 changed files with 517 additions and 120 deletions.
14 changes: 13 additions & 1 deletion DailyQuest/DailyQuest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
9BD8CCFB2937407100E6EA2F /* FollowingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8CCFA2937407100E6EA2F /* FollowingCell.swift */; };
9BD8CD00293829DD00E6EA2F /* FollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8CCFF293829DD00E6EA2F /* FollowingView.swift */; };
9BD8CD022938418500E6EA2F /* LastFollowingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8CD012938418500E6EA2F /* LastFollowingCell.swift */; };
9BED4DE2293DD53500C60631 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BED4DE0293D938400C60631 /* ProfileViewController.swift */; };
9BED4DE8293FA01400C60631 /* ProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BED4DE7293FA01400C60631 /* ProfileViewModel.swift */; };
9BED4DEA293FA92900C60631 /* UIImageView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BED4DE9293FA92900C60631 /* UIImageView+.swift */; };
A5003AB4293F5FEC00082A9C /* SignUpViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5003AB3293F5FEC00082A9C /* SignUpViewModel.swift */; };
A5003AB6293F601E00082A9C /* SignUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5003AB5293F601E00082A9C /* SignUpViewController.swift */; };
A5003AB9293F909300082A9C /* UserUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5003AB8293F909300082A9C /* UserUseCase.swift */; };
Expand Down Expand Up @@ -326,6 +329,9 @@
9BD8CCFA2937407100E6EA2F /* FollowingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingCell.swift; sourceTree = "<group>"; };
9BD8CCFF293829DD00E6EA2F /* FollowingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingView.swift; sourceTree = "<group>"; };
9BD8CD012938418500E6EA2F /* LastFollowingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastFollowingCell.swift; sourceTree = "<group>"; };
9BED4DE0293D938400C60631 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
9BED4DE7293FA01400C60631 /* ProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewModel.swift; sourceTree = "<group>"; };
9BED4DE9293FA92900C60631 /* UIImageView+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+.swift"; sourceTree = "<group>"; };
A5003AB3293F5FEC00082A9C /* SignUpViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpViewModel.swift; sourceTree = "<group>"; };
A5003AB5293F601E00082A9C /* SignUpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpViewController.swift; sourceTree = "<group>"; };
A5003AB8293F909300082A9C /* UserUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserUseCase.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -541,9 +547,9 @@
342830A5292E0F8600AE811B /* ViewController */ = {
isa = PBXGroup;
children = (
342830A9292E12C700AE811B /* SettingsViewController.swift */,
34113BEA2934A3B200AB4919 /* LoginViewController.swift */,
A5003AB5293F601E00082A9C /* SignUpViewController.swift */,
342830A9292E12C700AE811B /* SettingsViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
Expand Down Expand Up @@ -638,6 +644,7 @@
34874AA129250C43000570DF /* UIButton+.swift */,
A5656458292BBDD40033E763 /* String+.swift */,
A50F9A3829266FD8005C00FE /* Date+.swift */,
9BED4DE9293FA92900C60631 /* UIImageView+.swift */,
3436FCF9293F2654003575C3 /* Notification+.swift */,
);
path = Utils;
Expand Down Expand Up @@ -766,6 +773,7 @@
children = (
34A529DF29247F1F001BAD34 /* HomeViewController.swift */,
345687F32937329E00CA51E3 /* EnrollViewController.swift */,
9BED4DE0293D938400C60631 /* ProfileViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
Expand All @@ -775,6 +783,7 @@
children = (
345687FD29378AB900CA51E3 /* EnrollViewModel.swift */,
B5115452292CD07100FDBD22 /* CalendarViewModel.swift */,
9BED4DE7293FA01400C60631 /* ProfileViewModel.swift */,
348FCE012940294900E4940C /* HomeViewModel.swift */,
);
path = ViewModel;
Expand Down Expand Up @@ -1293,6 +1302,7 @@
A51F01D52923407E0031ECA2 /* BrowseQuestEntity.swift in Sources */,
3416FC8A292B560800B504C5 /* DefaultQuestUseCase.swift in Sources */,
9BD8CCF32935BC0D00E6EA2F /* DefaultBrowseRepository.swift in Sources */,
9BED4DEA293FA92900C60631 /* UIImageView+.swift in Sources */,
342830FD292E2AF200AE811B /* NavigateField.swift in Sources */,
342830F2292E196E00AE811B /* CommonField.swift in Sources */,
342830A8292E0FAC00AE811B /* SettingsCoordinator.swift in Sources */,
Expand All @@ -1305,12 +1315,14 @@
345687FA2937815900CA51E3 /* QuantityView.swift in Sources */,
342830AA292E12C700AE811B /* SettingsViewController.swift in Sources */,
34A529E029247F1F001BAD34 /* HomeViewController.swift in Sources */,
9BED4DE2293DD53500C60631 /* ProfileViewController.swift in Sources */,
34A529D529247932001BAD34 /* AppCoordinator.swift in Sources */,
B50078D629222F3F0070AFC4 /* CircleCheckView.swift in Sources */,
3499552729235D1E007AB99E /* BrowseItemViewModel.swift in Sources */,
9BD8CCFB2937407100E6EA2F /* FollowingCell.swift in Sources */,
A5D3C823293DDDAD00F43B76 /* ProtectedUserRepository.swift in Sources */,
347D258B292C60F40038FCA2 /* StatusView.swift in Sources */,
9BED4DE8293FA01400C60631 /* ProfileViewModel.swift in Sources */,
34642AB62925D9E40052FA0E /* UserInfoView.swift in Sources */,
349955292923600A007AB99E /* BrowseViewController.swift in Sources */,
34113BE82934917500AB4919 /* LoginViewModel.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,59 @@
import UIKit

final class HomeSceneDIContainer {

lazy var questsStorage: QuestsStorage = RealmQuestsStorage()

lazy var userStorage: UserInfoStorage = RealmUserInfoStorage()
lazy var networkService: NetworkService = FirebaseService.shared

// MARK: - Repositories
func makeQuestsRepository() -> QuestsRepository {
return DefaultQuestsRepository(persistentStorage: questsStorage)
}


func makeUserRepository() -> UserRepository {
return DefaultUserRepository(persistentStorage: userStorage, networkService: networkService)
}

// MARK: - Use Cases
func makeQuestUseCase() -> QuestUseCase {
return DefaultQuestUseCase(questsRepository: makeQuestsRepository())
}

func makeEnrollUseCase() -> EnrollUseCase {
return DefaultEnrollUseCase(questsRepository: makeQuestsRepository())
}


func makeUesrUseCase() -> UserUseCase {
return DefaultUserUseCase(userRepository: makeUserRepository())
}

// MARK: - View Models
func makeHomeViewModel() -> HomeViewModel {
return HomeViewModel(questUseCase: makeQuestUseCase())
}

func makeEnrollViewModel() -> EnrollViewModel {
return EnrollViewModel(enrollUseCase: makeEnrollUseCase())
}

func makeProfileViewModel() -> ProfileViewModel {
return ProfileViewModel(userUseCase: makeUesrUseCase())
}

// MARK: - View Controller
func makeHomeViewController() -> HomeViewController {
return HomeViewController.create(with: makeHomeViewModel())
}

func makeEnrollViewController() -> EnrollViewController {
return EnrollViewController.create(with: makeEnrollViewModel())
}

func makeProfileViewController() -> ProfileViewController {
return ProfileViewController.create(with: makeProfileViewModel())
}

// MARK: - Flow
func makeHomeCoordinator(navigationController: UINavigationController,
homeSceneDIContainer: HomeSceneDIContainer) -> HomeCoordinator {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "블러.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ struct UserDTO: DTO {
let nickName: String
let profileURL: String
let backgroundImageURL: String
let description: String
let introduce: String
let allow: Bool

init() {
self.uuid = ""
self.nickName = ""
self.profileURL = ""
self.backgroundImageURL = ""
self.description = ""
self.introduce = ""
self.allow = false
}

Expand All @@ -29,7 +29,7 @@ struct UserDTO: DTO {
self.nickName = user.nickName
self.profileURL = user.profileURL
self.backgroundImageURL = user.backgroundImageURL
self.description = user.description
self.introduce = user.introduce
self.allow = user.allow
}

Expand All @@ -38,7 +38,7 @@ struct UserDTO: DTO {
self.nickName = userDto.nickName
self.profileURL = userDto.profileURL
self.backgroundImageURL = userDto.backgroundImageURL
self.description = userDto.description
self.introduce = userDto.introduce
self.allow = userDto.allow
}
}
Expand All @@ -49,7 +49,7 @@ extension UserDTO {
nickName: nickName,
profileURL: profileURL,
backgroundImageURL: backgroundImageURL,
description: description,
introduce: introduce,
allow: allow)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extension BrowseQuestEntity {
nickName: nickName,
profileURL: profileImageURL,
backgroundImageURL: "",
description: "",
introduce: "",
allow: false),
quests: quests)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ final class UserInfoEntity: Object {
@Persisted var nickName: String
@Persisted var profileURL: String
@Persisted var backgroundImageURL: String
@Persisted var userDescription: String
@Persisted var introduce: String
@Persisted var allow: Bool

override init() { }

init(uuid: String, nickName: String, profileURL: String, backgroundImageURL: String, description: String, allow: Bool) {
init(uuid: String, nickName: String, profileURL: String, backgroundImageURL: String, introduce: String, allow: Bool) {
self.uuid = uuid
self.nickName = nickName
self.profileURL = profileURL
self.backgroundImageURL = backgroundImageURL
self.userDescription = description
self.introduce = introduce
self.allow = allow
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ final class RealmStorage {
@discardableResult
func saveEntity<O: Object>(entity: O) throws -> O {
guard let persistentContainer = persistentContainer else {
print(#function)
throw RealmStorageError.realmObjectError
}
try persistentContainer.write {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension UserInfoEntity {
nickName: user.nickName,
profileURL: user.profileURL,
backgroundImageURL: user.backgroundImageURL,
description: user.description,
introduce: user.introduce,
allow: user.allow)
}
}
Expand All @@ -26,7 +26,7 @@ extension UserInfoEntity {
nickName: nickName,
profileURL: profileURL,
backgroundImageURL: backgroundImageURL,
description: description,
introduce: introduce,
allow: allow)
}
}
59 changes: 48 additions & 11 deletions DailyQuest/DailyQuest/Data/Repositories/DefaultUserRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by 이전희 on 2022/12/01.
//

import Foundation
import RxSwift
import RxRelay

Expand All @@ -13,6 +14,8 @@ final class DefaultUserRepository {
private let persistentStorage: UserInfoStorage
private let networkService: NetworkService

private let disposeBag = DisposeBag()

init(persistentStorage: UserInfoStorage, networkService: NetworkService = FirebaseService.shared) {
self.persistentStorage = persistentStorage
self.networkService = networkService
Expand All @@ -24,42 +27,76 @@ extension DefaultUserRepository: UserRepository {
return networkService.uid
}

func readUser() -> Observable<User> {
func readUser() -> Single<User> {
return self.persistentStorage.fetchUserInfo()
.catch { [weak self] _ in
guard let self = self else { return Observable.just(User()) }
return self.fetchUserNetworkService()
}
.asSingle()
}

func updateUser(by user: User) -> Observable<User> {
func updateUser(by user: User) -> Single<User> {
return persistentStorage.updateUserInfo(user: user)
.asObservable()
.flatMap(updateUserNetworkService(user:))
.asSingle()
}

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

func saveProfileImage(data: Data) -> Single<Bool> {
networkService.uploadDataStorage(data: data, path: .profileImages)
.flatMap { [weak self] downloadUrl in
guard let self = self else { return Single.just(User()) }
return self.persistentStorage.fetchUserInfo()
.map { $0.setProfileImageURL(profileURL: downloadUrl) }
.asSingle()
}
.flatMap(updateUser(by:))
.map { _ in true }
.catchAndReturn(false)
}

func saveBackgroundImage(data: Data) -> Single<Bool> {
networkService.uploadDataStorage(data: data, path: .backgroundImages)
.flatMap { [weak self] downloadUrl in
guard let self = self else { return Single.just(User()) }
return self.persistentStorage.fetchUserInfo()
.map { $0.setBackgroundImageURL(backgroundImageURL: downloadUrl) }
.asSingle()
}
.flatMap(updateUser(by:))
.map { _ in true }
.catchAndReturn(false)

}

}

extension DefaultUserRepository: ProtectedUserRepository {
func deleteUser() -> Observable<Bool> {
// return self.persistentStorage.deleteUserInfo()
// .map { _ in true }
// .asObservable()
// .concatMap { _ in
// return self.networkService.delete(userCase: .currentUser, access: .userInfo, dto: UserDTO())
// .map { _ in true }
// }
return networkService.delete(userCase: .currentUser, access: .userInfo, dto: UserDTO())
return networkService
.delete(userCase: .currentUser, access: .userInfo, dto: UserDTO())
.flatMap { [weak self] _ in
guard let self = self else { return .just(true) }
return self.networkService.deleteUser() }
.map { _ in true }
.catchAndReturn(false)
.asObservable()
.do(onNext: { [weak self]_ in
guard let self = self else { return }
self.networkService.signOut().subscribe()
.disposed(by: self.disposeBag)
})

}
}

Expand Down
Loading

0 comments on commit 14c4342

Please sign in to comment.