From f841854c5f7e40a7248757098e6c7c530bbdddbe Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 21 Oct 2020 21:47:01 -0400 Subject: [PATCH] Fix crash logging into instances whose domain does not match the Instance uri field --- .../InstanceSelectorTableViewController.swift | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Tusker/Screens/Onboarding/InstanceSelectorTableViewController.swift b/Tusker/Screens/Onboarding/InstanceSelectorTableViewController.swift index 3dbb8993..726d04f2 100644 --- a/Tusker/Screens/Onboarding/InstanceSelectorTableViewController.swift +++ b/Tusker/Screens/Onboarding/InstanceSelectorTableViewController.swift @@ -57,7 +57,7 @@ class InstanceSelectorTableViewController: UITableViewController { dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in switch item { - case let .selected(instance): + case let .selected(_, instance): let cell = tableView.dequeueReusableCell(withIdentifier: instanceCell, for: indexPath) as! InstanceTableViewCell cell.updateUI(instance: instance) return cell @@ -113,8 +113,9 @@ class InstanceSelectorTableViewController: UITableViewController { private func updateSpecificInstance(domain: String) { let components = parseURLComponents(input: domain) + let url = components.url! - let client = Client(baseURL: components.url!) + let client = Client(baseURL: url) let request = Client.getInstance() client.run(request) { (response) in var snapshot = self.dataSource.snapshot() @@ -126,7 +127,7 @@ class InstanceSelectorTableViewController: UITableViewController { if !snapshot.sectionIdentifiers.contains(.selected) { snapshot.appendSections([.selected]) } - snapshot.appendItems([.selected(instance)], toSection: .selected) + snapshot.appendItems([.selected(url, instance)], toSection: .selected) DispatchQueue.main.async { self.dataSource.apply(snapshot) } @@ -168,10 +169,11 @@ class InstanceSelectorTableViewController: UITableViewController { return } switch item { - case let .selected(instance): - // we can't just turn the URI string from the API into a URL instance, because Mastodon only includes the domain in the "URI" - let components = parseURLComponents(input: instance.uri) - delegate.didSelectInstance(url: components.url!) + case let .selected(url, _): + // We can't rely on the URI reported by the instance API endpoint, because improperly configured instances may + // return a domain that they don't listen on. Instead, use the actual base URL that was used to make the /api/v1/instance + // request, since we know for certain that succeeded, otherwise this item wouldn't exist. + delegate.didSelectInstance(url: url) case let .recommended(instance): var components = URLComponents() components.scheme = "https" @@ -188,13 +190,13 @@ extension InstanceSelectorTableViewController { case recommendedInstances } enum Item: Equatable, Hashable { - case selected(Instance) + case selected(URL, Instance) case recommended(InstanceSelector.Instance) static func ==(lhs: Item, rhs: Item) -> Bool { - if case let .selected(instance) = lhs, - case let .selected(other) = rhs { - return instance.uri == other.uri + if case let .selected(url, instance) = lhs, + case let .selected(otherUrl, other) = rhs { + return url == otherUrl && instance.uri == other.uri } else if case let .recommended(instance) = lhs, case let .recommended(other) = rhs { return instance.domain == other.domain @@ -204,8 +206,9 @@ extension InstanceSelectorTableViewController { func hash(into hasher: inout Hasher) { switch self { - case let .selected(instance): + case let .selected(url, instance): hasher.combine(Section.selected) + hasher.combine(url) hasher.combine(instance.uri) case let .recommended(instance): hasher.combine(Section.recommendedInstances)