The ABFRealmSearchViewController
class creates a controller object that manages a table view and a search bar, to run text search against a Realm object class.
This allows for the creation of a text search interface in as little as 27 lines of code!
The class performs the text search on a background thread (via RBQFetchedResultsController) allowing for non-blocking, as-you-type searching.
The controller is meant to be subclassed. By default, the resultsDataSource
and resultsDelegate
protocols are set as self
, so that the subclass can implement these methods.
You can see the code for ABFRealmSearchController
on GitHub.
This tutorial uses ABFRealmSearchViewController
v1.2.
Overview
Search is an integral part of many mobile apps. Users want to find their information as quickly as possible, especially on mobile. In many cases, search is left out by developers due to how long it can take to implement. This add-on makes it easy to add search to any of your Realm objects based on specific properties.
It’s very fast and non-blocking, revealing results as you type. Let’s get started and create an app that uses this functionality!
You can see the final code on GitHub here.
Tutorial
Create a new Xcode project, using the “Single View Application” template. Be sure “Language” is set to Objective-C, and that “Use Core Data” is unchecked.
ABFRealmSearchViewController
is available through CocoaPods. (If you don’t have CocoaPods installed, follow their instructions before continuing.) In your terminal, cd
to the project folder you just created, and run touch Podfile
. To install ABFRealmSearchViewController
, simply add the following line to the Podfile
you just created:
pod "ABFRealmSearchViewController"
In your terminal, run pod install
. This will also install Realm automatically! (If this is your first time using CocoaPods, this could take a while. Future uses will be much faster.)
When it’s done, you’ll need to close the Xcode window and open the xcworkspace
file that CocoaPods created, so that you can use the classes inside the pods.
Go to Main.storyboard
and delete the view controller that was generated. Drag in a UINavigationController
. This will also create a UITableViewController
as its root view controller. On your newly added UINavigationController
, be sure to check “Is Initial View Controller” in the right side bar.
Create a class called BlogSearchViewController
and have it inherit from UIViewController
.
Go to BlogSearchViewController.h
, add #import "ABFRealmSearchViewController.h"
, and replace the subclass of UIViewController
with ABFRealmSearchViewController
. When you’re done, the file should look like this:
#import <UIKit/UIKit.h>
#import "ABFRealmSearchViewController.h"
@interface BlogSearchViewController : ABFRealmSearchViewController
@end
Download the sample data that we’ll be using for this tutorial: JHARealmSearchTutorialData. The data contains information about blog posts. Add BlogObject.h
, BlogObject.m
, blog.json
, and emoji.json
to your project. Be sure “Copy items if needed” is checked.
Go to main.storyboard
, click the UITableViewController
and change its “Class” (in the Identity Inspector, at the top right) to BlogSearchViewController
.
Go to BlogSearchViewController.m
. Add #import "BlogObject.h"
to the top. The file should now look like this:
#import "BlogSearchViewController.h"
#import "BlogObject.h"
@interface BlogSearchViewController ()
...
Go to AppDelegate.m
and load your blogposts. The code looks like this:
#import "AppDelegate.h"
#import "BlogObject.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[BlogObject loadBlogData];
return YES;
}
...
[BlogObject loadBlogData]
is a method that will convert the blog.json
data into objects in your Realm.
Go to Main.storyboard
, click on the table view cell and change its reuseIdentifier
to “blogCell”. (Be sure to hit Enter after typing it to confirm.)
Click on the BlogSearchViewController
(called “Root View Controller”), then the attributes tab. For “Entity Name”, type “BlogObject”. For “Search Property”, type “title”. (Be sure to hit Enter after typing each one to confirm it.) Set “Use Contains” to “On”.
Go to BlogSearchViewController.m
and add one of the search controller’s data source methods:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
...
#pragma mark - ABFRealmSearchControllerDataSource
- (UITableViewCell *)searchViewController:(ABFRealmSearchViewController *)searchViewController
cellForObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"blogCell" forIndexPath:indexPath];
BlogObject *blog = anObject;
cell.textLabel.text = [blog.title capitalizedString];
return cell;
}
Now if you run this now, you should see a list of blog posts! You’re pretty much done at this point; grab some coffee or a beer and celebrate! In the next part, we’ll go over how to style this so it looks similar to the example above.
First, create a custom table view cell called BlogPostTableViewCell
, inheriting from UITableViewCell
. Be sure to check “Also create XIB file”.
Go to BlogPostTableViewCell.xib
and increase the height of the cell to 88 by clicking and dragging the handle at the bottom. Then add 3 UILabel
s, which will represent title, emoji, and content. Style them however you’d like! Just be sure to set “Number of Lines” on the content label to 0, so that more than one line of text will show.
Don’t forget to add your “Identifier”! Set it to “blogCell”.
Next, set up the Auto Layout constraints as shown in the images below. We won’t go into Auto Layout too much in this tutorial, since we only need the basics. If you’re interested in learning more about Auto Layout, check out some of these great resources!
These constraints will let your cell resize to fit any phone and any content, without any work from you!
In BlogPostTableViewCell.h
, create IBOutlet
s for these labels. Call them titleLabel
, emojiLabel
, and contentLabel
.
In BlogSearchViewController.m
, import BlogPostTableViewCell.h
, and register your nib in viewDidLoad
. The code should look like this:
#import "BlogSearchViewController.h"
#import "BlogObject.h"
#import "BlogPostTableViewCell.h"
@interface BlogSearchViewController ()
@end
@implementation BlogSearchViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"Blogs";
self.tableView.estimatedRowHeight = 88.f;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView registerNib:[UINib nibWithNibName:@"BlogPostTableViewCell" bundle:nil] forCellReuseIdentifier:@"blogCell"];
}
Now we’ll update the data source method we created in the same file. We will use the cell we created, and set the labels to the correct text:
- (UITableViewCell *)searchViewController:(ABFRealmSearchViewController *)searchViewController
cellForObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
{
BlogPostTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"blogCell" forIndexPath:indexPath];
BlogObject *blog = anObject;
cell.titleLabel.text = [blog.title capitalizedString];
cell.emojiLabel.text = blog.emoji;
cell.contentLabel.text = blog.content;
return cell;
}
Go to Main.storyboard
and click on the cell in the UITableView
. Set its class to BlogPostTableViewCell
.
Fire up the app; you’re done!
Receive news and updates from Realm straight to your inbox