Get live previews to work
Signed-off-by: Billy Brawner <billy@wbrawner.com>
This commit is contained in:
parent
fb7aa8fec4
commit
5d76390e67
50 changed files with 639 additions and 253 deletions
|
@ -1,14 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>SchemeUserState</key>
|
|
||||||
<dict>
|
|
||||||
<key>Budget.xcscheme_^#shared#^_</key>
|
|
||||||
<dict>
|
|
||||||
<key>orderHint</key>
|
|
||||||
<integer>0</integer>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// BudgetRepository.swift
|
|
||||||
// Budget
|
|
||||||
//
|
|
||||||
// Created by Billy Brawner on 9/30/19.
|
|
||||||
// Copyright © 2019 William Brawner. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
class BudgetRepository {
|
|
||||||
let apiService: BudgetApiService
|
|
||||||
|
|
||||||
init(_ apiService: BudgetApiService) {
|
|
||||||
self.apiService = apiService
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBudgets() -> AnyPublisher<[Budget], NetworkError> {
|
|
||||||
return apiService.getBudgets()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
//
|
|
||||||
// CategoryRepository.swift
|
|
||||||
// Budget
|
|
||||||
//
|
|
||||||
// Created by Billy Brawner on 10/1/19.
|
|
||||||
// Copyright © 2019 William Brawner. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
class CategoryRepository {
|
|
||||||
let apiService: BudgetApiService
|
|
||||||
|
|
||||||
init(_ apiService: BudgetApiService) {
|
|
||||||
self.apiService = apiService
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCategories(budgetId: Int? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Category], NetworkError> {
|
|
||||||
return apiService.getCategories(budgetId: budgetId, count: count, page: page)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
//
|
|
||||||
// TransactionDetailsView.swift
|
|
||||||
// Budget
|
|
||||||
//
|
|
||||||
// Created by Billy Brawner on 10/1/19.
|
|
||||||
// Copyright © 2019 William Brawner. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct TransactionDetailsView: View {
|
|
||||||
@State var title: String = ""
|
|
||||||
@State var description: String? = nil
|
|
||||||
@State var date: Date = Date()
|
|
||||||
@State var amount: Int = 0
|
|
||||||
@State var category: Category? = nil
|
|
||||||
@State var expense: Bool = true
|
|
||||||
@State var createdBy: User? = nil
|
|
||||||
@State var budget: Budget? = nil
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
List {
|
|
||||||
TextField("prompt_title", text: self.$title)
|
|
||||||
// DatePicker(
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init(_ dataStoreProvider: DataStoreProvider, transaction: Transaction) {
|
|
||||||
// self.title = transaction.title
|
|
||||||
// self.description = transaction.description
|
|
||||||
// self.date = transaction.date
|
|
||||||
// self.amount = transaction.amount
|
|
||||||
// self.category = transaction.category
|
|
||||||
// self.expense = transaction.expense
|
|
||||||
// self.createdBy = transaction.createdBy
|
|
||||||
// self.budget = transaction.budget
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//struct TransactionDetailsView_Previews: PreviewProvider {
|
|
||||||
// static var previews: some View {
|
|
||||||
// TransactionDetailsView()
|
|
||||||
// }
|
|
||||||
//}
|
|
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// TransactionRepository.swift
|
|
||||||
// Budget
|
|
||||||
//
|
|
||||||
// Created by Billy Brawner on 9/25/19.
|
|
||||||
// Copyright © 2019 William Brawner. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
class TransactionRepository {
|
|
||||||
let apiService: BudgetApiService
|
|
||||||
|
|
||||||
init(_ apiService: BudgetApiService) {
|
|
||||||
self.apiService = apiService
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTransactions(categoryIds: [Int]? = nil, from: Date? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Transaction], NetworkError> {
|
|
||||||
return apiService.getTransactions(categoryIds: categoryIds, from: from, count: count, page: page)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
|
|
||||||
return apiService.newTransaction(transaction)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
//
|
|
||||||
// UserRepository.swift
|
|
||||||
// Budget
|
|
||||||
//
|
|
||||||
// Created by Billy Brawner on 9/25/19.
|
|
||||||
// Copyright © 2019 William Brawner. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
class UserRepository {
|
|
||||||
let apiService: BudgetApiService
|
|
||||||
|
|
||||||
init(_ apiService: BudgetApiService) {
|
|
||||||
self.apiService = apiService
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUser(id: Int) -> AnyPublisher<User, NetworkError> {
|
|
||||||
return apiService.getUser(id: id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func searchUsers(withUsername: String) -> AnyPublisher<[User], NetworkError> {
|
|
||||||
return apiService.searchUsers(query: withUsername)
|
|
||||||
}
|
|
||||||
|
|
||||||
func login(username: String, password: String) -> AnyPublisher<User, NetworkError> {
|
|
||||||
return apiService.login(username: username, password: password)
|
|
||||||
}
|
|
||||||
|
|
||||||
func register(username: String, email: String, password: String) -> AnyPublisher<User, NetworkError> {
|
|
||||||
return apiService.register(username: username, email: email, password: password)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -68,7 +68,7 @@
|
||||||
2857EAEC233DA30B0026BC83 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
|
2857EAEC233DA30B0026BC83 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
|
||||||
2888234623512DBF003D3847 /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
|
2888234623512DBF003D3847 /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
|
||||||
28A1E959235006A300CA57FE /* AddTransactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTransactionView.swift; sourceTree = "<group>"; };
|
28A1E959235006A300CA57FE /* AddTransactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTransactionView.swift; sourceTree = "<group>"; };
|
||||||
28AC94EA233C373900BFB70A /* Budget.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Budget.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
28AC94EA233C373900BFB70A /* BudgetApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BudgetApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
28AC94ED233C373900BFB70A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
28AC94ED233C373900BFB70A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
28AC94EF233C373900BFB70A /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
28AC94EF233C373900BFB70A /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||||
28AC94F1233C373900BFB70A /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
|
28AC94F1233C373900BFB70A /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -76,10 +76,10 @@
|
||||||
28AC94F6233C373A00BFB70A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
28AC94F6233C373A00BFB70A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
28AC94F9233C373A00BFB70A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
28AC94F9233C373A00BFB70A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
28AC94FB233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
28AC94FB233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
28AC9500233C373A00BFB70A /* BudgetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BudgetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
28AC9500233C373A00BFB70A /* BudgetAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BudgetAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
28AC9504233C373A00BFB70A /* BudgetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetTests.swift; sourceTree = "<group>"; };
|
28AC9504233C373A00BFB70A /* BudgetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetTests.swift; sourceTree = "<group>"; };
|
||||||
28AC9506233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
28AC9506233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
28AC950B233C373A00BFB70A /* BudgetUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BudgetUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
28AC950B233C373A00BFB70A /* BudgetAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BudgetAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
28AC950F233C373A00BFB70A /* BudgetUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetUITests.swift; sourceTree = "<group>"; };
|
28AC950F233C373A00BFB70A /* BudgetUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BudgetUITests.swift; sourceTree = "<group>"; };
|
||||||
28AC9511233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
28AC9511233C373A00BFB70A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
28AC9520233C381C00BFB70A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
28AC9520233C381C00BFB70A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
@ -161,9 +161,9 @@
|
||||||
28AC94E1233C373900BFB70A = {
|
28AC94E1233C373900BFB70A = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
28AC94EC233C373900BFB70A /* Budget */,
|
28AC94EC233C373900BFB70A /* BudgetApp */,
|
||||||
28AC9503233C373A00BFB70A /* BudgetTests */,
|
28AC9503233C373A00BFB70A /* BudgetAppTests */,
|
||||||
28AC950E233C373A00BFB70A /* BudgetUITests */,
|
28AC950E233C373A00BFB70A /* BudgetAppUITests */,
|
||||||
28AC94EB233C373900BFB70A /* Products */,
|
28AC94EB233C373900BFB70A /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -171,14 +171,14 @@
|
||||||
28AC94EB233C373900BFB70A /* Products */ = {
|
28AC94EB233C373900BFB70A /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
28AC94EA233C373900BFB70A /* Budget.app */,
|
28AC94EA233C373900BFB70A /* BudgetApp.app */,
|
||||||
28AC9500233C373A00BFB70A /* BudgetTests.xctest */,
|
28AC9500233C373A00BFB70A /* BudgetAppTests.xctest */,
|
||||||
28AC950B233C373A00BFB70A /* BudgetUITests.xctest */,
|
28AC950B233C373A00BFB70A /* BudgetAppUITests.xctest */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
28AC94EC233C373900BFB70A /* Budget */ = {
|
28AC94EC233C373900BFB70A /* BudgetApp */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2841022A2342D8CB00EAFA29 /* Category */,
|
2841022A2342D8CB00EAFA29 /* Category */,
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
28FE6AFD234428BF00D5543E /* DataStoreProvider.swift */,
|
28FE6AFD234428BF00D5543E /* DataStoreProvider.swift */,
|
||||||
2888234623512DBF003D3847 /* Observable.swift */,
|
2888234623512DBF003D3847 /* Observable.swift */,
|
||||||
);
|
);
|
||||||
path = Budget;
|
path = BudgetApp;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
28AC94F5233C373A00BFB70A /* Preview Content */ = {
|
28AC94F5233C373A00BFB70A /* Preview Content */ = {
|
||||||
|
@ -212,22 +212,22 @@
|
||||||
path = "Preview Content";
|
path = "Preview Content";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
28AC9503233C373A00BFB70A /* BudgetTests */ = {
|
28AC9503233C373A00BFB70A /* BudgetAppTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
28AC9504233C373A00BFB70A /* BudgetTests.swift */,
|
28AC9504233C373A00BFB70A /* BudgetTests.swift */,
|
||||||
28AC9506233C373A00BFB70A /* Info.plist */,
|
28AC9506233C373A00BFB70A /* Info.plist */,
|
||||||
);
|
);
|
||||||
path = BudgetTests;
|
path = BudgetAppTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
28AC950E233C373A00BFB70A /* BudgetUITests */ = {
|
28AC950E233C373A00BFB70A /* BudgetAppUITests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
28AC950F233C373A00BFB70A /* BudgetUITests.swift */,
|
28AC950F233C373A00BFB70A /* BudgetUITests.swift */,
|
||||||
28AC9511233C373A00BFB70A /* Info.plist */,
|
28AC9511233C373A00BFB70A /* Info.plist */,
|
||||||
);
|
);
|
||||||
path = BudgetUITests;
|
path = BudgetAppUITests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
28AC9526233C42F800BFB70A /* Transaction */ = {
|
28AC9526233C42F800BFB70A /* Transaction */ = {
|
||||||
|
@ -264,9 +264,9 @@
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
28AC94E9233C373900BFB70A /* Budget */ = {
|
28AC94E9233C373900BFB70A /* BudgetApp */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 28AC9514233C373A00BFB70A /* Build configuration list for PBXNativeTarget "Budget" */;
|
buildConfigurationList = 28AC9514233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetApp" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
28AC94E6233C373900BFB70A /* Sources */,
|
28AC94E6233C373900BFB70A /* Sources */,
|
||||||
28AC94E7233C373900BFB70A /* Frameworks */,
|
28AC94E7233C373900BFB70A /* Frameworks */,
|
||||||
|
@ -276,14 +276,14 @@
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = Budget;
|
name = BudgetApp;
|
||||||
productName = Budget;
|
productName = Budget;
|
||||||
productReference = 28AC94EA233C373900BFB70A /* Budget.app */;
|
productReference = 28AC94EA233C373900BFB70A /* BudgetApp.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
28AC94FF233C373A00BFB70A /* BudgetTests */ = {
|
28AC94FF233C373A00BFB70A /* BudgetAppTests */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 28AC9517233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetTests" */;
|
buildConfigurationList = 28AC9517233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetAppTests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
28AC94FC233C373A00BFB70A /* Sources */,
|
28AC94FC233C373A00BFB70A /* Sources */,
|
||||||
28AC94FD233C373A00BFB70A /* Frameworks */,
|
28AC94FD233C373A00BFB70A /* Frameworks */,
|
||||||
|
@ -294,14 +294,14 @@
|
||||||
dependencies = (
|
dependencies = (
|
||||||
28AC9502233C373A00BFB70A /* PBXTargetDependency */,
|
28AC9502233C373A00BFB70A /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = BudgetTests;
|
name = BudgetAppTests;
|
||||||
productName = BudgetTests;
|
productName = BudgetTests;
|
||||||
productReference = 28AC9500233C373A00BFB70A /* BudgetTests.xctest */;
|
productReference = 28AC9500233C373A00BFB70A /* BudgetAppTests.xctest */;
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
};
|
};
|
||||||
28AC950A233C373A00BFB70A /* BudgetUITests */ = {
|
28AC950A233C373A00BFB70A /* BudgetAppUITests */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 28AC951A233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetUITests" */;
|
buildConfigurationList = 28AC951A233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetAppUITests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
28AC9507233C373A00BFB70A /* Sources */,
|
28AC9507233C373A00BFB70A /* Sources */,
|
||||||
28AC9508233C373A00BFB70A /* Frameworks */,
|
28AC9508233C373A00BFB70A /* Frameworks */,
|
||||||
|
@ -312,9 +312,9 @@
|
||||||
dependencies = (
|
dependencies = (
|
||||||
28AC950D233C373A00BFB70A /* PBXTargetDependency */,
|
28AC950D233C373A00BFB70A /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = BudgetUITests;
|
name = BudgetAppUITests;
|
||||||
productName = BudgetUITests;
|
productName = BudgetUITests;
|
||||||
productReference = 28AC950B233C373A00BFB70A /* BudgetUITests.xctest */;
|
productReference = 28AC950B233C373A00BFB70A /* BudgetAppUITests.xctest */;
|
||||||
productType = "com.apple.product-type.bundle.ui-testing";
|
productType = "com.apple.product-type.bundle.ui-testing";
|
||||||
};
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
@ -340,7 +340,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "Budget" */;
|
buildConfigurationList = 28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "BudgetApp" */;
|
||||||
compatibilityVersion = "Xcode 9.3";
|
compatibilityVersion = "Xcode 9.3";
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
|
@ -354,9 +354,9 @@
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
28AC94E9233C373900BFB70A /* Budget */,
|
28AC94E9233C373900BFB70A /* BudgetApp */,
|
||||||
28AC94FF233C373A00BFB70A /* BudgetTests */,
|
28AC94FF233C373A00BFB70A /* BudgetAppTests */,
|
||||||
28AC950A233C373A00BFB70A /* BudgetUITests */,
|
28AC950A233C373A00BFB70A /* BudgetAppUITests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -445,12 +445,12 @@
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
28AC9502233C373A00BFB70A /* PBXTargetDependency */ = {
|
28AC9502233C373A00BFB70A /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 28AC94E9233C373900BFB70A /* Budget */;
|
target = 28AC94E9233C373900BFB70A /* BudgetApp */;
|
||||||
targetProxy = 28AC9501233C373A00BFB70A /* PBXContainerItemProxy */;
|
targetProxy = 28AC9501233C373A00BFB70A /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
28AC950D233C373A00BFB70A /* PBXTargetDependency */ = {
|
28AC950D233C373A00BFB70A /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 28AC94E9233C373900BFB70A /* Budget */;
|
target = 28AC94E9233C373900BFB70A /* BudgetApp */;
|
||||||
targetProxy = 28AC950C233C373A00BFB70A /* PBXContainerItemProxy */;
|
targetProxy = 28AC950C233C373A00BFB70A /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
@ -532,6 +532,7 @@
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
PRODUCT_NAME = "";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
@ -586,6 +587,7 @@
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_NAME = "";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
@ -598,10 +600,10 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Budget/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"BudgetApp/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = Budget/Info.plist;
|
INFOPLIST_FILE = BudgetApp/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -618,10 +620,10 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Budget/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"BudgetApp/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
DEVELOPMENT_TEAM = VJ33S6H7W7;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
INFOPLIST_FILE = Budget/Info.plist;
|
INFOPLIST_FILE = BudgetApp/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -639,7 +641,7 @@
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = BudgetTests/Info.plist;
|
INFOPLIST_FILE = BudgetAppTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -650,7 +652,7 @@
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Budget.app/Budget";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BudgetApp.app/BudgetApp";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -660,7 +662,7 @@
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = BudgetTests/Info.plist;
|
INFOPLIST_FILE = BudgetAppTests/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -671,7 +673,7 @@
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Budget.app/Budget";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BudgetApp.app/BudgetApp";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -680,7 +682,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = BudgetUITests/Info.plist;
|
INFOPLIST_FILE = BudgetAppUITests/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -699,7 +701,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = BudgetUITests/Info.plist;
|
INFOPLIST_FILE = BudgetAppUITests/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -716,7 +718,7 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "Budget" */ = {
|
28AC94E5233C373900BFB70A /* Build configuration list for PBXProject "BudgetApp" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
28AC9512233C373A00BFB70A /* Debug */,
|
28AC9512233C373A00BFB70A /* Debug */,
|
||||||
|
@ -725,7 +727,7 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
28AC9514233C373A00BFB70A /* Build configuration list for PBXNativeTarget "Budget" */ = {
|
28AC9514233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetApp" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
28AC9515233C373A00BFB70A /* Debug */,
|
28AC9515233C373A00BFB70A /* Debug */,
|
||||||
|
@ -734,7 +736,7 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
28AC9517233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetTests" */ = {
|
28AC9517233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetAppTests" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
28AC9518233C373A00BFB70A /* Debug */,
|
28AC9518233C373A00BFB70A /* Debug */,
|
||||||
|
@ -743,7 +745,7 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
28AC951A233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetUITests" */ = {
|
28AC951A233C373A00BFB70A /* Build configuration list for PBXNativeTarget "BudgetAppUITests" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
28AC951B233C373A00BFB70A /* Debug */,
|
28AC951B233C373A00BFB70A /* Debug */,
|
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "self:Budget.xcodeproj">
|
location = "self:/Users/billy/Projects/Budget/BudgetApp.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1100"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "28AC94E9233C373900BFB70A"
|
||||||
|
BuildableName = "BudgetApp.app"
|
||||||
|
BlueprintName = "BudgetApp"
|
||||||
|
ReferencedContainer = "container:BudgetApp.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "28AC94FF233C373A00BFB70A"
|
||||||
|
BuildableName = "BudgetAppTests.xctest"
|
||||||
|
BlueprintName = "BudgetAppTests"
|
||||||
|
ReferencedContainer = "container:BudgetApp.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "28AC950A233C373A00BFB70A"
|
||||||
|
BuildableName = "BudgetAppUITests.xctest"
|
||||||
|
BlueprintName = "BudgetAppUITests"
|
||||||
|
ReferencedContainer = "container:BudgetApp.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "28AC94E9233C373900BFB70A"
|
||||||
|
BuildableName = "BudgetApp.app"
|
||||||
|
BlueprintName = "BudgetApp"
|
||||||
|
ReferencedContainer = "container:BudgetApp.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "28AC94E9233C373900BFB70A"
|
||||||
|
BuildableName = "BudgetApp.app"
|
||||||
|
BlueprintName = "BudgetApp"
|
||||||
|
ReferencedContainer = "container:BudgetApp.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
|
@ -701,7 +701,7 @@
|
||||||
endingColumnNumber = "9223372036854775807"
|
endingColumnNumber = "9223372036854775807"
|
||||||
startingLineNumber = "52"
|
startingLineNumber = "52"
|
||||||
endingLineNumber = "52"
|
endingLineNumber = "52"
|
||||||
landmarkName = "createTransaction(_:)"
|
landmarkName = "getTransaction(_:)"
|
||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
@ -717,7 +717,7 @@
|
||||||
endingColumnNumber = "9223372036854775807"
|
endingColumnNumber = "9223372036854775807"
|
||||||
startingLineNumber = "59"
|
startingLineNumber = "59"
|
||||||
endingLineNumber = "59"
|
endingLineNumber = "59"
|
||||||
landmarkName = "createTransaction(_:)"
|
landmarkName = "getTransaction(_:)"
|
||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
@ -733,7 +733,7 @@
|
||||||
endingColumnNumber = "9223372036854775807"
|
endingColumnNumber = "9223372036854775807"
|
||||||
startingLineNumber = "47"
|
startingLineNumber = "47"
|
||||||
endingLineNumber = "47"
|
endingLineNumber = "47"
|
||||||
landmarkName = "createTransaction(_:)"
|
landmarkName = "getTransactions(_:)"
|
||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
@ -813,8 +813,8 @@
|
||||||
endingColumnNumber = "9223372036854775807"
|
endingColumnNumber = "9223372036854775807"
|
||||||
startingLineNumber = "24"
|
startingLineNumber = "24"
|
||||||
endingLineNumber = "24"
|
endingLineNumber = "24"
|
||||||
landmarkName = "createTransaction(_:)"
|
landmarkName = "NetworkTransactionRepository"
|
||||||
landmarkType = "7">
|
landmarkType = "3">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
<BreakpointProxy
|
<BreakpointProxy
|
||||||
|
@ -849,5 +849,37 @@
|
||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "E7F93AB9-4460-441B-9C79-F4B83BB30027"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Budget/Budget/BudgetRepository.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "26"
|
||||||
|
endingLineNumber = "26"
|
||||||
|
landmarkName = "init(_:)"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "E04190C6-277F-4BEF-B485-DD319C1514ED"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "Budget/Budget/BudgetRepository.swift"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "27"
|
||||||
|
endingLineNumber = "27"
|
||||||
|
landmarkName = "NetworkBudgetRepository"
|
||||||
|
landmarkType = "3">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>BudgetApp.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
<dict>
|
||||||
|
<key>28AC94E9233C373900BFB70A</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>28AC94FF233C373A00BFB70A</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>28AC950A233C373A00BFB70A</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// BudgetsView.swift
|
// BudgetsView.swift
|
||||||
// Budget
|
// Budget
|
||||||
|
@ -74,8 +75,8 @@ struct BudgetListItemView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//struct BudgetsView_Previews: PreviewProvider {
|
struct BudgetListsView_Previews: PreviewProvider {
|
||||||
// static var previews: some View {
|
static var previews: some View {
|
||||||
// BudgetsView(budgets: [])
|
BudgetListsView(MockDataStoreProvider())
|
||||||
// }
|
}
|
||||||
//}
|
}
|
101
BudgetApp/Budget/BudgetRepository.swift
Normal file
101
BudgetApp/Budget/BudgetRepository.swift
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
//
|
||||||
|
// BudgetRepository.swift
|
||||||
|
// Budget
|
||||||
|
//
|
||||||
|
// Created by Billy Brawner on 9/30/19.
|
||||||
|
// Copyright © 2019 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
protocol BudgetRepository {
|
||||||
|
func getBudgets(count: Int?, page: Int?) -> AnyPublisher<[Budget], NetworkError>
|
||||||
|
func getBudget(_ id: Int) -> AnyPublisher<Budget, NetworkError>
|
||||||
|
func getBudgetBalance(_ id: Int) -> AnyPublisher<Int, NetworkError>
|
||||||
|
func newBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError>
|
||||||
|
func updateBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError>
|
||||||
|
func deleteBudget(_ id: Int) -> AnyPublisher<Empty, NetworkError>
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkBudgetRepository: BudgetRepository {
|
||||||
|
let apiService: BudgetApiService
|
||||||
|
|
||||||
|
init(_ apiService: BudgetApiService) {
|
||||||
|
self.apiService = apiService
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBudgets(count: Int?, page: Int?) -> AnyPublisher<[Budget], NetworkError> {
|
||||||
|
return apiService.getBudgets(count: count, page: page)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBudget(_ id: Int) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return apiService.getBudget(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBudgetBalance(_ id: Int) -> AnyPublisher<Int, NetworkError> {
|
||||||
|
return apiService.getBudgetBalance(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return apiService.newBudget(budget)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return apiService.updateBudget(budget)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteBudget(_ id: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||||
|
return apiService.deleteBudget(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
class MockBudgetRepository: BudgetRepository {
|
||||||
|
func getBudgets(count: Int?, page: Int?) -> AnyPublisher<[Budget], NetworkError> {
|
||||||
|
return Result.Publisher([Budget(
|
||||||
|
id: 1,
|
||||||
|
name: "Test Budget",
|
||||||
|
description: "A mock budget used for testing",
|
||||||
|
users: []
|
||||||
|
)]).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBudget(_ id: Int) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return Result.Publisher(Budget(
|
||||||
|
id: 1,
|
||||||
|
name: "Test Budget",
|
||||||
|
description: "A mock budget used for testing",
|
||||||
|
users: []
|
||||||
|
)).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBudgetBalance(_ id: Int) -> AnyPublisher<Int, NetworkError> {
|
||||||
|
return Result.Publisher(10000).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return Result.Publisher(Budget(
|
||||||
|
id: 1,
|
||||||
|
name: "Test Budget",
|
||||||
|
description: "A mock budget used for testing",
|
||||||
|
users: []
|
||||||
|
)).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateBudget(_ budget: Budget) -> AnyPublisher<Budget, NetworkError> {
|
||||||
|
return Result.Publisher(Budget(
|
||||||
|
id: 1,
|
||||||
|
name: "Test Budget",
|
||||||
|
description: "A mock budget used for testing",
|
||||||
|
users: []
|
||||||
|
)).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteBudget(_ id: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||||
|
return Result.Publisher(Empty()).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,10 +21,10 @@ class BudgetsDataStore: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBudgets() {
|
func getBudgets(count: Int? = nil, page: Int? = nil) {
|
||||||
self.budgets = .failure(.loading)
|
self.budgets = .failure(.loading)
|
||||||
|
|
||||||
_ = self.budgetRepository.getBudgets()
|
_ = self.budgetRepository.getBudgets(count: count, page: page)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink(receiveCompletion: { (status) in
|
.sink(receiveCompletion: { (status) in
|
||||||
switch status {
|
switch status {
|
36
BudgetApp/Category/CategoryRepository.swift
Normal file
36
BudgetApp/Category/CategoryRepository.swift
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// CategoryRepository.swift
|
||||||
|
// Budget
|
||||||
|
//
|
||||||
|
// Created by Billy Brawner on 10/1/19.
|
||||||
|
// Copyright © 2019 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
protocol CategoryRepository {
|
||||||
|
func getCategories(budgetId: Int?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError>
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkCategoryRepository: CategoryRepository {
|
||||||
|
let apiService: BudgetApiService
|
||||||
|
|
||||||
|
init(_ apiService: BudgetApiService) {
|
||||||
|
self.apiService = apiService
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCategories(budgetId: Int?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||||
|
return apiService.getCategories(budgetId: budgetId, count: count, page: page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
class MockCategoryRepository: CategoryRepository {
|
||||||
|
func getCategories(budgetId: Int?, count: Int?, page: Int?) -> AnyPublisher<[Category], NetworkError> {
|
||||||
|
return Result.Publisher([]).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,7 +15,6 @@ class DataStoreProvider {
|
||||||
private let budgetRepository: BudgetRepository
|
private let budgetRepository: BudgetRepository
|
||||||
private let categoryRepository: CategoryRepository
|
private let categoryRepository: CategoryRepository
|
||||||
private let transactionRepository: TransactionRepository
|
private let transactionRepository: TransactionRepository
|
||||||
private let userRepository: UserRepository
|
|
||||||
|
|
||||||
private let _userDataStore: UserDataStore
|
private let _userDataStore: UserDataStore
|
||||||
|
|
||||||
|
@ -35,14 +34,30 @@ class DataStoreProvider {
|
||||||
return self._userDataStore
|
return self._userDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
init(_ baseUrl: String) {
|
init(
|
||||||
let requestHelper = RequestHelper(baseUrl)
|
budgetRepository: BudgetRepository,
|
||||||
let apiService = BudgetApiService(requestHelper)
|
categoryRepository: CategoryRepository,
|
||||||
budgetRepository = BudgetRepository(apiService)
|
transactionRepository: TransactionRepository,
|
||||||
categoryRepository = CategoryRepository(apiService)
|
userRepository: UserRepository
|
||||||
transactionRepository = TransactionRepository(apiService)
|
) {
|
||||||
userRepository = UserRepository(apiService)
|
self.budgetRepository = budgetRepository
|
||||||
|
self.categoryRepository = categoryRepository
|
||||||
_userDataStore = UserDataStore(userRepository)
|
self.transactionRepository = transactionRepository
|
||||||
|
self._userDataStore = UserDataStore(userRepository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
class MockDataStoreProvider: DataStoreProvider {
|
||||||
|
init() {
|
||||||
|
super.init(
|
||||||
|
budgetRepository: MockBudgetRepository(),
|
||||||
|
categoryRepository: MockCategoryRepository(),
|
||||||
|
transactionRepository: MockTransactionRepository(),
|
||||||
|
userRepository: MockUserRepository()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -45,10 +45,9 @@ class BudgetApiService {
|
||||||
return requestHelper.put("/budgets/\(budget.id!)", data: budget)
|
return requestHelper.put("/budgets/\(budget.id!)", data: budget)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Figure out how to implement this
|
func deleteBudget(_ id: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||||
// func deleteBudget(_ id: Int) -> AnyPublisher<Void, NetworkError> {
|
return requestHelper.delete("/budgets/\(id)")
|
||||||
// return requestHelper.delete("/budgets/\(id)")
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// MARK: Transactions
|
// MARK: Transactions
|
||||||
|
|
||||||
|
@ -94,10 +93,9 @@ class BudgetApiService {
|
||||||
return requestHelper.put("/transactions/\(transaction.id!)", data: transaction)
|
return requestHelper.put("/transactions/\(transaction.id!)", data: transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Figure out how to implement this
|
func deleteTransaction(_ id: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||||
// func deleteTransaction(_ id: Int) -> AnyPublisher<Void, NetworkError> {
|
return requestHelper.delete("/transactions/\(id)")
|
||||||
// return requestHelper.delete("/transactions/\(id)")
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// MARK: Categories
|
// MARK: Categories
|
||||||
|
|
||||||
|
@ -131,10 +129,9 @@ class BudgetApiService {
|
||||||
return requestHelper.put("/categories/\(category.id!)", data: category)
|
return requestHelper.put("/categories/\(category.id!)", data: category)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Figure out how to implement this
|
func deleteCategory(_ id: Int) -> AnyPublisher<Empty, NetworkError> {
|
||||||
// func deleteCategory(_ id: Int) -> AnyPublisher<Void, NetworkError> {
|
return requestHelper.delete("/categories/\(id)")
|
||||||
// return requestHelper.delete("/categories/\(id)")
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// MARK: Users
|
// MARK: Users
|
||||||
func login(username: String, password: String) -> AnyPublisher<User, NetworkError> {
|
func login(username: String, password: String) -> AnyPublisher<User, NetworkError> {
|
||||||
|
@ -188,6 +185,10 @@ class BudgetApiService {
|
||||||
func updateUser(_ user: User) -> AnyPublisher<User, NetworkError> {
|
func updateUser(_ user: User) -> AnyPublisher<User, NetworkError> {
|
||||||
return requestHelper.put("/users/\(user.id!)", data: user)
|
return requestHelper.put("/users/\(user.id!)", data: user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteUser(_ user: User) -> AnyPublisher<Empty, NetworkError> {
|
||||||
|
return requestHelper.delete("/users/\(user.id!)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestHelper {
|
class RequestHelper {
|
||||||
|
@ -280,6 +281,8 @@ class RequestHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Empty: Codable {}
|
||||||
|
|
||||||
enum NetworkError: Error, Equatable {
|
enum NetworkError: Error, Equatable {
|
||||||
static func == (lhs: NetworkError, rhs: NetworkError) -> Bool {
|
static func == (lhs: NetworkError, rhs: NetworkError) -> Bool {
|
||||||
switch (lhs, rhs) {
|
switch (lhs, rhs) {
|
|
@ -22,7 +22,19 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
#else
|
#else
|
||||||
let baseUrl = "https://budget-api.intra.wbrawner.com"
|
let baseUrl = "https://budget-api.intra.wbrawner.com"
|
||||||
#endif
|
#endif
|
||||||
dataStoreProvider = DataStoreProvider(baseUrl)
|
let requestHelper = RequestHelper(baseUrl)
|
||||||
|
let apiService = BudgetApiService(requestHelper)
|
||||||
|
let budgetRepository = MockBudgetRepository()
|
||||||
|
// let budgetRepository = NetworkBudgetRepository(apiService)
|
||||||
|
let categoryRepository = NetworkCategoryRepository(apiService)
|
||||||
|
let transactionRepository = NetworkTransactionRepository(apiService)
|
||||||
|
let userRepository = NetworkUserRepository(apiService)
|
||||||
|
dataStoreProvider = DataStoreProvider(
|
||||||
|
budgetRepository: budgetRepository,
|
||||||
|
categoryRepository: categoryRepository,
|
||||||
|
transactionRepository: transactionRepository,
|
||||||
|
userRepository: userRepository
|
||||||
|
)
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,7 @@ struct AddTransactionView: View {
|
||||||
return AnyView(EmptyView())
|
return AnyView(EmptyView())
|
||||||
|
|
||||||
case .failure(.loading):
|
case .failure(.loading):
|
||||||
return AnyView(VStack {
|
return AnyView(EmbeddedLoadingView())
|
||||||
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
|
||||||
})
|
|
||||||
default:
|
default:
|
||||||
// TODO: Handle each network failure type
|
// TODO: Handle each network failure type
|
||||||
return AnyView(Form {
|
return AnyView(Form {
|
||||||
|
@ -66,9 +64,7 @@ struct AddTransactionView: View {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
return AnyView(VStack {
|
return AnyView(EmbeddedLoadingView())
|
||||||
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,19 @@ class TransactionDataStore: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTransactions(_ category: Category? = nil) {
|
func getTransactions(_ category: Category? = nil, from: Date? = nil, count: Int? = nil, page: Int? = nil) {
|
||||||
self.transactions = .failure(.loading)
|
self.transactions = .failure(.loading)
|
||||||
|
|
||||||
var categoryIds: [Int] = []
|
var categoryIds: [Int] = []
|
||||||
if category != nil {
|
if category != nil {
|
||||||
categoryIds.append(category!.id!)
|
categoryIds.append(category!.id!)
|
||||||
}
|
}
|
||||||
_ = self.transactionRepository.getTransactions(categoryIds: categoryIds, from: Date(timeIntervalSince1970: 0))
|
_ = self.transactionRepository.getTransactions(
|
||||||
|
categoryIds: categoryIds,
|
||||||
|
from: Date(timeIntervalSince1970: 0),
|
||||||
|
count: count,
|
||||||
|
page: page
|
||||||
|
)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink(receiveCompletion: { (completion) in
|
.sink(receiveCompletion: { (completion) in
|
||||||
switch completion {
|
switch completion {
|
||||||
|
@ -43,6 +48,23 @@ class TransactionDataStore: ObservableObject {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTransaction(_ transactionId: Int) {
|
||||||
|
self.transaction = .failure(.loading)
|
||||||
|
|
||||||
|
_ = self.transactionRepository.getTransaction(transactionId)
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink(receiveCompletion: { (completion) in
|
||||||
|
switch completion {
|
||||||
|
case .finished:
|
||||||
|
return
|
||||||
|
case .failure(let error):
|
||||||
|
self.transaction = .failure(error)
|
||||||
|
}
|
||||||
|
}, receiveValue: { (transaction) in
|
||||||
|
self.transaction = .success(transaction)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func createTransaction(_ transaction: Transaction) {
|
func createTransaction(_ transaction: Transaction) {
|
||||||
self.transaction = .failure(.loading)
|
self.transaction = .failure(.loading)
|
||||||
|
|
41
BudgetApp/Transaction/TransactionDetailsView.swift
Normal file
41
BudgetApp/Transaction/TransactionDetailsView.swift
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// TransactionDetailsView.swift
|
||||||
|
// Budget
|
||||||
|
//
|
||||||
|
// Created by Billy Brawner on 10/1/19.
|
||||||
|
// Copyright © 2019 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct TransactionDetailsView: View {
|
||||||
|
var body: some View {
|
||||||
|
stateContent
|
||||||
|
}
|
||||||
|
|
||||||
|
var stateContent: AnyView {
|
||||||
|
switch transactionDataStore.transaction {
|
||||||
|
case .success(let transaction):
|
||||||
|
return AnyView(VStack {
|
||||||
|
Text(transaction.title)
|
||||||
|
})
|
||||||
|
case .failure(.loading):
|
||||||
|
return AnyView(EmbeddedLoadingView())
|
||||||
|
default:
|
||||||
|
return AnyView(Text("transaction_details_error"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let transactionDataStore: TransactionDataStore
|
||||||
|
init(_ dataStoreProvider: DataStoreProvider, transaction: Transaction) {
|
||||||
|
let transactionDataStore = dataStoreProvider.transactionDataStore()
|
||||||
|
transactionDataStore.getTransactions()
|
||||||
|
self.transactionDataStore = transactionDataStore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//struct TransactionDetailsView_Previews: PreviewProvider {
|
||||||
|
// static var previews: some View {
|
||||||
|
// TransactionDetailsView()
|
||||||
|
// }
|
||||||
|
//}
|
82
BudgetApp/Transaction/TransactionRepository.swift
Normal file
82
BudgetApp/Transaction/TransactionRepository.swift
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
//
|
||||||
|
// TransactionRepository.swift
|
||||||
|
// Budget
|
||||||
|
//
|
||||||
|
// Created by Billy Brawner on 9/25/19.
|
||||||
|
// Copyright © 2019 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
protocol TransactionRepository {
|
||||||
|
func getTransactions(categoryIds: [Int]?, from: Date?, count: Int?, page: Int?) -> AnyPublisher<[Transaction], NetworkError>
|
||||||
|
func getTransaction(_ transactionId: Int) -> AnyPublisher<Transaction, NetworkError>
|
||||||
|
func createTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError>
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkTransactionRepository: TransactionRepository {
|
||||||
|
let apiService: BudgetApiService
|
||||||
|
|
||||||
|
init(_ apiService: BudgetApiService) {
|
||||||
|
self.apiService = apiService
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTransactions(categoryIds: [Int]?, from: Date?, count: Int?, page: Int?) -> AnyPublisher<[Transaction], NetworkError> {
|
||||||
|
return apiService.getTransactions(categoryIds: categoryIds, from: from, count: count, page: page)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTransaction(_ transactionId: Int) -> AnyPublisher<Transaction, NetworkError> {
|
||||||
|
return apiService.getTransaction(transactionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
|
||||||
|
return apiService.newTransaction(transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
class MockTransactionRepository: TransactionRepository {
|
||||||
|
func getTransactions(categoryIds: [Int]? = nil, from: Date? = nil, count: Int? = nil, page: Int? = nil) -> AnyPublisher<[Transaction], NetworkError> {
|
||||||
|
return Result.Publisher([Transaction(
|
||||||
|
id: 2,
|
||||||
|
title: "Test Transaction",
|
||||||
|
description: "A mock transaction used for testing",
|
||||||
|
date: Date(),
|
||||||
|
amount: 10000,
|
||||||
|
categoryId: 3,
|
||||||
|
expense: true,
|
||||||
|
createdBy: 0,
|
||||||
|
budgetId: 1
|
||||||
|
)]).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTransaction(_ transactionId: Int) -> AnyPublisher<Transaction, NetworkError> {
|
||||||
|
return Result.Publisher(Transaction(
|
||||||
|
id: 2,
|
||||||
|
title: "Test Transaction",
|
||||||
|
description: "A mock transaction used for testing",
|
||||||
|
date: Date(),
|
||||||
|
amount: 10000,
|
||||||
|
categoryId: 3,
|
||||||
|
expense: true,
|
||||||
|
createdBy: 0,
|
||||||
|
budgetId: 1
|
||||||
|
)).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTransaction(_ transaction: Transaction) -> AnyPublisher<Transaction, NetworkError> {
|
||||||
|
return Result.Publisher(Transaction(
|
||||||
|
id: 2,
|
||||||
|
title: "Test Transaction",
|
||||||
|
description: "A mock transaction used for testing",
|
||||||
|
date: Date(),
|
||||||
|
amount: 10000,
|
||||||
|
categoryId: 3,
|
||||||
|
expense: true,
|
||||||
|
createdBy: 0,
|
||||||
|
budgetId: 1
|
||||||
|
)).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
67
BudgetApp/User/UserRepository.swift
Normal file
67
BudgetApp/User/UserRepository.swift
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//
|
||||||
|
// UserRepository.swift
|
||||||
|
// Budget
|
||||||
|
//
|
||||||
|
// Created by Billy Brawner on 9/25/19.
|
||||||
|
// Copyright © 2019 William Brawner. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
protocol UserRepository {
|
||||||
|
func getUser(id: Int) -> AnyPublisher<User, NetworkError>
|
||||||
|
func searchUsers(withUsername: String) -> AnyPublisher<[User], NetworkError>
|
||||||
|
func login(username: String, password: String) -> AnyPublisher<User, NetworkError>
|
||||||
|
func register(username: String, email: String, password: String) -> AnyPublisher<User, NetworkError>
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkUserRepository: UserRepository {
|
||||||
|
let apiService: BudgetApiService
|
||||||
|
|
||||||
|
init(_ apiService: BudgetApiService) {
|
||||||
|
self.apiService = apiService
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUser(id: Int) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return apiService.getUser(id: id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchUsers(withUsername: String) -> AnyPublisher<[User], NetworkError> {
|
||||||
|
return apiService.searchUsers(query: withUsername)
|
||||||
|
}
|
||||||
|
|
||||||
|
func login(username: String, password: String) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return apiService.login(username: username, password: password)
|
||||||
|
}
|
||||||
|
|
||||||
|
func register(username: String, email: String, password: String) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return apiService.register(username: username, email: email, password: password)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
class MockUserRepository: UserRepository {
|
||||||
|
func getUser(id: Int) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return Result<User, NetworkError>.Publisher(.failure(NetworkError.unknown))
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchUsers(withUsername: String) -> AnyPublisher<[User], NetworkError> {
|
||||||
|
return Result<[User], NetworkError>.Publisher(.failure(NetworkError.unknown))
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func login(username: String, password: String) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return Result<User, NetworkError>.Publisher(.failure(NetworkError.unknown))
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func register(username: String, email: String, password: String) -> AnyPublisher<User, NetworkError> {
|
||||||
|
return Result<User, NetworkError>.Publisher(.failure(NetworkError.unknown))
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -36,6 +36,14 @@ struct LoadingView<Content>: View where Content: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EmbeddedLoadingView: View {
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
ActivityIndicator(isAnimating: .constant(true), style: .large)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ActivityIndicator: UIViewRepresentable {
|
struct ActivityIndicator: UIViewRepresentable {
|
||||||
|
|
||||||
@Binding var isAnimating: Bool
|
@Binding var isAnimating: Bool
|
Loading…
Reference in a new issue