diff --git a/Tusker/CoreData/MastodonCachePersistentStore.swift b/Tusker/CoreData/MastodonCachePersistentStore.swift index 450eb74f..4807201d 100644 --- a/Tusker/CoreData/MastodonCachePersistentStore.swift +++ b/Tusker/CoreData/MastodonCachePersistentStore.swift @@ -41,27 +41,30 @@ class MastodonCachePersistentStore: NSPersistentContainer { } } - private func upsert(status: Status, incrementReferenceCount: Bool) { + @discardableResult + private func upsert(status: Status, incrementReferenceCount: Bool) -> StatusMO { if let statusMO = self.status(for: status.id, in: self.backgroundContext) { statusMO.updateFrom(apiStatus: status, container: self) if incrementReferenceCount { statusMO.incrementReferenceCount() } + return statusMO } else { let statusMO = StatusMO(apiStatus: status, container: self, context: self.backgroundContext) if incrementReferenceCount { statusMO.incrementReferenceCount() } + return statusMO } } - func addOrUpdate(status: Status, incrementReferenceCount: Bool, completion: (() -> Void)? = nil) { + func addOrUpdate(status: Status, incrementReferenceCount: Bool, completion: ((StatusMO) -> Void)? = nil) { backgroundContext.perform { - self.upsert(status: status, incrementReferenceCount: incrementReferenceCount) + let statusMO = self.upsert(status: status, incrementReferenceCount: incrementReferenceCount) if self.backgroundContext.hasChanges { try! self.backgroundContext.save() } - completion?() + completion?(statusMO) self.statusSubject.send(status.id) } } @@ -89,28 +92,30 @@ class MastodonCachePersistentStore: NSPersistentContainer { } } - private func upsert(account: Account) { + @discardableResult + private func upsert(account: Account) -> AccountMO { if let accountMO = self.account(for: account.id, in: self.backgroundContext) { accountMO.updateFrom(apiAccount: account, container: self) + return accountMO } else { - _ = AccountMO(apiAccount: account, container: self, context: self.backgroundContext) + return AccountMO(apiAccount: account, container: self, context: self.backgroundContext) } } - func addOrUpdate(account: Account, completion: (() -> Void)? = nil) { + func addOrUpdate(account: Account, completion: ((AccountMO) -> Void)? = nil) { backgroundContext.perform { - self.upsert(account: account) + let accountMO = self.upsert(account: account) if self.backgroundContext.hasChanges { try! self.backgroundContext.save() } - completion?() + completion?(accountMO) self.accountSubject.send(account.id) } } func addAll(accounts: [Account], completion: (() -> Void)? = nil) { backgroundContext.perform { - accounts.forEach(self.upsert(account:)) + accounts.forEach { self.upsert(account: $0) } if self.backgroundContext.hasChanges { try! self.backgroundContext.save() } diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index a69e80bb..63407c95 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -173,8 +173,7 @@ class ComposeViewController: UIViewController { let request = Client.getStatus(id: inReplyToID) mastodonController.run(request) { (response) in guard case let .success(status, _) = response else { return } - self.mastodonController.persistentContainer.addOrUpdate(status: status, incrementReferenceCount: true) { - guard let status = self.mastodonController.persistentContainer.status(for: inReplyToID) else { return } + self.mastodonController.persistentContainer.addOrUpdate(status: status, incrementReferenceCount: true) { (status) in DispatchQueue.main.async { self.updateInReplyTo(inReplyTo: status) loadingVC.removeViewAndController() diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index 0469e923..dd81a404 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -90,7 +90,7 @@ class ProfileTableViewController: EnhancedTableViewController { } return } - self.mastodonController.persistentContainer.addOrUpdate(account: account) { + self.mastodonController.persistentContainer.addOrUpdate(account: account) { (_) in DispatchQueue.main.async { self.updateAccountUI() self.tableView.reloadData() diff --git a/Tusker/XCallbackURL/XCBActions.swift b/Tusker/XCallbackURL/XCBActions.swift index 9ec6d1d9..4e5a40a6 100644 --- a/Tusker/XCallbackURL/XCBActions.swift +++ b/Tusker/XCallbackURL/XCBActions.swift @@ -38,62 +38,62 @@ struct XCBActions { private static func getStatus(from request: XCBRequest, session: XCBSession, completion: @escaping (Status) -> Void) { if let id = request.arguments["statusID"] { - mastodonController.cache.status(for: id) { (status) in - if let status = status { - completion(status) - } else { + let request = Client.getStatus(id: id) + mastodonController.run(request) { (response) in + guard case let .success(status, _) = response else { session.complete(with: .error, additionalData: [ "error": "Could not get status with ID \(id)" - ]) + ]) + return } + completion(status) } } else if let searchQuery = request.arguments["statusURL"] { let request = Client.search(query: searchQuery) mastodonController.run(request) { (response) in if case let .success(results, _) = response, let status = results.statuses.first { - mastodonController.cache.add(status: status) completion(status) } else { session.complete(with: .error, additionalData: [ "error": "Could not find status by searching '\(searchQuery)'" - ]) + ]) } } } else { session.complete(with: .error, additionalData: [ "error": "No status provided. Specify either instance-local statusID or remote statusURL." - ]) + ]) } } private static func getAccount(from request: XCBRequest, session: XCBSession, completion: @escaping (Account) -> Void) { if let id = request.arguments["accountID"] { - mastodonController.cache.account(for: id) { (account) in - if let account = account { - completion(account) - } else { + let request = Client.getAccount(id: id) + mastodonController.run(request) { (response) in + guard case let .success(account, _) = response else { session.complete(with: .error, additionalData: [ "error": "Could not get account with ID \(id)" - ]) + ]) + return } + completion(account) } } else if let searchQuery = request.arguments["accountURL"] { let request = Client.search(query: searchQuery) mastodonController.run(request) { (response) in if case let .success(results, _) = response { if let account = results.accounts.first { - mastodonController.cache.add(account: account) completion(account) } else { session.complete(with: .error, additionalData: [ "error": "Could not find account by searching '\(searchQuery)'" - ]) + ]) } } else if case let .failure(error) = response { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) } } } else if let acct = request.arguments["acct"] { @@ -101,23 +101,22 @@ struct XCBActions { mastodonController.run(request) { (response) in if case let .success(accounts, _) = response { if let account = accounts.first { - mastodonController.cache.add(account: account) completion(account) } else { session.complete(with: .error, additionalData: [ "error": "Could not find account \(acct)" - ]) + ]) } } else if case let .failure(error) = response { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) } } } else { session.complete(with: .error, additionalData: [ "error": "No status provided. Specify either instance-local ID, account URL, or qualified username." - ]) + ]) } } @@ -142,7 +141,7 @@ struct XCBActions { guard CharacterCounter.count(text: status) <= mastodonController.instance.maxStatusCharacters ?? 500 else { session.complete(with: .error, additionalData: [ "error": "Too many characters. Instance maximum is \(mastodonController.instance.maxStatusCharacters ?? 500)" - ]) + ]) return } let request = Client.createStatus(text: status, visibility: Preferences.shared.defaultPostVisibility) @@ -151,11 +150,11 @@ struct XCBActions { session.complete(with: .success, additionalData: [ "statusURL": status.url?.absoluteString, "statusURI": status.uri - ]) + ]) } else if case let .failure(error) = response { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) } } } else { @@ -179,7 +178,7 @@ struct XCBActions { } catch { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) return } } @@ -192,7 +191,7 @@ struct XCBActions { "posted": status.createdAt.timeIntervalSince1970.description, "content": content, "reblog": status.reblog?.id - ]) + ]) } } @@ -208,16 +207,15 @@ struct XCBActions { func performAction(status: Status, completion: ((Status) -> Void)?) { mastodonController.run(request(status.id)) { (response) in if case let .success(status, _) = response { - mastodonController.cache.add(status: status) completion?(status) session.complete(with: .success, additionalData: [ "statusURL": status.url?.absoluteString, "statusURI": status.uri - ]) + ]) } else if case let .failure(error) = response { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) } } } @@ -271,7 +269,7 @@ struct XCBActions { "url": account.url.absoluteString, "avatarURL": account.avatar.absoluteString, "headerURL": account.header.absoluteString - ]) + ]) } } @@ -286,22 +284,21 @@ struct XCBActions { "url": account.url.absoluteString, "avatarURL": account.avatar.absoluteString, "headerURL": account.header.absoluteString - ]) + ]) } static func followUser(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { func performAction(_ account: Account) { let request = Account.follow(account.id) mastodonController.run(request) { (response) in - if case let .success(relationship, _) = response { - mastodonController.cache.add(relationship: relationship) + if case .success(_, _) = response { session.complete(with: .success, additionalData: [ "url": account.url.absoluteString - ]) + ]) } else if case let .failure(error) = response { session.complete(with: .error, additionalData: [ "error": error.localizedDescription - ]) + ]) } } }