72 lines
2.3 KiB
Swift
72 lines
2.3 KiB
Swift
//
|
|
// FetchableTrait.swift
|
|
// Dip
|
|
//
|
|
// Created by Olivier Halligon on 09/10/2015.
|
|
// Copyright © 2015 AliSoftware. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
protocol FetchableTrait: AnyObject {
|
|
associatedtype ObjectType
|
|
var objects: [ObjectType]? { get set }
|
|
var batchRequestID: Int { get set }
|
|
var tableView: UITableView! { get }
|
|
|
|
func fetchIDs(completion: @escaping ([Int]) -> Void)
|
|
func fetchOne(id: Int, completion: @escaping (ObjectType?) -> Void)
|
|
var fetchProgress: (current: Int, total: Int?) { get set }
|
|
}
|
|
|
|
extension FetchableTrait {
|
|
func loadObjects(objectIDs: [Int]) {
|
|
self.batchRequestID += 1
|
|
let batch = self.batchRequestID
|
|
|
|
objects?.removeAll()
|
|
fetchProgress = (0,objectIDs.count)
|
|
for objectID in objectIDs {
|
|
fetchOne(id: objectID) { (object: ObjectType?) in
|
|
// Exit if we failed to retrive an object for this ID, or if the request
|
|
// should be ignored because a new batch request has been started since
|
|
guard let object = object, batch == self.batchRequestID else { return }
|
|
|
|
if self.objects == nil { self.objects = [] }
|
|
self.objects?.append(object)
|
|
self.fetchProgress.current = self.objects?.count ?? 0
|
|
self.tableView?.reloadData()
|
|
}
|
|
}
|
|
}
|
|
|
|
func loadFirstPage() {
|
|
self.batchRequestID += 1
|
|
let batch = self.batchRequestID
|
|
fetchProgress = (0, nil)
|
|
fetchIDs() { objectIDs in
|
|
guard batch == self.batchRequestID else { return }
|
|
self.loadObjects(objectIDs: objectIDs)
|
|
}
|
|
}
|
|
|
|
func displayProgressInNavBar(navigationItem: UINavigationItem) {
|
|
let text: String
|
|
if let total = fetchProgress.total {
|
|
if fetchProgress.current == fetchProgress.total {
|
|
text = "Done."
|
|
} else {
|
|
text = "Loading \(fetchProgress.current) / \(total)…"
|
|
}
|
|
} else {
|
|
text = "Loading IDs…"
|
|
}
|
|
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
|
|
label.text = text
|
|
label.textColor = .gray
|
|
label.font = UIFont.systemFont(ofSize: 12)
|
|
label.sizeToFit()
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: label)
|
|
}
|
|
}
|