使用Swift中的Apollo自动更新UI

时间:2017-03-11 16:04:49

标签: ios swift graphql apollo apollo-ios

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

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 { $0.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 = { $0["id"] }

我的问题是,是否可以通过此设置从自动UI更新中受益?目前,当执行CreateConferenceMutation时,表视图不会更新。我错过了什么,或者我是否达到docs中提到的限制:

  

在某些情况下,仅使用cacheKeyFromObject还不足以使应用程序UI正确更新。例如,如果要在不重新获取整个列表的情况下向对象列表添加内容,或者如果有一些对象无法为其分配对象标识符,则Apollo无法自动为您更新现有查询。

1 个答案:

答案 0 :(得分:4)

这确实是自动UI更新的限制。虽然Apollo使用cacheKeyFromObject来按ID匹配对象,但这涵盖了许多常见情况,但它无法自动更新对象列表。

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

因此,在这些情况下,您必须自己从服务器重新获取查询,或更改变异结果以包含更新的列表。

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