diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index 959e78f5..6d111989 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 36BE064F24C9A17F00CBBB68 /* ImageTanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE064E24C9A17F00CBBB68 /* ImageTanView.swift */; }; 36BE065724C9E04800CBBB68 /* UIKitImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE065624C9E04800CBBB68 /* UIKitImageView.swift */; }; 36BE065924CA3CAB00CBBB68 /* UIKitSearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE065824CA3CAB00CBBB68 /* UIKitSearchBar.swift */; }; + 36BE065B24CA4B3500CBBB68 /* SelectBankDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE065A24CA4B3500CBBB68 /* SelectBankDialog.swift */; }; + 36BE065D24CB08FC00CBBB68 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36BE065C24CB08FB00CBBB68 /* LazyView.swift */; }; 36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E7BA1324B3D05C00757859 /* ViewExtensions.swift */; }; 36FC929C24B39A05002B12E9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929B24B39A05002B12E9 /* AppDelegate.swift */; }; 36FC929E24B39A05002B12E9 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FC929D24B39A05002B12E9 /* SceneDelegate.swift */; }; @@ -127,6 +129,8 @@ 36BE064E24C9A17F00CBBB68 /* ImageTanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTanView.swift; sourceTree = ""; }; 36BE065624C9E04800CBBB68 /* UIKitImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitImageView.swift; sourceTree = ""; }; 36BE065824CA3CAB00CBBB68 /* UIKitSearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitSearchBar.swift; sourceTree = ""; }; + 36BE065A24CA4B3500CBBB68 /* SelectBankDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectBankDialog.swift; sourceTree = ""; }; + 36BE065C24CB08FB00CBBB68 /* LazyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyView.swift; sourceTree = ""; }; 36E7BA1324B3D05C00757859 /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = ""; }; 36E7BA1824B9E70C00757859 /* xcode-frameworks */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "xcode-frameworks"; path = "../../tools/BankFinder/build/xcode-frameworks"; sourceTree = ""; }; 36FC929824B39A05002B12E9 /* BankingiOSApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BankingiOSApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -317,6 +321,8 @@ 36BE064E24C9A17F00CBBB68 /* ImageTanView.swift */, 36BE065624C9E04800CBBB68 /* UIKitImageView.swift */, 36BE065824CA3CAB00CBBB68 /* UIKitSearchBar.swift */, + 36BE065A24CA4B3500CBBB68 /* SelectBankDialog.swift */, + 36BE065C24CB08FB00CBBB68 /* LazyView.swift */, ); path = views; sourceTree = ""; @@ -487,11 +493,13 @@ 36BCF89324C25BC3005BEC29 /* Mapper.swift in Sources */, 36FC92D724B3A3BA002B12E9 /* NSUrlWebClient.swift in Sources */, 36BCF89524C31F02005BEC29 /* AppData.swift in Sources */, + 36BE065B24CA4B3500CBBB68 /* SelectBankDialog.swift in Sources */, 36BCF88324C098BB005BEC29 /* BankListItem.swift in Sources */, 36BCF88D24C1C1EA005BEC29 /* TransferMoneyDialog.swift in Sources */, 36E7BA1424B3D05C00757859 /* ViewExtensions.swift in Sources */, 36BCF88924C0A7D7005BEC29 /* Message.swift in Sources */, 366FA4E024C4924A0094F009 /* RemitteeListItem.swift in Sources */, + 36BE065D24CB08FC00CBBB68 /* LazyView.swift in Sources */, 36BCF86C24BA5E72005BEC29 /* DispatchQueueAsyncRunner.swift in Sources */, 36BCF86324BA5097005BEC29 /* SwiftUiRouter.swift in Sources */, 36BCF88F24C1DFF7005BEC29 /* SheetPresenter.swift in Sources */, diff --git a/ui/BankingiOSApp/BankingiOSApp/Base.lproj/Localizable.strings b/ui/BankingiOSApp/BankingiOSApp/Base.lproj/Localizable.strings index 25abb1bb..2387fbee 100644 --- a/ui/BankingiOSApp/BankingiOSApp/Base.lproj/Localizable.strings +++ b/ui/BankingiOSApp/BankingiOSApp/Base.lproj/Localizable.strings @@ -4,13 +4,20 @@ "Add" = "Add"; +"Bank" = "Bank"; "Account" = "Account"; "Accounts" = "Accounts"; "Add account" = "Add account"; +/* SelectBankDialog */ + +"Select Bank Dialog Title" = "Select your bank ..."; + + /* AddAccountDialog */ +"Select your bank ..." = "Select your bank ..."; "Bank code" = "Bank code"; "Customer ID" = "Online banking login name"; "Password" = "Online banking password"; diff --git a/ui/BankingiOSApp/BankingiOSApp/de.lproj/Localizable.strings b/ui/BankingiOSApp/BankingiOSApp/de.lproj/Localizable.strings index c33fd161..ed9f3659 100644 --- a/ui/BankingiOSApp/BankingiOSApp/de.lproj/Localizable.strings +++ b/ui/BankingiOSApp/BankingiOSApp/de.lproj/Localizable.strings @@ -4,13 +4,20 @@ "Add" = "Hinzufügen"; +"Bank" = "Bank"; "Account" = "Konto"; "Accounts" = "Konten"; "Add account" = "Konto hinzufügen"; +/* SelectBankDialog */ + +"Select Bank Dialog Title" = "Bank auswählen"; + + /* AddAccountDialog */ +"Select your bank ..." = "Bank auswählen ..."; "Bank code" = "Bankleitzahl"; "Customer ID" = "Onlinebanking Login Name"; "Password" = "Online banking password"; diff --git a/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift b/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift index 6f5db726..eb504365 100644 --- a/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift +++ b/ui/BankingiOSApp/BankingiOSApp/persistence/Extensions.swift @@ -22,6 +22,13 @@ extension AccountTransaction : Identifiable { } +extension BankInfo : Identifiable { + + public var id: UUID { UUID() } + +} + + extension TanProcedure : Identifiable { public var id: String { self.bankInternalProcedureCode } diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift index b61176f0..834ec197 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift @@ -7,11 +7,11 @@ struct AddAccountDialog: View { @Environment(\.presentationMode) var presentation - @State private var enteredBank = "" + @State private var bank: BankInfo? = nil + @State private var customerId = "" @State private var password = "" - - @State private var bank: BankFinderBankInfo? = BankFinderBankInfo() + @State private var errorMessage: Message? = nil @@ -20,11 +20,19 @@ struct AddAccountDialog: View { var body: some View { - return Form { - Section { - TextField("Bank code", text: $enteredBank) - .onReceive(Just(enteredBank)) { newValue in - self.findBank() + Form { + Section(header: Text("Bank")) { + NavigationLink(destination: SelectBankDialog($bank)) { + if bank != nil { + bank.map { bank in + BankInfoListItem(bank: bank) + } + } + else { + Text("Select your bank ...") + .foregroundColor(.gray) + .frame(height: 50) + } } } @@ -43,6 +51,7 @@ struct AddAccountDialog: View { Spacer() } } + } .alert(item: $errorMessage) { message in Alert(title: message.title, message: message.message, dismissButton: message.primaryButton) @@ -52,10 +61,6 @@ struct AddAccountDialog: View { } - func findBank() { - self.bank = presenter.searchBanksByNameBankCodeOrCity(query: enteredBank).first - } - func isRequiredDataEntered() -> Bool { return bank != nil && customerId.isEmpty == false diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/BankInfoListItem.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankInfoListItem.swift new file mode 100644 index 00000000..21388f1c --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/BankInfoListItem.swift @@ -0,0 +1,42 @@ +import SwiftUI +import BankingUiSwift + + +struct BankInfoListItem: View { + + let bank: BankInfo + + + var body: some View { + VStack { + HStack { + Text(bank.name) + .font(.headline) + + Spacer() + } + + HStack { + Text(bank.bankCode) + + Text(bank.postalCode) + .padding(.leading, 4) + + Text(bank.city) + + Spacer() + } + .foregroundColor(.gray) + .padding(.top, 6.0) + } + } +} + + +struct BankInfoListItem_Previews: PreviewProvider { + + static var previews: some View { + BankInfoListItem(bank: BankInfo(name: "Abzockbank Berlin", bankCode: "12345678", bic: "ABZODEBBXXX", postalCode: "12345", city: "Berlin", checksumMethod: "", pinTanAddress: nil, pinTanVersion: "FinTS 3.0", oldBankCode: nil)) + } + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/SelectBankDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/SelectBankDialog.swift new file mode 100644 index 00000000..162c76e4 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/SelectBankDialog.swift @@ -0,0 +1,76 @@ +import SwiftUI +import BankingUiSwift + + +struct SelectBankDialog: View { + + @Environment(\.presentationMode) var presentation + + + private let bankFinder = InMemoryBankFinder() + + @Binding private var selectedBank: BankInfo? + + @State private var searchText = "" + + private var searchTextBinding: Binding { + Binding( + get: { self.searchText }, + set: { + self.searchText = $0 + self.findBanks($0) + }) + } + + @State private var searchResult: [BankInfo] + + + init(_ selectedBank: Binding) { + self._selectedBank = selectedBank + + bankFinder.preloadBankList() + + _searchResult = State(initialValue: bankFinder.getBankList()) + } + + + var body: some View { + Form { + Section { + UIKitSearchBar(text: searchTextBinding) // TODO: try to get rid of the two horizontal lines + } + + Section { + // TODO: showing only the first 100 items is a workaround as SwiftUI tries to compare the two lists (to be able to animate them!) which takes extremely long for the full data set + List(searchResult.prefix(100), id: \.self) { bank in + BankInfoListItem(bank: bank) + .onTapGesture { + self.handleSelectedBank(bank) + } + } + } + } + .showNavigationBarTitle("Select Bank Dialog Title") + } + + + private func findBanks(_ query: String) { + self.searchResult = self.bankFinder.findBankByNameOrCityForNonEmptyQuery(query: query) + } + + private func handleSelectedBank(_ bank: BankInfo) { + self.selectedBank = bank + + presentation.wrappedValue.dismiss() + } + +} + + +struct FindBankDialog_Previews: PreviewProvider { + + static var previews: some View { + SelectBankDialog(.constant(nil)) + } + +} diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitSearchBar.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitSearchBar.swift new file mode 100644 index 00000000..d8eb46bf --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitSearchBar.swift @@ -0,0 +1,39 @@ +import SwiftUI + + +struct UIKitSearchBar : UIViewRepresentable { + + @Binding var text : String + + + func makeUIView(context: UIViewRepresentableContext) -> UISearchBar { + let searchBar = UISearchBar(frame: .zero) + + searchBar.delegate = context.coordinator + + return searchBar + } + + func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext) { + uiView.text = text + } + + + class Cordinator : NSObject, UISearchBarDelegate { + + @Binding var text : String + + init(text : Binding) { + _text = text + } + + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + text = searchText + } + } + + func makeCoordinator() -> Cordinator { + return Cordinator(text: $text) + } + +}