mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #191 from writefreely/throw-keychain-errors-instead-of-crashing
Throw (and handle) Keychain error instead of crashing
This commit is contained in:
commit
b523606f6f
@ -6,6 +6,9 @@ enum AccountError: Error {
|
||||
case usernameNotFound
|
||||
case serverNotFound
|
||||
case invalidServerURL
|
||||
case couldNotSaveTokenToKeychain
|
||||
case couldNotFetchTokenFromKeychain
|
||||
case couldNotDeleteTokenFromKeychain
|
||||
}
|
||||
|
||||
extension AccountError: LocalizedError {
|
||||
@ -31,6 +34,21 @@ extension AccountError: LocalizedError {
|
||||
"Please enter a valid instance domain name. It should look like \"https://example.com\" or \"write.as\".", // swiftlint:disable:this line_length
|
||||
comment: ""
|
||||
)
|
||||
case .couldNotSaveTokenToKeychain:
|
||||
return NSLocalizedString(
|
||||
"There was a problem trying to save your access token to the device, please try logging in again.",
|
||||
comment: ""
|
||||
)
|
||||
case .couldNotFetchTokenFromKeychain:
|
||||
return NSLocalizedString(
|
||||
"There was a problem trying to fetch your access token from the device, please try logging in again.",
|
||||
comment: ""
|
||||
)
|
||||
case .couldNotDeleteTokenFromKeychain:
|
||||
return NSLocalizedString(
|
||||
"There was a problem trying to delete your access token from the device, please try logging out again.",
|
||||
comment: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,17 @@ extension WriteFreelyModel {
|
||||
let user = try result.get()
|
||||
fetchUserCollections()
|
||||
fetchUserPosts()
|
||||
saveTokenToKeychain(user.token, username: user.username, server: account.server)
|
||||
do {
|
||||
try saveTokenToKeychain(user.token, username: user.username, server: account.server)
|
||||
DispatchQueue.main.async {
|
||||
self.account.login(user)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
self.loginErrorMessage = "There was a problem storing your access token to the Keychain."
|
||||
self.isPresentingLoginErrorAlert = true
|
||||
}
|
||||
}
|
||||
} catch WFError.notFound {
|
||||
DispatchQueue.main.async {
|
||||
self.loginErrorMessage = AccountError.usernameNotFound.localizedDescription
|
||||
|
@ -1,7 +1,14 @@
|
||||
import Foundation
|
||||
|
||||
extension WriteFreelyModel {
|
||||
func saveTokenToKeychain(_ token: String, username: String?, server: String) {
|
||||
|
||||
enum WFKeychainError: Error {
|
||||
case saveToKeychainFailed
|
||||
case purgeFromKeychainFailed
|
||||
case fetchFromKeychainFailed
|
||||
}
|
||||
|
||||
func saveTokenToKeychain(_ token: String, username: String?, server: String) throws {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecValueData as String: token.data(using: .utf8)!,
|
||||
@ -10,7 +17,7 @@ extension WriteFreelyModel {
|
||||
]
|
||||
let status = SecItemAdd(query as CFDictionary, nil)
|
||||
guard status == errSecDuplicateItem || status == errSecSuccess else {
|
||||
fatalError("Error storing in Keychain with OSStatus: \(status)")
|
||||
throw WFKeychainError.saveToKeychainFailed
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,11 +29,11 @@ extension WriteFreelyModel {
|
||||
]
|
||||
let status = SecItemDelete(query as CFDictionary)
|
||||
guard status == errSecSuccess || status == errSecItemNotFound else {
|
||||
fatalError("Error deleting from Keychain with OSStatus: \(status)")
|
||||
throw WFKeychainError.purgeFromKeychainFailed
|
||||
}
|
||||
}
|
||||
|
||||
func fetchTokenFromKeychain(username: String?, server: String) -> String? {
|
||||
func fetchTokenFromKeychain(username: String?, server: String) throws -> String? {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: username ?? "anonymous",
|
||||
@ -41,7 +48,7 @@ extension WriteFreelyModel {
|
||||
return nil
|
||||
}
|
||||
guard status == errSecSuccess else {
|
||||
fatalError("Error fetching from Keychain with OSStatus: \(status)")
|
||||
throw WFKeychainError.fetchFromKeychainFailed
|
||||
}
|
||||
guard let existingSecItem = secItem as? [String: Any],
|
||||
let tokenData = existingSecItem[kSecValueData as String] as? Data,
|
||||
@ -50,4 +57,5 @@ extension WriteFreelyModel {
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,18 +51,25 @@ final class WriteFreelyModel: ObservableObject {
|
||||
print("Server URL not found")
|
||||
return
|
||||
}
|
||||
guard let token = self.fetchTokenFromKeychain(
|
||||
do {
|
||||
guard let token = try self.fetchTokenFromKeychain(
|
||||
username: self.account.username,
|
||||
server: self.account.server
|
||||
) else {
|
||||
print("Could not fetch token from Keychain")
|
||||
self.loginErrorMessage = AccountError.couldNotFetchTokenFromKeychain.localizedDescription
|
||||
self.isPresentingLoginErrorAlert = true
|
||||
return
|
||||
}
|
||||
|
||||
self.account.login(WFUser(token: token, username: self.account.username))
|
||||
self.client = WFClient(for: serverURL)
|
||||
self.client?.user = self.account.user
|
||||
self.fetchUserCollections()
|
||||
self.fetchUserPosts()
|
||||
} catch {
|
||||
self.loginErrorMessage = AccountError.couldNotFetchTokenFromKeychain.localizedDescription
|
||||
self.isPresentingLoginErrorAlert = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,7 +969,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 612;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = iOS/Info.plist;
|
||||
@ -978,7 +978,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||
SDKROOT = iphoneos;
|
||||
@ -993,7 +993,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 612;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEVELOPMENT_TEAM = TPPAB4YBA6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = iOS/Info.plist;
|
||||
@ -1002,7 +1002,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
|
||||
PRODUCT_NAME = "WriteFreely-MultiPlatform";
|
||||
SDKROOT = iphoneos;
|
||||
|
Loading…
Reference in New Issue
Block a user