Created
December 1, 2015 07:35
-
-
Save hsavit1/520ca852ca76c0f2209b to your computer and use it in GitHub Desktop.
Using generators with tableviews in swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol AsyncGeneratorType { | |
typealias Element | |
typealias Fetch | |
mutating func next(fetchNextBatch: Fetch, onFinish: ((Element) -> Void)?) | |
} | |
/// Generator is the class because struct is captured in asynchronous operations so offset won't update. | |
class PagingGenerator<T>: AsyncGeneratorType { | |
typealias Element = Array<T> | |
typealias Fetch = (offset: Int, limit: Int, completion: (result: Element) -> Void) -> Void | |
var offset:Int | |
let limit: Int | |
init(startOffset: Int = 0, limit: Int = 25) { | |
self.offset = startOffset | |
self.limit = limit | |
} | |
func next(fetchNextBatch: Fetch, onFinish: ((Element) -> Void)? = nil) { | |
fetchNextBatch(offset: offset, limit: limit) { [unowned self] (items) in | |
onFinish?(items) | |
self.offset += items.count | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ViewController: UIViewController { | |
@IBOutlet var tableView: UITableView! | |
private var paging = PagingGenerator<Contact>(startOffset: 0, limit: 25) | |
private var contacts = [Contact]() { | |
didSet { | |
tableView.reloadData() | |
} | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
paging.next(fetchNextBatch, onFinish: updateDataSource) // first page | |
} | |
} | |
//MARK: Paging | |
extension ViewController { | |
private func fetchNextBatch(offset: Int, limit: Int, completion: (Array<Contact>) -> Void) -> Void { | |
if let remotelyFetched = downloadGithubUsersPage(offset) { | |
completion(remotelyFetched) | |
} | |
} | |
private func updateDataSource(items: Array<Contact>) { | |
self.contacts += items | |
} | |
} | |
//MARK: UITableViewDataSource | |
extension ViewController: UITableViewDataSource { | |
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return contacts.count | |
} | |
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { | |
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil) | |
let contact = contacts[indexPath.row] | |
cell.textLabel?.text = "\(contact.firstName) \(contact.lastName)" | |
return cell | |
} | |
} | |
//MARK: UITableViewDelegate | |
extension ViewController: UITableViewDelegate { | |
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { | |
if indexPath.row == tableView.dataSource!.tableView(tableView, numberOfRowsInSection: indexPath.section) - 1 { | |
paging.next(fetchNextBatch, onFinish: updateDataSource) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment