From d320675bb9b62b0d18ebf801022f8406a886eebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Truszczy=C5=84ski?= Date: Tue, 30 Jan 2024 10:54:24 +0100 Subject: [PATCH] 0.25.0 Release (#1019) - Improved TorManager. Now app will not kill the Tor instance during bootstrap - Improved the way how the Tor state requests are handled - Set NextNet as a default network - Removed access to the StageNet network - Deep links will now survive the startup process - Fixed reported crash. The App will now replace the window with SplashView instead of the SwiftEntryKit window with the window containing HomeView. - Removed obsolete functionality. The App will no longer try to start the wallet without the passphrase. Reason: FFI library no longer is able to create a wallet without valid passphrase. - Set min iOS version to iOS 15 - Removed the majority of the iOS 15 obsolete warnings. - Updated code to be ready for Swift 6.0 - Added additional logging - Updated FFI Lib to v1.0.0-rc.3 - Updated Tor framework to 408.10.1 - Updated IPtProxy framework to 3.3.0 - Removed unused OpenSSL framework. This framework is used only internally by the Tor framework. - Updated SwiftLint config - Fixed SwiftLint warnings - Removed dead code - Updated README.md file - Updated fastlane config --- .swiftlint.yml | 8 +- MobileWallet.xcodeproj/project.pbxproj | 26 +++--- .../Backup/Dropbox/DropboxBackupService.swift | 15 ++-- MobileWallet/Common/AppRouter.swift | 4 +- .../DeepLinkDefaultActionsHandler.swift | 2 - .../Common/Deep Links/DeeplinkHandler.swift | 16 ++++ .../Common/Extensions/LAContext.swift | 4 +- .../Extensions/UIApplication+Keyboard.swift | 47 ---------- ...Window.swift => UIApplication+Utils.swift} | 34 +++++--- .../Extensions/UIViewController+Content.swift | 2 +- .../Managers/LocalNotificationsManager.swift | 9 +- .../StagedWalletSecurityManager.swift | 3 +- MobileWallet/Common/NotificationManager.swift | 2 +- .../Common/Theme/ThemeCoordinator.swift | 6 +- MobileWallet/Common/WebBrowserPresenter.swift | 2 +- .../Libraries/TariLib/Core/FFI/Wallet.swift | 6 +- .../TariLib/Core/FFIWalletManager.swift | 17 +++- .../Libraries/TariLib/Core/Tari.swift | 14 ++- .../Core/Tor/TorConnectionStatus.swift | 1 + .../Libraries/TariLib/Core/TorManager.swift | 49 ++++++++--- .../ConnectionMonitor.swift | 4 +- .../Utils/Loggers/ConsoleLogger.swift | 2 +- .../Utils/Network/NetworkManager.swift | 2 +- .../Wrappers/Utils/Network/TariNetwork.swift | 25 ++---- .../Utils/Settings/TariSettings.swift | 67 ++++----------- MobileWallet/SceneDelegate.swift | 5 ++ .../Contact Book/List/ContactBookModel.swift | 29 ------- .../Screens/Home/Home/HomeModel.swift | 1 + .../Home/Views/HomeViewTransactionCell.swift | 2 +- .../TransactionDetailsViewController.swift | 8 +- .../Other/UTXOsWalletTileListLayout.swift | 2 +- .../AddAmount/AddAmountViewController.swift | 2 +- .../Views/YatTransactionView.swift | 6 -- .../Settings/MoreSettings/AboutModel.swift | 85 +++++++++++++++---- MobileWallet/UIElements/EmojiIdView.swift | 16 ++-- .../Labels/AnimatedBalanceLabel.swift | 2 +- MobileWallet/UIElements/NavigationBar.swift | 2 +- .../UIElements/PendingView/PendingView.swift | 6 +- .../UIElements/TabBar/CustomTabBar.swift | 7 +- Podfile | 7 +- Podfile.lock | 26 +++--- README.md | 48 +++++------ dependencies.env | 2 +- fastlane/Fastfile | 82 ++---------------- fastlane/Pluginfile | 2 +- fastlane/README.md | 49 ----------- fastlane/Snapfile | 33 ------- fastlane/sync_libs.sh | 4 - readme-files/tari-logo.svg | 30 +++++++ 49 files changed, 341 insertions(+), 482 deletions(-) delete mode 100644 MobileWallet/Common/Extensions/UIApplication+Keyboard.swift rename MobileWallet/Common/Extensions/{UIApplication+KeyWindow.swift => UIApplication+Utils.swift} (69%) delete mode 100644 fastlane/README.md delete mode 100644 fastlane/Snapfile delete mode 100644 fastlane/sync_libs.sh create mode 100644 readme-files/tari-logo.svg diff --git a/.swiftlint.yml b/.swiftlint.yml index c3ab9a60..b3a5d195 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -7,8 +7,8 @@ type_body_length: # Target: 250/350 - 400 function_body_length: # Target: 50/100 - - 105 - - 120 + - 90 + - 100 file_length: # Target: 400/1000 - 675 @@ -24,9 +24,7 @@ excluded: - Pods - UnitTests # Files scheduled for refactor - - ./**/TariSettings.swift - ./**/SettingsViewController.swift - ./**/AddAmountViewController.swift - ./**/EmojiIdView.swift - - ./**/AnimatedBalanceLabel.swift - - ./**/TxsListViewController.swift \ No newline at end of file + - ./**/AnimatedBalanceLabel.swift \ No newline at end of file diff --git a/MobileWallet.xcodeproj/project.pbxproj b/MobileWallet.xcodeproj/project.pbxproj index 4ae01c7e..5c6165fd 100644 --- a/MobileWallet.xcodeproj/project.pbxproj +++ b/MobileWallet.xcodeproj/project.pbxproj @@ -57,7 +57,7 @@ 3730E15124C884D500827DFA /* MenuTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3730E15024C884D500827DFA /* MenuTabBarController.swift */; }; 373CCDBD2490B66E00D0A2C9 /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CCDBC2490B66E00D0A2C9 /* CircularProgressView.swift */; }; 373CCDC52490F3B600D0A2C9 /* FileManager+SecureCopy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373CCDC42490F3B600D0A2C9 /* FileManager+SecureCopy.swift */; }; - 37547D522460165500EB59CC /* UIApplication+KeyWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37547D512460165500EB59CC /* UIApplication+KeyWindow.swift */; }; + 37547D522460165500EB59CC /* UIApplication+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37547D512460165500EB59CC /* UIApplication+Utils.swift */; }; 37547D5624601BF600EB59CC /* UIView+GlobalFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37547D5524601BF600EB59CC /* UIView+GlobalFrame.swift */; }; 375AFDCF2475387700C62CA1 /* WebBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 375AFDCE2475387700C62CA1 /* WebBrowserViewController.swift */; }; 375DB1E0246E90D100B2BEF4 /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 375DB1DF246E90D100B2BEF4 /* NavigationBar.swift */; }; @@ -302,7 +302,6 @@ 3AE138CB28044B1E00443D34 /* CustomDeeplinkPopUpContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE138CA28044B1E00443D34 /* CustomDeeplinkPopUpContentView.swift */; }; 3AE138CF2804A88500443D34 /* ToastPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE138CE2804A88500443D34 /* ToastPresenter.swift */; }; 3AE138D12804A8B300443D34 /* SuccessToast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE138D02804A8B300443D34 /* SuccessToast.swift */; }; - 3AE138D32804AB4100443D34 /* UIApplication+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE138D22804AB4100443D34 /* UIApplication+Keyboard.swift */; }; 3AE138D52804ACE100443D34 /* WebBrowserPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE138D42804ACE100443D34 /* WebBrowserPresenter.swift */; }; 3AE1D58027E0A894001A46C4 /* TransactionDetailsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE1D57F27E0A894001A46C4 /* TransactionDetailsModel.swift */; }; 3AE1D58227E0A8C8001A46C4 /* TransactionDetailsConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE1D58127E0A8C8001A46C4 /* TransactionDetailsConstructor.swift */; }; @@ -339,7 +338,6 @@ 491AB8A023F3FF4400372189 /* AddAmountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 491AB89F23F3FF4400372189 /* AddAmountViewController.swift */; }; 49996E1923F164BA002B6696 /* AnimatedBalanceLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49996E1823F164BA002B6696 /* AnimatedBalanceLabel.swift */; }; 4C2C95C7237962CB005058AB /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C2C95C6237962CB005058AB /* libc++.tbd */; }; - 4C363B762574F15E00D99868 /* OpenSSL.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C363B372574EFE500D99868 /* OpenSSL.xcframework */; }; 4CD20A362407967B007B64D8 /* TransportConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD20A352407967B007B64D8 /* TransportConfig.swift */; }; 4CDEC323273A5E3600999DCB /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDEC322273A5E3500999DCB /* Balance.swift */; }; 515299BD56554003EF2BD2FD /* Pods_MobileWallet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0A04F26CF08C60019DAC177 /* Pods_MobileWallet.framework */; }; @@ -637,7 +635,7 @@ 3730E15024C884D500827DFA /* MenuTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuTabBarController.swift; sourceTree = ""; }; 373CCDBC2490B66E00D0A2C9 /* CircularProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = ""; }; 373CCDC42490F3B600D0A2C9 /* FileManager+SecureCopy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+SecureCopy.swift"; sourceTree = ""; }; - 37547D512460165500EB59CC /* UIApplication+KeyWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+KeyWindow.swift"; sourceTree = ""; }; + 37547D512460165500EB59CC /* UIApplication+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Utils.swift"; sourceTree = ""; }; 37547D5524601BF600EB59CC /* UIView+GlobalFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+GlobalFrame.swift"; sourceTree = ""; }; 375AFDCE2475387700C62CA1 /* WebBrowserViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebBrowserViewController.swift; sourceTree = ""; }; 375DB1DF246E90D100B2BEF4 /* NavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBar.swift; sourceTree = ""; }; @@ -883,7 +881,6 @@ 3AE138CA28044B1E00443D34 /* CustomDeeplinkPopUpContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDeeplinkPopUpContentView.swift; sourceTree = ""; }; 3AE138CE2804A88500443D34 /* ToastPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastPresenter.swift; sourceTree = ""; }; 3AE138D02804A8B300443D34 /* SuccessToast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessToast.swift; sourceTree = ""; }; - 3AE138D22804AB4100443D34 /* UIApplication+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Keyboard.swift"; sourceTree = ""; }; 3AE138D42804ACE100443D34 /* WebBrowserPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebBrowserPresenter.swift; sourceTree = ""; }; 3AE1D57F27E0A894001A46C4 /* TransactionDetailsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDetailsModel.swift; sourceTree = ""; }; 3AE1D58127E0A8C8001A46C4 /* TransactionDetailsConstructor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDetailsConstructor.swift; sourceTree = ""; }; @@ -921,7 +918,6 @@ 49996E1823F164BA002B6696 /* AnimatedBalanceLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedBalanceLabel.swift; sourceTree = ""; }; 4C2C95B8237959B3005058AB /* MobileWallet-bridging-header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MobileWallet-bridging-header.h"; sourceTree = ""; }; 4C2C95C6237962CB005058AB /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; - 4C363B372574EFE500D99868 /* OpenSSL.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = "Pods/OpenSSL-Universal/Frameworks/OpenSSL.xcframework"; sourceTree = ""; }; 4CD20A352407967B007B64D8 /* TransportConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransportConfig.swift; sourceTree = ""; }; 4CDEC322273A5E3500999DCB /* Balance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = ""; }; 540CB6ED29C1D519003FACEF /* SettingsProfileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsProfileCell.swift; sourceTree = ""; }; @@ -1147,7 +1143,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4C363B762574F15E00D99868 /* OpenSSL.xcframework in Frameworks */, 371189732488FF11004D0CE3 /* CloudKit.framework in Frameworks */, 00DC2E22238554FD00036DDC /* libsqlite3.tbd in Frameworks */, 0070A7BC2379847100C25E1C /* LocalAuthentication.framework in Frameworks */, @@ -1217,8 +1212,7 @@ 37CB9F892451A2AD00C495F2 /* String+Emoji.swift */, 54621F8A29E00E78000E9659 /* String+Tools.swift */, 549565DF2AA1D21E0092A10F /* Task+Utils.swift */, - 3AE138D22804AB4100443D34 /* UIApplication+Keyboard.swift */, - 37547D512460165500EB59CC /* UIApplication+KeyWindow.swift */, + 37547D512460165500EB59CC /* UIApplication+Utils.swift */, 3A8826C427F1B8320037F779 /* UICollectionViewDiffableDataSource+Animation.swift */, 3AECD493284F46FD00D81C80 /* UIColor+Utils.swift */, 37E0B007249B700F00DFE315 /* UIFont+FontStyle.swift */, @@ -1504,7 +1498,6 @@ isa = PBXGroup; children = ( 542725652AFB7E1000FA4973 /* libminotari_wallet_ffi_ios.xcframework */, - 4C363B372574EFE500D99868 /* OpenSSL.xcframework */, 371189722488FF11004D0CE3 /* CloudKit.framework */, 0070A7BB2379847100C25E1C /* LocalAuthentication.framework */, 00C520AE2469716E0077BF7F /* libc++.1.tbd */, @@ -3558,7 +3551,6 @@ 3AF97E6727CF769A00FF6A3F /* BaseNodesAddDeeplink.swift in Sources */, 3A8005CF28EAF9380022A38A /* BaseNodeConnectivityStatus.swift in Sources */, 5444C80F29F1B02B00BF3875 /* BluetoothSettingsHeaderView.swift in Sources */, - 3AE138D32804AB4100443D34 /* UIApplication+Keyboard.swift in Sources */, 3A115B1827EC4B14001259E5 /* TransactionDetailsSeparatorView.swift in Sources */, 549E1A012A5EB7B00063022C /* QRCodeScannerBoxView.swift in Sources */, 3A8473CC28EC562E0015E63A /* TariConnectionService.swift in Sources */, @@ -3676,7 +3668,7 @@ 3A530BCF290AEDB600C423C7 /* BackupServicable.swift in Sources */, 3AF79D602727206200613C24 /* ContactSearchView.swift in Sources */, 3AECD490284F3BB300D81C80 /* BaseNavigationContentView.swift in Sources */, - 37547D522460165500EB59CC /* UIApplication+KeyWindow.swift in Sources */, + 37547D522460165500EB59CC /* UIApplication+Utils.swift in Sources */, 3A87C3B727A9409E007A553F /* WalletError.swift in Sources */, 00A994332396434B007D9990 /* PulseButton.swift in Sources */, 5460258629A74D8200CF5764 /* ContactDetailsModel.swift in Sources */, @@ -3922,7 +3914,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -3979,7 +3971,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; OTHER_LDFLAGS = "-v"; @@ -4007,12 +3999,13 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = MobileWallet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.24.0; + MARKETING_VERSION = 0.25.0; PRODUCT_BUNDLE_IDENTIFIER = com.tari.wallet; PRODUCT_NAME = "Tari Aurora"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4039,12 +4032,13 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = MobileWallet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.24.0; + MARKETING_VERSION = 0.25.0; PRODUCT_BUNDLE_IDENTIFIER = com.tari.wallet; PRODUCT_NAME = "Tari Aurora"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/MobileWallet/Backup/Dropbox/DropboxBackupService.swift b/MobileWallet/Backup/Dropbox/DropboxBackupService.swift index 4398482e..51c3ce7d 100644 --- a/MobileWallet/Backup/Dropbox/DropboxBackupService.swift +++ b/MobileWallet/Backup/Dropbox/DropboxBackupService.swift @@ -210,20 +210,21 @@ final class DropboxBackupService { startBackgroundTask() Task { [weak self] in + guard let self else { return } do { _ = try dropboxClient try await uploadFile(password: password) - self?.syncDate = Date() - self?.syncStatus = .enabled + self.syncDate = Date() + self.syncStatus = .enabled } catch InternalError.noClient, InternalError.unableToAuthenticateUser { - self?.signIn(task: .upload) + self.signIn(task: .upload) } catch let error as DropboxBackupError { - self?.syncStatus = .failed(error: error) + self.syncStatus = .failed(error: error) } catch { - self?.syncStatus = .failed(error: DropboxBackupError.unknown) + self.syncStatus = .failed(error: DropboxBackupError.unknown) } - self?.endBackgroundTask() + self.endBackgroundTask() } } @@ -415,6 +416,8 @@ final class DropboxBackupService { return try await withCheckedThrowingContinuation { [weak self] continuation in + guard let self else { return } + let group = DispatchGroup() var encryptedFileTimestamp: Date? diff --git a/MobileWallet/Common/AppRouter.swift b/MobileWallet/Common/AppRouter.swift index dd188709..425a9d08 100644 --- a/MobileWallet/Common/AppRouter.swift +++ b/MobileWallet/Common/AppRouter.swift @@ -80,7 +80,7 @@ enum AppRouter { private static func transition(to controller: UIViewController, type: TransitionType) { - guard let window = UIApplication.shared.windows.first else { return } + guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let window = scene.windows.first else { return } guard type != .none else { window.rootViewController = controller @@ -132,7 +132,7 @@ enum AppRouter { static func presentOnTop(controller: UIViewController) { - guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return } + guard var topViewController = UIApplication.shared.topController else { return } while let presentedViewController = topViewController.presentedViewController { topViewController = presentedViewController diff --git a/MobileWallet/Common/Deep Links/DeepLinkDefaultActionsHandler.swift b/MobileWallet/Common/Deep Links/DeepLinkDefaultActionsHandler.swift index b0d1f55a..500ff7f2 100644 --- a/MobileWallet/Common/Deep Links/DeepLinkDefaultActionsHandler.swift +++ b/MobileWallet/Common/Deep Links/DeepLinkDefaultActionsHandler.swift @@ -55,7 +55,6 @@ enum DeepLinkDefaultActionsHandler { static func handle(baseNodesAddDeeplink: BaseNodesAddDeeplink) throws { Task { @MainActor in - try await Task.sleep(nanoseconds: 500000000) // FIXME: Replace it with App state handler self.showAddBaseNodePopUp(name: baseNodesAddDeeplink.name, peer: baseNodesAddDeeplink.peer) } } @@ -116,7 +115,6 @@ enum DeepLinkDefaultActionsHandler { } @MainActor private static func showAddContactsPopUp(contacts: [ContactData]) async throws { - try await Task.sleep(nanoseconds: 500000000) // FIXME: Replace it with App state handler guard await showAddContactsDialog(contacts: contacts) else { return } try add(contacts: contacts) } diff --git a/MobileWallet/Common/Deep Links/DeeplinkHandler.swift b/MobileWallet/Common/Deep Links/DeeplinkHandler.swift index 55b34228..539d4685 100644 --- a/MobileWallet/Common/Deep Links/DeeplinkHandler.swift +++ b/MobileWallet/Common/Deep Links/DeeplinkHandler.swift @@ -42,6 +42,8 @@ import UIKit enum DeeplinkHandler { + private static var storedDeeplink: DeepLinkable? + static func deeplink(rawDeeplink: String) throws -> DeepLinkable? { guard let deeplink = URL(string: rawDeeplink) else { return nil } @@ -74,6 +76,11 @@ enum DeeplinkHandler { actionType = .direct } + if actionType == .popUp, !(Tari.shared.isWalletConnected && AppRouter.isNavigationReady) { + retryHandle(deeplink: deeplink) + return + } + switch deeplink.type { case .baseNodesAdd: try handle(baseNodesAddDeeplink: deeplink) @@ -105,4 +112,13 @@ enum DeeplinkHandler { guard let deeplink = transactionSendDeepLink as? TransactionsSendDeeplink else { return } DeepLinkDefaultActionsHandler.handle(transactionSendDeepLink: deeplink) } + + private static func retryHandle(deeplink: DeepLinkable) { + storedDeeplink = deeplink + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + guard let storedDeeplink else { return } + self.storedDeeplink = nil + try? handle(deeplink: storedDeeplink, showDefaultDialogIfNeeded: true) + } + } } diff --git a/MobileWallet/Common/Extensions/LAContext.swift b/MobileWallet/Common/Extensions/LAContext.swift index 909f88ee..c745bc87 100644 --- a/MobileWallet/Common/Extensions/LAContext.swift +++ b/MobileWallet/Common/Extensions/LAContext.swift @@ -116,7 +116,7 @@ extension LAContext { onSuccess() })) - if let topController = UIApplication.shared.topController() { + if let topController = UIApplication.shared.topController { topController.present(alert, animated: true, completion: nil) } } @@ -136,7 +136,7 @@ extension LAContext { } })) - if let topController = UIApplication.shared.topController() { + if let topController = UIApplication.shared.topController { topController.present(alert, animated: true, completion: nil) } } diff --git a/MobileWallet/Common/Extensions/UIApplication+Keyboard.swift b/MobileWallet/Common/Extensions/UIApplication+Keyboard.swift deleted file mode 100644 index dbbb0a8a..00000000 --- a/MobileWallet/Common/Extensions/UIApplication+Keyboard.swift +++ /dev/null @@ -1,47 +0,0 @@ -// UIApplication+Keyboard.swift - -/* - Package MobileWallet - Created by Adrian Truszczynski on 11/04/2022 - Using Swift 5.0 - Running on macOS 12.3 - - Copyright 2019 The Tari Project - - Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the - following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of - its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -import UIKit - -extension UIApplication { - func hideKeyboard() { - sendAction(#selector(UIApplication.resignFirstResponder), to: nil, from: nil, for: nil) - } -} diff --git a/MobileWallet/Common/Extensions/UIApplication+KeyWindow.swift b/MobileWallet/Common/Extensions/UIApplication+Utils.swift similarity index 69% rename from MobileWallet/Common/Extensions/UIApplication+KeyWindow.swift rename to MobileWallet/Common/Extensions/UIApplication+Utils.swift index 089e6f40..1181babd 100644 --- a/MobileWallet/Common/Extensions/UIApplication+KeyWindow.swift +++ b/MobileWallet/Common/Extensions/UIApplication+Utils.swift @@ -1,4 +1,4 @@ -// UIApplication+keyWindow.swift +// UIApplication+Utils.swift /* Package MobileWallet @@ -41,26 +41,32 @@ import UIKit extension UIApplication { - var keyWindow: UIWindow? { - return UIApplication.shared.windows.filter({$0.isKeyWindow}).first - } + + var firstWindow: UIWindow? { windows.first } var menuTabBarController: MenuTabBarController? { - return findViewController(kindOf: MenuTabBarController.self) + findViewController(kindOf: MenuTabBarController.self) } - func topController() -> UIViewController? { - if var topController = keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController - } - return topController + var topController: UIViewController? { + guard var topController = firstWindow?.rootViewController else { return nil } + while let presentedViewController = topController.presentedViewController { + topController = presentedViewController } - return nil + return topController + } + + func hideKeyboard() { + sendAction(#selector(UIApplication.resignFirstResponder), to: nil, from: nil, for: nil) + } + + private var windows: [UIWindow] { + guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return [] } + return scene.windows } - func findViewController(kindOf: T.Type? = nil) -> T? { - guard let window = keyWindow else { return nil } + private func findViewController(kindOf: T.Type? = nil) -> T? { + guard let window = firstWindow else { return nil } if let vc = window.rootViewController as? T { return vc } else if let vc = window.rootViewController?.presentedViewController as? T { diff --git a/MobileWallet/Common/Extensions/UIViewController+Content.swift b/MobileWallet/Common/Extensions/UIViewController+Content.swift index 6b4b7907..54e1f522 100644 --- a/MobileWallet/Common/Extensions/UIViewController+Content.swift +++ b/MobileWallet/Common/Extensions/UIViewController+Content.swift @@ -41,7 +41,7 @@ import UIKit var hasNotch: Bool { - let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0 + let bottom = UIApplication.shared.firstWindow?.safeAreaInsets.bottom ?? 0 return bottom > 0 } diff --git a/MobileWallet/Common/Managers/LocalNotificationsManager.swift b/MobileWallet/Common/Managers/LocalNotificationsManager.swift index 33804063..2413f44a 100644 --- a/MobileWallet/Common/Managers/LocalNotificationsManager.swift +++ b/MobileWallet/Common/Managers/LocalNotificationsManager.swift @@ -129,13 +129,6 @@ final class LocalNotificationsManager: NSObject { } private func handleOpenNotification(userInfo: [AnyHashable: Any]) { - guard let rawDeeplink = userInfo[UserInfo.rawDeeplink.rawValue] as? String else { return } - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - try? DeeplinkHandler.handle(rawDeeplink: rawDeeplink, showDefaultDialogIfNeeded: true) - } - } - - private func handleContactsReceivedAction(userInfo: [AnyHashable: Any]) { guard let rawDeeplink = userInfo[UserInfo.rawDeeplink.rawValue] as? String else { return } try? DeeplinkHandler.handle(rawDeeplink: rawDeeplink, showDefaultDialogIfNeeded: true) } @@ -160,7 +153,7 @@ extension LocalNotificationsManager: UNUserNotificationCenterDelegate { switch actionType { case .contactReceivedConfirm: - handleContactsReceivedAction(userInfo: userInfo) + handleOpenNotification(userInfo: userInfo) case .contactReceivedReject: break } diff --git a/MobileWallet/Common/Managers/StagedWalletSecurityManager.swift b/MobileWallet/Common/Managers/StagedWalletSecurityManager.swift index afe8f1df..3142bb65 100644 --- a/MobileWallet/Common/Managers/StagedWalletSecurityManager.swift +++ b/MobileWallet/Common/Managers/StagedWalletSecurityManager.swift @@ -163,7 +163,8 @@ final class StagedWalletSecurityManager { ) } - @MainActor private func showPopUp(title: String, subtitle: String, message: String, messageBoldRanges: [NSRange] = [], mainActionTitle: String, mainActionCallback: @escaping () -> Void, helpActionCallback: @escaping () -> Void) { + @MainActor private func showPopUp(title: String, subtitle: String, message: String, messageBoldRanges: [NSRange] = [], mainActionTitle: String, + mainActionCallback: @escaping () -> Void, helpActionCallback: @escaping () -> Void) { let headerSection = PopUpStagedWalletSecurityHeaderView(title: title, subtitle: subtitle) let contentSection = PopUpDescriptionContentView() let buttonsSection = PopUpComponentsFactory.makeButtonsView(models: [ diff --git a/MobileWallet/Common/NotificationManager.swift b/MobileWallet/Common/NotificationManager.swift index 9461ada5..5e9a12b4 100644 --- a/MobileWallet/Common/NotificationManager.swift +++ b/MobileWallet/Common/NotificationManager.swift @@ -133,7 +133,7 @@ final class NotificationManager { func handleForegroundNotification(_ notification: UNNotification, completionHandler: (UNNotificationPresentationOptions) -> Void) { if notification.request.identifier == NotificationIdentifier.scheduledBackupFailure.rawValue { - completionHandler([.alert, .badge, .sound]) + completionHandler([.list, .banner, .badge, .sound]) } } diff --git a/MobileWallet/Common/Theme/ThemeCoordinator.swift b/MobileWallet/Common/Theme/ThemeCoordinator.swift index 59f29b33..1e80a84b 100644 --- a/MobileWallet/Common/Theme/ThemeCoordinator.swift +++ b/MobileWallet/Common/Theme/ThemeCoordinator.swift @@ -129,11 +129,11 @@ final class ThemeCoordinator { private func updateColorMode(colorScheme: ColorScheme) { switch colorScheme { case .system: - UIApplication.shared.windows.forEach { $0.overrideUserInterfaceStyle = .unspecified } + UIApplication.shared.firstWindow?.overrideUserInterfaceStyle = .unspecified case .light: - UIApplication.shared.windows.forEach { $0.overrideUserInterfaceStyle = .light } + UIApplication.shared.firstWindow?.overrideUserInterfaceStyle = .light case .dark, .tariPurple: - UIApplication.shared.windows.forEach { $0.overrideUserInterfaceStyle = .dark } + UIApplication.shared.firstWindow?.overrideUserInterfaceStyle = .dark } } diff --git a/MobileWallet/Common/WebBrowserPresenter.swift b/MobileWallet/Common/WebBrowserPresenter.swift index 9a4b88d4..24f76510 100644 --- a/MobileWallet/Common/WebBrowserPresenter.swift +++ b/MobileWallet/Common/WebBrowserPresenter.swift @@ -44,7 +44,7 @@ enum WebBrowserPresenter { static func open(url: URL) { DispatchQueue.main.async { - guard let topController = UIApplication.shared.topController() else { return } + guard let topController = UIApplication.shared.topController else { return } let webBrowserViewController = WebBrowserViewController() webBrowserViewController.url = url webBrowserViewController.modalPresentationStyle = UIDevice.current.userInterfaceIdiom == .pad ? .automatic :.popover diff --git a/MobileWallet/Libraries/TariLib/Core/FFI/Wallet.swift b/MobileWallet/Libraries/TariLib/Core/FFI/Wallet.swift index a9ccf392..f2d9130c 100644 --- a/MobileWallet/Libraries/TariLib/Core/FFI/Wallet.swift +++ b/MobileWallet/Libraries/TariLib/Core/FFI/Wallet.swift @@ -52,7 +52,7 @@ final class Wallet { // MARK: - Initialisers - init(commsConfig: CommsConfig, loggingFilePath: String, seedWords: SeedWords?, passphrase: String?, networkName: String) throws { + init(commsConfig: CommsConfig, loggingFilePath: String, seedWords: SeedWords?, passphrase: String?, networkName: String, logVerbosity: Int32) throws { let receivedTransactionCallback: @convention(c) (OpaquePointer?) -> Void = { pointer in WalletCallbacksManager.shared.post(name: .receivedTransaction, object: pointer) @@ -132,9 +132,12 @@ final class Wallet { let isRecoveryInProgressPointer = PointerHandler.pointer(for: &isRecoveryInProgress) let errorCodePointer = PointerHandler.pointer(for: &errorCode) + Logger.log(message: "Wallet created", domain: .general, level: .info) + let result = wallet_create( commsConfig.pointer, loggingFilePath, + logVerbosity, Self.numberOfRollingLogFiles, Self.logFileSize, passphrase, @@ -168,6 +171,7 @@ final class Wallet { // MARK: - Deinitialiser deinit { + Logger.log(message: "Wallet destoyed", domain: .general, level: .info) wallet_destroy(pointer) } } diff --git a/MobileWallet/Libraries/TariLib/Core/FFIWalletManager.swift b/MobileWallet/Libraries/TariLib/Core/FFIWalletManager.swift index b384e49a..37782bc7 100644 --- a/MobileWallet/Libraries/TariLib/Core/FFIWalletManager.swift +++ b/MobileWallet/Libraries/TariLib/Core/FFIWalletManager.swift @@ -39,6 +39,7 @@ */ import Combine +import UIKit final class FFIWalletManager { @@ -54,7 +55,9 @@ final class FFIWalletManager { // MARK: - Properties @Published private(set) var baseNodeConnectionStatus: BaseNodeConnectivityStatus = .offline - @Published private(set) var isWalletConnected: Bool = false + @Published private(set) var isWalletConnected: Bool = false { + didSet { Logger.log(message: "isWalletConnected: \(isWalletConnected)", domain: .general, level: .info) } + } private var wallet: Wallet? { didSet { isWalletConnected = wallet != nil } @@ -85,9 +88,11 @@ final class FFIWalletManager { // MARK: - Actions - func connectWallet(commsConfig: CommsConfig, logFilePath: String, seedWords: SeedWords?, passphrase: String?, networkName: String) throws { + func connectWallet(commsConfig: CommsConfig, logFilePath: String, seedWords: SeedWords?, passphrase: String?, networkName: String, logVerbosity: Int32) throws { do { - wallet = try Wallet(commsConfig: commsConfig, loggingFilePath: logFilePath, seedWords: seedWords, passphrase: passphrase, networkName: networkName) + let beforeWalletCreationDate = Date() + wallet = try Wallet(commsConfig: commsConfig, loggingFilePath: logFilePath, seedWords: seedWords, passphrase: passphrase, networkName: networkName, logVerbosity: logVerbosity) + Logger.log(message: "Wallet created after \(-beforeWalletCreationDate.timeIntervalSinceNow) seconds", domain: .general, level: .info) } catch { wallet = nil throw error @@ -95,8 +100,14 @@ final class FFIWalletManager { } func disconnectWallet() { + let taskID = UIApplication.shared.beginBackgroundTask() + Logger.log(message: "disconnectWallet Start: \(taskID)", domain: .general, level: .info) wallet = nil baseNodeConnectionStatus = .offline + DispatchQueue.main.asyncAfter(deadline: .now() + 20.0) { + Logger.log(message: "disconnectWallet: End: \(taskID)", domain: .general, level: .info) + UIApplication.shared.endBackgroundTask(taskID) + } } // MARK: - FFI Actions diff --git a/MobileWallet/Libraries/TariLib/Core/Tari.swift b/MobileWallet/Libraries/TariLib/Core/Tari.swift index c8b2b1c0..6c3d69e4 100644 --- a/MobileWallet/Libraries/TariLib/Core/Tari.swift +++ b/MobileWallet/Libraries/TariLib/Core/Tari.swift @@ -187,6 +187,7 @@ final class Tari: MainServiceable { func startWallet() async throws { await waitForTor() + guard await UIApplication.shared.applicationState != .background else { return } try startWallet(seedWords: nil) try connection.selectCurrentNode() } @@ -240,19 +241,16 @@ final class Tari: MainServiceable { let logFilePath = logFilePath Logger.log(message: "Log Path: \(logFilePath)", domain: .general, level: .info) - do { - try walletManager.connectWallet(commsConfig: commsConfig, logFilePath: logFilePath, seedWords: walletSeedWords, passphrase: passphrase, networkName: selectedNetwork.name) - resetServices() - } catch { - guard let error = error as? WalletError, error == WalletError.invalidPassphrase else { throw error } - try walletManager.connectWallet(commsConfig: commsConfig, logFilePath: logFilePath, seedWords: walletSeedWords, passphrase: nil, networkName: selectedNetwork.name) - } + let logVerbosity: Int32 = TariSettings.shared.environment == .debug ? 11 : 2 + + try walletManager.connectWallet(commsConfig: commsConfig, logFilePath: logFilePath, seedWords: walletSeedWords, passphrase: passphrase, networkName: selectedNetwork.name, logVerbosity: logVerbosity) + resetServices() } private func waitForTor() async { return await withCheckedContinuation { continuation in Tari.shared.connectionMonitor.$torConnection - .filter { $0 == .portsOpen || $0 == .connected } + .filter { $0 == .waitingForAuthorization || $0 == .portsOpen || $0 == .connected } .first() .sink { _ in continuation.resume() } .store(in: &cancellables) diff --git a/MobileWallet/Libraries/TariLib/Core/Tor/TorConnectionStatus.swift b/MobileWallet/Libraries/TariLib/Core/Tor/TorConnectionStatus.swift index 3863ed4d..01ed27b6 100644 --- a/MobileWallet/Libraries/TariLib/Core/Tor/TorConnectionStatus.swift +++ b/MobileWallet/Libraries/TariLib/Core/Tor/TorConnectionStatus.swift @@ -41,6 +41,7 @@ enum TorConnectionStatus { case disconnected case connecting + case waitingForAuthorization case portsOpen case connected case disconnecting diff --git a/MobileWallet/Libraries/TariLib/Core/TorManager.swift b/MobileWallet/Libraries/TariLib/Core/TorManager.swift index ebe7639d..42a72164 100644 --- a/MobileWallet/Libraries/TariLib/Core/TorManager.swift +++ b/MobileWallet/Libraries/TariLib/Core/TorManager.swift @@ -70,10 +70,20 @@ final class TorManager { private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid private var controller: TorController? - private var queuedAction: Action? + private var queuedAction: Action? { + didSet { + guard let queuedAction else { + Logger.log(message: "queuedAction: None", domain: .tor, level: .info) + return + } + Logger.log(message: "queuedAction: \(queuedAction)", domain: .tor, level: .info) + } + } private var retryAction: DispatchWorkItem? private var observers: [Any?] = [] - private var isConnecting = false + private var isActionLocked = false { + didSet { Logger.log(message: "isActionLocked: \(isActionLocked)", domain: .tor, level: .info) } + } private var cancellables = Set() private var isThreadRunning: Bool { TorThread.active != nil } @@ -108,11 +118,11 @@ final class TorManager { case 0: break case 100: - self?.isConnecting = false + self?.isActionLocked = false self?.cancelRetry() self?.runQueuedAction() default: - self?.isConnecting = true + self?.isActionLocked = true } } .store(in: &cancellables) @@ -135,7 +145,7 @@ final class TorManager { Logger.log(message: "Start", domain: .tor, level: .info) - guard !isConnecting else { + guard !isActionLocked else { queuedAction = .connect return } @@ -154,29 +164,34 @@ final class TorManager { Logger.log(message: "Stop", domain: .tor, level: .info) - guard !isConnecting else { + guard !isActionLocked else { queuedAction = .disconnect return } + endBackgroundTask() + startBackgroundTask() + Task { do { - startBackgroundTask() try await disconnect() endBackgroundTask() } catch { handle(error: error) + endBackgroundTask() } } } func disconnect() async throws { Logger.log(message: "Disconnect: Start", domain: .tor, level: .info) + isActionLocked = true stopController() connectionStatus = .disconnecting bootstrapProgress = 0 try await waitingForThread() connectionStatus = .disconnected + isActionLocked = false Logger.log(message: "Disconnect: Done", domain: .tor, level: .info) } @@ -190,11 +205,13 @@ final class TorManager { private func connect() async throws { Logger.log(message: "Connect: Start", domain: .tor, level: .info) connectionStatus = .connecting + isActionLocked = true try createDirectories() try createThread() startIObfs4Proxy() createController() try await startController() + connectionStatus = .waitingForAuthorization guard try await auth() else { throw TorError.authenticationFailed } connectionStatus = .portsOpen try observeConnection() @@ -233,7 +250,15 @@ final class TorManager { // MARK: - Proxy private func startIObfs4Proxy() { - IPtProxyStartObfs4Proxy(nil, false, false, nil) + + guard let iptStateLocation = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("pt_state").path else { + Logger.log(message: "No IPtProxy state location", domain: .tor, level: .error) + return + } + + IPtProxy.setStateLocation(iptStateLocation) + IPtProxyStartLyrebird(nil, false, false, nil) + Logger.log(message: "IPtProxy state location set", domain: .tor, level: .info) } // MARK: - Controller @@ -245,18 +270,20 @@ final class TorManager { private func startController(retryCount: Int = 0) async throws { + Logger.log(message: "Controller Connecting", domain: .tor, level: .info) + let maxRetryCount = 5 do { try existingController.connect() - isConnecting = true + isActionLocked = true Logger.log(message: "Controller Connected", domain: .tor, level: .info) } catch { Logger.log(message: "Waiting for connection: \(retryCount)", domain: .tor, level: .info) let retryCount = retryCount + 1 guard retryCount < maxRetryCount else { guard let posixError = error.posixError else { throw TorError.connectionFailed(error: error) } - isConnecting = false + isActionLocked = false throw TorError.connectionFailed(error: posixError) } @@ -385,9 +412,11 @@ final class TorManager { backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in self?.endBackgroundTask() } + Logger.log(message: "Background Task - Start: \(backgroundTaskID)", domain: .tor, level: .info) } private func endBackgroundTask() { + Logger.log(message: "Background Task - End: \(backgroundTaskID)", domain: .tor, level: .info) guard backgroundTaskID != .invalid else { return } Logger.log(message: "End Background Task", domain: .tor, level: .info) UIApplication.shared.endBackgroundTask(backgroundTaskID) diff --git a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Connection Monitor/ConnectionMonitor.swift b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Connection Monitor/ConnectionMonitor.swift index 662ca15e..37dec4f3 100644 --- a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Connection Monitor/ConnectionMonitor.swift +++ b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Connection Monitor/ConnectionMonitor.swift @@ -114,7 +114,7 @@ private extension TorConnectionStatus { switch self { case .disconnected, .disconnecting: return localized("connection_status.popUp.label.tor_status.disconnected") - case .connecting, .portsOpen: + case .connecting, .waitingForAuthorization, .portsOpen: return localized("connection_status.popUp.label.tor_status.connecting") case .connected: return localized("connection_status.popUp.label.tor_status.connected") @@ -125,7 +125,7 @@ private extension TorConnectionStatus { switch self { case .disconnected, .disconnecting: return .error - case .connecting, .portsOpen: + case .connecting, .waitingForAuthorization, .portsOpen: return .warning case .connected: return .ok diff --git a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Loggers/ConsoleLogger.swift b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Loggers/ConsoleLogger.swift index 03e3e242..679f9aeb 100644 --- a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Loggers/ConsoleLogger.swift +++ b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Loggers/ConsoleLogger.swift @@ -46,6 +46,6 @@ extension ConsoleLogger: Logable { func log(message: String, domain: Logger.Domain, logLevel: Logger.Level) { let formattedMessage = LogFormatter.formattedMessage(message: message, domain: domain, logLevel: logLevel, showPrefix: true) - os_log("%@", formattedMessage) + os_log("%@ %@", Date().description, formattedMessage) } } diff --git a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/NetworkManager.swift b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/NetworkManager.swift index 50b64067..27d8ab84 100644 --- a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/NetworkManager.swift +++ b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/NetworkManager.swift @@ -48,7 +48,7 @@ final class NetworkManager { @Published var selectedNetwork: TariNetwork - private static var defaultNetwork: TariNetwork { .stagenet } + private static var defaultNetwork: TariNetwork { .nextnet } private var cancelables = Set() // MARK: - Initializers diff --git a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/TariNetwork.swift b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/TariNetwork.swift index c39b140c..a8da41f8 100644 --- a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/TariNetwork.swift +++ b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Network/TariNetwork.swift @@ -89,28 +89,17 @@ extension TariNetwork { extension TariNetwork { - static var all: [TariNetwork] { [stagenet].compactMap { $0 } } + static var all: [TariNetwork] { [nextnet].compactMap { $0 } } - static var stagenet: Self { + static var nextnet: Self { makeNetwork( - name: "stagenet", - presentedName: "StageNet (\(localized("common.recommended")))", + name: "nextnet", + presentedName: "NextNet (\(localized("common.recommended")))", isMainNet: false, rawBaseNodes: [ - "StageNet 01": "1a294e0312ba507899a3f3eadc390d492ab620ce29cad94ba496b4d4fd78aa16::/ip4/34.252.174.111/tcp/18189", - "StageNet 02": "1a294e0312ba507899a3f3eadc390d492ab620ce29cad94ba496b4d4fd78aa16::/onion3/mfqsxcw4fsq7djzbbgcgfvx3tl6zcciqxzdrl7w5axozbs654zojijyd:18141", - "StageNet 03": "34cfce7c91290a7eb82127a76d7608d18df3992ec66fbcf9d6f97ca85fe10c17::/onion3/2tmbjqsvnaelbxv66tm3wze3oudwzdlfifwqptofgcmuvgvhdw563oid:18141", - "StageNet 04": "38feed1438270fc8c9c7211d3a5faf0aeab1b65d5bce2083476be6483b35b217::/onion3/2cufeex4t2rr3466cw5ijhexsapyg2hwkoc6mlwfiusiyg5dr7wkxdad:18141", - "StageNet 05": "3cfd696d646c0b2b2ab19de2f76727553d34e4bf1c5be41a1b9079430f0ea331::/ip4/54.77.66.39/tcp/18189", - "StageNet 06": "3cfd696d646c0b2b2ab19de2f76727553d34e4bf1c5be41a1b9079430f0ea331::/onion3/b6gtdaogqgs26jy32nb2u3elpalfzcnaa5krkpczeltpod5i54anh2id:18141", - "StageNet 07": "502f6306c80293e0455b1dd9b05aefaa32002630e7d1f628f09a652479f26727::/onion3/t76s5ngz3j6vxt2isjlp5utwrwjw2wl56ffknar62q24y33ucuzswhid:18141", - "StageNet 08": "6222a5627a0d53cc2fcc8d829ea79b7e07af6e305133bb71e8e72475f34cea29::/onion3/fc5apmwrtt3nmuw7srp4khcnpedzhfwynxmf4nwceqrn5xwutvtkg6ad:18141", - "StageNet 09": "70a5a84c75a7950cc805c17c6cf99160e8df6786df82cb93a044df1456ff566d::/onion3/whwgiuqkc23jtx266nbbjilzz6lrc7enljtef6tjlgvxijunkwmwh6yd:18141", - "StageNet 10": "b040d2e4cabad05fa0bb671bcfc822bd26fb526a3b116bfe74d0d516c4589b41::/ip4/63.35.51.217/tcp/18189", - "StageNet 11": "b040d2e4cabad05fa0bb671bcfc822bd26fb526a3b116bfe74d0d516c4589b41::/onion3/6idckzqo5hejteuitzbzthstf22ux5schi5f5wjia5w3pvbtt7hrb3ad:18141", - "StageNet 12": "c81a8e314b7c06fd136d7e836b26fe821de36ebb42a3c47f671190eb9fc5695d::/ip4/54.73.25.246/tcp/18189", - "StageNet 13": "c81a8e314b7c06fd136d7e836b26fe821de36ebb42a3c47f671190eb9fc5695d::/onion3/yhvolqnqbznwc2fet7laxmusqcoeaie3bfc3vnmq26udz67ayscqgyqd:18141", - "StageNet 14": "d80b5ccaea9d85f868ba55c243f8fc5c7c8a31ead0c28f072e42ac8ae862dd00::/onion3/dskj4ecpegae2ypzq7icpmhcu7ylbbo7siqqdul6537zi3ykx3hzqsqd:18141" + "NextNet 1": "0cff11dff44458bfea3e39444d440e54260746ff2a5ce6a6c3f7355decff2167::/ip4/54.195.217.107/tcp/18189", + "NextNet 2": "0cff11dff44458bfea3e39444d440e54260746ff2a5ce6a6c3f7355decff2167::/onion3/h6oj2cusgtaxo63zbfw2wjir4mltkqzz4jquoak2i5mvgyszaieowwad:18141", + "NextNet 3": "4c236de788e803ef9615f72a4d973cf3f8a9b83c9d2fb176cbaf65c1b0442572::/onion3/3jtk3e2ud3zqtbrq36sw6ata6u5epkjmqgr5tfuemcfpyhisrzkgbtyd:18141" ] ) } diff --git a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Settings/TariSettings.swift b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Settings/TariSettings.swift index 4b213879..092e459e 100644 --- a/MobileWallet/Libraries/TariLib/Wrappers/Utils/Settings/TariSettings.swift +++ b/MobileWallet/Libraries/TariLib/Wrappers/Utils/Settings/TariSettings.swift @@ -38,7 +38,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import Foundation import SwiftKeychainWrapper enum AppEnvironment { @@ -132,55 +131,25 @@ struct TariSettings { do { let data = try Data(contentsOf: URL(fileURLWithPath: envPath), options: .mappedIfSafe) - let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) - - if let jsonResult = jsonResult as? [String: AnyObject] { - if let pushServerApiKey = jsonResult["pushServerApiKey"] as? String, !pushServerApiKey.isEmpty { - self.pushServerApiKey = pushServerApiKey - } else { - Logger.log(message: "pushServerApiKey not set in env.json. Sending push notifications will be disabled.", domain: .general, level: .warning) - } - if let sentryPublicDSN = jsonResult["sentryPublicDSN"] as? String, !sentryPublicDSN.isEmpty { - self.sentryPublicDSN = sentryPublicDSN - } else { - Logger.log(message: "sentryPublicDSN not set in env.json. Crash reporting will not work.", domain: .general, level: .warning) - } - - if let giphyApiKey = jsonResult["giphyApiKey"] as? String, !giphyApiKey.isEmpty { - self.giphyApiKey = giphyApiKey - } else { - Logger.log(message: "giphyApiKey not set in env.json. Appending gifs to transaction notes will not work.", domain: .general, level: .warning) - } - - if let appleTeamID = jsonResult["appleTeamID"] as? String, !appleTeamID.isEmpty { - TariSettings.appleTeamID = appleTeamID - } else { - fatalError("appleTeamID not set in env.json. Shared keychain will not work.") - } - if let yatReturnLink = jsonResult["yatReturnLink"] as? String, !yatReturnLink.isEmpty { - self.yatReturnLink = yatReturnLink - } else { - fatalError("yatReturnLink not set in env.json. Yat related funtionalities will not work.") - } - if let yatOrganizationName = jsonResult["yatOrganizationName"] as? String, !yatOrganizationName.isEmpty { - self.yatOrganizationName = yatOrganizationName - } else { - fatalError("yatOrganizationName not set in env.json. Yat related funtionalities will not work.") - } - if let yatOrganizationKey = jsonResult["yatOrganizationKey"] as? String, !yatOrganizationKey.isEmpty { - self.yatOrganizationKey = yatOrganizationKey - } else { - fatalError("yatOrganizationKey not set in env.json. Yat related funtionalities will not work.") - } - if let yatWebServiceURL = jsonResult["yatWebServiceURL"] as? String, !yatWebServiceURL.isEmpty, let url = URL(string: yatWebServiceURL) { - self.yatWebServiceURL = url - } - if let yatApiURL = jsonResult["yatApiURL"] as? String, !yatApiURL.isEmpty, let url = URL(string: yatApiURL) { - self.yatApiURL = url - } - - dropboxApiKey = jsonResult["dropboxApiKey"] as? String + guard let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String: AnyObject] else { return } + + pushServerApiKey = jsonResult["pushServerApiKey"] as? String + sentryPublicDSN = jsonResult["sentryPublicDSN"] as? String + giphyApiKey = jsonResult["giphyApiKey"] as? String + TariSettings.appleTeamID = jsonResult["appleTeamID"] as? String + yatReturnLink = jsonResult["yatReturnLink"] as? String + yatOrganizationName = jsonResult["yatOrganizationName"] as? String + yatOrganizationKey = jsonResult["yatOrganizationKey"] as? String + + if let yatWebServiceRawURL = jsonResult["yatWebServiceURL"] as? String, !yatWebServiceRawURL.isEmpty, let url = URL(string: yatWebServiceRawURL) { + yatWebServiceURL = url } + + if let yatApiRawURL = jsonResult["yatApiURL"] as? String, !yatApiRawURL.isEmpty, let url = URL(string: yatApiRawURL) { + self.yatApiURL = url + } + + dropboxApiKey = jsonResult["dropboxApiKey"] as? String } catch { Logger.log(message: "Could not load env vars: \(error)", domain: .general, level: .error) } diff --git a/MobileWallet/SceneDelegate.swift b/MobileWallet/SceneDelegate.swift index ee9755c4..14998ba3 100644 --- a/MobileWallet/SceneDelegate.swift +++ b/MobileWallet/SceneDelegate.swift @@ -97,10 +97,15 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate { } func sceneWillEnterForeground(_ scene: UIScene) { + Logger.log(message: "App State: Foreground", domain: .general, level: .info) UIApplication.shared.applicationIconBadgeNumber = 0 LogFilesManager.cleanupLogs() } + func sceneDidEnterBackground(_ scene: UIScene) { + Logger.log(message: "App State: Background", domain: .general, level: .info) + } + func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { ShortcutsManager.handle(shortcut: shortcutItem) } diff --git a/MobileWallet/Screens/Contact Book/List/ContactBookModel.swift b/MobileWallet/Screens/Contact Book/List/ContactBookModel.swift index ddc9c294..85374d02 100644 --- a/MobileWallet/Screens/Contact Book/List/ContactBookModel.swift +++ b/MobileWallet/Screens/Contact Book/List/ContactBookModel.swift @@ -40,7 +40,6 @@ import UIKit import Combine -import YatLib final class ContactBookModel { @@ -88,10 +87,6 @@ final class ContactBookModel { case externalContacts } - // MARK: - Constants - - private let maxYatIDLenght: Int = 5 - // MARK: - View Model @Published var searchText: String = "" @@ -109,7 +104,6 @@ final class ContactBookModel { // MARK: - Properties - @Published private var enteredAddress: TariAddress? @Published private var contactModels: [[ContactsManager.Model]] = [] private let contactsManager = ContactsManager() @@ -146,10 +140,6 @@ final class ContactBookModel { .assignPublisher(to: \.favoriteContactsList, on: self) .store(in: &cancellables) - $searchText - .sink { [weak self] in self?.generateAddress(text: $0) } - .store(in: &cancellables) - $contentMode .filter { $0 == .normal } .sink { [weak self] _ in self?.selectedIDs = [] } @@ -350,25 +340,6 @@ final class ContactBookModel { return try DeepLinkFormatter.deeplink(model: model) } - private func generateAddress(text: String) { - guard let address = makeAddress(text: text), verify(address: address) else { - enteredAddress = nil - return - } - enteredAddress = address - } - - private func makeAddress(text: String) -> TariAddress? { - do { return try TariAddress(emojiID: text) } catch {} - do { return try TariAddress(hex: text) } catch {} - return nil - } - - private func verify(address: TariAddress) -> Bool { - guard let hex = try? address.byteVector.hex, let userHex = try? Tari.shared.walletAddress.byteVector.hex, hex != userHex else { return false } - return true - } - private func filter(contactsSections: [[ContactsManager.Model]], searchText: String) -> [[ContactsManager.Model]] { guard !searchText.isEmpty else { return contactsSections } diff --git a/MobileWallet/Screens/Home/Home/HomeModel.swift b/MobileWallet/Screens/Home/Home/HomeModel.swift index 0a87713c..628b9028 100644 --- a/MobileWallet/Screens/Home/Home/HomeModel.swift +++ b/MobileWallet/Screens/Home/Home/HomeModel.swift @@ -134,6 +134,7 @@ final class HomeModel { (.connected, .disconnecting, _, _): connectionStatusIcon = .icons.network.off case (.connected, .connecting, _, _), + (.connected, .waitingForAuthorization, _, _), (.connected, .portsOpen, _, _), (.connected, .connected, .offline, _), (.connected, .connected, .connecting, _), diff --git a/MobileWallet/Screens/Home/Home/Views/HomeViewTransactionCell.swift b/MobileWallet/Screens/Home/Home/Views/HomeViewTransactionCell.swift index 34dcf8e2..d988ea96 100644 --- a/MobileWallet/Screens/Home/Home/Views/HomeViewTransactionCell.swift +++ b/MobileWallet/Screens/Home/Home/Views/HomeViewTransactionCell.swift @@ -51,7 +51,7 @@ final class HomeViewTransactionCell: UITableViewCell { static func == (lhs: HomeViewTransactionCell.ViewModel, rhs: HomeViewTransactionCell.ViewModel) -> Bool { lhs.id == rhs.id - && lhs.titleComponents.map { $0.text } == lhs.titleComponents.map { $0.text } + && lhs.titleComponents.map { $0.text } == rhs.titleComponents.map { $0.text } && lhs.timestamp == rhs.timestamp && lhs.amount == rhs.amount } diff --git a/MobileWallet/Screens/Home/Transaction Details/TransactionDetailsViewController.swift b/MobileWallet/Screens/Home/Transaction Details/TransactionDetailsViewController.swift index eae885fb..1c84e765 100644 --- a/MobileWallet/Screens/Home/Transaction Details/TransactionDetailsViewController.swift +++ b/MobileWallet/Screens/Home/Transaction Details/TransactionDetailsViewController.swift @@ -69,13 +69,14 @@ final class TransactionDetailsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - setupCallbacks() + setupModelCallbacks() + setupViewCallbacks() hideKeyboardWhenTappedAroundOrSwipedDown() } // MARK: - Setups - private func setupCallbacks() { + private func setupModelCallbacks() { model.$title .receive(on: DispatchQueue.main) @@ -180,6 +181,9 @@ final class TransactionDetailsViewController: UIViewController { model.userAliasUpdateSuccessCallback = { UINotificationFeedbackGenerator().notificationOccurred(.success) } + } + + private func setupViewCallbacks() { mainView.valueView.feeButton.onTap = { [weak self] in self?.showFeeInfo() diff --git a/MobileWallet/Screens/Home/UTXOs Wallet/Other/UTXOsWalletTileListLayout.swift b/MobileWallet/Screens/Home/UTXOs Wallet/Other/UTXOsWalletTileListLayout.swift index 36ef0211..536c3cd3 100644 --- a/MobileWallet/Screens/Home/UTXOs Wallet/Other/UTXOsWalletTileListLayout.swift +++ b/MobileWallet/Screens/Home/UTXOs Wallet/Other/UTXOsWalletTileListLayout.swift @@ -81,7 +81,7 @@ final class UTXOsWalletTileListLayout: UICollectionViewLayout { let data = (0..= offsetIndex { + if let offsetIndex, data.offset >= offsetIndex { topOffset = self.topOffset * -1.0 } else { topOffset = 0.0 diff --git a/MobileWallet/UIElements/NavigationBar.swift b/MobileWallet/UIElements/NavigationBar.swift index c689a03b..58676734 100644 --- a/MobileWallet/UIElements/NavigationBar.swift +++ b/MobileWallet/UIElements/NavigationBar.swift @@ -267,7 +267,7 @@ final class NavigationBar: DynamicThemeView { return } - let topController = UIApplication.shared.topController() + let topController = UIApplication.shared.topController guard let navigationController = topController as? UINavigationController else { topController?.dismiss(animated: true) diff --git a/MobileWallet/UIElements/PendingView/PendingView.swift b/MobileWallet/UIElements/PendingView/PendingView.swift index c5b7f2d7..4a1d5432 100644 --- a/MobileWallet/UIElements/PendingView/PendingView.swift +++ b/MobileWallet/UIElements/PendingView/PendingView.swift @@ -81,9 +81,9 @@ final class PendingView: DynamicThemeView { private func setupPendingView() { let view: UIView - if let keyWindow = UIApplication.shared.keyWindow { - view = keyWindow - } else if let topController = UIApplication.shared.topController() { + if let firstWindow = UIApplication.shared.firstWindow { + view = firstWindow + } else if let topController = UIApplication.shared.topController { view = topController.view } else { return } diff --git a/MobileWallet/UIElements/TabBar/CustomTabBar.swift b/MobileWallet/UIElements/TabBar/CustomTabBar.swift index 8bf40b11..2c518beb 100644 --- a/MobileWallet/UIElements/TabBar/CustomTabBar.swift +++ b/MobileWallet/UIElements/TabBar/CustomTabBar.swift @@ -63,7 +63,7 @@ final class CustomTabBar: DynamicThemeTabBar { override func sizeThatFits(_ size: CGSize) -> CGSize { super.sizeThatFits(size) var sizeThatFits = super.sizeThatFits(size) - let bottomInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0 + let bottomInset = UIApplication.shared.firstWindow?.safeAreaInsets.bottom ?? 0 sizeThatFits.height = 59 + bottomInset return sizeThatFits } @@ -77,9 +77,6 @@ final class CustomTabBar: DynamicThemeTabBar { appearance.stackedLayoutAppearance.selected.iconColor = theme.icons.active standardAppearance = appearance - - if #available(iOS 15.0, *) { - scrollEdgeAppearance = appearance - } + scrollEdgeAppearance = appearance } } diff --git a/Podfile b/Podfile index 0b2278ab..c90447bc 100644 --- a/Podfile +++ b/Podfile @@ -1,18 +1,17 @@ -platform :ios, '13.0' +platform :ios, '15.0' use_frameworks! inhibit_all_warnings! target 'MobileWallet' do - pod 'Tor', '408.7.2' + pod 'Tor', '408.10.1' pod 'lottie-ios' pod 'SwiftEntryKit', '2.0.0' pod 'ReachabilitySwift' pod 'Sentry', '8.14.2' pod 'SwiftKeychainWrapper', '3.4.0' pod 'Giphy', '2.1.22' - pod 'IPtProxy', '1.10.1' - pod 'OpenSSL-Universal' + pod 'IPtProxy', '3.3.0' pod 'Zip', '2.1.2' pod 'SwiftyDropbox', '8.2.1' pod 'YatLib', '0.3.3' diff --git a/Podfile.lock b/Podfile.lock index 46b5df9d..634f9c89 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,7 +2,7 @@ PODS: - Alamofire (5.4.4) - Giphy (2.1.22): - libwebp - - IPtProxy (1.10.1) + - IPtProxy (3.3.0) - libwebp (1.2.3): - libwebp/demux (= 1.2.3) - libwebp/mux (= 1.2.3) @@ -13,7 +13,6 @@ PODS: - libwebp/demux - libwebp/webp (1.2.3) - lottie-ios (3.2.3) - - OpenSSL-Universal (1.1.1900) - ReachabilitySwift (5.0.0) - Sentry (8.14.2): - Sentry/Core (= 8.14.2) @@ -26,10 +25,10 @@ PODS: - SwiftyDropbox (8.2.1): - Alamofire (~> 5.4.3) - TariCommon (0.2.0) - - Tor (408.7.2): - - Tor/CTor (= 408.7.2) - - Tor/Core (408.7.2) - - Tor/CTor (408.7.2): + - Tor (408.10.1): + - Tor/CTor (= 408.10.1) + - Tor/Core (408.10.1) + - Tor/CTor (408.10.1): - Tor/Core - YatLib (0.3.3): - TariCommon (~> 0.2.0) @@ -37,16 +36,15 @@ PODS: DEPENDENCIES: - Giphy (= 2.1.22) - - IPtProxy (= 1.10.1) + - IPtProxy (= 3.3.0) - lottie-ios - - OpenSSL-Universal - ReachabilitySwift - Sentry (= 8.14.2) - SwiftEntryKit (= 2.0.0) - SwiftKeychainWrapper (= 3.4.0) - SwiftyDropbox (= 8.2.1) - TariCommon (= 0.2.0) - - Tor (= 408.7.2) + - Tor (= 408.10.1) - YatLib (= 0.3.3) - Zip (= 2.1.2) @@ -57,7 +55,6 @@ SPEC REPOS: - IPtProxy - libwebp - lottie-ios - - OpenSSL-Universal - ReachabilitySwift - Sentry - SentryPrivate @@ -72,10 +69,9 @@ SPEC REPOS: SPEC CHECKSUMS: Alamofire: f3b09a368f1582ab751b3fff5460276e0d2cf5c9 Giphy: 6757d929878ef45f70ed62a02a2c9a03994e7b6c - IPtProxy: 17a32bf135d3824e8cbc3fba0fa5bc404490ac84 + IPtProxy: 2136e276560ffd3a1d017683259f52552fc7c2e5 libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c lottie-ios: c058aeafa76daa4cf64d773554bccc8385d0150e - OpenSSL-Universal: 84efb8a29841f2764ac5403e0c4119a28b713346 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 Sentry: e0ea366f95ebb68f26d6030d8c22d6b2e6d23dd0 SentryPrivate: 949a21fa59872427edc73b524c3ec8456761d97f @@ -83,10 +79,10 @@ SPEC CHECKSUMS: SwiftKeychainWrapper: 6fc49fbf7d4a6b0772917acb0e53a1639f6078d6 SwiftyDropbox: f6c55aae36c4ea944fe6b35f807c19897f78b09b TariCommon: 2c8bb97359f59d6b302d2e96c191ff95931da8ac - Tor: 7e7ab1fa8b5140b0b5038cff45b9c9472ad73951 + Tor: 4aa4aee031f892efa43d1afb01c90565990c6312 YatLib: f56aa60679b20e989a41b6bc92c0081c013b523a Zip: b3fef584b147b6e582b2256a9815c897d60ddc67 -PODFILE CHECKSUM: 78481b66b4ba45f09ba6fe28f4de98e3ab98cccf +PODFILE CHECKSUM: 43b8e66d361bf301a04d308d4daf6088dedeab0f -COCOAPODS: 1.13.0 +COCOAPODS: 1.14.3 diff --git a/README.md b/README.md index 04ef5837..20016bb7 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@

- +

-[![Build Status](https://travis-ci.com/tari-project/wallet-ios.svg?branch=development)](https://travis-ci.com/tari-project/wallet-ios) +![Build Status](https://app.bitrise.io/app/b525265e43df3333/status.svg?token=4FoLfg9CpiFswB2syqYexA&branch=master) ## What is Aurora? -Aurora is a reference-design mobile wallet app for the forthcoming [Tari](https://www.tari.com/) digital currency. The goal is for creators and developers to be able to use the open-source Aurora libraries and codebase as a starting point for developing their own Tari wallets and applications. Aurora also sets the bar for applications that use the Tari protocol. In its production-ready state, it will be a beautiful, easy to use Tari wallet focused on Tari as a default-private digital currency. +Aurora is a reference-design mobile wallet app for the forthcoming [Tari](https://www.tari.com/) digital currency. The goal is for creators and developers to be able to use the open-source Aurora libraries and codebase as a starting point for developing their own Tari wallets and applications. Aurora also sets the bar for applications that use the Tari protocol. In its production-ready state, it will be a beautiful, easy-to-use Tari wallet focused on Tari as a default-private digital currency. Want to contribute to Aurora? Get started here in this repository. @@ -28,37 +28,37 @@ This will also create a default `env.json` file for sensitive vars. Adjust these ### Dependencies -Third party frameworks and Library are managed using a pre-compiled [Tari](https://github.com/tari-project/tari) binary from https://www.tari.com/downloads/ as well as packages from Cocoapods and Carthage. +Third-party frameworks and libraries are managed using a pre-compiled [Tari](https://github.com/tari-project/tari) binary from https://www.tari.com/downloads/ as well as packages from Cocoapods. ### Pods used ```ruby -- pod 'SwiftLint' +- pod 'Tor' - pod 'FloatingPanel' - pod 'lottie-ios' -- pod 'SwiftEntryKit', '1.2.3' +- pod 'SwiftEntryKit' - pod 'ReachabilitySwift' +- pod 'Sentry' +- pod 'SwiftKeychainWrapper' +- pod 'Giphy' +- pod 'IPtProxy' +- pod 'Zip' +- pod 'SwiftyDropbox' +- pod 'YatLib' +- pod 'TariCommon' ``` -### Carthage packages used used - - - binary "https://icepa.github.io/Tor.framework/Tor.json" == 400.6.3 - - ### Version Management -* Build Number willl increased for each iTunes submission and are increased automatically with fastlane -* App version will only increase on app submiting to App Store - -### Folder Structure and Architecture - -Coming soon. - -### Git - -- `development` will be the semi-stable branch with `tag` on each stable merge. This is the branch from where IPA should be published to iTunes Test Flight. -- `master` will have code that are fully stable with `release` on each merge. App store publishing should be done from this branch only. +* Build Number will be increased with every merge to the `develop` and `release` branches. The action is handled by the external CI. +* The app version will be increased when the App will be submitted to AppStore. + * The major revision will be increased only after significant and breaking changes. + * The minor revision will be increased when new features or improvements are introduced. + * The patch revision will be increased when the new version contains only hotfixes -### UI testing +### Git Branches -Right now we don't have UI tests using asserts but running `generate_screenshots.sh` will automatically generate a report containing screenshots of each view on multiple simulators. This report can be used to visually inspect each PR for any possible UI or layout bugs that might have been introduced. \ No newline at end of file +- `develop/` are development branches. They contain new features, improvements, and bug fixes that will be published with the specified version. At the end of the development cycle `develop/` will become a root for the `release/` branch. +- `feautre/` are working branches. They contain a single feature, improvement of other code alternation. When the new feature is ready it needs to pass the core review before it will be merged with `develop/`. +- `release/` the release branch is created at the end of the development cycle from the `develop` branch. All builds made from this branch become potential release candidates. After the official release, this branch will be merged with the `master` branch. +- `master` this branch is a collection of releases snapshots. Every merge with this branch should be tagged with the App and libwallet versions (format: `-libwallet-`). diff --git a/dependencies.env b/dependencies.env index c7a6981b..1e52e6ce 100644 --- a/dependencies.env +++ b/dependencies.env @@ -1 +1 @@ -FFI_VERSION="0.52.0" \ No newline at end of file +FFI_VERSION="1.0.0-rc.3" \ No newline at end of file diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 85186363..11fca467 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,79 +1,13 @@ -# This file contains the fastlane.tools configuration -# You can find the documentation at https://docs.fastlane.tools -# -# For a list of all available actions, check out -# -# https://docs.fastlane.tools/actions -# -# For a list of all available plugins, check out -# -# https://docs.fastlane.tools/plugins/available-plugins -# - -# Uncomment the line if you want fastlane to automatically update itself -update_fastlane - default_platform(:ios) platform :ios do - desc "Run tests on simulator" - lane :tests do - run_tests() - end - desc "Just push a new beta build to App Store Connect" - lane :push do - increment_build_number(xcodeproj: "MobileWallet.xcodeproj") - build_app(workspace: "MobileWallet.xcworkspace", scheme: "MobileWallet") - upload_to_testflight - end - desc "Build number bump" - lane :bump do - increment_build_number(xcodeproj: "MobileWallet.xcodeproj") - end - lane :qa do - group_name = 'QA - Internal' - - sh "sh sync_libs.sh" - - run_tests() - increment_build_number(xcodeproj: "MobileWallet.xcodeproj") - build_app(workspace: "MobileWallet.xcworkspace", scheme: "MobileWallet") - upload_to_testflight - - puts ["Uploading new build and adding to group: ", group_name] - - fastlane_require 'spaceship' - - app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) - qa_group_name = CredentialsManager::AppfileConfig.try_fetch_value(:qa_group_name) - - Spaceship::Tunes.login($apple_id) - - app = Spaceship::ConnectAPI::App.find(app_identifier) - groups = app.get_beta_groups(filter: {name: group_name}) - group = groups.first - - builds = Spaceship::ConnectAPI::Build.all( - app_id: app.id - ) - - latest_build = builds.first - - puts ["Latest build", latest_build.version] - - Spaceship::ConnectAPI.add_beta_groups_to_build(build_id: latest_build.id, beta_group_ids: [group.id]) - - upload_to_browserstack_app_live( - browserstack_username: ENV["BROWSERSTACK_USERNAME"], - browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"] - ) - end - desc "Only build and upload the IPA to browserstack" - lane :browserstack do - build_app(workspace: "MobileWallet.xcworkspace", scheme: "MobileWallet") - upload_to_browserstack_app_live( - browserstack_username: ENV["BROWSERSTACK_USERNAME"], - browserstack_access_key: ENV["BROWSERSTACK_ACCESS_KEY"] + lane :dsym do |options| + sentry_upload_dsym( + auth_token: options[:auth_token], + org_slug: options[:org_slug], + project_slug: options[:project_slug], + dsym_path: options[:dsym_path] ) -end + skip_docs() + end end diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile index 6bf5b47f..a152560f 100644 --- a/fastlane/Pluginfile +++ b/fastlane/Pluginfile @@ -2,4 +2,4 @@ # # Ensure this file is checked in to source control! -gem 'fastlane-plugin-browserstack' +gem 'fastlane-plugin-sentry' diff --git a/fastlane/README.md b/fastlane/README.md deleted file mode 100644 index 65eca3fd..00000000 --- a/fastlane/README.md +++ /dev/null @@ -1,49 +0,0 @@ -fastlane documentation -================ -# Installation - -Make sure you have the latest version of the Xcode command line tools installed: - -``` -xcode-select --install -``` - -Install _fastlane_ using -``` -[sudo] gem install fastlane -NV -``` -or alternatively using `brew cask install fastlane` - -# Available Actions -## iOS -### ios tests -``` -fastlane ios tests -``` -Run tests on simulator -### ios push -``` -fastlane ios push -``` -Just push a new beta build to App Store Connect -### ios bump -``` -fastlane ios bump -``` -Build number bump -### ios qa -``` -fastlane ios qa -``` - -### ios browserstack -``` -fastlane ios browserstack -``` -Only build and upload the IPA to browserstack - ----- - -This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. -More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). -The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). diff --git a/fastlane/Snapfile b/fastlane/Snapfile deleted file mode 100644 index 18696b9b..00000000 --- a/fastlane/Snapfile +++ /dev/null @@ -1,33 +0,0 @@ -# Uncomment the lines below you want to change by removing the # in the beginning - -# A list of devices you want to take the screenshots from - devices([ - "iPhone 8", - "iPhone 8 Plus", - "iPhone 11", - "iPhone 11 Pro", - "iPhone 11 Pro Max" - ]) - -languages([ - "en-US", -]) - -# The name of the scheme which contains the UI Tests -# scheme("MobileWalletUISnapshots") - -# Where should the resulting screenshots be stored? -# output_directory("./screenshots") - -# remove the '#' to clear all previously generated screenshots before creating new ones -clear_previous_screenshots(true) -reinstall_app(true) -erase_simulator(true) -skip_open_summary(true) -disable_slide_to_type(true) - -# Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments -# launch_arguments(["-favColor red"]) - -# For more information about all available options run -# fastlane action snapshot diff --git a/fastlane/sync_libs.sh b/fastlane/sync_libs.sh deleted file mode 100644 index f9171a10..00000000 --- a/fastlane/sync_libs.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -cd ../ -sh update_dependencies.sh \ No newline at end of file diff --git a/readme-files/tari-logo.svg b/readme-files/tari-logo.svg new file mode 100644 index 00000000..61391f5e --- /dev/null +++ b/readme-files/tari-logo.svg @@ -0,0 +1,30 @@ + + + + Tari Logo + Created with Sketch. + + + + + + + + + + + \ No newline at end of file