Search restaurant by city

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
Search restaurant by city

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.

What just happened

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 text
  • searchBar:shouldChangeTextInRange:replacementText: This asks the delegate if text in a specified range should be replaced with the given text
  • searchBarShouldBeginEditing: This asks the delegate if editing should begin in the specified search bar
  • searchBarTextDidBeginEditing: This tells the delegate when the user begins editing the search text
  • searchBarShouldEndEditing: This asks the delegate if editing should stop in the specified search bar
  • searchBarTextDidEndEditing: This tells the delegate that the user finished editing the search text

The 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 tapped
  • searchBarCancelButtonClicked: This tells the delegate that the cancel button was tapped
  • searchBarSearchButtonClicked: This tells the delegate that the search results list button was tapped
  • searchBarResultsListButtonClicked: This tells the delegate that the search button was tapped

The method used for the scope button is as follows:

  • searchBar:selectedScopeButtonIndexDidChange: This tells the delegate that the scope button selection changed

Tip

As a minimum, the delegate needs to perform the actual search when the text is entered in the text field.

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.126.239