MagicalRecord Tutorial for iOS
A MagicalRecord tutorial for iOS that introduces the basics of setting up a CoreData stack and working with this popular library. By Andy Pereira.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
MagicalRecord Tutorial for iOS
35 mins
Demo Data
It might be nice to give your users some initial data so they can see how easily they can keep track of their favorite beers. In AppDelegate.m, import Beer.h, BeerDetails.h. Then, just after you setup the Core Data stack, add the following:
// Setup App with prefilled Beer items.
if (![[NSUserDefaults standardUserDefaults] objectForKey:@"MR_HasPrefilledBeers"]) {
// Create Blond Ale
Beer *blondAle = [Beer createEntity];
blondAle.name = @"Blond Ale";
blondAle.beerDetails = [BeerDetails createEntity];
blondAle.beerDetails.rating = @4;
[ImageSaver saveImageToDisk:[UIImage imageNamed:@"blond.jpg"] andToBeer:blondAle];
// Create Wheat Beer
Beer *wheatBeer = [Beer createEntity];
wheatBeer.name = @"Wheat Beer";
wheatBeer.beerDetails = [BeerDetails createEntity];
wheatBeer.beerDetails.rating = @2;
[ImageSaver saveImageToDisk:[UIImage imageNamed:@"wheat.jpg"] andToBeer:wheatBeer];
// Create Pale Lager
Beer *paleLager = [Beer createEntity];
paleLager.name = @"Pale Lager";
paleLager.beerDetails = [BeerDetails createEntity];
paleLager.beerDetails.rating = @3;
[ImageSaver saveImageToDisk:[UIImage imageNamed:@"pale.jpg"] andToBeer:paleLager];
// Create Stout
Beer *stout = [Beer createEntity];
stout.name = @"Stout Lager";
stout.beerDetails = [BeerDetails createEntity];
stout.beerDetails.rating = @5;
[ImageSaver saveImageToDisk:[UIImage imageNamed:@"stout.jpg"] andToBeer:stout];
// Save Managed Object Context
[[NSManagedObjectContext defaultContext] saveToPersistentStoreWithCompletion:nil];
// Set User Default to prevent another preload of data on startup.
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MR_HasPrefilledBeers"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
The starter app you downloaded at the beginning of this tutorial includes four frosty beer images. Here, you just create four different beers, and save them. Storing a flag in NSUserDefaults makes sure the app pre-fills the data model only once when it launches for the very fist time.
Run the app again, so you can see all the new beers. Try deleting one and re-launching the app; it won’t come back. If you want to see all the sample beers again, delete the app from the simulator or device, and re-launch.
Searching
Now that you have more than 1 beer, test the search capabilities. The starter app already included a Search Bar, – scroll to the top of the table to see it. The only thing you need to add is the logic to search the list of beers.
Earlier, you used a MagicalRecord helper method to do a fetch of all beers, and it simply returned all of the beers. Now, you want to retrieve all the beers that match a specific search term.
For this, you’ll need to use an NSPredicate. Earlier, this tutorial explained a method for fetching with an NSPredicate – can you guess how to do the search? The logic should live inside of doSearch
in the MasterViewController.m file.
[spoiler]
Add the following to doSearch:
- (void)doSearch {
// 1. Get the text from the search bar.
NSString *searchText = self.searchBar.text;
// 2. Do a fetch on the beers that match Predicate criteria.
// In this case, if the name contains the string
self.beers = [[Beer findAllSortedBy:SORT_KEY_NAME ascending:YES withPredicate:[NSPredicate predicateWithFormat:@"name contains[c] %@", searchText] inContext:[NSManagedObjectContext defaultContext]] mutableCopy];
// 3. Reload the table to show the query results.
[self.tableView reloadData];
}
For other methods to fetch results, check the MagicalRecord header files.
[/spoiler]
Run the app again and drag the beer list down until the search bar is revealed. Search for one of the beers in the list, then search for one that isn’t in the list. Do you get the expected behavior?
Where to go from here
Hopefully, this MagicalRecord tutorial showed you how easy it is to get up and running with MagicalRecord. It really helps cut down the boilerplate! The fundamentals you’ve explored in this tutorial can help you develop all kinds of apps that help users keep track of things they like with pictures, notes, and ratings. Enjoy!
You can download the finished project here, which could be helpful if you get stuck somewhere.
If you want to develop further the BeerTracker project here follow few ideas to get you started:
- Add a “no beers created yet” message to the MasterViewController – lookup the
hasAtLeastOneEntity
method in MagicalRecord and use it. - Add a message to indicate how many beers match the search patter to the search controller – use the
countOfEntitiesWithPredicate:
method. - Implement a database reset function – lookup the
truncateAll
method from MagicalRecord - For fun open up MagicalRecordShorthand.h and read through the method names – most of them are pretty self explanatory, this header file should give you an even better idea how to use MagicalRecord
If you have any questions or comments about this tutorial, please join the forum discussion below!