From bdd2ee9a9d174476ac9bf3a6c844223aa336214c Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Wed, 26 Aug 2020 02:19:38 -0700 Subject: [PATCH] Refactoring --- Shared/Databases/ContentDatabase.swift | 3 ++- Shared/Databases/IdentityDatabase.swift | 22 ++++++++++++------- Shared/Services/IdentitiesService.swift | 22 +++++++++---------- Shared/Services/IdentityService.swift | 14 ++++++------ .../Status List Services/ContextService.swift | 2 +- .../StatusListService.swift | 2 +- .../TimelineService.swift | 2 +- Shared/Services/StatusService.swift | 2 +- Shared/View Models/AddIdentityViewModel.swift | 17 +++++++++----- ...otificationTypesPreferencesViewModel.swift | 2 +- .../PostingReadingPreferencesViewModel.swift | 2 +- Shared/View Models/StatusViewModel.swift | 4 ++-- Shared/View Models/StatusesViewModel.swift | 4 ++-- iOS/View Models/TabNavigationViewModel.swift | 6 ++--- 14 files changed, 58 insertions(+), 46 deletions(-) diff --git a/Shared/Databases/ContentDatabase.swift b/Shared/Databases/ContentDatabase.swift index 85e812e..18c2f9f 100644 --- a/Shared/Databases/ContentDatabase.swift +++ b/Shared/Databases/ContentDatabase.swift @@ -29,7 +29,7 @@ struct ContentDatabase { } extension ContentDatabase { - func insert(statuses: [Status], collection: StatusCollection? = nil) -> AnyPublisher { + func insert(statuses: [Status], collection: StatusCollection? = nil) -> AnyPublisher { databaseQueue.writePublisher { try collection?.save($0) @@ -41,6 +41,7 @@ extension ContentDatabase { try collection?.joinRecord(status: status).save($0) } } + .ignoreOutput() .eraseToAnyPublisher() } diff --git a/Shared/Databases/IdentityDatabase.swift b/Shared/Databases/IdentityDatabase.swift index a2947aa..275f9da 100644 --- a/Shared/Databases/IdentityDatabase.swift +++ b/Shared/Databases/IdentityDatabase.swift @@ -30,7 +30,7 @@ struct IdentityDatabase { } extension IdentityDatabase { - func createIdentity(id: UUID, url: URL) -> AnyPublisher { + func createIdentity(id: UUID, url: URL) -> AnyPublisher { databaseQueue.writePublisher( updates: StoredIdentity( id: id, @@ -41,25 +41,27 @@ extension IdentityDatabase { lastRegisteredDeviceToken: nil, pushSubscriptionAlerts: .initial) .save) + .ignoreOutput() .eraseToAnyPublisher() } - func deleteIdentity(id: UUID) -> AnyPublisher { + func deleteIdentity(id: UUID) -> AnyPublisher { return databaseQueue.writePublisher(updates: StoredIdentity.filter(Column("id") == id).deleteAll) - .map { _ in () } + .ignoreOutput() .eraseToAnyPublisher() } - func updateLastUsedAt(identityID: UUID) -> AnyPublisher { + func updateLastUsedAt(identityID: UUID) -> AnyPublisher { databaseQueue.writePublisher { try StoredIdentity .filter(Column("id") == identityID) .updateAll($0, Column("lastUsedAt").set(to: Date())) } + .ignoreOutput() .eraseToAnyPublisher() } - func updateInstance(_ instance: Instance, forIdentityID identityID: UUID) -> AnyPublisher { + func updateInstance(_ instance: Instance, forIdentityID identityID: UUID) -> AnyPublisher { databaseQueue.writePublisher { try Identity.Instance( uri: instance.uri, @@ -71,10 +73,11 @@ extension IdentityDatabase { .filter(Column("id") == identityID) .updateAll($0, Column("instanceURI").set(to: instance.uri)) } + .ignoreOutput() .eraseToAnyPublisher() } - func updateAccount(_ account: Account, forIdentityID identityID: UUID) -> AnyPublisher { + func updateAccount(_ account: Account, forIdentityID identityID: UUID) -> AnyPublisher { databaseQueue.writePublisher( updates: Identity.Account( id: account.id, @@ -88,11 +91,12 @@ extension IdentityDatabase { headerStatic: account.headerStatic, emojis: account.emojis) .save) + .ignoreOutput() .eraseToAnyPublisher() } func updatePreferences(_ preferences: Identity.Preferences, - forIdentityID identityID: UUID) -> AnyPublisher { + forIdentityID identityID: UUID) -> AnyPublisher { databaseQueue.writePublisher { let data = try StoredIdentity.databaseJSONEncoder(for: "preferences").encode(preferences) @@ -100,12 +104,13 @@ extension IdentityDatabase { .filter(Column("id") == identityID) .updateAll($0, Column("preferences").set(to: data)) } + .ignoreOutput() .eraseToAnyPublisher() } func updatePushSubscription(alerts: PushSubscription.Alerts, deviceToken: String? = nil, - forIdentityID identityID: UUID) -> AnyPublisher { + forIdentityID identityID: UUID) -> AnyPublisher { databaseQueue.writePublisher { let data = try StoredIdentity.databaseJSONEncoder(for: "pushSubscriptionAlerts").encode(alerts) @@ -119,6 +124,7 @@ extension IdentityDatabase { .updateAll($0, Column("lastRegisteredDeviceToken").set(to: deviceToken)) } } + .ignoreOutput() .eraseToAnyPublisher() } diff --git a/Shared/Services/IdentitiesService.swift b/Shared/Services/IdentitiesService.swift index aacc25a..9e98ec0 100644 --- a/Shared/Services/IdentitiesService.swift +++ b/Shared/Services/IdentitiesService.swift @@ -26,11 +26,11 @@ extension IdentitiesService { environment: environment) } - func createIdentity(id: UUID, instanceURL: URL) -> AnyPublisher { + func createIdentity(id: UUID, instanceURL: URL) -> AnyPublisher { identityDatabase.createIdentity(id: id, url: instanceURL) } - func authorizeIdentity(id: UUID, instanceURL: URL) -> AnyPublisher { + func authorizeIdentity(id: UUID, instanceURL: URL) -> AnyPublisher { let secretsService = SecretsService(identityID: id, keychainService: environment.keychainServiceType) let authenticationService = AuthenticationService(environment: environment) @@ -42,22 +42,19 @@ extension IdentitiesService { return (instanceURL, appAuthorization) } .flatMap(authenticationService.authenticate(instanceURL:appAuthorization:)) - .tryMap { accessToken -> Void in - try secretsService.set(accessToken.accessToken, forItem: .accessToken) - - return () - } + .tryMap { try secretsService.set($0.accessToken, forItem: .accessToken) } + .ignoreOutput() .eraseToAnyPublisher() } - func deleteIdentity(_ identity: Identity) -> AnyPublisher { + func deleteIdentity(_ identity: Identity) -> AnyPublisher { let secretsService = SecretsService(identityID: identity.id, keychainService: environment.keychainServiceType) let networkClient = MastodonClient(environment: environment) networkClient.instanceURL = identity.url return identityDatabase.deleteIdentity(id: identity.id) - .tryMap { + .tryMap { _ in DeletionEndpoint.oauthRevoke( token: try secretsService.item(.accessToken), clientID: try secretsService.item(.clientID), @@ -65,12 +62,13 @@ extension IdentitiesService { } .flatMap(networkClient.request) .tryMap { _ in try secretsService.deleteAllItems() } + .ignoreOutput() .eraseToAnyPublisher() } - func updatePushSubscriptions(deviceToken: String) -> AnyPublisher { + func updatePushSubscriptions(deviceToken: String) -> AnyPublisher { identityDatabase.identitiesWithOutdatedDeviceTokens(deviceToken: deviceToken) - .tryMap { identities -> [AnyPublisher] in + .tryMap { identities -> [AnyPublisher] in try identities.map { try identityService(id: $0.id) .createPushSubscription(deviceToken: deviceToken, alerts: $0.pushSubscriptionAlerts) @@ -79,7 +77,7 @@ extension IdentitiesService { } } .map(Publishers.MergeMany.init) - .map { _ in () } + .ignoreOutput() .eraseToAnyPublisher() } } diff --git a/Shared/Services/IdentityService.swift b/Shared/Services/IdentityService.swift index 8b4e095..c2c543d 100644 --- a/Shared/Services/IdentityService.swift +++ b/Shared/Services/IdentityService.swift @@ -52,18 +52,18 @@ class IdentityService { extension IdentityService { var isAuthorized: Bool { networkClient.accessToken != nil } - func updateLastUse() -> AnyPublisher { + func updateLastUse() -> AnyPublisher { identityDatabase.updateLastUsedAt(identityID: identity.id) } - func verifyCredentials() -> AnyPublisher { + func verifyCredentials() -> AnyPublisher { networkClient.request(AccountEndpoint.verifyCredentials) .zip(Just(identity.id).first().setFailureType(to: Error.self)) .flatMap(identityDatabase.updateAccount) .eraseToAnyPublisher() } - func refreshServerPreferences() -> AnyPublisher { + func refreshServerPreferences() -> AnyPublisher { networkClient.request(PreferencesEndpoint.preferences) .zip(Just(self).first().setFailureType(to: Error.self)) .map { ($1.identity.preferences.updated(from: $0), $1.identity.id) } @@ -71,7 +71,7 @@ extension IdentityService { .eraseToAnyPublisher() } - func refreshInstance() -> AnyPublisher { + func refreshInstance() -> AnyPublisher { networkClient.request(InstanceEndpoint.instance) .zip(Just(identity.id).first().setFailureType(to: Error.self)) .flatMap(identityDatabase.updateInstance) @@ -86,7 +86,7 @@ extension IdentityService { identityDatabase.recentIdentitiesObservation(excluding: identity.id) } - func updatePreferences(_ preferences: Identity.Preferences) -> AnyPublisher { + func updatePreferences(_ preferences: Identity.Preferences) -> AnyPublisher { identityDatabase.updatePreferences(preferences, forIdentityID: identity.id) .zip(Just(self).first().setFailureType(to: Error.self)) .filter { $1.identity.preferences.useServerPostingReadingPreferences } @@ -95,7 +95,7 @@ extension IdentityService { .eraseToAnyPublisher() } - func createPushSubscription(deviceToken: String, alerts: PushSubscription.Alerts) -> AnyPublisher { + func createPushSubscription(deviceToken: String, alerts: PushSubscription.Alerts) -> AnyPublisher { let publicKey: String let auth: String @@ -122,7 +122,7 @@ extension IdentityService { .eraseToAnyPublisher() } - func updatePushSubscription(alerts: PushSubscription.Alerts) -> AnyPublisher { + func updatePushSubscription(alerts: PushSubscription.Alerts) -> AnyPublisher { let identityID = identity.id return networkClient.request(PushSubscriptionEndpoint.update(alerts: alerts)) diff --git a/Shared/Services/Status List Services/ContextService.swift b/Shared/Services/Status List Services/ContextService.swift index 3282864..0c627f6 100644 --- a/Shared/Services/Status List Services/ContextService.swift +++ b/Shared/Services/Status List Services/ContextService.swift @@ -60,7 +60,7 @@ extension ContextService: StatusListService { return status.id != contextParentID && nextStatus.inReplyToId == status.id } - func request(maxID: String?, minID: String?) -> AnyPublisher { + func request(maxID: String?, minID: String?) -> AnyPublisher { Publishers.Merge( networkClient.request(StatusEndpoint.status(id: status.id)) .map { ([$0], collection) } diff --git a/Shared/Services/Status List Services/StatusListService.swift b/Shared/Services/Status List Services/StatusListService.swift index dccb8e0..0b6b21b 100644 --- a/Shared/Services/Status List Services/StatusListService.swift +++ b/Shared/Services/Status List Services/StatusListService.swift @@ -9,7 +9,7 @@ protocol StatusListService { func isPinned(status: Status) -> Bool func isReplyInContext(status: Status) -> Bool func hasReplyFollowing(status: Status) -> Bool - func request(maxID: String?, minID: String?) -> AnyPublisher + func request(maxID: String?, minID: String?) -> AnyPublisher func statusService(status: Status) -> StatusService func contextService(status: Status) -> ContextService } diff --git a/Shared/Services/Status List Services/TimelineService.swift b/Shared/Services/Status List Services/TimelineService.swift index 99cb9f5..11b57ea 100644 --- a/Shared/Services/Status List Services/TimelineService.swift +++ b/Shared/Services/Status List Services/TimelineService.swift @@ -21,7 +21,7 @@ struct TimelineService { } extension TimelineService: StatusListService { - func request(maxID: String?, minID: String?) -> AnyPublisher { + func request(maxID: String?, minID: String?) -> AnyPublisher { return networkClient.request(timeline.endpoint) .map { ($0, timeline) } .flatMap(contentDatabase.insert(statuses:collection:)) diff --git a/Shared/Services/StatusService.swift b/Shared/Services/StatusService.swift index e9a256a..139117b 100644 --- a/Shared/Services/StatusService.swift +++ b/Shared/Services/StatusService.swift @@ -16,7 +16,7 @@ struct StatusService { } extension StatusService { - func toggleFavorited() -> AnyPublisher { + func toggleFavorited() -> AnyPublisher { networkClient.request(status.favourited ? StatusEndpoint.unfavourite(id: status.id) : StatusEndpoint.favourite(id: status.id)) diff --git a/Shared/View Models/AddIdentityViewModel.swift b/Shared/View Models/AddIdentityViewModel.swift index 44f1f4d..b8b4f21 100644 --- a/Shared/View Models/AddIdentityViewModel.swift +++ b/Shared/View Models/AddIdentityViewModel.swift @@ -31,15 +31,19 @@ class AddIdentityViewModel: ObservableObject { } identitiesService.authorizeIdentity(id: identityID, instanceURL: instanceURL) - .map { (identityID, instanceURL) } + .collect() + .map { _ in (identityID, instanceURL) } .flatMap(identitiesService.createIdentity(id:instanceURL:)) - .map { identityID } .assignErrorsToAlertItem(to: \.alertItem, on: self) .receive(on: RunLoop.main) .handleEvents( receiveSubscription: { [weak self] _ in self?.loading = true }, receiveCompletion: { [weak self] _ in self?.loading = false }) - .sink(receiveValue: addedIdentityIDInput.send) + .sink { [weak self] in + guard let self = self, case .finished = $0 else { return } + + self.addedIdentityIDInput.send(identityID) + } receiveValue: { _ in } .store(in: &cancellables) } @@ -57,9 +61,12 @@ class AddIdentityViewModel: ObservableObject { // TODO: Ensure instance has not disabled public preview identitiesService.createIdentity(id: identityID, instanceURL: instanceURL) - .map { identityID } .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink(receiveValue: addedIdentityIDInput.send) + .sink { [weak self] in + guard let self = self, case .finished = $0 else { return } + + self.addedIdentityIDInput.send(identityID) + } receiveValue: { _ in } .store(in: &cancellables) } } diff --git a/Shared/View Models/NotificationTypesPreferencesViewModel.swift b/Shared/View Models/NotificationTypesPreferencesViewModel.swift index 28cef2b..6dc2da4 100644 --- a/Shared/View Models/NotificationTypesPreferencesViewModel.swift +++ b/Shared/View Models/NotificationTypesPreferencesViewModel.swift @@ -38,7 +38,7 @@ private extension NotificationTypesPreferencesViewModel { self.alertItem = AlertItem(error: error) self.pushSubscriptionAlerts = self.identityService.identity.pushSubscriptionAlerts - } receiveValue: {} + } receiveValue: { _ in } .store(in: &cancellables) } } diff --git a/Shared/View Models/PostingReadingPreferencesViewModel.swift b/Shared/View Models/PostingReadingPreferencesViewModel.swift index 489522f..6585bd4 100644 --- a/Shared/View Models/PostingReadingPreferencesViewModel.swift +++ b/Shared/View Models/PostingReadingPreferencesViewModel.swift @@ -24,7 +24,7 @@ class PostingReadingPreferencesViewModel: ObservableObject { .dropFirst() .flatMap(identityService.updatePreferences) .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink {} + .sink { _ in } .store(in: &cancellables) } } diff --git a/Shared/View Models/StatusViewModel.swift b/Shared/View Models/StatusViewModel.swift index da34133..42dbfb6 100644 --- a/Shared/View Models/StatusViewModel.swift +++ b/Shared/View Models/StatusViewModel.swift @@ -19,10 +19,10 @@ struct StatusViewModel { var isReplyInContext = false var hasReplyFollowing = false var sensitiveContentToggled = false - let events: AnyPublisher, Never> + let events: AnyPublisher, Never> private let statusService: StatusService - private let eventsInput = PassthroughSubject, Never>() + private let eventsInput = PassthroughSubject, Never>() init(statusService: StatusService) { self.statusService = statusService diff --git a/Shared/View Models/StatusesViewModel.swift b/Shared/View Models/StatusesViewModel.swift index dc7466b..81c9e07 100644 --- a/Shared/View Models/StatusesViewModel.swift +++ b/Shared/View Models/StatusesViewModel.swift @@ -37,7 +37,7 @@ extension StatusesViewModel { .handleEvents( receiveSubscription: { [weak self] _ in self?.loading = true }, receiveCompletion: { [weak self] _ in self?.loading = false }) - .sink {} + .sink { _ in } .store(in: &cancellables) } @@ -53,7 +53,7 @@ extension StatusesViewModel { statusViewModelCache[status] = (statusViewModel, statusViewModel.events .flatMap { $0 } .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink {}) + .sink { _ in }) } statusViewModel.isContextParent = status.id == contextParentID diff --git a/iOS/View Models/TabNavigationViewModel.swift b/iOS/View Models/TabNavigationViewModel.swift index ed62d61..a93b4e2 100644 --- a/iOS/View Models/TabNavigationViewModel.swift +++ b/iOS/View Models/TabNavigationViewModel.swift @@ -31,20 +31,20 @@ extension TabNavigationViewModel { if identityService.isAuthorized { identityService.verifyCredentials() .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink(receiveValue: {}) + .sink { _ in } .store(in: &cancellables) if identity.preferences.useServerPostingReadingPreferences { identityService.refreshServerPreferences() .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink(receiveValue: {}) + .sink { _ in } .store(in: &cancellables) } } identityService.refreshInstance() .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink(receiveValue: {}) + .sink { _ in } .store(in: &cancellables) }