As a developer, there will be many different situations when you will need to store data. Users will expect your app to remember preferences and other information each time they launch it. Previous chapters discussed the BookStore app. With this app, users will expect your application to remember all of the books in the bookstore. Your application will need a way to store this information, retrieve it, and possibly search and sort this data. Working with data can sometimes be difficult. Fortunately, Apple has provided methods and frameworks to make this process easier.
This chapter discusses two different formats in which data will need to be stored. It discusses how to save a preference file for an iOS device and then how to use a SQLite database in your application to store and retrieve data.
Storage Considerations
There are some major storage differences between the Mac and the iPhone, and these differences will affect how you work with data. Let’s start by discussing the Mac and how you will need to develop for it.
On the Mac, by default, applications are stored in the Applications folder. Each user has their own home folder where preferences and information related to that user are stored. Not all of the users will have access to write to the Applications folder or to the application bundle itself.
On the iPhone and iPad, developers do not need to deal with different users. Every person who uses the iPhone has the same permissions and the same folders. There are some other factors to consider with the iPhone, though. Every application on an iOS device is in its own sandbox . This means that files written by an app can be seen and used only by that individual app. This makes for a more secure environment for the iPhone, iPad, Apple TV, and Apple Watch, but it also presents some changes in the way you work with data storage.
Preferences/UserDefaults
All of the data is both read and written at the same time. If you are going to be writing often or writing and reading large amounts of data, this could take time and slow down your application. As a general rule, your preferences file should never be larger than 100 KB. If your preferences file starts to become larger than 100 KB, consider using Core Data as a way to store your information.
The preferences file does not provide many options when it comes to searching and ordering information.
The preferences file is really nothing more than a standardized XML file with accompanying classes and methods to store application-specific information. A preference would be, for example, the sorting column and direction (ascending/descending) of a list. Anything that is generally customizable within an app should be stored in a preferences file.
Caution
Sensitive data should not be stored in the preferences file or in a database without additional encryption. Luckily, Apple provides a way to store sensitive information. It is called the keychain. Securing data in the keychain is beyond the scope of this book.
Writing Preferences
Apple has provided developers with the UserDefaults class; this class makes it easy to read and write preferences for iOS, macOS, tvOS, and watchOS. The great thing is that, in this case, you can use the same code for iOS, macOS, and tvOS. The only difference between the several implementations is the location of the preferences file.
Note
For macOS, the preferences file is named com.yourcompany.applicationname.plist and is located in the /Users/username/Library/Preferences folder. On iOS, the preferences file is located in your application’s container in the /Library/Preferences folder.
This instantiates the prefs object so you can use it to set preference values. Next, you need to set the preference keys for the values that you want to save. The BookStore app example will be used to demonstrate specific instructions throughout this chapter. When running a bookstore, you might want to save a username in the preferences. You also might want to save things such as a default book category or recent searches. The preferences file is a great place to store this type of information because this is the kind of information that needs to be read only when the application is launched.
Also, on iOS, it is often necessary to save your current state. If a person is using your application and then gets a phone call, you want to be able to bring them back to the exact place they were in your application when they are done with their phone call. This is less necessary now with the implementation of multitasking, but your users will still appreciate it if your application remembers what they were doing the next time they launch.
Reading Preferences
Pay close attention to what is happening in each of these lines. You start by declaring the variable username, which is a String. This variable will be used to store the preference value of the username you stored in the preferences. Then, you just assign it to the value of the preference username. You will notice that in the read example you do not use the synchronize method . This is because you have not changed the values of the preferences; therefore, you do not need to make sure they are written to a disk.
Databases
You have learned how to store some small pieces of information and retrieve them at a later point. What if you have more information that needs to be stored? What if you need to conduct a search within this information or put it in some sort of order? These kinds of situations call for a database.
A database is a tool for storing a significant amount of information in a way that it can be easily searched or retrieved. When reading data from a database, pieces of data are returned rather than the entire file. Many applications you use in your daily life are based on databases of some sort. Your online banking application retrieves your account activity from a database. Your supermarket uses a database to retrieve prices for different items. A simple example of a database is a spreadsheet. You may have many columns and many rows in your spreadsheet. The columns in your spreadsheet represent different types of information you want to store. In a database, these are considered attributes . The rows in your spreadsheet would be considered different records in your database.
Storing Information in a Database
Databases are usually an intimidating subject for a developer; most developers associate databases with enterprise database servers such as Microsoft SQL Server or Oracle. These applications can take time to set up and require constant management. For most developers, a database system like Oracle would be too much to handle. Luckily, Apple has included a small and efficient database engine called SQLite in iOS, macOS, and tvOS. This allows you to gain many of the features of complex database servers without the overhead.
SQLite will provide you with a lot of flexibility in storing information for your application. It stores the entire database in a single file. It is fast, reliable, and easy to implement in your application. The best thing about the SQLite database is that there is no need to install any software; Apple has taken care of that for you.
SQLite was designed as a single-user database. You will not want to use SQLite in an environment where more than one person will be accessing the same database. This could lead to data loss or corruption.
In the business world, databases can grow to become very large. It is not surprising for a database manager to handle databases as large as half a terabyte, and in some cases databases can become much larger than that. SQLite should be able to handle smaller databases without any issues, but you will begin to see performance issues if your database starts to get too large.
SQLite lacks some of the backup and data restore features of the enterprise database solutions.
For the purposes of this chapter, you will focus on using SQLite as your database engine. If any of the mentioned limitations are present in the application you are developing, you may need to look into an enterprise database solution, which is beyond the scope of this book.
Note
SQLite (pronounced “sequel-lite”) gets its name from Structured Query Language (SQL, pronounced “sequel”). SQL is the language used to enter, search, and retrieve data from a database.
Apple has worked hard to iron out a lot of the challenges of database development. As a developer, you will not need to become familiar with SQL because Apple has taken care of the direct database interaction for you through a framework called Core Data, which makes interacting with the database much easier. Core Data has been adapted by Apple from a NeXT product called Enterprise Object Framework, and working with Core Data is a lot easier than interfacing directly with the SQLite database. Directly accessing a database via SQL is beyond the scope of this book.
Getting Started with Core Data
- 1.Open Xcode and select File ➤ New ➤ Project. To create an iOS Core Data project, select iOS from the menu on the top. Then select Single View App, as shown in Figure 11-1.Figure 11-1.
Creating a new project
- 2.
Click the Next button when you’re done. The next screen will allow you to enter the name you want to use. For the purposes of this chapter, you will use the name BookStore.
- 3.
Near the bottom, you will see the check box called Use Core Data. Make sure this is checked and then click Next, as shown in Figure 11-2.
Note Core Data can be added to any project at any point. Checking that box when creating a project will add the Core Data frameworks and a default data model to your application. If you know you are going to use Core Data, checking this box will save you time.
Figure 11-2.Adding Core Data to your project
- 4.
Select a location to save the project and click Create.
Once you are done with that, your new project will open. It will look similar to a standard application, except now you will have a BookStore.xcdatamodeld file. This file is called a data model and will contain the information about the data that you will be storing in Core Data.
The Model

The blank model
The window is divided into two sections. On the left, you have your entities. In more common terms, these are the objects or items that you want to store in the database. Fetch Requests and Configurations are beyond the scope of this book and could be covered in a more deep investigation of CoreData. Fetch Requests allow you to create filters or queries for your data.
The right section will contain the entity’s attributes once a new Entity has been created. Attributes are pieces of information about the entities. For example, a book would be an entity, and the title of the book would be an attribute of that entity.
Note
In database terms, entities are your tables, and the attributes of the entities are called columns. The objects created from those entities are referred to as rows.
The panel on the right will also show you all the relationships of an entity once one has been created. A relationship connects one entity to another. For example, you will create a Book entity and an Author entity . You will then relate them so that every book can have an author.
- 1.Click the Add Entity button on the bottom of the window, or select Editor ➤ Add Entity from the menu, as shown in Figure 11-4.Figure 11-4.
Adding a new entity
- 2.
On the left side, double-click the Entity name and change the name to Book.
Note You must capitalize your entities’ names.
- 3.Now let’s add some attributes. Attributes would be considered the details of a book, so you will store the title, author, price, and year the book was published. Obviously, in your own applications, you may want to store more information, such as the publisher, page count, and genre, but you want to start simple. Click the Add Attribute button at the bottom right of the window, or select Editor ➤ Add Attribute, as shown in Figure 11-5. If you do not see the option to add an attribute, make sure you have selected the Book entity on the left side.Figure 11-5.
Adding a new attribute
- 4.
You will be given only two options for your attribute: the name and the data type. Let’s call this attribute title. Unlike entities, attribute names must be lowercase.
- 5.
Now, you will need to select a data type. Selecting the correct data type is important. It will affect how your data is stored and retrieved from the database. The list has 13 items in it and can be daunting. We will discuss the most common options and, as you become more familiar with Core Data, you can experiment with the other options. The most common options are String, Integer 32, Decimal, and Date. For the title of the book, select String.
String: This is the type of attribute used to store text. This should be used to store any kind of information that is not a number or a date. In this example, the book title and author will be strings.
Integer 32: There are three different integer values possible for an attribute. Each of the integer types differs only in the minimum and maximum values possible. Integer 32 should cover most of your needs when storing an integer. An integer is a number without a decimal. If you try to save a decimal in an integer attribute, the decimal portion will be truncated. In this example, the year published will be an integer.
Decimal: A decimal is a type of attribute that can store numbers with decimals. A decimal is similar to a double attribute, but they differ in their minimum and maximum values and precision. A decimal should be able to handle any currency values. In this example, you will use a decimal to store the price of the book.
Date: A date attribute is exactly what it sounds like. It allows you to store a date and time and then performs searches and lookups based on these values. You will not use this type in this example.
- 6.
Let’s create the rest of the attributes for the book. Now, add price. It should be a Decimal. Add the year the book was published. For two-word attributes, it is standard to make the first word lowercase and the second word start with a capital letter. For example, an ideal name for the attribute for the year the book was published would be yearPublished. Select Integer 32 as the attribute type. Once you have added all of your attributes, your screen should look like Figure 11-6.
Note
Attribute names cannot contain spaces.

The finished Book entity
Note
If you are used to working with databases, you will notice that you did not add a primary key. A primary key is a field (usually a number) that is used to uniquely identify each record in a database. In Core Data databases, there is no need to create primary keys. The Framework will manage all of that for you.
- 1.
Add a new entity and call it Author.
- 2.
To this entity, add lastName and firstName, both of which are strings.
- 1.Click the Book entity, and then click and hold on the Add Attribue button that is located on the bottom right of the screen. Select Add Relationship, as shown in Figure 11-7. (You can also click the plus under the Relationships section of the Core Data model.)Figure 11-7.
Adding a new relationship
- 2.
You will be given the opportunity to name your relationship. You usually give a relationship the same name as the entity that you are referencing. Type in author as the name and select Author from the Destination drop-down menu.
- 3.
You have created one-half of your relationship. To create the other half, click the Author entity. Click and hold the Add Attributebutton located at the bottom right of the screen and select Add Relationship. You will use the entity name that you are connecting to as the name of this relationship, so you will call it books. (You are adding an s to the relationship name because an author can have many books.) Under Destination, select Book, and under Inverse, select the author relationship you made in the previous step. In the Utilities window on the right side of the screen, select the Data Model Inspector. Select To Many for the type of the relationship. Your model should now look like Figure 11-8.
Note
Sometimes in Xcode, when working with models, it is necessary to press the Tab key for the names of entities, attributes, and relationships to update. This little quirk can be traced all the way back to WebObjects tools.
Figure 11-8The final relationship

Checking an Entity’s Codegen status
When Xcode generates the Class Definitions for your entities, it will then make subclasses of NSManagedObject. NSManagedObject is an object that handles all of the Core Data database interaction. It provides the methods and properties you will be using in this example.
Managed Object Context
Xcode will create a managed object class called Book. In Core Data, every managed object should exist within a managed object context. The context is responsible for tracking changes to objects, carrying out undo operations, and writing the data to the database. This is helpful because you can now save a bunch of changes at once rather than saving each individual change. This speeds up the process of saving the records. As a developer, you do not need to track when an object has been changed. The managed object context will handle all of that for you.
Setting Up the Interface
- 1.In the BookStore folder in your project, you should have a Main.storyboard file. Click this file and Xcode will open it in the editing window, as shown in Figure 11-10.Figure 11-10.
Creating the interface
- 2.There should be a blank window. To add some functionality to your window, you need to add some objects from the Object Library. Click the Object Library button and type table into the search field. This should narrow the objects, and you should see Table View Controller and Table View. Drag the Table View to the view, as shown in Figure 11-11.Figure 11-11.
Adding the Table View
- 3.You now have a Table View. You will need to stretch the Table View to fill your view. Drag all four corners of the Table View so that it covers your entire view as shown in Figure 11-12.Figure 11-12.
Stretching the Table View
- 4.To create cells in your Table View, you need to add a UITableViewCell. Your current search of table should show a Table View Cell beneath the Table View object. Drag a Table View Cell to your table. You now have a table and a cell on your view, as shown in Figure 11-13.Figure 11-13.
Adding the Table View Cell
- 5.Select the cell, and in the Attributes Inspector in the utilities section set Style to Basic. Also, set the Identifier to Cell. The identifier is used for when your Table View contains multiple styles of cells. You will need to differentiate them with unique identifiers. For simple projects, you can set this to Cell and not worry about it, as shown in Figure 11-14.Figure 11-14.
Changing the style and identifier of the cell
- 6.When using a Table View, it is usually a good idea to put it in a Navigation Controller. You will be using the Navigation Controller to give you space to put an Add button on your Table View. To add a Navigation Controller, select your View Controller in the Scene list, which is the window to the left of your storyboard that shows your View Controllers (your View Controller will have a yellow icon next to it). From the Application menu, select Editor ➤ Embed In ➤ Navigation Controller, as shown in Figure 11-15.Figure 11-15.
Embedding in a Navigation Controller
- 7.You will now have a navigation bar at the top of your view. You will now add a button to the bar. This type of button is called a UIBarButtonItem. Search for bar button in your Object Library and drag a Bar Button item to the top right of your view on the navigation bar, as shown in Figure 11-16.Figure 11-16.
Adding a Bar Button Item to the navigation bar
- 8.Select the Bar Button Item and change the System Item from Custom to Add as shown in Figure 11-17. This will change the look of your Bar Button Item from the word Item to a plus icon.Figure 11-17.
Changing the Bar Button Item
- 9.Now you have created the interface, you need to hook it up to your code. Hold down the Control key and drag your Table view to the View Controller in the Document Outline, as shown in Figure 11-18.Figure 11-18.
Connecting the Table View
- 10.A pop-up will appear allowing you to select either the dataSource or the delegate, as shown in Figure 11-19. You will need to assign both to the View Controller. The order in which you select the items does not matter, but you will have to Control-drag the Table View twice.Figure 11-19.
Hooking up the Table View
- 11.Now your Table View should be ready to go. You need to hook up your button to make it do something. In the top right of your Xcode window, click the Assistant Editor button (it looks like two circles). This will open your code on the right side and your storyboard on the left side. Now Control-drag your Add button to the View Controller code on the right, as shown in Figure 11-20.Figure 11-20.
Adding an action for your Button object
- 12.It does not matter where you place the Add button in your code as long as it is in your class and outside of any methods. It should be after your class properties just for organization. When you let go, you will be prompted for the type of connection you are creating. Set Connection to Action. Then add a name for your new method, such as addNew, as shown in Figure 11-21. Click Connect to finish the connection.Figure 11-21.
Changing the type and name of the connection
- 13.You also need to create an outlet for your Table View. Drag your Table View from the View Controller scene to the top of the code (just under the class definition, as seen in Figure 11-22). Make sure the connection is set to Outlet and name the Table View myTableView. You will need this outlet later to tell your Table View to refresh. Click Connect to finish the connection.Figure 11-22.
Creating an outlet for the Table View
Without this method, the Table View will not know how many rows to draw.
The first line creates a constant that points to your application delegate. The second line points your managedObjectContext variable to the application delegate’s managedObjectContext. It is usually a good idea to use the same managed object context throughout your app.
This code is a little more complex than what you have seen before, so let’s walk through it. Line 1 declares a new function called loadBooks, which returns an array of Books. You then return the array once you have it loaded.
In line 2, you call a count on your array of Book for the number of rows in your Table view. In lines 5–9, you create your cell and return it. Line 6 creates a cell for you to use. This is standard code for creating a cell. The identifier allows you to have more than one type of cell in a Table View, but that is more complex. Line 7 grabs your Book object from your loadBooks() array . Line 8 assigns the book title to your textLabel in the cell. The textLabel is the default label in the cell. This is all you need to do to display the results of your loadBooks method in the Table view. You still have one problem. You do not have any books in your database yet.
Line 2 creates a new Book object for your book in the database from the Entity name and inserts that object into the managedObjectContext you created before. Remember that once the object is inserted into the managed object context, its changes are tracked, and it can be saved. Line 3 sets the book title to My Book and adds the number of items in the array. Obviously, in real life, you would want to set this to a name either given by the user or from some other list. Lines 4–8 save the managed object context.

The final app
This was a cursory introduction to Core Data for iOS. Core Data is a powerful API, but it can also take a lot of time to master.
Summary
Preferences: You learned to use UserDefaults to save and read preferences from a file, on iOS, macOS, tvOS, and watchOS.
Databases: You learned what a database is and why using one can be preferable to saving information in a preferences file.
Database engine: You learned about the SQLite database engine that Apple has integrated into macOS, tvOS, and iOS and its advantages and limitations.
Core Data: Apple provides a framework for interfacing with the SQLite database. This framework makes the interface much easier to use.
Bookstore application: You created a simple Core Data application and used Xcode to create a data model for your bookstore. You also learned how to create a relationship between two entities. Finally, you used Xcode to create a simple interface for your Core Data model.
Exercises
Add a new view to the app for allowing the user to enter the name of a book.
Provide a way to remove a book from the list.
Create an Author object and add it to a Book object.