Files
Andrey Scherbovich f6aa3bd807 refs/heads/wc-prototype2-merging Merge branch 'main' of github.com:gnosis/safe-ios into wc-prototype-2
# Conflicts:
#	Multisig.xcodeproj/project.pbxproj
#	Multisig/App/NSNotification+Events.swift
#	Multisig/App/RemoteNotificationHandler.swift
#	Multisig/App/SceneDelegate.swift
#	Multisig/Assets.xcassets/ic-face-id.imageset/Contents.json
#	Multisig/Assets.xcassets/ic-touch-id.imageset/Contents.json
#	Multisig/Assets.xcassets/ico-created-active.imageset/Contents.json
#	Multisig/Assets.xcassets/ico-incoming-tx.imageset/Contents.json
#	Multisig/Assets.xcassets/ico-reject.imageset/Contents.json
#	Multisig/Assets.xcassets/wc-button.imageset/Contents.json
#	Multisig/Cross-layer/App.swift
#	Multisig/Cross-layer/Configuration/Config.Example.xcconfig
#	Multisig/Cross-layer/Configuration/Configuration.swift
#	Multisig/Data/Services/Safe Client Gateway Service/SafeInfoRequest.swift
#	Multisig/Data/Services/Utils/GSError.swift
#	Multisig/Info.plist
#	Multisig/Logic/AppReviewController.swift
#	Multisig/Logic/AuthenticationController.swift
#	Multisig/Logic/Ethereum/GnosisSafe.swift
#	Multisig/Logic/Ethereum/idn2/unistring.xcframework/ios-arm64_armv7_armv7s/libunistring.a
#	Multisig/Logic/Models/AppSettings.swift
#	Multisig/Logic/Models/KeyInfo.swift
#	Multisig/Logic/Models/Multisig.xcdatamodeld/Multisig.xcdatamodel/contents
#	Multisig/Logic/Models/Safe.swift
#	Multisig/Logic/Models/Transaction.swift
#	Multisig/Logic/PrivateKeyController.swift
#	Multisig/UI/App/HeaderViewController/HeaderViewController.swift
#	Multisig/UI/App/HeaderViewController/SafeBarView.xib
#	Multisig/UI/App/ViewControllerFactory.swift
#	Multisig/UI/Assets/BalancesViewController/BalancesViewController.swift
#	Multisig/UI/Settings/AppSettingsViewController/AppSettingsViewController.swift
#	Multisig/UI/Settings/AppSettingsViewController/ImportedKeyCell.xib
#	Multisig/UI/Settings/ImportOwnerKey/EnterKeyOrSeedPhraseViewController.swift
#	Multisig/UI/Settings/ImportOwnerKey/EnterKeyOrSeedPhraseViewController.xib
#	Multisig/UI/Settings/ImportOwnerViewController/OnboardingImportOwnerKeyViewController.swift
#	Multisig/UI/Settings/ImportOwnerViewController/OnboardingImportOwnerKeyViewController.xib
#	Multisig/UI/Settings/OwnerKeyManagement/ChooseOwnerKeyViewController/ChooseOwnerKeyViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/EnterKeyOrSeedPhraseViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/EnterKeyOrSeedPhraseViewController.xib
#	Multisig/UI/Settings/OwnerKeyManagement/ImportOwnerKey/EnterKeyOrSeedPhraseViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/ImportOwnerKey/EnterKeyOrSeedPhraseViewController.xib
#	Multisig/UI/Settings/OwnerKeyManagement/ImportOwnerKey/OnboardingImportOwnerKeyViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/ImportOwnerKey/OnboardingImportOwnerKeyViewController.xib
#	Multisig/UI/Settings/OwnerKeyManagement/KeyPickerController/KeyPickerController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/OnboardingImportOwnerKeyViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/OnboardingImportOwnerKeyViewController.xib
#	Multisig/UI/Settings/OwnerKeyManagement/OwnerKeysListViewController/OwnerKeysListTableViewCell.swift
#	Multisig/UI/Settings/OwnerKeyManagement/OwnerKeysListViewController/OwnerKeysListViewController.swift
#	Multisig/UI/Settings/OwnerKeyManagement/WalletConnectOwnerKey/WalletConnectQRCodeViewController.xib
#	Multisig/UI/Settings/Passcode/PasscodeSettingsViewController.swift
#	Multisig/UI/Settings/Passcode/PasscodeViewController.swift
#	Multisig/UI/Settings/Passcode/PasscodeViewController.xib
#	Multisig/UI/Settings/Passcode/SwitchTableViewCell.xib
#	Multisig/UI/Settings/SafeSettingsViewController/AdvancedSafeSettingsViewController.swift
#	Multisig/UI/SwiftUI/Onboarding/TermsView.swift
#	Multisig/UI/Transaction/TransactionDetailsViewController/Transaction Detail Cells/DetailConfirmationCell.swift
#	Multisig/UI/Transaction/TransactionDetailsViewController/Transaction Detail Cells/DetailRejectionInfoCell.swift
#	Multisig/UI/Transaction/TransactionDetailsViewController/TransactionDetailCellBuilder.swift
#	Multisig/UI/Transaction/TransactionListViewController/Cells/TransactionListTableViewCell.xib
#	Multisig/UI/Transaction/TransactionListViewController/TransactionListViewController.swift
#	Multisig/UI/UI Library/Views/BasicCell.xib
#	Multisig/UI/UI Library/Views/TableViewCell/CardTableViewCell/CardTableViewCell.swift
#	Multisig/UI/UI Library/Views/TableViewCell/CardTableViewCell/CardTableViewCell.xib
#	MultisigIntegrationTests/Info.plist
#	MultisigTests/Info.plist
#	NotificationServiceExtension/Info.plist
#	Podfile
#	Podfile.lock
#	Pods/Manifest.lock
#	Pods/Pods.xcodeproj/project.pbxproj
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig-acknowledgements.markdown
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig-acknowledgements.plist
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.debug.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-Multisig/Pods-Multisig.release.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.debug.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigIntegrationTests/Pods-MultisigIntegrationTests.release.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.debug.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-MultisigTests/Pods-MultisigTests.release.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.staging.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.development.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.development.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.production.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.production.rinkeby.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.staging.mainnet.xcconfig
#	Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.staging.rinkeby.xcconfig
#	Pods/idn2Swift/idn2/lib/libidn2.a
#	Pods/idn2Swift/unistring/lib/libunistring.a
#	README.md
2021-04-30 14:10:26 +07:00

150 lines
4.8 KiB
Swift

//
// NetworkContentViewModel.swift
// Multisig
//
// Created by Andrey Scherbovich on 15.10.20.
// Copyright © 2020 Gnosis Ltd. All rights reserved.
//
import Foundation
import Combine
protocol LoadingModel: AnyObject {
associatedtype ResultType
var status: ViewLoadingStatus { get set }
var result: ResultType { get set }
var reloadSubject: PassthroughSubject<Void, Never> { get set }
var cancellables: Set<AnyCancellable> { get set }
var coreDataCancellable: AnyCancellable? { get set }
func buildReload()
}
extension LoadingModel {
func buildCoreDataPipeline() {
coreDataCancellable =
Publishers
.onCoreDataSave
.sink { [weak self] _ in
guard let `self` = self else { return }
self.cancellables = .init()
self.reloadSubject = .init()
self.status = .initial
self.buildReload()
}
}
func buildReloadPipelineWith<Failure>(loadData: (AnyPublisher<Void, Never>) -> AnyPublisher<ResultType, Failure>) {
reloadSubject
.status(.loading, path: \.status, object: self, set: &cancellables)
let outputFork =
loadData(reloadSubject.eraseToAnyPublisher())
.transformToResult()
.multicast { PassthroughSubject<Result<ResultType, Failure>, Never>() }
outputFork
.onSuccessResult()
.assign(to: \.result, on: self)
.store(in: &cancellables)
outputFork
.onSuccessResult()
.status(.success, path: \.status, object: self, set: &cancellables)
outputFork
.handleError(statusPath: \.status, object: self, set: &cancellables)
outputFork
.connect()
.store(in: &cancellables)
}
func reload() {
self.cancellables = .init()
self.reloadSubject = .init()
self.buildReload()
reloadSubject.send()
}
}
extension Publisher {
func selectedSafe() -> AnyPublisher<Safe, Error> {
self
.tryCompactMap { _ -> Safe? in
let context = App.shared.coreDataStack.viewContext
let fr = Safe.fetchRequest().selected()
let safe = try context.fetch(fr).first
return safe
}
.eraseToAnyPublisher()
}
func safeToAddress() -> AnyPublisher<Address, Error> where Output == Safe {
self
.tryCompactMap { safe in
guard let address = safe.address else { return nil }
return try Address(from: address)
}
.eraseToAnyPublisher()
}
}
extension Publisher {
func transformToResult() -> AnyPublisher<Result<Output, Failure>, Never> {
self
.map { value -> Result<Output, Failure> in .success(value) }
.catch { error in
Just(.failure(error))
}
.eraseToAnyPublisher()
}
}
// Result<K, Failure>
extension Publisher {
func handleError<Root, Success, Failed>(statusPath: ReferenceWritableKeyPath<Root, ViewLoadingStatus>, object: Root, set: inout Set<AnyCancellable>) where Output == Result<Success, Failed>, Failure == Never {
self
.onFailedResult()
.map { error -> Void in
App.shared.snackbar.show(message: error.localizedDescription)
}
.status(.failure, path: statusPath, object: object, set: &set)
}
func status<Root>(_ status: ViewLoadingStatus, path: ReferenceWritableKeyPath<Root, ViewLoadingStatus>, object: Root, set: inout Set<AnyCancellable>) where Failure == Never {
self
.map { _ -> ViewLoadingStatus in status }
.assign(to: path, on: object)
.store(in: &set)
}
func onSuccessResult<Success, Failed>() -> AnyPublisher<Success, Never> where Output == Result<Success, Failed>, Failure == Never {
self
.compactMap { result -> Success? in
guard case .success(let value) = result else { return nil }
return value
}
.eraseToAnyPublisher()
}
func onFailedResult<Success, Failed>() -> AnyPublisher<Failed, Never> where Output == Result<Success, Failed>, Failure == Never {
self
.compactMap { result -> Failed? in
guard case .failure(let value) = result else { return nil }
return value
}
.eraseToAnyPublisher()
}
}
extension Publishers {
static var onCoreDataSave: AnyPublisher<Notification, Never> {
NotificationCenter.default
.publisher(for: .NSManagedObjectContextDidSave, object: App.shared.coreDataStack.viewContext)
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
}