iOS UISearchBar with UITableView example

UISearchBar class provides a text field for entering text, a search button, a bookmark button, and a cancel button. With the help of the UISearchBarDelegate protocol you can implement the actions that will perform search on a database locally or send a request to the remote server when text is entered or buttons are clicked. In this example we implement the search bar to find a country by its name. The search request is sent to the remote server where a Java Servlet performs a simple query over the MySQL database to return a JSON array that is then displayed to the user using the Table view.

iOS UISearchBar with UITableView example iOS UISearchBar query with results in TableView iOS UISearchBar query with No Results

Java Servlet backend for remote search - CountrySearch.java

package com.as400samplecode;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import com.as400samplecode.util.Country;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class CountrySearch extends HttpServlet {
 
 private static final long serialVersionUID = 1L;
 
 public CountrySearch() {
  super();
 }

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  PrintWriter out = response.getWriter();
  
  //check of query data is sent
  String queryString = request.getParameter("queryString");
  if(queryString == null){
   queryString = "";
  }
  
  //get list of countries and prepare JSON array to send back
  ArrayList<Country> countryList = new ArrayList<Country>();
  Connection conn = null;             
  PreparedStatement stmt = null;      
  String sql = null;
  
  try {       
   Context ctx = (Context) new InitialContext().lookup("java:comp/env");
   conn = ((DataSource) ctx.lookup("jdbc/mysql")).getConnection(); 

   sql = "Select * from country where code <> 'CIV' "; 
   if(!queryString.trim().equals("")){
    sql += "and lcase(name) like ?";
   }
   
   stmt = conn.prepareStatement(sql);
   if(!queryString.trim().equals("")){
    stmt.setString(1, "%" + queryString.trim().toLowerCase() + "%" );
   }
   
   ResultSet rs = stmt.executeQuery();  
   while(rs.next()){ 
    
    Country country = new Country();
    country.setCode(rs.getString("code").trim());
    country.setName(rs.getString("name").trim());
    countryList.add(country);
    
   }                                                                          
   rs.close();                                                                
   
   stmt.close();                                                              
   stmt = null;                                                               
   conn.close();                                                              
   conn = null;  
   
  }                                                                
  catch(Exception e){
   e.printStackTrace();
  }                       

  finally {                                                        
   
   if (stmt != null) {                                             
    try {                                                          
     stmt.close();                                                 
    } catch (SQLException sqlex) {                                 
     // ignore -- as we can't do anything about it here            
    }                                                              

    stmt = null;                                             
   }                                                         

   if (conn != null) {                                       
    try {                                                    
     conn.close();                                           
    } catch (SQLException sqlex) {                           
     // ignore -- as we can't do anything about it here      
    }                                                        

    conn = null;                                             
   }                                                         
  } 
  
  Gson gson = new Gson();
  JsonObject myObj = new JsonObject();
  myObj.add("countryList", gson.toJsonTree(countryList));
  myObj.addProperty("success", true);
  out.println(myObj.toString());

 }
 
}

Interface file for the App Delegate - MySearchBarAppDelegate.h

#import <UIKit/UIKit.h>

@class MySearchBarViewController;

@interface MySearchBarAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) MySearchBarViewController *viewController;

@end

Implementation file for the App Delegate - MySearchBarAppDelegate.m

#import "MySearchBarAppDelegate.h"
#import "MySearchBarViewController.h"

@implementation MySearchBarAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[MySearchBarViewController alloc]
                           initWithNibName:@"MySearchBarViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

@end

Interface file for the UISearchBar View Controller - MySearchBarViewController.h

#import <UIKit/UIKit.h>

@interface MySearchBarViewController : UIViewController <UISearchBarDelegate,
                                UITableViewDelegate,UITableViewDataSource>

@property (nonatomic, strong) UISearchBar *mySearchBar;
@property (nonatomic, strong) UITableView *myTableView;
@property (nonatomic, strong) NSMutableArray *countryList;

@property (nonatomic, strong) NSString *queryString;

@end

Implementation file for the UISearchBar View Controller - MySearchBarViewController.m

#import "MySearchBarViewController.h"

@interface MySearchBarViewController ()

@end

@implementation MySearchBarViewController

@synthesize mySearchBar;
@synthesize myTableView;
@synthesize countryList;
@synthesize queryString;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //create a search bar and add to the top of the screen
 CGRect myFrame = CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y,
                                self.view.bounds.size.width, 44.0f);
    self.mySearchBar = [[UISearchBar alloc] initWithFrame:myFrame];
    //set the delegate to self so we can listen for events
    self.mySearchBar.delegate = self;
    //display the cancel button next to the search bar
    self.mySearchBar.showsCancelButton = YES;
    //add the search bar to the view
    [self.view addSubview:self.mySearchBar];
    
    //set the frame for the table view
    myFrame.origin.y += 44;
    myFrame.size.height = self.view.bounds.size.height - 44;
    self.myTableView = [[UITableView alloc] initWithFrame:myFrame
                                                    style:UITableViewStylePlain];
    //set the table view delegate and the data source
    self.myTableView.delegate = self;
    self.myTableView.dataSource = self;
    //set table view resize attribute
    self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                                        UIViewAutoresizingFlexibleHeight;
    //set background view and color
    self.myTableView.backgroundColor = [UIColor whiteColor];
    self.myTableView.backgroundView = nil;
    //add table view to the main view
    [self.view addSubview:self.myTableView];
    
    //execute the search without any query to display all countries
    [self handleSearch:self.mySearchBar];
}

//search button was tapped
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [self handleSearch:searchBar];
}

//user finished editing the search text
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
    [self handleSearch:searchBar];
}

//do our search on the remote server using HTTP request
- (void)handleSearch:(UISearchBar *)searchBar {
    
    //check what was passed as the query String and get rid of the keyboard
    NSLog(@"User searched for %@", searchBar.text);
    self.queryString = searchBar.text;
    [searchBar resignFirstResponder];
    
    //setup the remote server URI
    NSString *hostServer = @"http://demo.mysamplecode.com/Servlets_JSP/";
    NSString *myUrlString = [NSString stringWithFormat:@"%@CountrySearch",hostServer];
    
    //pass the query String in the body of the HTTP post
    NSString *body;
    if(self.queryString){
        body =  [NSString stringWithFormat:@"queryString=%@", self.queryString];
    }
    NSURL *myUrl = [NSURL URLWithString:myUrlString];
    
    //make the HTTP request
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:myUrl];
    [urlRequest setTimeoutInterval:60.0f];
    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection
     sendAsynchronousRequest:urlRequest
     queue:queue
     completionHandler:^(NSURLResponse *response,
                         NSData *data,
                         NSError *error) {
         //we got something in reponse to our request lets go ahead and process this
         if ([data length] >0 && error == nil){
                 [self parseResponse:data];
         }
         else if ([data length] == 0 && error == nil){
             NSLog(@"Empty Response, not sure why?");
         }
         else if (error != nil){
             NSLog(@"Not again, what is the error = %@", error);
         }
     }];
    
}

//parse our JSON response from the server and load the NSMutableArray of countries
- (void) parseResponse:(NSData *) data {
    
    NSString *myData = [[NSString alloc] initWithData:data
                                             encoding:NSUTF8StringEncoding];
    NSLog(@"JSON data = %@", myData);
    NSError *error = nil;
    
    id jsonObject = [NSJSONSerialization
                     JSONObjectWithData:data
                     options:NSJSONReadingAllowFragments
                     error:&error];
    if (jsonObject != nil && error == nil){
        NSLog(@"Successfully deserialized...");
        
        NSNumber *success = [jsonObject objectForKey:@"success"];
        if([success boolValue] == YES){
            
            self.countryList = [jsonObject objectForKey:@"countryList"];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.myTableView reloadData];
            });
        }
        else {
            [self.navigationController popToRootViewControllerAnimated:YES];
        }
    }
    
}

//number of rows in a given section of a table view
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section{
    
    NSInteger numberOfRows = 0;
    //get the count from the array
    if ([tableView isEqual:self.myTableView]){
        numberOfRows = self.countryList.count;
    }
    //if user searched for something and found nothing just add a row to display a message
    if(numberOfRows == 0 && [self.queryString length] > 0){
        numberOfRows = 1;
    }
    NSLog(@"Rows: %i", numberOfRows);
    return numberOfRows;
}


//asks the data source for a cell to insert in a particular location of the table view
- (UITableViewCell *) tableView:(UITableView *)tableView
          cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    UITableViewCell *myCellView = nil;
    
    if ([tableView isEqual:self.myTableView]){
        
        static NSString *TableViewCellIdentifier = @"CountryCells";
        //create a reusable table-view cell object located by its identifier
        myCellView = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier];
        if (myCellView == nil){
            myCellView = [[UITableViewCell alloc]
                          initWithStyle:UITableViewCellStyleValue1
                          reuseIdentifier:TableViewCellIdentifier];
        }
        
        //if there are countries to display
        if(self.countryList.count > 0){
            NSDictionary *countryInfo = [self.countryList objectAtIndex:indexPath.row];
            NSLog(@"Country Info = %@",countryInfo);
            
            NSString *countryCode = [countryInfo  valueForKey:@"code"];
            NSString *countryName = [countryInfo  valueForKey:@"name"];
            myCellView.textLabel.text = [NSString stringWithFormat:@"%@",countryName];
            myCellView.detailTextLabel.text = countryCode;
        }
        //display message to user
        else {
            myCellView.textLabel.text = @"No Results found, try again!";
            myCellView.detailTextLabel.text = @"";
        }
        
        //set the table view cell style
        [myCellView setSelectionStyle:UITableViewCellSelectionStyleNone];
        
    }
    return myCellView;
}

//user tapped on the cancel button
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
    NSLog(@"User canceled search");
    [searchBar resignFirstResponder];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Reference



34 comments :

  1. Really Excellent Amazing Super Woooooooooooowwwwwwwwwww.......... I searched for this code a lot.... Thanks buddy... Keep doing...

    ReplyDelete
  2. Use the difference in rate----you can listen faster fifa 14 coins than you can talk. So use this rate difference to your advantage by staying on the right track, anticipating cheap fifa 14 coins what they are going to say, thinking back over what they have just said and evaluating the development of their argument. You speak at about 100 to 150 words cheap fifa 14 coins per minute, but you think at 250 to 500.

    ReplyDelete
  3. Really good blog writing! To update the blog with this blog you can terrifically do a great work and I was glad that able to follow this and attain useful guidelines. Good work!

    Captain America Jacket

    ReplyDelete
  4. Regardless of whether You will hunt around You will find This almost all the fellow mates ALONG WITH friends in addition operate the products and services regarding online writing companies.essay writing help

    ReplyDelete
  5. Hi!
    Can you send me a mail (lock95@yandex.ru) project or give a link to it?
    Thank you!

    ReplyDelete
  6. đồng tâm
    game mu
    cho thuê nhà trọ
    cho thuê phòng trọ
    nhac san cuc manh
    số điện thoại tư vấn pháp luật miễn phí
    văn phòng luật
    tổng đài tư vấn pháp luật
    dịch vụ thành lập công ty trọn gói
    lý thuyết trò chơi trong kinh tế học
    đức phật và nàng audio
    hồ sơ mật dinh độc lập audio
    đừng hoang tưởng về biển lớn ebook
    chiến thắng trò chơi cuộc sống ebook
    bước nhảy lượng tử
    ngồi khóc trên cây audio
    truy tìm ký ức audio
    mặt dày tâm đen audio
    thế giới như tôi thấy ebook

    “Trừ phi có ai đó có thể khuyên bệ hạ thu hồi lại mệnh lệnh.”

    “Cho dù bệ hạ thu hồi lại mệnh lệnh thì Thái tử phi cũng sẽ không dừng tay.”

    “Cái này…thực ra nữ nhân này không quyết định được tất cả. Chỉ cần bệ hạ thu hồi lại mệnh lệnh thì chúng ta có thể trì hoãn chuyện này thêm tám đến mười năm nữa cũng không thành vấn đề,” Phùng Nguyệt nói.

    “Nhưng ai là người có thể khuyên bảo bệ hạ đây?” Bạch Thọ nhíu mày hỏi.

    “Ta có thể.” Từ bên ngoài phòng đột nhiên truyền đến một âm thanh.

    Hai người bất giác kinh hãi. Phương viên chung quanh của biệt viện được Cẩm y vệ canh phòng cẩn mật. Như thế nào có người tiến được vào đây?

    “Không cần lo lắng! Là ta.” Người này vội vàng lên tiếng trấn an.

    Phùng Nguyệt trong lòng vui mừng, hắn giờ phút này đã biết được đối phương là ai.

    “Trương Thiên Sư, quả nhiên là người đã quay lại.”

    Trương Thiên Sư từ ngoài bước vào, sắc mặt bình tĩnh nói: “Các ngươi làm việc thật quá ngu ngốc, các ngươi đắc tội với Lưu Phong, đắc tội với Phượng viên nhưng lại không chịu điều tra cho rõ thân phận thực sự của Trương Mỹ Nhân.”

    Phùng Nguyệt, Bạch Thọ sắc mặt đại biến. Từ trước đến nay, đây là lần duy nhất Trương Thiên Sư dùng khẩu khí như thế này để giáo huấn bọn họ.

    “Thỉnh đại nhân chỉ giáo.” Bạch Thọ cung kính nói.

    Trương Thiên Sư nghiêm mặt nói: “Các ngươi chút nữa đã phá hỏng đại sự. Trương Mỹ Nhân đến từ Vân Mộng trạch, ngoại hiệu Xà Hạt tiên tử, tu vi cường hãn, lòng dạ độc ác, cực kỳ khó đối phó. Nếu nàng ta biết các ngươi

    ReplyDelete
  7. I enjoyed over read your blog post. Your blog have nice information, I got good ideas from this amazing blog. I am always searching like this type blog post. I hope I will see again..
    Assignment Help

    ReplyDelete
  8. I love all the posts, I really enjoyed, I would like more information about this, because it is very nice., Thanks for sharing.
    Signature:
    i like play happy wheels demo online and play happy wheels games full and friv , girlsgogames , games2girls

    ReplyDelete
  9. I hope today can better yet, share permissions
    Visit to play: Agar io est un jeu affronte des milliers de concurrents. agario - agar io - agar - agar.io - agario jeu - agario - agar - agar.io - agar io - agario jeu

    ReplyDelete
  10. I have read your article several times. It really made me feel important, I think people would not ignore it. Thanks for sharing it. faceboook descargar , faceboook descargar , whatsapp baixar , descargar whatsapp gratis , baixar whatsapp gratis , mobogenie baixar , download mobogenie free

    ReplyDelete
  11. Nice post. I was convinced by your arguments. Surely you must have extensive knowledge and understanding very much. I admire you, write more. baixar facebook movel , baixar facebook movel , facebook gratis , descargar whatsapp , mobogenie , mobogenie , download whatsapp messenger

    ReplyDelete
  12. While the primary components of iOS 6 have been reported in the meeting formally, shrewd iOS designers and developers would stand separated taking in the elements those are not all that known. They can encourage create redid iOS applications utilizing those extraordinary components. economics tuition singapore

    ReplyDelete
  13. Appreciate your sharing. I understand what you bring it very meaningful and useful, thanks.
    Signature:
    Download retrica online includes more than eighty different filters with many different styles and include retrica indir , and zombie tsunami is the ideal game for anyone who loves the running game genre

    ReplyDelete
  14. A good blog. Thanks for sharing the information. It is very useful for my future. keep sharing
    happywheels , agar , happy wheels game , agar io ,

    ReplyDelete
  15. Excellent post!!! Java is most popular and efficient programming language available in the market today. It helps developers to create stunning desktop/web applications loaded with stunning functionalities. Java Course in Chennai | Best JAVA Training in Chennai

    ReplyDelete
  16. Thank you for your post. This was really an appreciating one. You done a good job. Keep on blogging like this unique information with us.

    SAP ABAP Training in Chennai

    ReplyDelete
  17. I read your articles to saying worth information,it's very helpful in my studies.thanks for sharing that valuable information.

    digital marketing training in chennai

    ReplyDelete
  18. I am an antique article collector and this article is one of the best I have ever read. I hope to see the same amazing work from you in future. Thanks Assignment help

    ReplyDelete
  19. Software testing industry offer huge career opportunity for talented professionals. software testing course in Chennai

    ReplyDelete
  20. Thank you for sharing valuable information. Nice post. I enjoyed reading this post.
    - Mortal Kombat XL
    - Atari Breakout
    - Dragon Ball Z Games

    ReplyDelete
  21. Thank you for sharing your thoughts.I truly appreciate your post thank you once again.
    minecraft games | fnaf
    abcdeya | brain games
    happy wheels | agario hi
    tetris - puzzle games

    ReplyDelete
  22. Thanks for sharing this Post, Keep Updating such topics.
    العاب بنات

    ReplyDelete
  23. Very interesting blog. Alot of blogs I see these days don't really provide anything that I'm interested in, but I'm most definately interested in this one. Just thought that I would post and let you know.
    facebook lite |resignation letter|qr code generator

    ReplyDelete
  24. I would very much like to agree with the previous commenter! I find this blog really useful for my uni project. I hope to add more useful posts later.
    Open Facebook
    | Science Kombat
    | Science Kombat Game
    | Earn to Die
    | Tank Trouble

    ReplyDelete
  25. مرحبا بكم على اجمل واحسن موقع يختص فقط في العاب بنات تلبيس كما انها من افضل واجمل الالعاب المطلوبة كثيرا على الانترنت عربيا لانها تحتوي على تلبيس بنات وفتيات جميلات وانيقات جدا وايضا عمل لهن مكياج و ميك اب واختيار ازياء تناسبهن وايضا اختيار افضل قصات الشعر الخاصة بالفتيات والعديد من الاشياء نتركم لاكتشافها على موقع العاب تلبيس بنات ستايل جديدة وجميلة وممتعة كثيرا وسوف تحبونها كثيرا العاب بنات ستايل والعاب فلاس والعاب باربي

    ReplyDelete
  26. This is also a very good post which I really enjoyed reading. Please visit our website and play exciting games:
    Science Kombat | Science Kombat Game.
    Play the fabolous earn to die game and complete all the levels.You can play all the seven parts of the game on our website :
    Tank trouble | Tank trouble 2 | Tank trouble 3 | Tank trouble 4

    ReplyDelete