Fix crash logging into instances whose domain does not match the Instance uri field

This commit is contained in:
Shadowfacts 2020-10-21 21:47:01 -04:00
parent 1c871a12a1
commit f841854c5f
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 15 additions and 12 deletions

View File

@ -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)