In the previous section we were only showing restaurants in Chicago. If you noticed, it was hardcoded in the URL itself and was not generic. In this section we will make the application more generic and allow the user to search data based on a parameter city.
Update restro_controller.rb
as follows:
class RestroController < UITableViewController def viewDidLoad super @restaurants = [] searchBar = UISearchBar.alloc.initWithFrame(CGRectMake(0, 0, self.tableView.frame.size.width, 0)) searchBar.delegate = self; searchBar.showsCancelButton = true; searchBar.sizeToFit view.tableHeaderView = searchBar view.dataSource = view.delegate = self searchBar.text = 'Chicago' searchBarSearchButtonClicked(searchBar) end def searchBarSearchButtonClicked(searchBar) query = searchBar.text.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) url = "http://restro.nalwaya.com/restaurants/search.json?city=#{query}" @restaurants.clear json = nil begin json = JSONParser.parse_from_url(url) rescue RuntimeError => e presentError e.message end @restaurants = [] json.each do |restaurant| @restaurants << Restaurant.new(restaurant) end view.reloadData searchBar.resignFirstResponder end def searchBarCancelButtonClicked(searchBar) searchBar.resignFirstResponder end def tableView(tableView, numberOfRowsInSection:section) @restaurants.count end def tableView(tableView, cellForRowAtIndexPath:indexPath) @reuseIdentifier ||= "CELL_IDENTIFIER" cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier) || begin UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:@reuseIdentifier) end cell.textLabel.text = @restaurants[indexPath.row].name cell end end
Start the simulator by the rake
command, and you can see that your toolbar is replaced with a search box with the default value Chicago.
The UISearchBar
class implements a text field control for text-based searches. The UISearchBar
object does not actually perform any search; it is just a view, which we can see on the device. To make the search work, we use a delegate, which is an object conforming to the UISearchBarDelegate
protocol, to implement the actions when text is entered and buttons are clicked. The UISearchBarDelegate
protocol defines the optional methods you implement to make a UISearchBar
control functional.
The UISearchBar
object provides the user interface for a search field on a bar, but it's the application's responsibility to implement the actions when buttons are tapped. We can implement this using various methods available, which are explained next.
The methods used for editing text are as follows:
searchBar:textDidChange
: This tells the delegate that the user changed the search textsearchBar:shouldChangeTextInRange:replacementText
: This asks the delegate if text in a specified range should be replaced with the given textsearchBarShouldBeginEditing
: This asks the delegate if editing should begin in the specified search barsearchBarTextDidBeginEditing
: This tells the delegate when the user begins editing the search textsearchBarShouldEndEditing
: This asks the delegate if editing should stop in the specified search barsearchBarTextDidEndEditing
: This tells the delegate that the user finished editing the search textThe methods used for different click events on various buttons in the search bar are as follows:
searchBarBookmarkButtonClicked
: This tells the delegate that the bookmark button was tappedsearchBarCancelButtonClicked
: This tells the delegate that the cancel button was tappedsearchBarSearchButtonClicked
: This tells the delegate that the search results list button was tappedsearchBarResultsListButtonClicked
: This tells the delegate that the search button was tappedThe method used for the scope button is as follows:
We have implemented searchBarSearchButtonClicked(searchBar)
, and whenever the search button is clicked this action will be called:
def searchBarSearchButtonClicked(searchBar) query = searchBar.text.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) url = "http://restro.nalwaya.com/restaurants/search.json?city=#{query}" @restaurants.clear json = nil begin json = JSONParser.parse_from_url(url) rescue RuntimeError => e presentError e.message end @restaurants = [] json.each do |restaurant| @restaurants << Restaurant.new(restaurant) end view.reloadData searchBar.resignFirstResponder end
So, all the results that we have fetched from our web service are stored in the json
variable. We will loop through this object and store the information in our restaurant model, which we have created in the previous section.
We have to reload the view once we complete the entire task, and this can be done by using the view.reloadData
class.
3.133.126.239