metatext/Shared/Services/IdentityService.swift

89 lines
3.2 KiB
Swift
Raw Normal View History

2020-08-07 21:57:18 +00:00
// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
import Combine
2020-08-08 23:08:47 +00:00
class IdentityService {
2020-08-09 08:04:43 +00:00
@Published private(set) var identity: Identity
2020-08-07 21:57:18 +00:00
let observationErrors: AnyPublisher<Error, Never>
private let identityDatabase: IdentityDatabase
2020-08-09 05:37:04 +00:00
private let environment: AppEnvironment
private let networkClient: MastodonClient
2020-08-07 21:57:18 +00:00
private let observationErrorsInput = PassthroughSubject<Error, Never>()
init(identityID: UUID,
identityDatabase: IdentityDatabase,
environment: AppEnvironment) throws {
self.identityDatabase = identityDatabase
2020-08-09 05:37:04 +00:00
self.environment = environment
2020-08-07 21:57:18 +00:00
observationErrors = observationErrorsInput.eraseToAnyPublisher()
let observation = identityDatabase.identityObservation(id: identityID).share()
2020-08-07 21:57:18 +00:00
var initialIdentity: Identity?
2020-08-09 08:04:43 +00:00
_ = observation.first().sink(
2020-08-07 21:57:18 +00:00
receiveCompletion: { _ in },
receiveValue: { initialIdentity = $0 })
guard let identity = initialIdentity else { throw IdentityDatabaseError.identityNotFound }
self.identity = identity
2020-08-12 07:24:39 +00:00
networkClient = MastodonClient(session: environment.session)
2020-08-07 21:57:18 +00:00
networkClient.instanceURL = identity.url
2020-08-09 08:04:43 +00:00
networkClient.accessToken = try SecretsService(
identityID: identityID,
2020-08-12 07:24:39 +00:00
keychainServiceType: environment.keychainServiceType)
2020-08-09 08:04:43 +00:00
.item(.accessToken)
2020-08-07 21:57:18 +00:00
observation.catch { [weak self] error -> Empty<Identity, Never> in
self?.observationErrorsInput.send(error)
return Empty()
}
.assign(to: &$identity)
}
}
2020-08-08 23:08:47 +00:00
extension IdentityService {
2020-08-07 21:57:18 +00:00
var isAuthorized: Bool { networkClient.accessToken != nil }
2020-08-09 05:37:04 +00:00
func updateLastUse() -> AnyPublisher<Void, Error> {
identityDatabase.updateLastUsedAt(identityID: identity.id)
2020-08-09 05:37:04 +00:00
}
2020-08-07 21:57:18 +00:00
func verifyCredentials() -> AnyPublisher<Void, Error> {
networkClient.request(AccountEndpoint.verifyCredentials)
2020-08-12 08:45:01 +00:00
.zip(Just(identity.id).first().setFailureType(to: Error.self))
.flatMap(identityDatabase.updateAccount)
2020-08-07 21:57:18 +00:00
.eraseToAnyPublisher()
}
func refreshServerPreferences() -> AnyPublisher<Void, Error> {
networkClient.request(PreferencesEndpoint.preferences)
2020-08-12 08:45:01 +00:00
.zip(Just(self).first().setFailureType(to: Error.self))
2020-08-07 21:57:18 +00:00
.map { ($1.identity.preferences.updated(from: $0), $1.identity.id) }
.flatMap(identityDatabase.updatePreferences)
2020-08-07 21:57:18 +00:00
.eraseToAnyPublisher()
}
func refreshInstance() -> AnyPublisher<Void, Error> {
networkClient.request(InstanceEndpoint.instance)
2020-08-12 08:45:01 +00:00
.zip(Just(identity.id).first().setFailureType(to: Error.self))
.flatMap(identityDatabase.updateInstance)
2020-08-07 21:57:18 +00:00
.eraseToAnyPublisher()
}
func identitiesObservation() -> AnyPublisher<[Identity], Error> {
identityDatabase.identitiesObservation()
2020-08-07 21:57:18 +00:00
}
func recentIdentitiesObservation() -> AnyPublisher<[Identity], Error> {
identityDatabase.recentIdentitiesObservation(excluding: identity.id)
2020-08-07 21:57:18 +00:00
}
func updatePreferences(_ preferences: Identity.Preferences) -> AnyPublisher<Void, Error> {
identityDatabase.updatePreferences(preferences, forIdentityID: identity.id)
2020-08-07 21:57:18 +00:00
}
}