In Siesta’s view of the world, one url ⟺ one resource. There is thus a “summary list” resource, /entity
, plus a separate “entity detail” resource for each row, /entity/1
etc. It doesn’t matter that they happen to share some of the same data; Siesta itself doesn’t make any effort to merge, synchronize, prepopulate one resource from the other. Separate URLs, separate resources.
The rule of thumb is, “If you need data from a resource, observe that resource.” Since you want to use both summary info from /entities
and detail info from /entities/n
, you observe both resources.
Here is a sketch of an approach you might use:
- Get your table view showing just the info from
/entities
, no avatars. You can use RepositoryListViewController from the example project as a starting point.
Make each table cell accept a summary model, and observe its corresponding detail resource:
class EntityTableViewCell: UITableViewCell, ResourceObserver {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var avatar: RemoteImageView!
private var summary: EntitySummary?
private var detailResource: Resource?
func showEntity(summary: EntitySummary) {
self.summary = summary
detailResource?.removeObservers(ownedBy: self)
detailResource = MyApi.resource(absoluteURL: summary?.url)
detailResource.addObserver(self).loadIfNeeded()
}
Now populate the cell in resourceChanged()
, mixing and matching from the summary and detail as you see fit:
func resourceChanged(resource: Resource, event: ResourceEvent) {
let detail: EntityDetail? = detailResource?.typedContent()
nameLabel.text = detail?.name ?? summary?.name
avatar.imageURL = detail?.avatar
}
You might also want to stop observing when the cell moves out of view:
override func prepareForReuse() {
showEntity(nil)
}
}
(This sketch assumes that you have separate EntitySummary
and EntityDetail
models. You might also have a single Entity
model with the detail-only fields optional, or you might just be using raw JSON dictionaries. The approach is the same regardless.)
Here’s what happens when a cell scrolls into view:
- Your
cellForRowAtIndexPath
calls showEntity(_:)
, passing an EntitySummary
it got from the /entities
resource.
- The cell starts observing
/entities/n
.
- This immediate triggers
resourceChanged()
. The detail resource has no data yet, so your cell immediately gets populated with summary info only.
- Eventually the detail resource loads. If your cell is still observing it, then
resourceChanged()
gets called again, and this time it sees the detail info.
Note that in #4, if your cell got scrolled out of view and reused before that detail resource loaded, then your cell will no longer be observing it — and thus the late-arriving response will not clobber the reused cell’s contents.