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

Feature/quest repository #34

Merged
merged 23 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
010514b
[feat] add Date Extension
Jeonhui Nov 17, 2022
dc4e6d2
[feat] NetworkService & FirebaseService - Base Settings
Jeonhui Nov 17, 2022
078c39e
[feat] NetworkService protocol
Jeonhui Nov 21, 2022
ac9696f
Merge pull request #29 from boostcampwm-2022/feature/QuestRepositoryP…
sprituz Nov 21, 2022
946c2a3
[feat] create DefaultQuestsRepository
Jeonhui Nov 21, 2022
cbaa233
[feat] Add DTO
sprituz Nov 21, 2022
751b921
[feat] firebase test
Jeonhui Nov 21, 2022
cdce33b
[feat] update DTO Protocol
Jeonhui Nov 21, 2022
1f20391
[feat] update NetworkService & firebaseService
Jeonhui Nov 21, 2022
69c184e
[fix] UserQuestEntity
Jeonhui Nov 21, 2022
9ebd39c
[fix] UserQuestEntity
Jeonhui Nov 21, 2022
9946293
[fix] change func name (updateEntity->saveEntity))
Jeonhui Nov 21, 2022
bc20aa6
[feat] DefaultQuestsRepository
Jeonhui Nov 21, 2022
e145dfe
[fix] change EntityName (UserQuestEntity->QuestEntity))
Jeonhui Nov 21, 2022
278303c
[feat] RealmQuestsStorage
Jeonhui Nov 21, 2022
b865ad0
[fix] change Directory name (UserQuestsStorage->QuestsStorage)
Jeonhui Nov 21, 2022
5e9f0a1
[fix] Quest struct (add Date)
Jeonhui Nov 21, 2022
b694713
[feat] add String extension
Jeonhui Nov 21, 2022
263d8e1
[feat] Implement update and delete function
sprituz Nov 21, 2022
0a93ed0
[feat] DefaultQuestsRepository
Jeonhui Nov 22, 2022
d596b49
Merge branch 'develop' into feature/QuestRepository
Jeonhui Nov 22, 2022
219a05e
[feat] Delete Completion
sprituz Nov 22, 2022
31c8b09
Merge branch 'feature/firebase' into feature/QuestRepository
Jeonhui Nov 22, 2022
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
166 changes: 117 additions & 49 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions DailyQuest/DailyQuest/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import UIKit
import RxSwift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

Expand All @@ -26,6 +27,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
self.window?.rootViewController = tabbarController
self.window?.makeKeyAndVisible()

//_ = FirebaseService.shared.update(userCase: .currentUser, access: .quests, dto: QuestDTO(uuid: UUID(uuidString: "16AF9B21-4C85-4EF9-9DF5-B1A3385C9D56") ?? UUID(), title: "λ°”κΎΈκΈ°", currentCount: 0, totalCount: 0, groupUid: UUID(uuidString: "98AC0127-5CAF-4DC7-9365-9E5F819053BE") ?? UUID()))
_ = FirebaseService.shared.create(userCase: .currentUser, access: .quests, dto: QuestDTO(uuid: UUID(), title: "", currentCount: 0, totalCount: 0, groupUid: UUID()))

self.appCoordinator = AppCoordinator(tabBarController: tabbarController,
appDIContainer: appDIContainer)
self.appCoordinator?.start()
Expand Down
12 changes: 12 additions & 0 deletions DailyQuest/DailyQuest/Data/Network/DataMapping/DTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// DTO.swift
// DailyQuest
//
// Created by 이전희 on 2022/11/21.
//

import Foundation

protocol DTO: Codable {
var uuid: UUID { get }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// QuestDTO+Mapping.swift
// DailyQuest
//
// Created by 이닀연 on 2022/11/21.
//

import Foundation

struct QuestDTO: DTO {
let uuid: UUID
let title: String
let currentCount: Int
let totalCount: Int
let groupUid: UUID
}

extension QuestDTO {
func toDomain() -> Quest {
return Quest(groupId: groupUid,
uuid: uuid,
title: title,
currentCount: currentCount,
totalCount: totalCount)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Foundation

extension BrowseQuestEntity {
convenience init(browseQuest: BrowseQuest) {
let questsEntities = browseQuest.quests.compactMap { UserQuestEntity(quest: $0) }
let questsEntities = browseQuest.quests.compactMap { QuestEntity(quest: $0) }

self.init(uuid: browseQuest.uuid,
nickName: browseQuest.nickName,
quests: questsEntities)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension RealmBrowseQuestsStorage: BrowseQuestsStorage {
let browseQuestEntity = BrowseQuestEntity(browseQuest: browseQuest)

do {
try realmStorage.updateEntity(entity: browseQuestEntity)
try realmStorage.saveEntity(entity: browseQuestEntity)
single(.success(browseQuest))
} catch let error {
single(.failure(RealmStorageError.saveError(error)))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// QuestsStorage.swift
// DailyQuest
//
// Created by 이전희 on 2022/11/14.
//

import Foundation
import RxSwift

protocol QuestsStorage {
func saveQuests(with quests: [Quest]) -> Single<[Quest]>
func fetchQuests(by date: Date) -> Observable<[Quest]>
func updateQuest(with quest: Quest) -> Single<Quest>
func deleteQuest(with questId: UUID) -> Single<Quest>
func deleteQuestGroup(with groupId: UUID) -> Single<[Quest]>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// QuestEntity+Mapping.swift
// DailyQuest
//
// Created by 이전희 on 2022/11/14.
//

import Foundation

extension QuestEntity {
convenience init(quest: Quest) { // Quest에 date λ“€μ–΄κ°€λ©΄ μˆ˜μ •
self.init(
groupId: quest.groupId,
uuid: quest.uuid,
date: quest.date.toString,
title: quest.title,
currentCount: quest.currentCount,
totalCount: quest.totalCount)
}
}

extension QuestEntity {
func toDomain() -> Quest {
return Quest(groupId: groupId,
uuid: uuid,
date: date.toDate() ?? Date(),
title: title,
currentCount: currentCount,
totalCount: totalCount)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//
// RealmQuestsStorage.swift
// DailyQuest
//
// Created by 이전희 on 2022/11/14.
//

import Foundation
import RxSwift

final class RealmQuestsStorage {

private let realmStorage: RealmStorage

init(realmStorage: RealmStorage = RealmStorage.shared) {
self.realmStorage = realmStorage
}
}

extension RealmQuestsStorage: QuestsStorage {

func saveQuests(with quests: [Quest]) -> Single<[Quest]> {
return Single.create { [weak self] single in
guard let realmStorage = self?.realmStorage else {
return Disposables.create()
}

do {
for quest in quests {
let questEntity = QuestEntity(quest: quest)
try realmStorage.saveEntity(entity: questEntity)
}
single(.success(quests))
} catch let error {
single(.failure(RealmStorageError.saveError(error)))

}
return Disposables.create()
}
}

func fetchQuests(by date: Date) -> Observable<[Quest]> {
return Observable<[Quest]>.create { [weak self] observer in
guard let realmStorage = self?.realmStorage else {
return Disposables.create()
}

do {
let quests = try realmStorage
.fetchEntities(type: QuestEntity.self, filter: NSPredicate(format: "date == %@", date.toString))
Copy link
Collaborator

Choose a reason for hiding this comment

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

개인적인 μ˜κ²¬μž…λ‹ˆλ‹€λ§Œ κ°€λŠ₯ν•˜λ‹€λ©΄ NSPredicate듀을 enum μ΄λ‚˜ struct둜 predicate에 λŒ€ν•΄ 이름이 있으면 훨씬 읽기 μ‰¬μšΈ 것 κ°™μŠ΅λ‹ˆλ‹Ή. μ•„λ‹ˆλ©΄ ν•¨μˆ˜ λ‚΄μ—μ„œ let으둜 λΉΌκ±°λ‚˜?

.compactMap { $0.toDomain() }
observer.onNext(quests)
observer.onCompleted()
} catch let error {
observer.onError(error)
}

return Disposables.create()
}
}

func updateQuest(with quest: Quest) -> Single<Quest> {
return Single.create { [weak self] single in
guard let realmStorage = self?.realmStorage else {
return Disposables.create()
}
let questEntity = QuestEntity(quest: quest)
do {
try realmStorage.updateEntity(entity: questEntity)
single(.success(quest))
} catch let error {
single(.failure(RealmStorageError.saveError(error)))
}

return Disposables.create()
}
}

func deleteQuest(with questId: UUID) -> Single<Quest> {
return Single.create { [weak self] single in
guard let realmStorage = self?.realmStorage else {
return Disposables.create()
}

do {
guard let entity = try realmStorage.findEntities(type: QuestEntity.self, filter: NSPredicate(format: "uuid == %@", questId as CVarArg)).first else {
throw RealmStorageError.noDataError
}
let quest = entity.toDomain()
try realmStorage.deleteEntity(entity: entity)
single(.success(quest))

} catch let error {
single(.failure(RealmStorageError.saveError(error)))
}

return Disposables.create()
}

}

func deleteQuestGroup(with groupId: UUID) -> Single<[Quest]> {
return Single.create { [weak self] single in
guard let realmStorage = self?.realmStorage else {
return Disposables.create()
}

do {
let entities = try realmStorage.findEntities(type: QuestEntity.self, filter: NSPredicate(format: "groupId == %@", groupId as CVarArg))
let quests = entities.compactMap { $0.toDomain() }
for entity in entities {
try realmStorage.deleteEntity(entity: entity)
}
single(.success(quests))

} catch let error {
single(.failure(RealmStorageError.saveError(error)))
}

return Disposables.create()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import RealmSwift
final class BrowseQuestEntity: Object {
@Persisted var uuid: UUID
@Persisted var nickName: String
@Persisted var quests: List<UserQuestEntity>
@Persisted var quests: List<QuestEntity>

override init() { }

init(uuid: UUID, nickName: String, quests: [UserQuestEntity]) {
init(uuid: UUID, nickName: String, quests: [QuestEntity]) {
self.uuid = uuid
self.nickName = nickName
let realmList = List<UserQuestEntity>()
let realmList = List<QuestEntity>()
realmList.append(objectsIn: quests)
self.quests = realmList
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,25 @@
import Foundation
import RealmSwift

final class UserQuestEntity: Object {
final class QuestEntity: Object {
@Persisted var groupId: UUID
@Persisted var uuid: UUID
@Persisted var date: String
@Persisted var title: String
@Persisted var startDay: Date
@Persisted var endDay: Date
@Persisted var `repeat`: Int
@Persisted var currentCount: Int
@Persisted var totalCount: Int

override init() { }

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

override class func primaryKey() -> String? {
"uuid"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,67 @@ enum RealmStorageError: Error {

final class RealmStorage {
static let shared = RealmStorage()

private init() {
// Realm file path
#if DEBUG
print(Realm.Configuration.defaultConfiguration.fileURL!)
#endif
}

private let persistentContainer = try? Realm()

func updateEntity(entity: Object) throws {
@discardableResult
func saveEntity<O: Object>(entity: O) throws -> O {
guard let persistentContainer = persistentContainer else {
throw RealmStorageError.realmObjectError
}
try persistentContainer.write {
persistentContainer.add(entity)
}
return entity
}

func fetchEntities<O: Object>(type: O.Type, filter: NSPredicate? = nil) throws -> [O] {
guard let persistentContainer = persistentContainer else {
throw RealmStorageError.realmObjectError
}
if let filter = filter {
print(filter)
return Array(persistentContainer.objects(type).filter(filter))
} else {
return Array(persistentContainer.objects(type))
}
}

func fetchEntities<O: Object>(type: O.Type) throws -> [O] {
@discardableResult
func updateEntity<O: Object>(entity: O) throws -> O {
guard let persistentContainer = persistentContainer else {
throw RealmStorageError.realmObjectError
}
return Array(persistentContainer.objects(type))
try persistentContainer.write {
persistentContainer.add(entity, update: .modified)
}
return entity
}

@discardableResult
func deleteEntity<O: Object>(entity: O) throws -> O {
guard let persistentContainer = persistentContainer else {
throw RealmStorageError.realmObjectError
}
try persistentContainer.write {
persistentContainer.delete(entity)
}

return entity
}

func findEntities<O: Object>(type: O.Type, filter: NSPredicate) throws -> [O] {
guard let persistentContainer = persistentContainer else {
throw RealmStorageError.realmObjectError
}
return Array(persistentContainer.objects(type).filter(filter))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extension RealmUserInfoStorage: UserInfoStorage {

do {
// update μ„±κ³΅ν–ˆμ„ 경우, success(user)
try realmStorage.updateEntity(entity: userInfo)
try realmStorage.saveEntity(entity: userInfo)
single(.success(user))
} catch let error {
// update μ„±κ³΅ν•˜μ§€ λͺ»ν–ˆμ„ 경우, failure(error)
Expand Down
Loading