diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index a25f75de..48390e0f 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -17,9 +17,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Override point for customization after application launch. if LocalData.shared.onboardingComplete { - MastodonController.shared.createClient() - MastodonController.shared.getOwnAccount() - MastodonController.shared.getOwnInstance() + MastodonController.createClient() + MastodonController.getOwnAccount() + MastodonController.getOwnInstance() } else { showOnboarding() } diff --git a/Tusker/Controllers/MastodonController.swift b/Tusker/Controllers/MastodonController.swift index 5cf7c0d8..f74141a4 100644 --- a/Tusker/Controllers/MastodonController.swift +++ b/Tusker/Controllers/MastodonController.swift @@ -11,17 +11,14 @@ import Pachyderm class MastodonController { - static let shared = MastodonController() + static var client: Client! - var client: Client! + static var account: Account! + static var instance: Instance! - var account: Account! - var instance: Instance! + private init() {} - private init() { - } - - func createClient() { + static func createClient() { guard let url = LocalData.shared.instanceURL else { fatalError("Can't connect without instance URL") } client = Client(baseURL: url) @@ -31,7 +28,7 @@ class MastodonController { client.accessToken = LocalData.shared.accessToken } - func registerApp(completion: @escaping () -> Void) { + static func registerApp(completion: @escaping () -> Void) { guard LocalData.shared.clientID == nil, LocalData.shared.clientSecret == nil else { completion() @@ -46,7 +43,7 @@ class MastodonController { } } - func authorize(authorizationCode: String, completion: @escaping () -> Void) { + static func authorize(authorizationCode: String, completion: @escaping () -> Void) { client.getAccessToken(authorizationCode: authorizationCode, redirectURI: "tusker://oauth") { response in guard case let .success(settings, _) = response else { fatalError() } LocalData.shared.accessToken = settings.accessToken @@ -54,7 +51,7 @@ class MastodonController { } } - func getOwnAccount(completion: ((Account) -> Void)? = nil) { + static func getOwnAccount(completion: ((Account) -> Void)? = nil) { if account != nil { completion?(account) } else { @@ -67,7 +64,7 @@ class MastodonController { } } - func getOwnInstance() { + static func getOwnInstance() { let request = client.getInstance() client.run(request) { (response) in guard case let .success(instance, _) = response else { fatalError() } diff --git a/Tusker/MastodonCache.swift b/Tusker/MastodonCache.swift index c7afafab..1567e7e7 100644 --- a/Tusker/MastodonCache.swift +++ b/Tusker/MastodonCache.swift @@ -32,8 +32,8 @@ class MastodonCache { } static func status(for id: String, completion: @escaping (Status?) -> Void) { - let request = MastodonController.shared.client.getStatus(id: id) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.getStatus(id: id) + MastodonController.client.run(request) { response in guard case let .success(status, _) = response else { completion(nil) return @@ -61,8 +61,8 @@ class MastodonCache { } static func account(for id: String, completion: @escaping (Account?) -> Void) { - let request = MastodonController.shared.client.getAccount(id: id) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.getAccount(id: id) + MastodonController.client.run(request) { response in guard case let .success(account, _) = response else { completion(nil) return @@ -90,8 +90,8 @@ class MastodonCache { } static func relationship(for id: String, completion: @escaping (Relationship?) -> Void) { - let request = MastodonController.shared.client.getRelationships(accounts: [id]) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.getRelationships(accounts: [id]) + MastodonController.client.run(request) { response in guard case let .success(relationships, _) = response, let relationship = relationships.first else { completion(nil) diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index 0a8a5b06..14194cf9 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -98,10 +98,10 @@ class ComposeViewController: UIViewController { } } inReplyToLabel.text = "In reply to \(inReplyTo.account.realDisplayName)" - if inReplyTo.account != MastodonController.shared.account { + if inReplyTo.account != MastodonController.account { statusTextView.text = "@\(inReplyTo.account.acct) " } - statusTextView.text += inReplyTo.mentions.filter({ $0.id != MastodonController.shared.account.id }).map({ "@\($0.acct) " }).joined() + statusTextView.text += inReplyTo.mentions.filter({ $0.id != MastodonController.account.id }).map({ "@\($0.acct) " }).joined() contentWarning = inReplyTo.sensitive contentWarningTextField.text = inReplyTo.spoilerText visibility = inReplyTo.visibility @@ -138,7 +138,7 @@ class ComposeViewController: UIViewController { func updateCharactersRemaining() { let count = CharacterCounter.count(text: statusTextView.text) - let remaining = (MastodonController.shared.instance.maxStatusCharacters ?? 500) - count + let remaining = (MastodonController.instance.maxStatusCharacters ?? 500) - count if remaining < 0 { charactersRemainingLabel.textColor = .red postButton.isEnabled = false @@ -243,8 +243,8 @@ class ComposeViewController: UIViewController { attachments.append(nil) progressView.steps += 1 group.enter() - let request = MastodonController.shared.client.upload(attachment: FormAttachment(pngData: data), description: mediaView.mediaDescription) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.upload(attachment: FormAttachment(pngData: data), description: mediaView.mediaDescription) + MastodonController.client.run(request) { response in guard case let .success(attachment, _) = response else { fatalError() } attachments[index] = attachment self.progressView.step() @@ -258,13 +258,13 @@ class ComposeViewController: UIViewController { group.notify(queue: .main) { let attachments = attachments.compactMap { $0 } - let request = MastodonController.shared.client.createStatus(text: text, + let request = MastodonController.client.createStatus(text: text, inReplyTo: self.inReplyToID, media: attachments, sensitive: sensitive, spoilerText: contentWarning, visibility: visibility) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in guard case let .success(status, _) = response else { fatalError() } self.status = status MastodonCache.add(status: status) diff --git a/Tusker/Screens/Conversation/ConversationViewController.swift b/Tusker/Screens/Conversation/ConversationViewController.swift index d6446743..8c2684b6 100644 --- a/Tusker/Screens/Conversation/ConversationViewController.swift +++ b/Tusker/Screens/Conversation/ConversationViewController.swift @@ -43,7 +43,7 @@ class ConversationViewController: UIViewController, UITableViewDataSource, UITab guard let mainStatus = MastodonCache.status(for: mainStatusID) else { fatalError("Missing cached status \(mainStatusID!)") } let request = Status.getContext(mainStatus) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in guard case let .success(context, _) = response else { fatalError() } let parents = self.getDirectParents(of: mainStatus, from: context.ancestors) MastodonCache.addAll(statuses: parents) diff --git a/Tusker/Screens/Main/MainTabBarViewController.swift b/Tusker/Screens/Main/MainTabBarViewController.swift index a9170241..8c12b4c3 100644 --- a/Tusker/Screens/Main/MainTabBarViewController.swift +++ b/Tusker/Screens/Main/MainTabBarViewController.swift @@ -35,7 +35,7 @@ class MainTabBarViewController: UITabBarController { preferences ] - MastodonController.shared.getOwnAccount { (account) in + MastodonController.getOwnAccount { (account) in ownProfile.accountID = account.id } } diff --git a/Tusker/Screens/Notifications/NotificationsTableViewController.swift b/Tusker/Screens/Notifications/NotificationsTableViewController.swift index 96ee9764..56511a47 100644 --- a/Tusker/Screens/Notifications/NotificationsTableViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsTableViewController.swift @@ -43,8 +43,8 @@ class NotificationsTableViewController: UITableViewController { tableView.register(UINib(nibName: "ActionNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "actionCell") tableView.register(UINib(nibName: "FollowNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "followCell") - let request = MastodonController.shared.client.getNotifications() - MastodonController.shared.client.run(request) { result in + let request = MastodonController.client.getNotifications() + MastodonController.client.run(request) { result in guard case let .success(notifications, pagination) = result else { fatalError() } self.notifications = notifications MastodonCache.addAll(statuses: notifications.compactMap { $0.status }) @@ -112,8 +112,8 @@ class NotificationsTableViewController: UITableViewController { if indexPath.row == notifications.count - 1 { guard let older = older else { return } - let request = MastodonController.shared.client.getNotifications(range: older) - MastodonController.shared.client.run(request) { result in + let request = MastodonController.client.getNotifications(range: older) + MastodonController.client.run(request) { result in guard case let .success(newNotifications, pagination) = result else { fatalError() } self.older = pagination?.older self.notifications.append(contentsOf: newNotifications) @@ -136,8 +136,8 @@ class NotificationsTableViewController: UITableViewController { @IBAction func refreshNotifications(_ sender: Any) { guard let newer = newer else { return } - let request = MastodonController.shared.client.getNotifications(range: newer) - MastodonController.shared.client.run(request) { result in + let request = MastodonController.client.getNotifications(range: newer) + MastodonController.client.run(request) { result in guard case let .success(newNotifications, pagination) = result else { fatalError() } self.newer = pagination?.newer MastodonCache.addAll(statuses: newNotifications.compactMap { $0.status }) diff --git a/Tusker/Screens/Onboarding/OnboardingViewController.swift b/Tusker/Screens/Onboarding/OnboardingViewController.swift index 292daeae..67bcb45f 100644 --- a/Tusker/Screens/Onboarding/OnboardingViewController.swift +++ b/Tusker/Screens/Onboarding/OnboardingViewController.swift @@ -33,8 +33,8 @@ class OnboardingViewController: UIViewController { var components = URLComponents(string: text) else { return } LocalData.shared.instanceURL = url - MastodonController.shared.createClient() - MastodonController.shared.registerApp { + MastodonController.createClient() + MastodonController.registerApp { let clientID = LocalData.shared.clientID! let callbackURL = "tusker://oauth" @@ -55,7 +55,7 @@ class OnboardingViewController: UIViewController { let item = components.queryItems?.first(where: { $0.name == "code" }), let authCode = item.value else { fatalError() } - MastodonController.shared.authorize(authorizationCode: authCode) { + MastodonController.authorize(authorizationCode: authCode) { DispatchQueue.main.async { self.delegate?.didFinishOnboarding() } diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index e2504518..1c3364e3 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -120,7 +120,7 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive { func getStatuses(for range: RequestRange = .default, completion: @escaping Client.Callback<[Status]>) { let request = Account.getStatuses(accountID, range: range, onlyMedia: false, pinned: false, excludeReplies: !Preferences.shared.showRepliesInProfiles) - MastodonController.shared.client.run(request, completion: completion) + MastodonController.client.run(request, completion: completion) } func sendMessageMentioning() { @@ -251,7 +251,7 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate { alert.addAction(UIAlertAction(title: title, style: .default, handler: { (_) in UIImpactFeedbackGenerator(style: .medium).impactOccurred() let request = (relationship.following ? Account.unfollow : Account.follow)(account.id) - MastodonController.shared.client.run(request, completion: { (response) in + MastodonController.client.run(request, completion: { (response) in if case let .success(relationship, _) = response { MastodonCache.add(relationship: relationship) } else { diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 0f631cf0..fd1e9880 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -67,9 +67,9 @@ class TimelineTableViewController: UITableViewController { tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") - guard MastodonController.shared.client?.accessToken != nil else { return } - let request = MastodonController.shared.client.getStatuses(timeline: timeline) - MastodonController.shared.client.run(request) { response in + guard MastodonController.client?.accessToken != nil else { return } + let request = MastodonController.client.getStatuses(timeline: timeline) + MastodonController.client.run(request) { response in guard case let .success(statuses, pagination) = response else { fatalError() } self.statusIDs = statuses.map { $0.id } MastodonCache.addAll(statuses: statuses) @@ -125,8 +125,8 @@ class TimelineTableViewController: UITableViewController { if indexPath.row == statusIDs.count - 1 { guard let older = older else { return } - let request = MastodonController.shared.client.getStatuses(timeline: timeline, range: older) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.getStatuses(timeline: timeline, range: older) + MastodonController.client.run(request) { response in guard case let .success(newStatuses, pagination) = response else { fatalError() } self.older = pagination?.older MastodonCache.addAll(statuses: newStatuses) @@ -150,8 +150,8 @@ class TimelineTableViewController: UITableViewController { @IBAction func refreshStatuses(_ sender: Any) { guard let newer = newer else { return } - let request = MastodonController.shared.client.getStatuses(timeline: timeline, range: newer) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.getStatuses(timeline: timeline, range: newer) + MastodonController.client.run(request) { response in guard case let .success(newStatuses, pagination) = response else { fatalError() } self.newer = pagination?.newer MastodonCache.addAll(statuses: newStatuses) diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 06db6f9c..3419939e 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -176,7 +176,7 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive let realStatus: Status = status.reblog ?? status let request = (favorited ? Status.favourite : Status.unfavourite)(realStatus) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in self.favorited = realStatus.favourited ?? false DispatchQueue.main.async { if case .success = response { @@ -199,7 +199,7 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive let realStatus: Status = status.reblog ?? status let request = (reblogged ? Status.reblog : Status.unreblog)(realStatus) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in self.reblogged = realStatus.reblogged ?? false DispatchQueue.main.async { if case .success = response { diff --git a/Tusker/Views/Status/StatusTableViewCell.swift b/Tusker/Views/Status/StatusTableViewCell.swift index 0a401336..7d6ff1c8 100644 --- a/Tusker/Views/Status/StatusTableViewCell.swift +++ b/Tusker/Views/Status/StatusTableViewCell.swift @@ -205,7 +205,7 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { let realStatus: Status = status.reblog ?? status let request = (favorited ? Status.favourite : Status.unfavourite)(realStatus) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in DispatchQueue.main.async { self.favorited = realStatus.favourited ?? false if case .success = response { @@ -230,7 +230,7 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { let realStatus: Status = status.reblog ?? status let request = (reblogged ? Status.reblog : Status.unreblog)(realStatus) - MastodonController.shared.client.run(request) { response in + MastodonController.client.run(request) { response in self.reblogged = realStatus.reblogged ?? false DispatchQueue.main.async { if case .success = response { @@ -284,7 +284,7 @@ extension StatusTableViewCell: TableViewSwipeActionProvider { favoriteColor = UIColor(displayP3Red: 1, green: 204/255, blue: 0, alpha: 1) } let favorite = UIContextualAction(style: .normal, title: favoriteTitle) { (action, view, completion) in - MastodonController.shared.client.run(favoriteRequest, completion: { response in + MastodonController.client.run(favoriteRequest, completion: { response in DispatchQueue.main.async { guard case let .success(status, _) = response else { completion(false) @@ -312,7 +312,7 @@ extension StatusTableViewCell: TableViewSwipeActionProvider { reblogColor = tintColor } let reblog = UIContextualAction(style: .normal, title: reblogTitle) { (action, view, completion) in - MastodonController.shared.client.run(reblogRequest, completion: { response in + MastodonController.client.run(reblogRequest, completion: { response in DispatchQueue.main.async { guard case let .success(status, _) = response else { completion(false) diff --git a/Tusker/XCallbackURL/XCBActions.swift b/Tusker/XCallbackURL/XCBActions.swift index 033c07c9..f80b63bf 100644 --- a/Tusker/XCallbackURL/XCBActions.swift +++ b/Tusker/XCallbackURL/XCBActions.swift @@ -35,8 +35,8 @@ struct XCBActions { } } } else if let searchQuery = request.arguments["statusURL"] { - let request = MastodonController.shared.client.search(query: searchQuery) - MastodonController.shared.client.run(request) { (response) in + let request = MastodonController.client.search(query: searchQuery) + MastodonController.client.run(request) { (response) in if case let .success(results, _) = response, let status = results.statuses.first { MastodonCache.add(status: status) @@ -66,8 +66,8 @@ struct XCBActions { } } } else if let searchQuery = request.arguments["accountURL"] { - let request = MastodonController.shared.client.search(query: searchQuery) - MastodonController.shared.client.run(request) { (response) in + let request = MastodonController.client.search(query: searchQuery) + MastodonController.client.run(request) { (response) in if case let .success(results, _) = response { if let account = results.accounts.first { MastodonCache.add(account: account) @@ -84,8 +84,8 @@ struct XCBActions { } } } else if let acct = request.arguments["acct"] { - let request = MastodonController.shared.client.searchForAccount(query: acct) - MastodonController.shared.client.run(request) { (response) in + let request = MastodonController.client.searchForAccount(query: acct) + MastodonController.client.run(request) { (response) in if case let .success(accounts, _) = response { if let account = accounts.first { MastodonCache.add(account: account) @@ -126,14 +126,14 @@ struct XCBActions { var status = "" if let mentioning = mentioning { status += mentioning } if let text = text { status += text } - guard CharacterCounter.count(text: status) <= MastodonController.shared.instance.maxStatusCharacters ?? 500 else { + guard CharacterCounter.count(text: status) <= MastodonController.instance.maxStatusCharacters ?? 500 else { session.complete(with: .error, additionalData: [ - "error": "Too many characters. Instance maximum is \(MastodonController.shared.instance.maxStatusCharacters ?? 500)" + "error": "Too many characters. Instance maximum is \(MastodonController.instance.maxStatusCharacters ?? 500)" ]) return } - let request = MastodonController.shared.client.createStatus(text: status, visibility: Preferences.shared.defaultPostVisibility) - MastodonController.shared.client.run(request) { response in + let request = MastodonController.client.createStatus(text: status, visibility: Preferences.shared.defaultPostVisibility) + MastodonController.client.run(request) { response in if case let .success(status, _) = response { session.complete(with: .success, additionalData: [ "statusURL": status.url?.absoluteString, @@ -191,7 +191,7 @@ struct XCBActions { static func statusAction(request: @escaping (Status) -> Request, alertTitle: String, _ url: XCBRequest, _ session: XCBSession, _ silent: Bool?) { func performAction(status: Status, completion: ((Status) -> Void)?) { - MastodonController.shared.client.run(request(status)) { (response) in + MastodonController.client.run(request(status)) { (response) in if case let .success(status, _) = response { MastodonCache.add(status: status) completion?(status) @@ -261,7 +261,7 @@ struct XCBActions { } static func getCurrentUser(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { - let account = MastodonController.shared.account! + let account = MastodonController.account! session.complete(with: .success, additionalData: [ "username": account.acct, "displayName": account.displayName, @@ -277,7 +277,7 @@ struct XCBActions { static func followUser(_ request: XCBRequest, _ session: XCBSession, _ silent: Bool?) { func performAction(_ account: Account) { let request = Account.follow(account.id) - MastodonController.shared.client.run(request) { (response) in + MastodonController.client.run(request) { (response) in if case let .success(relationship, _) = response { MastodonCache.add(relationship: relationship) session.complete(with: .success, additionalData: [