The Best Way to Connect Your iOS App to MySQL Database (4 Steps)

This is Chapter 2 of 5
This article is the second chapter of my guide on Building Apps With MySQL and WordPress.

This guide shows you how to make three different MySQL/Wordpress powered apps that all leverage the benefit of having a web hosting account.

The first chapter shows you how to sign up for one.

In this chapter, we’ll set up our MySQL database and create the first app that will read data from it.

The title of this article is a little “off” because the app won’t directly connect to the MySQL database in order to retrieve data, however, this is the way that most people phrase it when they ask me this question! Let’s take a look at the outline of what we’re going to accomplish in this tutorial:


1. How to setup your database
   1.1 Create a new database
   1.2 Create a new database user
   1.3 Add the user to the database

2. How to connect your iPhone app to a MySQL database
   2.1 Launching phpMyAdmin
   2.2 Creating a database table
   2.3 Inserting data into the database table

3. How to write a simple PHP web service to query your MySQL database and return the results to your iPhone app
   3.1 Creating the PHP service
   3.2 Uploading the PHP file to the server

4. How to make an iPhone app that will parse the MySQL database results and show them in a table view
   4.1 Creating a new Xcode project
   4.2 Creating the model for the data
   4.3 Downloading and parsing the JSON feed
   4.4 Populating the table view with locations
   4.5 Adding a second view controller: the map view
   4.6 Adding the MapKit framework
   4.7 Transitioning to the map view
   4.8 Mapping the location

If you missed the steps before arriving here, read chapter 1 here.

1. How to setup your database

Once you’ve received your confirmation email from signing up, you can now create a new database in your Bluehost control panel.

Start by clicking the database menu item:

Next you’ll get to the database screen where you’ll do 3 things:
– Create a new database
– Create a new database user
– Add the user to the database

1.1 Create a new database

So in the screenshot below, I’ve named my database sampledb.
Then click “Create Database”.

Creating a new database with Bluehost

1.2 Create a new database user

Next, we need to create a new database user.
Give the user a name and password and click “Create User”.

Creating a new database user

1.3 Add the user to the database

Finally, we need to give this user access to the newly created database so in the form below, choose the database you created from the dropdown and choose the user that you just created and click “Add”.

Adding a user to the database

For now, let’s grant this user all the privileges so that we can set up our database tables.
Later on, we’ll remove most of these privileges and limit the user to just reading data to secure it.
Alternatively, you can create two new database users, one with only read privileges and one with all privileges to act as an administrator.

Adding database user privileges in Bluehost

Click “Make Changes” and now we’re ready to go!

2. How to connect your iPhone app to a MySQL database

In this section, I’m going to explain how we’re going to get our iPhone app to connect to the MySQL database and we’ll also create some database tables and fill it with some data.

First, let’s explain how we’re going to do this.

Unfortunately the iPhone app is not going to be able to connect directly to our MySQL database. What we need is to create a middle-man that will facilitate the database operations.

This is where the PHP web service comes in. The web service is going to sit on our web server and when the iPhone app sends a request to it, it’s going to query the database for the requested data and then return it to the iPhone app in a format that it can understand.

Now, you’re not limited to using PHP to write your web service but PHP and MySQL usually go hand in hand so that’s what we’ll be doing today.

Here’s a diagram of what the system looks like:

How an iPhone app connects to a remote MySQL database

So before we build the iPhone app or the PHP web service, let’s create some database tables and fill it with data.

In this example app, I’m going to demonstrate a common scenario of pulling a list of locations down from the database and displaying the locations in a tableview (scrollable list).

When the user taps on a location, it will show a map view with a pin indicating the location.

So, in our database we’re going to want to store a list of locations.

2.1 Launching phpMyAdmin

Start by going back out to your Bluehost control panel and looking for the phpMyAdmin icon.
It should be under the “Database Tools” section. When you find it, click it to go into the database management tool.
(If you don’t see the icon, double check the menu at the top that you’re in the “cPanel” tab and not “Home”)

Bluehost phpMyAdmin icon

When you encounter the login screen, you should login with the same database user credentials that you created earlier.

phpMyAdmin login screen

By logging in as the database user that you created, you’ll have access to the new database you created because you granted this user access to it!

After you log in, you’ll see your database on the left hand side.

phpMyAdmin select database

Click the database that you created and the right hand side will change to allow us to create a new database table.

2.2 Creating a database table

Creating a new database table in phpMyAdmin

Call your new database table “Locations”, enter “4” for the number of columns and click “Go”.

In the pop up dialog, you’ll be able to customize the 4 table columns. Follow the screenshot below and then click “Save”.

Creating columns in a MySQL database table

On the next screen, you’ll see your newly created database table.

2.3 Inserting data into the database table

We’re going to insert a couple of locations into the table now so click “Insert” as shown below:

Inserting data into the database table

I decided to add the locations of the Apple and Google headquarters. You can fill in the same thing or fill in some different locations of your own!

If you need to find the lat long of an address, just use this website.

When you’re ready, click the last “Go” button to insert both rows into your database table.

Adding locations to our database table

Now you’ll see the actual SQL statement which added the data!
SQL stands for Structured Query Language and it’s a programming language to express queries from simple ones to really complex ones that involve multiple tables and constraints.

When you’re using this web interface, phpMyAdmin, to work with your database, you’re running SQL statements in the background when you click a “Go” or “Save” button.

If you’re working with databases a lot, it would really pay to learn SQL!

After inserting rows into the table

Next, click the “Browse” button and see the data in the table.

Browsing our Locations MySQL table

Now that we have some sample data in the MySQL database, let’s move on to creating that PHP web service that’ll connect to the MySQL database and query it for the list of locations (and then return the results to the iPhone app).

3. How to write a simple PHP web service to query your MySQL database and return the results to your iPhone app

Now let’s create a simple PHP service to query our database for the results.

3.1 Creating the PHP service

Open up a text editor and paste the following code into it, then save it as service.php:

In line 4, you’ll want to change the following placeholders:
-username : use the username of the db user that you set up in step 1
-password : use the password for the db user
-dbname : use the name of the database you created in step 1

Read the comments in the code above to see what each line does.

When you save the file, it should have a .php extension like this:
PHP file in finder

3.2 Uploading the PHP file to the server

Now you can use your favorite FTP client to upload this file to the root of your web host so that you can access this file from:

If you’re unsure of what FTP means, you can also upload this file from your Bluehost control panel.

Login to your cPanel and look for the “File Manager” icon:

Bluehost cPanel file manager icon

Click into that icon and it’ll bring you to a screen where you can see all the files on your web host.

In the left side panel, you’ll see a tree view navigation.

You want to click “public_html” which will open up the folder, then click “Upload” as shown below:

going to public_html in your file manager and uploading a file

On the next screen, choose “service.php” from your local system and upload the file.

Now you’ll be able to access it from:

Test this by going to that URL in your browser.

You should see something like this:

JSON results from the php service and MySQL database!

Now we’re ready to build the iPhone app that will read this feed!

4. How to make an iPhone app that will parse the MySQL database results and show them in a table view

4.1 Creating a new Xcode project
We’re going to start by creating a new single view application Xcode project.

Create a new Xcode single view application

Make sure Swift is selected as the language and we are going to be creating this app for the iPhone.

Select Swift as the language

Let’s do some housekeeping before we actually start coding. For this tutorial, we going to arbitrarily use the iPhone 6s as our simulator. Click on the the name of iPhone at the top left corner and change it to iPhone 6s.

Change the simulator

To better visualize the final look of our platform, we also going to change the size of our view controller to 4.7 in, the size of the iPhone 6s. To do this, head to Main.storyboard, click on the yellow circle at the top of the view, and the on the right side under “Simulated Metrics” you should find the drop down menu.

Simulated metrics

Let’s change that to 4.7 in. You should notice that width of the view has changed.

iPhone 4.7 Simulated metrics

Our next step is to edit our Info.plist file to make sure it allows us to pull data from an external source. Click on Info.plist, then right click to add a new row and type “App Transport Security Settings”. Inside of that we want to add another row, (make sure the down arrow is clicked on the first row) “Allow Arbitrary Loads” and set that to “YES”.

App Transport

Done correctly, it will look like this. Also note that it should autofill to the correct name.

Next, go to Main.storyboard and we are going to add a table view element to the view controller’s view.

In the lower right hand corner, search for table view in the library pane and you should see the Table View and Table View Cell elements come up.

If you don’t see them, double check that you’re looking at the correct tab as indicated by the screenshot below.

First drag and drop the Table View element over the view(not the “table view controller” element) and resize it to fit the whole view. You will actually want to position it just under the battery symbol, there should be a blue dotted line letting you know where to drag down to.

Next, drag and drop a Table View Cell over the Table View.

Adding a table view and table view cell to the view

We also need to give the table cell a reuse identifier which we’re going to use later down the line. Click the cell, then on the right panel in the “attributes inspector”, change the Identifier to “BasicCell”.

Setting reuse identifier on the table cell

Also, a good way to see where you are in your view controller is to to check the hierarchy of elements. You can do this by clicking on this icon at the bottom of your scene.

Document outline button

This will bring up the following hierarchal view in the left pane.

Document outline pane

The next step is to connect our Table View element to our View Controller so that we can reference it when writing our Swift code.

To do this, we first need to split our session into two panes, one containing the Main.storyboard, and the other containing our ViewController.swift. If you cannot find the ViewController.swift, follow the breadcrumbs at the very top of the file.

Now to perform the connection, hold control, click the table view element from the storyboard, and then drag the blue line to the view controller. A prompt should pop up and you should name the table view “listTableView” . At this point you can use this name to refer to the table view element as you write your Swift code.

Exposing the table view as an IBOutlet

Note that this creates a UITableView which is already unwrapped. In other words, this table view definitely exists, it will never be nil.

At this point, this should be the only variable in your ViewController.swift.

Connected UITableView element

4.2 Creating the model for the data

We want to follow the model, view, controller (MVC) convention in this tutorial and create separate classes to handle and store the data. Let’s create two new Swift files (classes) to help us with these tasks, HomeModel and LocationModel.

Right click or CMD + Left click and select new file from the File Inspector.

Adding a new class in Xcode

Home model class

Location model class

Let’s start with our location model class, this will serve as our container to store the incoming data.

Notice that this class inherits from the root NSObject, and has four variables which represent our properties. Each of these are optionals because we do not know if they will contain a value or not, however, in this tutorial we will make sure that each property does indeed contain a value.

This class also conventionally has an empty constructor, a parameter accepting constructor, and a function to output it’s state.

Now we can set up HomeModel.swift, which will pull the JSON data from our service.php file, parse it accordingly, and send it to our view.

We’ll need to declare a protocol to broadcast to our view controller which method it should expect to handle if it receives a notification. Specifically, this protocol will serve to transfer data from the home model to the view controller.

Let’s also set up a few variables that we will need.

In lines 3-7, we declare our HomeModel protocol and we also declare a delegate property in line 11 which is explicitly of type HomeModelProtocal.

This let’s other classes know that if they want to handle the delegate method in this protocol, they must conform to the protocol to set themselves as the delegate (assign themselves to the delegate property).

You’ll see this in action later on.

Line 14 declares our data variable which will be responsible for storing the incoming bits and Line 16 declares the urlPath to connect to.

Remember to change the URL to your own PHP service.

4.3 Downloading and parsing the JSON feed

In the previous section when we worked on the PHP service, we returned the results as JSON.

Now we are actually going to parse those items here in the HomeModel class. To do this, we are going to create a function “downloadItems”, which will be responsible for the process of retrieving the data from the MySQL database and handling it.

We’re going to use the NSURLSession class to download the JSON feed, and conform it to the NSURLSessionDataDelegate which will let us implement the appropriate delegate methods that get fired when certain events happen during the download process.

Let’s see what our HomeModel.Swift should look like now:

Ok let’s notice a few things here. On line 8 we are now conforming to the NSURLSessionDataDelegate, and line 18 declares the downloadItems function.

Lines 20-27 initialize the NSURLSession, assign it a task, and start the data retrieval process.

Line 31 is a delegate method which appends the data to our NSMutableData instance variable as it receives the data from the source. This function is responsible for storing the incoming data.

Line 36 is also a delegate method that checks to see if the data was received without error, and if so, calls the parseJSON method which we will see in the next screenshot. Note that it checks to see if the optional parameter error is nil, meaning that it has not been set, and then acts upon that accordingly. This a is a good example of the advantage of using optionals.

Line 53 actually parses the JSON using the data that was received from our NSURLSession.

Line 64 loops through the JSON objects and stores them in an NSDictionary object so that they can be split into key-value pairs.

Line 69 instantiates a LocationModel object which will be used to store each element in the specific JSON object.

Lines 72-75 use optional binding, the “if let” checking mechanism, to make sure none of the JSON elements are nil. After the check, if all elements have values, the location object is set.

Line 85 adds the current location object to a mutable array and is now ready to be sent to the view controller via the protocol method.

Lines 89-91 pass the locations array to the protocol method making it available for the view controller to use.

Notice on line 89, the “dispatch_asynch” closure that wraps the delegate call. This is a thread issue, and it is the convention for methods that call UI updates to be wrapped with this particular closure to access the main queue. If you are also unfamiliar with the syntax, make sure to review closures in the Swift docs.

The next thing we have to do is implement the “downloadItems” method in the view controller to let it know when the locations array is passed so that it can populate the table view.

4.4 Populating the table view with locations

Now our focus is back to the view controller.

Let’s navigate to ViewController.swift and set up a few things. Just like we are going to conform to the HomeModelProtocol to get notified when the locations array is ready, we need to also conform to the UITableView protocols to interact with the table view.

Let’s first notice on line 3 that we are conforming to the protocols mentioned above.

Lines 7 and 8 declare a NSArray to store the location objects and also declare a reference to our location model for use down the line.

In the “ViewDidLoad” method, we’re setting the ViewController object as the data source and delegate for the table view element.
This will let us implement the table view delegate methods farther down to populate the table view with data.

We also instantiate a HomeModel object, set this ViewController object as the delegate, and call the downloadItems method which starts the data retrieval from our database.

Lines 25-28 implement the HomeModel’s protocol method, “itemsDownloaded”. In this method, we store the results passed back to us through delegation and call “reloadData” on the table view which will cause it to fire off the delegate methods down below.

Line 31, the method specified by “numberOfRowsInSection” returns the expected number of rows in the view. This will cause the table view to call the “cellForRowAtIndexPath” method on line 37 that many number times (one for each row). It will only call that method if the row is in the view.

On Line 37, this method expects us to create a table view cell, initialize it with some data, and return it for display. To do this, we get a copy of the cell we added to our storyboard which we named “BasicCell”.

This method also tells us which row of data it’s trying to display, so we can use this information to access our feed data array to get the appropriate Location object that this table row is tying to display, Line 42.

We then configure the table cell with the data from the Location object, specifically the address, and then return it, Line 44 and 46.

At this point if you run your application you should see your table view populate with the addresses from the MySQL database!

Showing MySQL database data in a table view!

4.5 Adding a second view controller: the map view

The first thing we need to do here is add a second view controller.

Let’s head to our Main.Storyboard, drag the view controller element from the object library, and place into our scene. Just like we did for the first view, lets set the size to 4.7 in.

Adding a second view controller in Xcode

We are going to need some sort of navigation mechanism to allow us to switch from one view to the other.

To do this, click on the first ViewController we created with the table view making sure there’s a blue outline around it.

Then, go up to the “Editor” on the menu bar and select “Embed In” followed by “Navigation Controller”

Embed view controller in a navigation controller in Xcode

If done correctly, you should now have a navigation controller which connects to our first view controller. Change the size on the navigation controller to 4.7 in. like we have done previously. Also notice that there is a arrow pointing to the navigation controller, this is our entry point to our scene. As of now, there is nothing connecting our first view to our second, and we need to fix that.

Lets make sure you storyboard looks like this first:

Adding a second view controller to your Storyboard

Before we actually make a connection between our two view controllers, lets add a map view to the empty view controller.

Search for the Map Kit View in the object library and drag it onto the view. Resize it so that it fills the entire view.

Adding a map view in the storyboard

Now lets create a new Swift file so that we can interact with this Map View. Right click the root folder and create a new Swift file named “DetailViewController”

Adding detail view controller

Let’s now define our class:

Notice that we subclassing UIViewController and have the viewDidLoad method just like our other view controller.

After creating the class, go back to Main.Storyboard and select your second view controller. To make sure you are actually on the view, click on the following icon at the top of the view:

The view controller icon in the storyboard

This will create that surrounding blue outline.

Now under the “Identity Inspector” in the right pane, we are going to specify that this view will be controlled by our DetailViewController.Swift class.

Setting the custom class of a view controller through storyboards

Now we need to control drag the map view to the our DetailViewController.Swift as we did previously when we connected our table view. If you forgot how to do this, please review the previous sections.

Name the IBOutlet “mapView”.

At this point you will notice an error, and that perfectly normal. We need to add the MapKit framework to our Xcode project so that it knows what MKMapView is.

Let’s also added a variable “selectedLocation”. This will store the location that is passed through the table view.

4.6 Adding the MapKit framework

Click the project node in your file navigator and the center pane will change to the project settings.

Project settings in Xcode

Scroll down to “Linked Frameworks and Libraries”, click on the + sign, then search and add the MapKit.framework

Adding the MapKit framework to Xcode

Now go back to the DetailViewController.Swift and under “import UIKit” add “import MapKit”. This will fix the previous error you were getting.

Now time to write some code!

4.7 Transitioning to the map view

Actually, there’s one more thing to do before we can start coding. We need to connect the the two view controllers so that when an address is selected from the table view, it can transition to the map view.

To accomplish this, we need to add a segue of the transition. A segue is like a transition that we call in our code to trigger between scenes.

To do this, we will control click on the yellow icon of our first view controller containing the table view, then drag the blue connection to the adjacent view controller containing out map view.

Head over to Main.Storyboard and let’s add that segue.

Adding a segue to a second view controller in storyboard

We are just going to use a “Show” segue, which essentially pushes the destination view controller onto the navigation stack and provides a back button to navigate back to the source.

After clicking “Show” on the segue menu, you should now see the connection between the two controllers.

segue in your storyboard

Now we have to give this segue an identifier so that we can trigger it programmatically in our code.

Click on the actual segue and then under the “Attributes inspector” on the right pane, name the identifier “detailSegue”

Naming the segue in your storyboard

Let’s navigate back to our ViewController.swift so that we can add the code behind the segue.

On Line 50 we see another UITableView delegate method “didSelectedRowAtIndexPath”. This method gets triggered specifically when the user taps a row.

Since this ViewController has already assigned itself as the delegate of the table view element, it can implement this method.

In this method we store the Location object that the user clicks on via our “selectedLocation” instance variable.

Then we use our segue which we name “detailSegue” and call the “performSegueWithIdentifier” method listed on line 57. This method gives us the opportunity to execute some code before the view finishes transitioning.

At this point, the DetailViewController has already been created and we are referencing it via “segue.destinationViewController” on line 59.

Line 62 passes the Location object that was set in the previous method to our DetailViewController instance variable “selectedLocation”.

Now when the user taps an address, the view will transition to the second view controller containing the mapView.

It’s time to implement the code that will map the location!

4.8 Mapping the location

Let’s head over to our DetailViewController.swift. We have access to the location object that we need to map thanks to the “prepareForSegue” method in our ViewController.

However, if we try to set the map location in the “viewDidLoad”, the map may have not finished initializing yet and we will not be able to see the animation to our desired location.

To fix this, we’re going to override the “viewDIdAppear” method and place the code there to allow a zoom in animation to our desire coordinates.

Here is the code you should add to your DetailViewController to make this happen:

Looking at the viewDidAppear method on line 15, we see the code that sets up our map.

Lines 17-20 set up the coordinates using the latitude and longitude properties of our location object.

Lines 22 and 23 initialize the mapView property and specify it to the appropriate region.

Lines 25-27 set up a pin and place it at the appropriate place on the mapView, and line 30 creates a name title for the pin when clicked.

Now try building your application and you should be able to transition from the table view to the map view where you will see a pin located at the address tapped.

Mapping a location from the MySQL database

4.9 Finishing touches

Let’s go ahead and do a little customization for the fun of it.

Head over to the Main.storyboard and click on the top portion of the view controller containing the table view. This should pull up the “Navigation Item” menu under the “Attributes inspector” in the top right pane.

You can adjust the title of this view controller and the title of the back button located on the other view controller containing the map view.

Changing the title of the view controller

Final location demo

Final location demo Map View


So there you have it! How to connect to a MySQL database from an iPhone app or more accurately put, how to retrieve data from a MySQL databased from your app.

If you enjoyed this tutorial:
Please help me by sharing, tweeting and liking it with the social buttons below. I really appreciate it!

I realize that some of the Swift code in this article may be foreign to you but for students of my course, this is all code which they have learned already.
I highly encourage you to check out the course or start with the basics if you haven’t done that yet.

If you run into some errors, check out my write up of common Xcode errors first and then leave a comment below and we’ll get to the bottom of it!

What’s next

One app down, two to go!

Click here to go to the next chapter
Click here to go back to the guide main page