Wiring up iOS add account settings

This commit is contained in:
Jeremy Beker 2019-06-16 18:22:00 -04:00
parent 19395779c8
commit 125ea59cd6
No known key found for this signature in database
GPG Key ID: CD5EE767A4A34FD0
6 changed files with 197 additions and 3 deletions

View File

@ -66,7 +66,7 @@ class AccountsGoogleReaderCompatibleWindowController: NSWindowController {
progressIndicator.startAnimation(self)
guard let apiURL = URL(string: apiURLTextField.stringValue) else {
self.errorMessageLabel.stringValue = NSLocalizedString("Invalie API URL.", comment: "Credentials Error")
self.errorMessageLabel.stringValue = NSLocalizedString("Invalid API URL.", comment: "Credentials Error")
return
}

View File

@ -154,6 +154,7 @@
51F85BF92274AA7B00C787DC /* UIBarButtonItem-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF82274AA7B00C787DC /* UIBarButtonItem-Extensions.swift */; };
51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BFA2275D85000C787DC /* Array-Extensions.swift */; };
51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BFC2275DCA800C787DC /* SingleLineUILabelSizer.swift */; };
557EE1AE22B6F4E1004206FA /* SettingsGoogleReaderCompatibleAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557EE1A522B6F4E1004206FA /* SettingsGoogleReaderCompatibleAccountView.swift */; };
55E15BCB229D65A900D6602A /* AccountsGoogleReaderCompatible.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsGoogleReaderCompatible.xib */; };
55E15BCC229D65A900D6602A /* AccountsGoogleReaderCompatibleWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsGoogleReaderCompatibleWindowController.swift */; };
6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; };
@ -750,6 +751,7 @@
51F85BF82274AA7B00C787DC /* UIBarButtonItem-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem-Extensions.swift"; sourceTree = "<group>"; };
51F85BFA2275D85000C787DC /* Array-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array-Extensions.swift"; sourceTree = "<group>"; };
51F85BFC2275DCA800C787DC /* SingleLineUILabelSizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleLineUILabelSizer.swift; sourceTree = "<group>"; };
557EE1A522B6F4E1004206FA /* SettingsGoogleReaderCompatibleAccountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsGoogleReaderCompatibleAccountView.swift; sourceTree = "<group>"; };
55E15BC1229D65A900D6602A /* AccountsGoogleReaderCompatible.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsGoogleReaderCompatible.xib; sourceTree = "<group>"; };
55E15BCA229D65A900D6602A /* AccountsGoogleReaderCompatibleWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsGoogleReaderCompatibleWindowController.swift; sourceTree = "<group>"; };
6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -1050,6 +1052,7 @@
5183CCEB227117C70010922C /* Settings */ = {
isa = PBXGroup;
children = (
557EE1A522B6F4E1004206FA /* SettingsGoogleReaderCompatibleAccountView.swift */,
510D708122B041CC004E8F65 /* SettingsAccountLabelView.swift */,
510D707322B028E1004E8F65 /* SettingsAddAccountView.swift */,
51F772EC22B2789B0087D9D1 /* SettingsDetailAccountView.swift */,
@ -2375,6 +2378,7 @@
51F85BF722749FA100C787DC /* UIFont-Extensions.swift in Sources */,
515436882291D75D005E1CDF /* AddLocalAccountViewController.swift in Sources */,
51C452AF2265108300C03939 /* ArticleArray.swift in Sources */,
557EE1AE22B6F4E1004206FA /* SettingsGoogleReaderCompatibleAccountView.swift in Sources */,
51C4528E2265099C00C03939 /* SmartFeedsController.swift in Sources */,
51C4529C22650A1000C03939 /* SingleFaviconDownloader.swift in Sources */,
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,

View File

@ -16,6 +16,9 @@ struct SettingsAddAccountView : View {
destination: SettingsLocalAccountView(name: "")).padding(.all, 4)
PresentationButton(SettingsAccountLabelView(accountImage: "accountFeedbin", accountLabel: "Feedbin"),
destination: SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())).padding(.all, 4)
PresentationButton(SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: "Google Reader Compatible"),
destination: SettingsGoogleReaderCompatibleAccountView(viewModel: SettingsGoogleReaderCompatibleAccountView.ViewModel())).padding(.all, 4)
}
.listStyle(.grouped)
.navigationBarTitle(Text("Add Account"), displayMode: .inline)

View File

@ -80,7 +80,7 @@ struct SettingsFeedbinAccountView : View {
switch result {
case .success(let authenticated):
if authenticated {
if (authenticated != nil) {
var newAccount = false
let workAccount: Account

View File

@ -0,0 +1,187 @@
//
// SettingsGoogleReaderCompatibleAccountView.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 6/11/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import SwiftUI
import Combine
import Account
import RSWeb
struct SettingsGoogleReaderCompatibleAccountView : View {
@Environment(\.isPresented) private var isPresented
@ObjectBinding var viewModel: ViewModel
@State var busy: Bool = false
@State var error: Text = Text("")
var body: some View {
NavigationView {
List {
Section(header:
SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: "Google Reader Compatible").padding()
) {
HStack {
Text("Email:")
Divider()
TextField($viewModel.email)
.textContentType(.username)
}
HStack {
Text("Password:")
Divider()
SecureField($viewModel.password)
}
HStack {
Text("API URL:")
Divider()
TextField($viewModel.apiURL)
.textContentType(.URL)
}
}
Section(footer:
HStack {
Spacer()
error.color(.red)
Spacer()
}
) {
HStack {
Spacer()
Button(action: { self.addAccount() }) {
if viewModel.isUpdate {
Text("Update Account")
} else {
Text("Add Account")
}
}
.disabled(!viewModel.isValid)
Spacer()
}
}
}
.disabled(busy)
.listStyle(.grouped)
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(leading:
Button(action: { self.dismiss() }) { Text("Cancel") }
)
}
}
private func addAccount() {
busy = true
error = Text("")
let emailAddress = viewModel.email.trimmingCharacters(in: .whitespaces)
let credentials = Credentials.basic(username: emailAddress, password: viewModel.password)
guard let apiURL = URL(string: viewModel.apiURL) else {
self.error = Text("Invalide API URL.")
return
}
Account.validateCredentials(type: .googleReaderCompatible, credentials: credentials, endpoint: apiURL) { result in
self.busy = false
switch result {
case .success(let authenticated):
if (authenticated != nil) {
var newAccount = false
let workAccount: Account
if self.viewModel.account == nil {
workAccount = AccountManager.shared.createAccount(type: .googleReaderCompatible)
newAccount = true
} else {
workAccount = self.viewModel.account!
}
do {
do {
try workAccount.removeBasicCredentials()
} catch {}
workAccount.endpointURL = apiURL
try workAccount.storeCredentials(credentials)
if newAccount {
workAccount.refreshAll() { result in }
}
self.dismiss()
} catch {
self.error = Text("Keychain error while storing credentials.")
}
} else {
self.error = Text("Invalid email/password combination.")
}
case .failure:
self.error = Text("Network error. Try again later.")
}
}
}
private func dismiss() {
isPresented?.value = false
}
class ViewModel: BindableObject {
let didChange = PassthroughSubject<ViewModel, Never>()
var account: Account? = nil
init() {
}
init(account: Account) {
self.account = account
if case .basic(let username, let password) = try? account.retrieveBasicCredentials() {
self.email = username
self.password = password
}
}
var email: String = "" {
didSet {
didChange.send(self)
}
}
var password: String = "" {
didSet {
didChange.send(self)
}
}
var apiURL: String = "" {
didSet {
didChange.send(self)
}
}
var isUpdate: Bool {
return account != nil
}
var isValid: Bool {
return !email.isEmpty && !password.isEmpty
}
}
}
#if DEBUG
struct SettingsGoogleReaderCompatibleAccountView_Previews : PreviewProvider {
static var previews: some View {
SettingsGoogleReaderCompatibleAccountView(viewModel: SettingsGoogleReaderCompatibleAccountView.ViewModel())
}
}
#endif

View File

@ -67,7 +67,7 @@ class FeedbinAccountViewController: UIViewController {
switch result {
case .success(let authenticated):
if authenticated {
if (authenticated != nil) {
var newAccount = false
if self.account == nil {
self.account = AccountManager.shared.createAccount(type: .feedbin)