在 Swift 中使用 Apollo 自动 UI 更新不工作

Automatic UI updates with Apollo in Swift not working

我有一个小型 Apollo iOS 应用程序的以下设置,我在 table 视图中显示 会议 的列表,并希望能够将 会议 添加到列表中:

GraphQL:

query AllConferences {
  allConferences {
    ...ConferenceDetails
  }
}

mutation CreateConference($name: String!, $city: String!, $year: String!) {
  createConference(name: $name, city: $city, year: $year) {
    ...ConferenceDetails
  }
}

fragment ConferenceDetails on Conference {
  id
  name
  city
  year
  attendees {
    ...AttendeeDetails
  }
}

fragment AttendeeDetails on Attendee {
  id
  name
  conferences {
    id
  }
}

ConferencesTableViewController:

class ConferencesTableViewController: UITableViewController {

  var allConferencesWatcher: GraphQLQueryWatcher<AllConferencesQuery>?

  var conferences: [ConferenceDetails] = [] {
    didSet {
      tableView.reloadData()
    }
  }

  deinit {
    allConferencesWatcher?.cancel()
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    allConferencesWatcher = apollo.watch(query: AllConferencesQuery()) { result, error in
      print("Updating conferences: ", result?.data?.allConferences)
      guard let conferences = result?.data?.allConferences else {
        return
      }
      self.conferences = conferences.map { [=13=].fragments.conferenceDetails }
    }
  }

  // ...
  // standard implementation of UITableViewDelegate
  // ...

}

AddConferenceViewController:

class AddConferenceViewController: UIViewController {

  // ... IBOutlets

  @IBAction func saveButtonPressed() {
    let name = nameTextField.text!
    let city = cityTextField.text!
    let year = yearTextField.text!

    apollo.perform(mutation: CreateConferenceMutation(name: name, city: city, year: year)) { result, error in
      if let _ = result?.data?.createConference {
        self.presentingViewController?.dismiss(animated: true)
      }
    }

  }
}

我还在 AppDelegate 中实现了 cacheKeyForObject,如下所示:

apollo.cacheKeyForObject = { [=15=]["id"] }

我的问题是是否可以使用此设置从自动 UI 更新中获益?当前执行 CreateConferenceMutation 时,不会更新 table 视图。我是不是遗漏了什么,或者我是否达到了 docs 中提到的限制:

In some cases, just using cacheKeyFromObject is not enough for your application UI to update correctly. For example, if you want to add something to a list of objects without refetching the entire list, or if there are some objects that to which you can’t assign an object identifier, Apollo cannot automatically update existing queries for you.

这确实是自动 UI 更新的一个限制。虽然 Apollo 使用 cacheKeyFromObject 通过 ID 匹配 objects,并且涵盖了很多常见情况,但它无法自动更新 objects.

的列表

在您的架构中,Apollo 无法知道应将新添加的会议添加到 allConferences 列表中。它只知道 allConferences returns 会议列表 objects,但这些可以任意选择和排序。

所以在这种情况下,您将不得不自己从服务器重新获取查询,或者更改变异结果以包含更新后的列表。

另一种选择是手动将新会议添加到客户商店的列表中。为此,下一版本的 Apollo iOS 将在 Apollo JavaScript 客户端中包含一个类似于 updateQueries 的手动更新选项。