Skip to content

Commit

Permalink
Merge pull request #101 from boostcampwm-2024/feature/load-page-data
Browse files Browse the repository at this point in the history
CoreData에서 Page 데이터 읽어오기 및 보여주기 (멀티미디어 포함 X)
  • Loading branch information
k2645 authored Nov 30, 2024
2 parents 6e8201f + c5b6e0c commit fa83564
Show file tree
Hide file tree
Showing 27 changed files with 441 additions and 279 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
BookCategoryStorage.self,
object: CoreDataBookCategoryStorage(coreDataStorage: coreDataStorage)
)
DIContainer.shared.register(
BookCoverStorage.self,
object: CoreDataBookCoverStorage(coreDataStorage: coreDataStorage)
)
DIContainer.shared.register(
BookStorage.self,
object: CoreDataBookStorage(coreDataStorage: coreDataStorage)
)
}

private func registerRepositoryDependency() throws {
Expand All @@ -67,6 +75,16 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
BookCategoryRepository.self,
object: LocalBookCategoryRepository(storage: bookCategoryStorage)
)
let bookCoverStorage = try DIContainer.shared.resolve(BookCoverStorage.self)
DIContainer.shared.register(
BookCoverRepository.self,
object: LocalBookCoverRepository(storage: bookCoverStorage)
)
let bookStorage = try DIContainer.shared.resolve(BookStorage.self)
DIContainer.shared.register(
BookRepository.self,
object: LocalBookRepository(storage: bookStorage)
)
}

private func registerUseCaseDependency() throws {
Expand Down Expand Up @@ -95,6 +113,25 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
DeleteBookCategoryUseCase.self,
object: DefaultDeleteBookCategoryUseCase(repository: bookCategoryRepository)
)

// MARK: - Book UseCase
let bookRepository = try DIContainer.shared.resolve(BookRepository.self)
DIContainer.shared.register(
CreateBookUseCase.self,
object: DefaultCreateBookUseCase(repository: bookRepository)
)
DIContainer.shared.register(
FetchBookUseCase.self,
object: DefaultFetchBookUseCase(repository: bookRepository)
)
DIContainer.shared.register(
UpdateBookUseCase.self,
object: DefaultUpdateBookUseCase(repository: bookRepository)
)
DIContainer.shared.register(
DeleteBookUseCase.self,
object: DefaultDeleteBookUseCase(repository: bookRepository)
)
}

private func registerViewModelFactoryDependency() throws {
Expand Down Expand Up @@ -123,5 +160,18 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
deleteBookCategoryUseCase: deleteBookCategoryUseCase
)
)

// MARK: - Book ViewModel
let fetchBookUseCase = try DIContainer.shared.resolve(FetchBookUseCase.self)
DIContainer.shared.register(
BookViewModelFactory.self,
object: BookViewModelFactory(fetchBookUseCase: fetchBookUseCase)
)

// MARK: - Page ViewModel
DIContainer.shared.register(
ReadPageViewModelFactory.self,
object: ReadPageViewModelFactory()
)
}
}
15 changes: 11 additions & 4 deletions MemorialHouse/MHData/MHData/DTO/BookCoverDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@ import MHFoundation
import MHDomain

public struct BookCoverDTO {
let identifier: UUID
let id: UUID
let title: String
let imageURL: String?
let color: String
let category: String?
let favorite: Bool

public init(identifier: UUID, title: String, imageURL: String?, color: String, category: String?, favorite: Bool) {
self.identifier = identifier
public init(
id: UUID,
title: String,
imageURL: String?,
color: String,
category: String?,
favorite: Bool
) {
self.id = id
self.title = title
self.imageURL = imageURL
self.color = color
Expand All @@ -22,7 +29,7 @@ public struct BookCoverDTO {
guard let color = BookColor(rawValue: self.color) else { return nil }

return BookCover(
identifier: self.identifier,
id: self.id,
title: self.title,
imageURL: self.imageURL,
color: color,
Expand Down
9 changes: 8 additions & 1 deletion MemorialHouse/MHData/MHData/DTO/BookDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ import MHDomain

public struct BookDTO {
let id: UUID
let title: String
let pages: [PageDTO]

public init(id: UUID, pages: [PageDTO]) {
public init(
id: UUID,
title: String,
pages: [PageDTO]
) {
self.id = id
self.title = title
self.pages = pages
}

func convertToBook() -> Book {
return Book(
id: self.id,
title: self.title,
pages: self.pages.map { $0.convertToPage() }
)
}
Expand Down
6 changes: 5 additions & 1 deletion MemorialHouse/MHData/MHData/DTO/MediaDescriptionDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ public struct MediaDescriptionDTO {
let type: String
let attributes: Data?

public init(id: UUID, type: String, attributes: Data?) {
public init(
id: UUID,
type: String,
attributes: Data?
) {
self.id = id
self.type = type
self.attributes = attributes
Expand Down
6 changes: 5 additions & 1 deletion MemorialHouse/MHData/MHData/DTO/PageDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ public struct PageDTO {
let metadata: [Int: MediaDescriptionDTO]
let text: String

public init(id: UUID, metadata: [Int: MediaDescriptionDTO], text: String) {
public init(
id: UUID,
metadata: [Int: MediaDescriptionDTO],
text: String
) {
self.id = id
self.metadata = metadata
self.text = text
Expand Down
2 changes: 1 addition & 1 deletion MemorialHouse/MHData/MHData/LocalStorage/BookStorage.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MHFoundation
import MHCore

public protocol BookStorage {
public protocol BookStorage: Sendable {
func create(data: BookDTO) async -> Result<Void, MHDataError>
func fetch(with id: UUID) async -> Result<BookDTO, MHDataError>
func update(with id: UUID, data: BookDTO) async -> Result<Void, MHDataError>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,68 +8,49 @@ public final class CoreDataBookCategoryStorage {
public init(coreDataStorage: CoreDataStorage) {
self.coreDataStorage = coreDataStorage
}

private func performDatabaseTask<T>(
_ task: @escaping (NSManagedObjectContext) throws -> T
) async -> Result<T, MHDataError> {
let context = coreDataStorage.persistentContainer.viewContext
do {
return try await context.perform {
do {
return .success(try task(context))
} catch let error as MHDataError {
MHLogger.debug("Core Data 에러: \(error.description)")
throw error
} catch {
MHLogger.debug("알 수 없는 Core Data 에러: \(error.localizedDescription)")
throw error
}
}
} catch let error as MHDataError {
return .failure(error)
} catch {
return .failure(MHDataError.generalFailure)
}
}
}

extension CoreDataBookCategoryStorage: BookCategoryStorage {
public func create(with category: BookCategoryDTO) async -> Result<Void, MHDataError> {
return await performDatabaseTask { context in
return await coreDataStorage.performDatabaseTask { context in
guard let entity = NSEntityDescription.entity(forEntityName: "BookCategoryEntity", in: context) else {
throw MHDataError.noSuchEntity(key: "BookCategoryEntity")
}
let bookCategory = NSManagedObject(entity: entity, insertInto: context)
bookCategory.setValue(category.order, forKey: "order")
bookCategory.setValue(category.name, forKey: "name")

try context.save()
}
}

public func fetch() async -> Result<[BookCategoryDTO], MHDataError> {
return await performDatabaseTask { [weak self] context in
return await coreDataStorage.performDatabaseTask { [weak self] context in
let request = BookCategoryEntity.fetchRequest()
let bookCategoryEntities = try context.fetch(request)

return bookCategoryEntities.compactMap { self?.coreBookCategoryToDTO($0) }
}
}

public func update(oldName: String, with category: BookCategoryDTO) async -> Result<Void, MHDataError> {
return await performDatabaseTask { context in
return await coreDataStorage.performDatabaseTask { context in
let request = BookCategoryEntity.fetchRequest()
if let entity = try context.fetch(request).first(where: { $0.name == oldName }) {
entity.setValue(category.name, forKey: "name")
entity.setValue(category.order, forKey: "order")

try context.save()
}
}
}

public func delete(with categoryName: String) async -> Result<Void, MHDataError> {
return await performDatabaseTask { context in
return await coreDataStorage.performDatabaseTask { context in
let request = BookCategoryEntity.fetchRequest()
if let entity = try context.fetch(request).first(where: { $0.name == categoryName }) {
context.delete(entity)

try context.save()
}
}
Expand Down
Loading

0 comments on commit fa83564

Please sign in to comment.