Im trying to create a GenericListController for my app.
I have a ProductListController that extend this generic controller which extends UIViewController. I have
Ill post some code i have archieved with help from user R menke and others. My goal is to have a GenericListProtocol that can handle UISearchBarDelegate, UITableViewDelegate and my getData method (which needs a type class to be able to correctly parse json.
import Foundation
import UIKit
protocol GenericListProtocol : UISearchBarDelegate, UITableViewDelegate{
typealias T : MyModel // MyModel is a model i use for getId, getDate...
var list : [T] { get set }
var filteredlist : [T] { get set }
var searchActive : Bool { get set }
func setData(tableView : UITableView, myList : [T])
func setData()
func getData(tableView : UITableView, objectType : T, var myList : [T])
func filterContentForSearchText(searchText: String)
}
extension GenericListProtocol {
func setData(atableView : UITableView, myList : [T]) {
print("reloading tableView data")
atableView.reloadData()
}
func getData(tableView : UITableView, objectType : T, var myList : [T]) {
let dao: GenericDao = GenericDao()
let view : UIView = UIView()
let c: CallListListener = CallListListener(view: view, loadingLabel: "loading", save: true, name: "ProductModel")
c.onSuccess = { (onSuccess: JsonMessageList) in
print("status " + onSuccess._meta!.status!) // this is from my ws
myList = onSuccess.records
self.setData(tableView, myList: myList)
}
c.onFinally = { (any: AnyObject) in
// tableView.stopPullToRefresh()
}
// my dao saves json list on NSUSER, so we check if its already downloaded
let savedList = c.getDefaultList()
if (savedList == nil) {
dao.getAll(c);
}
else {
myList = savedList!
print(String(myList.count))
self.setData(tableView, myList: myList)
}
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
print("searching")
self.filterContentForSearchText(searchText)
if(filteredlist.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.setData()
}
}
Although i was able to implement most UISearchBarDelegate, UITableViewDelegate methods, i still have to implement 2 of them on my default class:
import Foundation
import UIKit
import EVReflection
import AlamofireJsonToObjects
class ProductListController : GenericListController, GenericListProtocol {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var list : [ProductModel] = [ProductModel]()
var filteredlist : [ProductModel] = [ProductModel]()
var searchActive : Bool = false
override func setInit() {
self.searchBar.delegate = self
self.listName = "ProductModel"
self.setTableViewStyle(self.tableView, searchBar4 : self.searchBar)
getData(self.tableView, objectType: ProductModel(), myList: self.list)
}
// this method hasnt worked from extension, so i just pasted it here
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
self.filterContentForSearchText(searchText)
if(filteredlist.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.setData(self.tableView, myList: list)
}
// this method hasnt worked from extension, so i just pasted it here
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchActive {
return self.filteredlist.count
} else {
return self.list.count
}
}
// self.list = myList hasnt worked from extension, so i just pasted it here
func setData(atableView: UITableView, myList : [ProductModel]) {
print(String(myList.count))
self.list = myList
print(String(self.list.count))
self.tableView.reloadData()
}
// i decided to implement this method because of the tableView
func setData() {
self.tableView.reloadData()
}
// this method hasnt worked from extension, so i just pasted it here
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:GenericListCell = tableView.dequeueReusableCellWithIdentifier("cell") as! GenericListCell
var object : ProductModel
if searchActive {
object = filteredlist[indexPath.row]
} else {
object = list[indexPath.row]
}
cell.formatData(object.name!, subtitle: object.price ?? "valor", char: object.name!)
print("returning cell")
return cell
}
override func viewDidLoad() {
// searchFuckinBar.delegate = self
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func filterContentForSearchText(searchText: String) {
// Filter the array using the filter method
self.filteredlist = self.list.filter({( object: ProductModel) -> Bool in
// let categoryMatch = (scope == "All") || (object.category == scope)
let stringMatch = object.name!.lowercaseString.rangeOfString(searchText.lowercaseString)
return (stringMatch != nil)
})
}
func formatCell(cell : GenericListCell, object : ProductModel) {
cell.formatData(object.name!, subtitle: object.price ?? "valor", char: object.name!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
*GenericListController is just a UIViewController with some helper methods