Skip to content
Permalink
Browse files

Adoption of UUID and Identifiable for Models and ViewModels

  • Loading branch information
thiagoricieri committed Jan 8, 2020
1 parent 8b5a46f commit c8c673209a2709acfa251ee7c9fdb2e8ab5586c9
@@ -40,6 +40,7 @@
B09CAB1623BBDFDE00485A78 /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09CAB1523BBDFDE00485A78 /* Currency.swift */; };
B0CBF69723AEA09B004ECC91 /* dataReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0CBF69623AEA09B004ECC91 /* dataReducer.swift */; };
B0CBF69923AEA0A1004ECC91 /* uiReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0CBF69823AEA0A1004ECC91 /* uiReducer.swift */; };
B0D600DB23C5F44E00CEAC46 /* ExpenseListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0D600DA23C5F44E00CEAC46 /* ExpenseListViewModel.swift */; };
B0E073D223C3837C00E72D6E /* EntryFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0E073D123C3837C00E72D6E /* EntryFormViewModel.swift */; };
B0E1EEE123AEA3BB00EF9F7E /* mockCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0E1EEE023AEA3BB00EF9F7E /* mockCreator.swift */; };
B0E1EEE323AEE77800EF9F7E /* domainSpecs.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0E1EEE223AEE77800EF9F7E /* domainSpecs.swift */; };
@@ -114,6 +115,7 @@
B0BB801923AE492300E7DBB8 /* Yearvu.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Yearvu.entitlements; sourceTree = "<group>"; };
B0CBF69623AEA09B004ECC91 /* dataReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dataReducer.swift; sourceTree = "<group>"; };
B0CBF69823AEA0A1004ECC91 /* uiReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = uiReducer.swift; sourceTree = "<group>"; };
B0D600DA23C5F44E00CEAC46 /* ExpenseListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpenseListViewModel.swift; sourceTree = "<group>"; };
B0E073D123C3837C00E72D6E /* EntryFormViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFormViewModel.swift; sourceTree = "<group>"; };
B0E1EEE023AEA3BB00EF9F7E /* mockCreator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = mockCreator.swift; sourceTree = "<group>"; };
B0E1EEE223AEE77800EF9F7E /* domainSpecs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = domainSpecs.swift; sourceTree = "<group>"; };
@@ -358,6 +360,7 @@
isa = PBXGroup;
children = (
B0E073D123C3837C00E72D6E /* EntryFormViewModel.swift */,
B0D600DA23C5F44E00CEAC46 /* ExpenseListViewModel.swift */,
);
path = viewModels;
sourceTree = "<group>";
@@ -746,6 +749,7 @@
B0E1EEE323AEE77800EF9F7E /* domainSpecs.swift in Sources */,
B06614CD23BD4652006D3AAD /* ExpenseEntryRowView.swift in Sources */,
B09B057F23B3D5E10086B30A /* Taxes.swift in Sources */,
B0D600DB23C5F44E00CEAC46 /* ExpenseListViewModel.swift in Sources */,
B0CBF69723AEA09B004ECC91 /* dataReducer.swift in Sources */,
B06614C723BD3AA0006D3AAD /* Date+Formatted.swift in Sources */,
B0E073D223C3837C00E72D6E /* EntryFormViewModel.swift in Sources */,
@@ -7,26 +7,26 @@
//
import class Foundation.Bundle
import class Foundation.JSONDecoder
import struct Foundation.Data
import class Foundation.JSONDecoder

let expenses: [Expense] = load("expenses.json")
let currencies = ["BRL", "USD", "EUR", "GBP"]

func load<T: Decodable>(_ filename: String) -> T {
let data: Data

guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
else {
fatalError("Couldn't find \(filename) in main bundle.")
}

do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}

do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
@@ -19,7 +19,6 @@ extension ExpenseEntry {
daysForward days: Int = 0
) -> ExpenseEntry {
return ExpenseEntry(
id: String(faker.number.increasingUniqueId()),
value: faker.number.randomDouble(min: valueMin, max: valueMax).money,
currency: .usDollars,
createdAt: faker.date.forward(days)
@@ -45,7 +44,6 @@ extension ExpenseEntry {
extension Expense {
static func mock() -> Expense {
return Expense(
id: String(faker.number.increasingUniqueId()),
name: faker.name.name(),
value: faker.number.randomDouble(min: 0, max: 1_000).money,
currency: USD.currency,
@@ -60,7 +58,6 @@ extension Expense {
valueMax: Double = Double.infinity
) -> Expense {
return Expense(
id: String(faker.number.increasingUniqueId()),
name: faker.name.name(),
value: faker.number.randomDouble(min: valueMin, max: valueMax).money,
currency: USD.currency,
@@ -76,7 +73,6 @@ extension Expense {
valueMax: Double = Double.infinity
) -> Expense {
return Expense(
id: String(faker.number.increasingUniqueId()),
name: faker.name.name(),
value: faker.number.randomDouble(min: valueMin, max: valueMax).money,
currency: USD.currency,
@@ -102,7 +98,6 @@ extension Expense {
let minValue = money.value * (1 - range)
let maxValue = money.value * (1 + range)
return ExpenseEntry(
id: String(faker.number.increasingUniqueId()),
value: faker.number.randomDouble(min: minValue, max: maxValue).money,
currency: .usDollars,
createdAt: faker.date.forward(Int(Double(num) * recurrence.daysMultiplier))
@@ -7,9 +7,10 @@
//
import struct Foundation.Date
import struct Foundation.UUID

struct Expense: Model, HasName, MonetaryRecurrent, Codable, Identifiable {
var id: String
var id: UUID = UUID()
var name: String
var value: Double = 0.0
var currency: Currency
@@ -7,14 +7,15 @@
//
import struct Foundation.Date
import struct Foundation.UUID

struct ExpenseEntry: Model, IsDated, Monetary, Codable, Identifiable {
var id: String
var id: UUID = UUID()
var value: Double
var currency: Currency
var createdAt: Date = Date()
}

extension ExpenseEntry {
static let empty = ExpenseEntry(id: "", value: 0.0, currency: .none)
static let empty = ExpenseEntry(value: 0.0, currency: .none)
}
@@ -7,15 +7,20 @@
//
import struct Foundation.Date
import struct Foundation.UUID

// MARK: - Convenience Types
typealias Percentage = Float

// MARK: - Models
protocol Model {
var id: String { get set }
protocol Model: Identifiable {
var id: UUID { get }
}

protocol ViewModel: Identifiable {
var id: UUID { get }
}

protocol HasName {
@@ -9,9 +9,11 @@
import protocol Combine.ObservableObject
import struct Combine.Published
import struct Foundation.Date
import struct Foundation.UUID
import struct SwiftUI.Binding

class EntryFormViewModel: ObservableObject {
class EntryFormViewModel: ObservableObject, ViewModel {
var id: UUID = UUID()
var entry: ExpenseEntry
let currencies: [String]

@@ -0,0 +1,9 @@
//
// ExpenseListViewModel.swift
// Yearvu
//
// Created by Thiago Ricieri on 08/01/20.
// Copyright © 2020 Thiago Ricieri. All rights reserved.
//
import Foundation

0 comments on commit c8c6732

Please sign in to comment.
You can’t perform that action at this time.