diff --git a/Pachyderm/Client.swift b/Pachyderm/Client.swift index a2fbf7fd..3fb9faf6 100644 --- a/Pachyderm/Client.swift +++ b/Pachyderm/Client.swift @@ -130,180 +130,155 @@ public class Client { } // MARK: - Self - public func getSelfAccount(completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/accounts/verify_credentials") - run(request, completion: completion) + public func getSelfAccount() -> Request { + return Request(method: .get, path: "/api/v1/accounts/verify_credentials") } - public func getFavourites(completion: @escaping Callback<[Status]>) { - let request = Request<[Status]>(method: .get, path: "/api/v1/favourites") - run(request, completion: completion) + public func getFavourites() -> Request<[Status]> { + return Request<[Status]>(method: .get, path: "/api/v1/favourites") } - public func getRelationships(accounts: [Account]? = nil, completion: @escaping Callback<[Relationship]>) { - let request = Request<[Relationship]>(method: .get, path: "/api/v1/accounts/relationships", queryParameters: "id" => accounts?.map { $0.id }) - run(request, completion: completion) + public func getRelationships(accounts: [Account]? = nil) -> Request<[Relationship]> { + return Request<[Relationship]>(method: .get, path: "/api/v1/accounts/relationships", queryParameters: "id" => accounts?.map { $0.id }) } - public func getInstance(completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/instance") - run(request, completion: completion) + public func getInstance() -> Request { + return Request(method: .get, path: "/api/v1/instance") } - public func getCustomEmoji(completion: @escaping Callback<[Emoji]>) { - let request = Request<[Emoji]>(method: .get, path: "/api/v1/custom_emojis") - run(request, completion: completion) + public func getCustomEmoji() -> Request<[Emoji]> { + return Request<[Emoji]>(method: .get, path: "/api/v1/custom_emojis") } // MARK: - Accounts - public func getAccount(id: String, completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/accounts/\(id)") - run(request, completion: completion) + public func getAccount(id: String) -> Request { + return Request(method: .get, path: "/api/v1/accounts/\(id)") } - public func searchForAccount(query: String, limit: Int? = nil, following: Bool? = nil, completion: @escaping Callback<[Account]>) { - let request = Request<[Account]>(method: .get, path: "/api/v1/accounts/search", queryParameters: [ + public func searchForAccount(query: String, limit: Int? = nil, following: Bool? = nil) -> Request<[Account]> { + return Request<[Account]>(method: .get, path: "/api/v1/accounts/search", queryParameters: [ "q" => query, "limit" => limit, "following" => following ]) - run(request, completion: completion) } // MARK: - Blocks - public func getBlocks(completion: @escaping Callback<[Account]>) { - let request = Request<[Account]>(method: .get, path: "/api/v1/blocks") - run(request, completion: completion) + public func getBlocks() -> Request<[Account]> { + return Request<[Account]>(method: .get, path: "/api/v1/blocks") } - public func getDomainBlocks(completion: @escaping Callback<[String]>) { - let request = Request<[String]>(method: .get, path: "api/v1/domain_blocks") - run(request, completion: completion) + public func getDomainBlocks() -> Request<[String]> { + return Request<[String]>(method: .get, path: "api/v1/domain_blocks") } - public func block(domain: String, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/domain_blocks", body: .parameters([ + public func block(domain: String) -> Request { + return Request(method: .post, path: "/api/v1/domain_blocks", body: .parameters([ "domain" => domain ])) - run(request, completion: completion) } - public func unblock(domain: String, completion: @escaping Callback) { - let request = Request(method: .delete, path: "/api/v1/domain_blocks", body: .parameters([ + public func unblock(domain: String) -> Request { + return Request(method: .delete, path: "/api/v1/domain_blocks", body: .parameters([ "domain" => domain ])) - run(request, completion: completion) } // MARK: - Filters - public func getFilters(completion: @escaping Callback<[Filter]>) { - let request = Request<[Filter]>(method: .get, path: "/api/v1/filters") - run(request, completion: completion) + public func getFilters() -> Request<[Filter]> { + return Request<[Filter]>(method: .get, path: "/api/v1/filters") } - public func createFilter(phrase: String, context: [Filter.Context], irreversible: Bool? = nil, wholeWord: Bool? = nil, expiresAt: Date? = nil, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/filters", body: .parameters([ + public func createFilter(phrase: String, context: [Filter.Context], irreversible: Bool? = nil, wholeWord: Bool? = nil, expiresAt: Date? = nil) -> Request { + return Request(method: .post, path: "/api/v1/filters", body: .parameters([ "phrase" => phrase, "irreversible" => irreversible, "whole_word" => wholeWord, "expires_at" => expiresAt ] + "context" => context.contextStrings)) - run(request, completion: completion) } - public func getFilter(id: String, completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/filters/\(id)") - run(request, completion: completion) + public func getFilter(id: String) -> Request { + return Request(method: .get, path: "/api/v1/filters/\(id)") } // MARK: - Follows - public func getFollowRequests(range: RequestRange = .default, completion: @escaping Callback<[Account]>) { + public func getFollowRequests(range: RequestRange = .default) -> Request<[Account]> { var request = Request<[Account]>(method: .get, path: "/api/v1/follow_requests") request.range = range - run(request, completion: completion) + return request } - public func getFollowSuggestions(completion: @escaping Callback<[Account]>) { - let request = Request<[Account]>(method: .get, path: "/api/v1/suggestions") - run(request, completion: completion) + public func getFollowSuggestions() -> Request<[Account]> { + return Request<[Account]>(method: .get, path: "/api/v1/suggestions") } - public func followRemote(acct: String, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/follows", body: .parameters(["uri" => acct])) - run(request, completion: completion) + public func followRemote(acct: String) -> Request { + return Request(method: .post, path: "/api/v1/follows", body: .parameters(["uri" => acct])) } // MARK: - Lists - public func getLists(completion: @escaping Callback<[List]>) { - let request = Request<[List]>(method: .get, path: "/api/v1/lists") - run(request, completion: completion) + public func getLists() -> Request<[List]> { + return Request<[List]>(method: .get, path: "/api/v1/lists") } - public func getList(id: String, completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/lists/\(id)") - run(request, completion: completion) + public func getList(id: String) -> Request { + return Request(method: .get, path: "/api/v1/lists/\(id)") } - public func createList(title: String, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/lists", body: .parameters(["title" => title])) - run(request, completion: completion) + public func createList(title: String) -> Request { + return Request(method: .post, path: "/api/v1/lists", body: .parameters(["title" => title])) } // MARK: - Media - public func upload(attachment: FormAttachment, description: String? = nil, focus: (Float, Float)? = nil, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/media", body: .formData([ + public func upload(attachment: FormAttachment, description: String? = nil, focus: (Float, Float)? = nil) -> Request { + return Request(method: .post, path: "/api/v1/media", body: .formData([ "description" => description, "focus" => focus ], attachment)) - run(request, completion: completion) } // MARK: - Mutes - public func getMutes(range: RequestRange, completion: @escaping Callback<[Account]>) { + public func getMutes(range: RequestRange) -> Request<[Account]> { var request = Request<[Account]>(method: .get, path: "/api/v1/mutes") request.range = range - run(request, completion: completion) + return request } // MARK: - Notifications - public func getNotifications(range: RequestRange = .default, completion: @escaping Callback<[Notification]>) { + public func getNotifications(range: RequestRange = .default) -> Request<[Notification]> { var request = Request<[Notification]>(method: .get, path: "/api/v1/notifications") request.range = range - run(request, completion: completion) + return request } - public func clearNotifications(completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/notifications/clear") - run(request, completion: completion) + public func clearNotifications() -> Request { + return Request(method: .post, path: "/api/v1/notifications/clear") } // MARK: - Reports - public func getReports(completion: @escaping Callback<[Report]>) { - let request = Request<[Report]>(method: .get, path: "/api/v1/reports") - run(request, completion: completion) + public func getReports() -> Request<[Report]> { + return Request<[Report]>(method: .get, path: "/api/v1/reports") } - public func report(account: Account, statuses: [Status], comment: String, completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/reports", body: .parameters([ + public func report(account: Account, statuses: [Status], comment: String) -> Request { + return Request(method: .post, path: "/api/v1/reports", body: .parameters([ "account_id" => account.id, "comment" => comment ] + "status_ids" => statuses.map { $0.id })) - run(request, completion: completion) } // MARK: - Search - public func search(query: String, resolve: Bool? = nil, completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v2/search", queryParameters: [ + public func search(query: String, resolve: Bool? = nil) -> Request { + return Request(method: .get, path: "/api/v2/search", queryParameters: [ "q" => query, "resolve" => resolve ]) - run(request, completion: completion) } // MARK: - Statuses - public func getStatus(id: String, completion: @escaping Callback) { - let request = Request(method: .get, path: "/api/v1/statuses/\(id)") - run(request, completion: completion) + public func getStatus(id: String) -> Request { + return Request(method: .get, path: "/api/v1/statuses/\(id)") } public func createStatus(text: String, @@ -312,9 +287,8 @@ public class Client { sensitive: Bool? = nil, spoilerText: String? = nil, visiblity: Status.Visibility? = nil, - language: String? = nil, - completion: @escaping Callback) { - let request = Request(method: .post, path: "/api/v1/statuses", body: .parameters([ + language: String? = nil) -> Request { + return Request(method: .post, path: "/api/v1/statuses", body: .parameters([ "status" => text, "in_reply_to_id" => inReplyTo?.id, "sensitive" => sensitive, @@ -322,13 +296,11 @@ public class Client { "visibility" => visiblity?.rawValue, "language" => language ] + "media_ids" => media?.map { $0.id })) - run(request, completion: completion) } // MARK: - Timelines - public func getStatuses(timeline: Timeline, range: RequestRange = .default, completion: @escaping Callback<[Status]>) { - let request = timeline.request(range: range) - run(request, completion: completion) + public func getStatuses(timeline: Timeline, range: RequestRange = .default) -> Request<[Status]> { + return timeline.request(range: range) } } diff --git a/Tusker/Controllers/MastodonController.swift b/Tusker/Controllers/MastodonController.swift index 1987c998..65a261d0 100644 --- a/Tusker/Controllers/MastodonController.swift +++ b/Tusker/Controllers/MastodonController.swift @@ -54,7 +54,8 @@ class MastodonController { } func getOwnAccount() { - client.getSelfAccount { response in + let request = client.getSelfAccount() + client.run(request) { response in guard case let .success(account, _) = response else { fatalError() } self.account = account } diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index 6839ca73..6aafef59 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -203,7 +203,8 @@ class ComposeViewController: UIViewController { attachments.append(nil) progressView.steps += 1 group.enter() - MastodonController.shared.client.upload(attachment: FormAttachment(pngData: data), description: mediaView.mediaDescription) { response in + let request = MastodonController.shared.client.upload(attachment: FormAttachment(pngData: data), description: mediaView.mediaDescription) + MastodonController.shared.client.run(request) { response in guard case let .success(attachment, _) = response else { fatalError() } attachments[index] = attachment self.progressView.step() @@ -217,12 +218,13 @@ class ComposeViewController: UIViewController { group.notify(queue: .main) { let attachments = attachments.compactMap { $0 } - MastodonController.shared.client.createStatus(text: text, - inReplyTo: self.inReplyTo, - media: attachments, - sensitive: sensitive, - spoilerText: contentWarning, - visiblity: visibility) { response in + let request = MastodonController.shared.client.createStatus(text: text, + inReplyTo: self.inReplyTo, + media: attachments, + sensitive: sensitive, + spoilerText: contentWarning, + visiblity: visibility) + MastodonController.shared.client.run(request) { response in guard case let .success(status, _) = response else { fatalError() } self.status = status DispatchQueue.main.async { diff --git a/Tusker/Screens/Notifications/NotificationsTableViewController.swift b/Tusker/Screens/Notifications/NotificationsTableViewController.swift index ef6b3d4d..adc8d652 100644 --- a/Tusker/Screens/Notifications/NotificationsTableViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsTableViewController.swift @@ -43,7 +43,8 @@ class NotificationsTableViewController: UITableViewController { tableView.register(UINib(nibName: "ActionNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "actionCell") tableView.register(UINib(nibName: "FollowNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "followCell") - MastodonController.shared.client.getNotifications() { result in + let request = MastodonController.shared.client.getNotifications() + MastodonController.shared.client.run(request) { result in guard case let .success(notifications, pagination) = result else { fatalError() } self.notifications = notifications self.newer = pagination?.newer @@ -110,7 +111,8 @@ class NotificationsTableViewController: UITableViewController { if indexPath.row == notifications.count - 1 { guard let older = older else { return } - MastodonController.shared.client.getNotifications(range: older) { result in + let request = MastodonController.shared.client.getNotifications(range: older) + MastodonController.shared.client.run(request) { result in guard case let .success(newNotifications, pagination) = result else { fatalError() } self.older = pagination?.older self.notifications.append(contentsOf: newNotifications) @@ -133,7 +135,8 @@ class NotificationsTableViewController: UITableViewController { @IBAction func refreshNotifications(_ sender: Any) { guard let newer = newer else { return } - MastodonController.shared.client.getNotifications(range: newer) { result in + let request = MastodonController.shared.client.getNotifications(range: newer) + MastodonController.shared.client.run(request) { result in guard case let .success(newNotifications, pagination) = result else { fatalError() } self.newer = pagination?.newer self.notifications.insert(contentsOf: newNotifications, at: 0) diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 792e844e..815b99e8 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -70,7 +70,8 @@ class TimelineTableViewController: UITableViewController { tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") guard MastodonController.shared.client?.accessToken != nil else { return } - MastodonController.shared.client.getStatuses(timeline: timeline) { response in + let request = MastodonController.shared.client.getStatuses(timeline: timeline) + MastodonController.shared.client.run(request) { response in guard case let .success(statuses, pagination) = response else { fatalError() } self.statuses = statuses self.newer = pagination?.newer @@ -125,7 +126,8 @@ class TimelineTableViewController: UITableViewController { if indexPath.row == statuses.count - 1 { guard let older = older else { return } - MastodonController.shared.client.getStatuses(timeline: timeline, range: older) { response in + let request = MastodonController.shared.client.getStatuses(timeline: timeline, range: older) + MastodonController.shared.client.run(request) { response in guard case let .success(newStatuses, pagination) = response else { fatalError() } self.older = pagination?.older self.statuses.append(contentsOf: newStatuses) @@ -148,7 +150,8 @@ class TimelineTableViewController: UITableViewController { @IBAction func refreshStatuses(_ sender: Any) { guard let newer = newer else { return } - MastodonController.shared.client.getStatuses(timeline: timeline, range: newer) { response in + let request = MastodonController.shared.client.getStatuses(timeline: timeline, range: newer) + MastodonController.shared.client.run(request) { response in guard case let .success(newStatuses, pagination) = response else { fatalError() } self.newer = pagination?.newer self.statuses.insert(contentsOf: newStatuses, at: 0)