Merge pull request #45 from RobotsAndPencils/error-handling-library

Add ErrorHandling library and naively integrate
This commit is contained in:
Brandon Evans 2021-01-07 21:19:31 -07:00 committed by GitHub
commit d8f00dbcdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 37 deletions

View file

@ -42,6 +42,7 @@
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */; };
CAA1CB49255A5C97003FD669 /* SignInSMSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB48255A5C97003FD669 /* SignInSMSView.swift */; };
CAA1CB4D255A5CFD003FD669 /* SignInPhoneListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB4C255A5CFD003FD669 /* SignInPhoneListView.swift */; };
CAA858CD25A3D8BC00ACF8C0 /* ErrorHandling in Frameworks */ = {isa = PBXBuildFile; productRef = CAA858CC25A3D8BC00ACF8C0 /* ErrorHandling */; };
CABFA9BB2592EEEA00380FEE /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFA9BA2592EEEA00380FEE /* DateFormatter+.swift */; };
CABFA9BD2592EEEA00380FEE /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFA9A92592EEE900380FEE /* Environment.swift */; };
CABFA9BF2592EEEA00380FEE /* URLSession+DownloadTaskPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFA9B32592EEEA00380FEE /* URLSession+DownloadTaskPublisher.swift */; };
@ -233,6 +234,7 @@
CABFA9FD2592F13300380FEE /* LegibleError in Frameworks */,
CA9FF86D25951C6E00E47BAF /* XCModel in Frameworks */,
CABFA9F82592F0F900380FEE /* KeychainAccess in Frameworks */,
CAA858CD25A3D8BC00ACF8C0 /* ErrorHandling in Frameworks */,
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */,
CABFA9DF2592F07A00380FEE /* Path in Frameworks */,
CABFA9EE2592F0CC00380FEE /* SwiftSoup in Frameworks */,
@ -508,6 +510,7 @@
CABFA9F72592F0F900380FEE /* KeychainAccess */,
CABFA9FC2592F13300380FEE /* LegibleError */,
CA9FF86C25951C6E00E47BAF /* XCModel */,
CAA858CC25A3D8BC00ACF8C0 /* ErrorHandling */,
);
productName = XcodesMac;
productReference = CAD2E79E2449574E00113D76 /* Xcodes.app */;
@ -569,6 +572,7 @@
CABFA9F62592F0F900380FEE /* XCRemoteSwiftPackageReference "KeychainAccess" */,
CABFA9FB2592F13300380FEE /* XCRemoteSwiftPackageReference "LegibleError" */,
CA9FF86B25951C6E00E47BAF /* XCRemoteSwiftPackageReference "data" */,
CAA858CB25A3D8BC00ACF8C0 /* XCRemoteSwiftPackageReference "ErrorHandling" */,
);
productRefGroup = CAD2E79F2449574E00113D76 /* Products */;
projectDirPath = "";
@ -1162,6 +1166,14 @@
revision = b47228c688b608e34b3b84079ab6052a24c7a981;
};
};
CAA858CB25A3D8BC00ACF8C0 /* XCRemoteSwiftPackageReference "ErrorHandling" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/RobotsAndPencils/ErrorHandling";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.1.0;
};
};
CABFA9DD2592F07A00380FEE /* XCRemoteSwiftPackageReference "Path" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mxcl/Path.swift";
@ -1214,6 +1226,11 @@
isa = XCSwiftPackageProductDependency;
productName = AppleAPI;
};
CAA858CC25A3D8BC00ACF8C0 /* ErrorHandling */ = {
isa = XCSwiftPackageProductDependency;
package = CAA858CB25A3D8BC00ACF8C0 /* XCRemoteSwiftPackageReference "ErrorHandling" */;
productName = ErrorHandling;
};
CABFA9DE2592F07A00380FEE /* Path */ = {
isa = XCSwiftPackageProductDependency;
package = CABFA9DD2592F07A00380FEE /* XCRemoteSwiftPackageReference "Path" */;

View file

@ -10,6 +10,15 @@
"version": null
}
},
{
"package": "ErrorHandling",
"repositoryURL": "https://github.com/RobotsAndPencils/ErrorHandling",
"state": {
"branch": null,
"revision": "7be837fcb515447c0776805c3288fb7d5181ec68",
"version": "0.1.0"
}
},
{
"package": "KeychainAccess",
"repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess",

View file

@ -38,7 +38,7 @@ extension AppState {
receiveCompletion: { [unowned self] completion in
switch completion {
case let .failure(error):
self.error = AlertContent(title: "Update Error", message: error.legibleLocalizedDescription)
self.error = error
case .finished:
Current.defaults.setDate(Current.date(), forKey: "lastUpdated")
}

View file

@ -27,14 +27,17 @@ class AppState: ObservableObject {
}
@Published var updatePublisher: AnyCancellable?
var isUpdating: Bool { updatePublisher != nil }
@Published var error: AlertContent?
@Published var authError: AlertContent?
@Published var presentingSignInAlert = false
@Published var isProcessingAuthRequest = false
@Published var secondFactorData: SecondFactorData?
@Published var xcodeBeingConfirmedForUninstallation: Xcode?
@Published var helperInstallState: HelperInstallState = .notInstalled
// MARK: - Errors
@Published var error: Error?
@Published var authError: Error?
init() {
try? loadCachedAvailableXcodes()
checkIfHelperIsInstalled()
@ -158,7 +161,7 @@ class AppState: ObservableObject {
}
// This error message is not user friendly... need to extract some meaningful data in the different cases
self.authError = AlertContent(title: "Error signing in", message: error.legibleLocalizedDescription)
self.authError = error
case .finished:
switch self.authenticationState {
case .authenticated, .unauthenticated:
@ -220,7 +223,7 @@ class AppState: ObservableObject {
.sink(
receiveCompletion: { [unowned self] completion in
if case let .failure(error) = completion {
self.error = AlertContent(title: "Error uninstalling Xcode", message: error.legibleLocalizedDescription)
self.error = error
}
self.uninstallPublisher = nil
},
@ -251,7 +254,7 @@ class AppState: ObservableObject {
.sink(
receiveCompletion: { [unowned self] completion in
if case let .failure(error) = completion {
self.error = AlertContent(title: "Error selecting Xcode", message: error.legibleLocalizedDescription)
self.error = error
}
self.selectPublisher = nil
},

View file

@ -1,3 +1,4 @@
import ErrorHandling
import SwiftUI
struct MainWindow: View {
@ -31,11 +32,7 @@ struct MainWindow: View {
)
.navigationSubtitle(subtitleText)
.frame(minWidth: 600, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
.alert(item: $appState.error) { error in
Alert(title: Text(error.title),
message: Text(verbatim: error.message),
dismissButton: .default(Text("OK")))
}
.emittingError($appState.error, recoveryHandler: { _ in })
.sheet(isPresented: $appState.secondFactorData.isNotNil) {
secondFactorView(appState.secondFactorData!)
.environmentObject(appState)

View file

@ -34,11 +34,7 @@ struct SignIn2FAView: View {
.frame(height: 25)
}
.padding()
.alert(item: $appState.authError) { error in
Alert(title: Text(error.title),
message: Text(verbatim: error.message),
dismissButton: .default(Text("OK")))
}
.emittingError($appState.authError, recoveryHandler: { _ in })
}
}

View file

@ -38,11 +38,7 @@ struct SignInCredentialsView: View {
.frame(height: 25)
}
.padding()
.alert(item: $appState.authError) { error in
Alert(title: Text(error.title),
message: Text(verbatim: error.message),
dismissButton: .default(Text("OK")))
}
.emittingError($appState.authError, recoveryHandler: { _ in })
}
}

View file

@ -39,11 +39,7 @@ struct SignInPhoneListView: View {
}
.padding()
.frame(width: 400, height: 200)
.alert(item: $appState.authError) { error in
Alert(title: Text(error.title),
message: Text(verbatim: error.message),
dismissButton: .default(Text("OK")))
}
.emittingError($appState.authError, recoveryHandler: { _ in })
}
}

View file

@ -34,11 +34,7 @@ struct SignInSMSView: View {
.frame(height: 25)
}
.padding()
.alert(item: $appState.authError) { error in
Alert(title: Text(error.title),
message: Text(verbatim: error.message),
dismissButton: .default(Text("OK")))
}
.emittingError($appState.authError, recoveryHandler: { _ in })
}
}

View file

@ -31,6 +31,34 @@ SOFTWARE.\
\
\
\fs34 ErrorHandling\
\
\fs26 MIT License\
\
Copyright (c) 2020 Robots and Pencils\
Copyright (c) 2020 John Sundell\
\
Permission is hereby granted, free of charge, to any person obtaining a copy\
of this software and associated documentation files (the "Software"), to deal\
in the Software without restriction, including without limitation the rights\
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\
copies of the Software, and to permit persons to whom the Software is\
furnished to do so, subject to the following conditions:\
\
The above copyright notice and this permission notice shall be included in all\
copies or substantial portions of the Software.\
\
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\
SOFTWARE.\
\
\
\fs34 Path.swift\
\

View file

@ -9,18 +9,18 @@ struct SettingsView: View {
VStack(alignment: .leading) {
GroupBox(label: Text("Apple ID")) {
VStack(alignment: .leading) {
if let username = Current.defaults.string(forKey: "username") {
Text(username)
if appState.authenticationState == .authenticated {
Text(Current.defaults.string(forKey: "username") ?? "-")
Button("Sign Out", action: appState.signOut)
} else {
Button("Sign In", action: { self.appState.presentingSignInAlert = true })
.sheet(isPresented: $appState.presentingSignInAlert) {
SignInCredentialsView(isPresented: $appState.presentingSignInAlert)
.environmentObject(appState)
}
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.sheet(isPresented: $appState.presentingSignInAlert) {
SignInCredentialsView(isPresented: $appState.presentingSignInAlert)
.environmentObject(appState)
}
}
GroupBox(label: Text("Data Source")) {