Remove persistence for user (IOS-192)

This commit is contained in:
Nathan Mattes 2024-02-14 10:44:32 +01:00
parent 94fb3f6c7e
commit 7024823cbf
8 changed files with 28 additions and 293 deletions

View File

@ -187,7 +187,6 @@ extension AuthenticationViewModel {
userToken: Mastodon.Entity.Token
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Account>, Error> {
let authorization = Mastodon.API.OAuth.Authorization(accessToken: userToken.accessToken)
let managedObjectContext = context.backgroundManagedObjectContext
return context.apiService.accountVerifyCredentials(
domain: info.domain,
@ -195,23 +194,21 @@ extension AuthenticationViewModel {
)
.tryMap { response -> Mastodon.Response.Content<Mastodon.Entity.Account> in
let account = response.value
let mastodonUserRequest = MastodonUser.sortedFetchRequest
mastodonUserRequest.predicate = MastodonUser.predicate(domain: info.domain, id: account.id)
mastodonUserRequest.fetchLimit = 1
guard let mastodonUser = try? managedObjectContext.fetch(mastodonUserRequest).first else {
throw AuthenticationError.badCredentials
}
let authentication = MastodonAuthentication.createFrom(domain: info.domain,
userID: account.id,
username: account.username,
appAccessToken: userToken.accessToken, // TODO: swap app token
userAccessToken: userToken.accessToken,
clientID: info.clientID,
clientSecret: info.clientSecret)
AuthenticationServiceProvider.shared
.authentications
.insert(MastodonAuthentication.createFrom(domain: info.domain,
userID: mastodonUser.id,
username: mastodonUser.username,
appAccessToken: userToken.accessToken, // TODO: swap app token
userAccessToken: userToken.accessToken,
clientID: info.clientID,
clientSecret: info.clientSecret), at: 0)
.insert(authentication, at: 0)
FileManager.default.store(account: account, forUserID: authentication.userIdentifier())
return response
}
.eraseToAnyPublisher()

View File

@ -182,6 +182,10 @@ class ProfileViewModel: NSObject {
let mastodonAuthentication = authContext.mastodonAuthenticationBox.authentication
let authorization = Mastodon.API.OAuth.Authorization(accessToken: mastodonAuthentication.userAccessToken)
return context.apiService.accountVerifyCredentials(domain: domain, authorization: authorization)
.tryMap { response in
FileManager.default.store(account: response.value, forUserID: mastodonAuthentication.userIdentifier())
return response
}.eraseToAnyPublisher()
}
}
@ -226,10 +230,14 @@ extension ProfileViewModel {
source: nil,
fieldsAttributes: fieldsAttributes
)
return try await context.apiService.accountUpdateCredentials(
let response = try await context.apiService.accountUpdateCredentials(
domain: domain,
query: query,
authorization: authorization
)
FileManager.default.store(account: response.value, forUserID: authenticationBox.authentication.userIdentifier())
return response
}
}

View File

@ -1,151 +0,0 @@
//
// Persistence+MastodonUser.swift
// Persistence+MastodonUser
//
// Created by Cirno MainasuK on 2021-8-18.
// Copyright © 2021 Twidere. All rights reserved.
//
import CoreData
import CoreDataStack
import Foundation
import MastodonSDK
extension Persistence.MastodonUser {
public struct PersistContext {
public let domain: String
public let entity: Mastodon.Entity.Account
public let cache: Persistence.PersistCache<MastodonUser>?
public let networkDate: Date
public init(
domain: String,
entity: Mastodon.Entity.Account,
cache: Persistence.PersistCache<MastodonUser>?,
networkDate: Date
) {
self.domain = domain
self.entity = entity
self.cache = cache
self.networkDate = networkDate
}
}
public struct PersistResult {
public let user: MastodonUser
public let isNewInsertion: Bool
public init(
user: MastodonUser,
isNewInsertion: Bool
) {
self.user = user
self.isNewInsertion = isNewInsertion
}
}
public static func createOrMerge(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> PersistResult {
if let oldMastodonUser = fetch(in: managedObjectContext, context: context) {
merge(mastodonUser: oldMastodonUser, context: context)
return PersistResult(user: oldMastodonUser, isNewInsertion: false)
} else {
let user = create(in: managedObjectContext, context: context)
return PersistResult(user: user, isNewInsertion: true)
}
}
}
extension Persistence.MastodonUser {
public static func fetch(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> MastodonUser? {
if let cache = context.cache {
return cache.dictionary[context.entity.id]
} else {
let request = MastodonUser.sortedFetchRequest
request.predicate = MastodonUser.predicate(
domain: context.domain,
id: context.entity.id
)
request.fetchLimit = 1
do {
return try managedObjectContext.fetch(request).first
} catch {
assertionFailure(error.localizedDescription)
return nil
}
}
}
@discardableResult
public static func create(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> MastodonUser {
let property = MastodonUser.Property(
entity: context.entity,
domain: context.domain,
networkDate: context.networkDate
)
let user = MastodonUser.insert(into: managedObjectContext, property: property)
return user
}
public static func merge(
mastodonUser user: MastodonUser,
context: PersistContext
) {
guard context.networkDate > user.updatedAt else { return }
let property = MastodonUser.Property(
entity: context.entity,
domain: context.domain,
networkDate: context.networkDate
)
user.update(property: property)
}
}
extension Persistence.MastodonUser {
public struct RelationshipContext {
public let entity: Mastodon.Entity.Relationship
public let me: MastodonUser
public let networkDate: Date
public init(
entity: Mastodon.Entity.Relationship,
me: MastodonUser,
networkDate: Date
) {
self.entity = entity
self.me = me
self.networkDate = networkDate
}
}
public static func update(
mastodonUser user: MastodonUser,
context: RelationshipContext
) {
guard context.entity.id != context.me.id else { return } // not update relationship for self
let relationship = context.entity
let me = context.me
user.update(isFollowing: relationship.following, by: me)
user.update(isFollowRequested: relationship.requested, by: me)
// relationship.endorsed.flatMap { user.update(isEndorsed: $0, by: me) }
me.update(isFollowing: relationship.followedBy, by: user)
user.update(isMuting: relationship.muting, by: me)
user.update(isBlocking: relationship.blocking, by: me)
user.update(isDomainBlocking: relationship.domainBlocking, by: me)
me.update(isBlocking: relationship.blockedBy, by: user)
me.update(isShowingReblogs: relationship.showingReblogs, by: user)
}
}

View File

@ -41,16 +41,13 @@ extension Persistence.Status {
public struct PersistResult {
public let status: Status
public let isNewInsertion: Bool
public let isNewInsertionAuthor: Bool
public init(
status: Status,
isNewInsertion: Bool,
isNewInsertionAuthor: Bool
isNewInsertion: Bool
) {
self.status = status
self.isNewInsertion = isNewInsertion
self.isNewInsertionAuthor = isNewInsertionAuthor
}
}
@ -78,8 +75,7 @@ extension Persistence.Status {
merge(in: managedObjectContext, mastodonStatus: oldStatus, context: context)
return PersistResult(
status: oldStatus,
isNewInsertion: false,
isNewInsertionAuthor: false
isNewInsertion: false
)
} else {
let poll: Poll? = {
@ -98,16 +94,6 @@ extension Persistence.Status {
let card = createCard(in: managedObjectContext, context: context)
let authorResult = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: context.domain,
entity: context.entity.account,
cache: context.userCache,
networkDate: context.networkDate
)
)
let author = authorResult.user
let application: Application? = createApplication(in: managedObjectContext, context: .init(entity: context.entity))
let relationship = Status.Relationship(
@ -124,8 +110,7 @@ extension Persistence.Status {
return PersistResult(
status: status,
isNewInsertion: true,
isNewInsertionAuthor: authorResult.isNewInsertion
isNewInsertion: true
)
}
}

View File

@ -50,33 +50,6 @@ extension APIService {
domain: domain,
authorization: authorization
)
.flatMap { response -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Account>, Error> in
let account = response.value
let managedObjectContext = self.backgroundManagedObjectContext
return managedObjectContext.performChanges {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: domain,
entity: account,
cache: nil,
networkDate: response.networkDate
)
)
}
.setFailureType(to: Error.self)
.tryMap { result -> Mastodon.Response.Content<Mastodon.Entity.Account> in
switch result {
case .success:
return response
case .failure(let error):
throw error
}
}
.eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
public func accountUpdateCredentials(
@ -91,19 +64,6 @@ extension APIService {
authorization: authorization
).singleOutput()
let managedObjectContext = self.backgroundManagedObjectContext
try await managedObjectContext.performChanges {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: domain,
entity: response.value,
cache: nil,
networkDate: response.networkDate
)
)
}
return response
}

View File

@ -62,7 +62,6 @@ extension APIService {
query: Mastodon.API.Statuses.RebloggedByQuery,
authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> {
let managedObjectContext = backgroundManagedObjectContext
let statusID: Status.ID = status.reblog?.id ?? status.id
let response = try await Mastodon.API.Statuses.rebloggedBy(
@ -72,21 +71,7 @@ extension APIService {
query: query,
authorization: authenticationBox.userAuthorization
).singleOutput()
try await managedObjectContext.performChanges {
for entity in response.value {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: .init(
domain: authenticationBox.domain,
entity: entity,
cache: nil,
networkDate: response.networkDate
)
)
} // end for in
}
return response
} // end func
}
}

View File

@ -26,21 +26,6 @@ extension APIService {
authorization: authenticationBox.userAuthorization
).singleOutput()
let managedObjectContext = backgroundManagedObjectContext
try await managedObjectContext.performChanges {
for entity in response.value {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: authenticationBox.domain,
entity: entity,
cache: nil,
networkDate: response.networkDate
)
)
} // end for in
}
return response
}
@ -55,24 +40,8 @@ extension APIService {
authorization: authenticationBox.userAuthorization
).singleOutput()
let managedObjectContext = backgroundManagedObjectContext
try await managedObjectContext.performChanges {
for entity in response.value {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: authenticationBox.domain,
entity: entity.account,
cache: nil,
networkDate: response.networkDate
)
)
} // end for in
}
return response
}
}
extension APIService {
@ -88,24 +57,6 @@ extension APIService {
authorization: authenticationBox.userAuthorization
).singleOutput()
let managedObjectContext = backgroundManagedObjectContext
try await managedObjectContext.performChanges {
for entity in response.value {
for account in entity.accounts {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: authenticationBox.domain,
entity: account,
cache: nil,
networkDate: response.networkDate
)
)
} // end for account in
} // end for entity in
}
return response
}

View File

@ -701,7 +701,7 @@ extension StatusView.ViewModel {
let menuContext = StatusAuthorView.AuthorMenuContext(
name: name,
isMuting: rel.muting ?? false,
isMuting: rel.muting,
isBlocking: rel.blocking,
isMyself: isMyself,
isBookmarking: isBookmark,