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/user use case #102

Merged
merged 21 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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