protocol ProjectRepositoryProtocol {
mutating func create(data: ProjectModel)
func read() -> [ProjectModel]
mutating func update(id: String,
data: ProjectModel)
mutating func delete(id: String)
}
struct TemporaryProjectRepository: ProjectRepositoryProtocol {
private var temporaryStore: [ProjectModel]
init() {
temporaryStore = [ProjectModel]()
}
mutating func create(data: ProjectModel) {
temporaryStore.append(data)
}
func read() -> [ProjectModel] {
return temporaryStore
}
mutating func update(id: String,
data: ProjectModel) {
temporaryStore.indices.forEach {
temporaryStore[$0] = temporaryStore[$0].id == id ? data : temporaryStore[$0]
}
}
mutating func delete(id: String) {
temporaryStore.removeAll(where: { $0.id == id })
}
}
struct ProjectModel: Decodable {
let id: String
let title: String
let body: String
let date: Date
let workState: ProjectState
}
enum ProjectState: String, Decodable, CaseIterable {
case todo, doing, done
var name: String {
switch self {
case .todo:
return "TODO"
case .doing:
return "DOING"
case .done:
return "DONE"
}
}
var actionTitles: (first: String,
second: String) {
switch self {
case .todo:
return ("Move To DOING", "Move To DONE")
case .doing:
return ("Move To TODO", "Move To DONE")
case .done:
return ("Move To TODO", "Move To DOING")
}
}
}
protocol ProjectUseCaseProtocol {
var repository: ProjectRepositoryProtocol { get }
mutating func create(data: ProjectTranslaterModel)
func read() -> [ProjectTranslaterModel]
mutating func update(id: String,
data: ProjectTranslaterModel)
mutating func delete(id: String)
}
struct ProjectUseCase: ProjectUseCaseProtocol, ProjectTranslater {
var repository: ProjectRepositoryProtocol
init() {
repository = TemporaryProjectRepository()
}
mutating func create(data: ProjectTranslaterModel) {
repository.create(data: translateTo(ProjectModel: data))
}
func read() -> [ProjectTranslaterModel] {
let models = repository.read().map {
translateTo(ProjectTranslaterModel: $0)
}
return models
}
mutating func update(id: String,
data: ProjectTranslaterModel) {
repository.update(id: id, data: translateTo(ProjectModel: data))
}
mutating func delete(id: String) {
repository.delete(id: id)
}
}
struct ProjectTranslaterModel {
let id: String
let title: String
let body: String
let date: String
let workState: ProjectState
}
protocol ProjectTranslater {
func translateTo(ProjectModel data: ProjectTranslaterModel) -> ProjectModel
func translateTo(ProjectTranslaterModel data: ProjectModel) -> ProjectTranslaterModel
}
extension ProjectTranslater {
func translateTo(ProjectModel data: ProjectTranslaterModel) -> ProjectModel {
let date = Date(timeIntervalSince1970: Double(data.date) ?? 0)
let model = ProjectModel(id: data.id,
title: data.title,
body: data.body,
date: date,
workState: data.workState)
return model
}
func translateTo(ProjectTranslaterModel data: ProjectModel) -> ProjectTranslaterModel {
let model = ProjectTranslaterModel(id: data.id,
title: data.title,
body: data.body,
date: data.date.convertLocalization(),
workState: data.workState)
return model
}
}
protocol ProjectManagerViewModelProtocol: ViewModelIntput, ViewModelOutput {}
protocol ViewModelIntput {
var didSelectCreate: (ProjectTranslaterModel) -> Void { get set }
var didSelectUpdate: (ProjectTranslaterModel, ProjectState) -> Void { get set }
var didSelectDelete: (String) -> Void { get set }
var didSelectChangeState: (ProjectTranslaterModel, ProjectState) -> Void { get set }
}
protocol ViewModelOutput {
var retrieveDateLabelColor: (ProjectTranslaterModel) -> UIColor { get }
var retrieveItems: (ProjectState) -> [ProjectTranslaterModel] { get }
}
class ProjectListViewModel: ProjectManagerViewModelProtocol {
private var useCase: ProjectUseCaseProtocol
var didSelectChangeState: (ProjectTranslaterModel, ProjectState) -> Void
var didSelectCreate: (ProjectTranslaterModel) -> Void
var didSelectUpdate: (ProjectTranslaterModel, ProjectState) -> Void
var didSelectDelete: (String) -> Void
var retrieveDateLabelColor: (ProjectTranslaterModel) -> UIColor
var retrieveItems: (ProjectState) -> [ProjectTranslaterModel]
init() {
useCase = ProjectUseCase()
}
func didSelectCreate(data: ProjectTranslaterModel) {
useCase.create(data: data)
}
private func read() -> [ProjectTranslaterModel] {
return useCase.read()
}
func didSelectUpdate(id: String,
data: ProjectTranslaterModel) {
useCase.update(id: id, data: data)
}
func didSelectDelete(id: String) {
useCase.delete(id: id)
}
func changeState(item: ProjectTranslaterModel,
state: ProjectState) {
let newItem = ProjectTranslaterModel(id: item.id,
title: item.title,
body: item.body,
date: item.date,
workState: state)
useCase.update(id: item.id,
data: newItem)
}
func retrieveDateLabelColor(data: ProjectTranslaterModel) -> UIColor {
let date = Date(timeIntervalSince1970: Double(data.date) ?? 0)
let currentDate = Date()
if data.date != currentDate.convertLocalization() && date < currentDate {
return .systemRed
}
return .black
}
func retrieveItems(state: ProjectState) -> [ProjectTranslaterModel] {
let data = read()
switch state {
case .todo:
return data.filter {
$0.workState == .todo
}
case .doing:
return data.filter {
$0.workState == .doing
}
case .done:
return data.filter {
$0.workState == .done
}
}
}
}
MVVM 망해라