Skip to content

Instantly share code, notes, and snippets.

@kenechiokolo
Last active April 24, 2017 17:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenechiokolo/d10cbbe351b3580e9dc14eaf13498fa1 to your computer and use it in GitHub Desktop.
Save kenechiokolo/d10cbbe351b3580e9dc14eaf13498fa1 to your computer and use it in GitHub Desktop.
APISearchControllerTutorial using delegation instead of KVO
//
// RequestManager.swift
// APISearchControllerTutorial
//
// Created by Kc on 24/03/2016.
// Copyright © 2016 Kenechi Okolo. All rights reserved.
//
import Foundation
import Alamofire
import SwiftyJSON
protocol RequestManagerSearchResultsDelegate: class {
func updateSearchResults(sender: RequestManager)
}
class RequestManager {
weak var delegate: RequestManagerSearchResultsDelegate?
var searchResults = [JSON]()
var pageString: String {
if pageNumber == 1 {
return ""
} else {
return "page=\(pageNumber)&"
}
}
var pageNumber = 1
var hasMore = false
func search(searchText: String) {
let url = "https://api.stackexchange.com/2.2/search?\(pageString)order=desc&sort=activity&tagged=\(searchText)&site=stackoverflow"
print(url)
Alamofire.request(.GET, url).responseJSON { [unowned self] response in
if let results = response.result.value as? [String:AnyObject] {
print("Results: \(results)")
let items = JSON(results["items"]!).arrayValue
self.hasMore = JSON(results["has_more"]!).boolValue
self.searchResults += items
if self.delegate != nil {
self.delegate?.updateSearchResults(self)
}
// NSNotificationCenter.defaultCenter().postNotificationName("searchResultsUpdated", object: nil)
}
}
}
func getNextPage(searchText: String) {
pageNumber += 1
search(searchText)
}
func resetSearch() {
searchResults = []
}
}
//
// SearchResultsTableViewController.swift
//
//
// Created by Kc on 24/03/2016.
//
//
import UIKit
import SwiftyJSON
class SearchResultsTableViewController: UITableViewController, RequestManagerSearchResultsDelegate {
let requestManager = RequestManager()
let searchController = UISearchController(searchResultsController: nil)
var searchResults: [JSON] {
return requestManager.searchResults
}
var validatedText: String {
return searchController.searchBar.text!.stringByReplacingOccurrencesOfString(" ", withString: "").lowercaseString
}
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchBar.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Enter tag..."
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
requestManager.delegate = self
// NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SearchResultsTableViewController.updateSearchResults), name: "searchResultsUpdated", object: nil)
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
func updateSearchResults(sender: RequestManager) {
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return searchResults.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("itemCell", forIndexPath: indexPath)
cell.textLabel?.text = searchResults[indexPath.row]["owner"]["display_name"].stringValue
cell.detailTextLabel?.text = searchResults[indexPath.row]["title"].stringValue
if indexPath.row == searchResults.count - 10 {
if requestManager.hasMore {
requestManager.getNextPage(validatedText)
}
}
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
// deinit {
// NSNotificationCenter.defaultCenter().removeObserver(self)
// }
}
extension SearchResultsTableViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
requestManager.resetSearch()
// updateSearchResults()
tableView.reloadData()
requestManager.search(validatedText)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment