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

In this article I’ll show you from start to finish, how to connect an iOS app to a MySQL database.

Note: Newly updated for the latest version of Swift and Xcode!

If you’re used to working on websites and web apps, you might think that your iPhone app can connect directly to MySQL but unfortunately that isn’t the case.

We need a middle layer that sits in between the app and the database which will manage the transactions between them.

Don’t worry, we’ll go through all of that in this tutorial.

Here’s what we’re going to go through:

1. Sign Up For Web Hosting And Database

For web hosting, I choose to go with Bluehost because of their excellent customer support (I can get ahold of a real person pretty easily). Furthermore, I can create multiple MySQL databases and attach unlimited domains to one hosting plan which means that I can use this single plan for multiple websites or projects.

If you already have web hosting then feel free to use that. As long as you’re able to create MySQL databases, then you’re good to go!

Otherwise if you’re thinking of creating your own website or MySQL powered iPhone app, Bluehost is a great choice and you can also get a discounted price by going through the link below:

Just to be transparent with you guys, at no extra cost to you, I’ll earn a commission if you decide to sign up so thank you for your support! It allows me to continue to provide high quality tutorials for you guys free of charge.

So if you’ve already got your own hosting, you can skip this next part; otherwise, I’m going to walk you through how to sign up for your hosting and set up your MySQL database so that later on, we can use our iPhone app to connect to the data we store inside of it.

1.1 Bluehost landing page

On this page, click the green “get started now” button.

On the next screen, you’ll be able to select a hosting tier.

Typically I just choose the cheapest option because you can always upgrade later on if you need more power.

Select a tier (I chose Basic) and you’ll see the next screen:

1.2 Sign up page

On this page, you can either choose to sign up for a new domain or use an existing one that you have.

A free domain name is included with your plan, so I would recommend creating a new one as it’s worth about $10 a year.

The second option to “transfer your domain” is worded a little strangely because you don’t actually have to transfer the domain to Bluehost. Rather, you just have to go to your registrar where you registered your existing domain name and then change some configuration settings to point to Bluehost.

In this tutorial, I already have an existing domain name to use so I’m going to type it into the “I have a domain” box and click next.

If you need a new domain name, then type in your desired domain into the “new domain” box and click next.

1.3 Account information and web hosting plan selection

This is the final page of the sign up process and you’ll have to provide your account information, select a web hosting plan and enter your billing information.

The account information part is pretty straight forward but I will say that you need to provide a real telephone number because they’ll give you a call to confirm your order (they’re on the ball with fraud and security!).

For the hosting plan, you’ll get the best rate if you go with a 3 year plan but it depends on your budget. One thing to note is that the payment is up front, however it’s not a contract and you can cancel at anytime (you’ll get a full refund within 30 days or after 30 days, you’ll get a refund for the unused portion of your selected plan).

If you choose to go with the 1 year plan, you end up paying less up front but more in the long run if your app or website is successful and you need to renew it in a year.

As for the other options like SiteLock or Site Backup, I usually opt out of those but for the Domain Whois Privacy option, I do consider getting that to keep my domain registration information private. You can click the “more information” link to see a comparison of what your domain registrant information would look like with and without whois privacy.

After you enter your billing information, you’ll be directed to a confirmation page.

1.4 Confirmation page

Congratulations! You’re nearly finished with setting up your account. The next step is to set a password. Follow the link to create a password.

Be careful to choose a password that will satisfy all the conditions it outlines.

You won’t be able to save your password until the “password strength” bar is green.

Once you come up with a worthy password, click “Save”.

1.5 Setting up your account

Now that you’ve signed up and set your password, all you have to do is wait for your activation email to arrive in your inbox.

Until then, there are certain areas of your control panel which you won’t be able to access because they’re still setting up your account. Unfortunately, setting up a new database is one of those tasks where you have to wait until you get your confirmation email in order to do.

Usually it’ll take about 15 minutes but if you don’t receive it after a while, don’t hesitate to contact support via live chat. You can get a hold of a live person in a few minutes and they’ll help you resolve any issues!

What’s next

Now you’re ready to create some sites and databases to power your iPhone apps.

Let’s move forward!

2. How To Set Up Your Database

Once you’ve received your confirmation email from signing up, you can now login:

Click the “Control Panel” link.

You’ll be brought to a screen with lots of options and icons.

Scroll down until you find the “Database Tools” option and then click “MySQL Databases“:

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

2.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

2.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

2.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.4 Setting up database tables and users

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.5 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

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

If it doesn’t prompt you to login, you’ll arrive at a screen like this:

PhpMyAdmin Main Screen

If you notice in the left hand side, it’s the database we created!

Click that database that we created and then the right hand pane will change to show us its details.

2.6 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.7 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 PHP Web Service To Query The Database

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 pop up a dialog screen to ask where you want to start:

file manager webroot

After clicking “Submit“, it’ll bring you to a screen where you can see all the files on your web root.

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 To Show The Data

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

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.

While still having the Table View element highlighted, click the add constraints button shown in the screenshot below and then click each of the margins so it activates (it’ll become red). Make sure all the margins are 0 and “constrain to margins” is unchecked. Then click Add 4 constraints.

Setting constraints for mapview

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.

Click on the Assistant Editor button illustrated in the screenshot below:
assistant editor button

If you cannot find the ViewController.swift on the right hand pane, 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.

Connecting an IBOutlet

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 HomeModelProtocol.

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. 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

While still having the MapView highlighted, click the add constraints button shown in the screenshot below and then click each of the margins so it activates (it’ll become red). Make sure all the margins are 0 and “constrain to margins” is unchecked. Then click Add 4 constraints.

Setting constraints for mapview

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.

Hold CTRL and click the table cell and drag to a second view controller in storyboard

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.

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.

Source Code
Click here to download the source code for this project.
If you enjoyed this tutorial:
Please help me by sharing, tweeting and liking it with the social buttons below. I really appreciate it!

178 thoughts on “The Best Way to Connect Your iOS App to MySQL Database (4 Steps)”

  1. Hello one and all. This is my first ever blog post, I am a total newbie to php, C and mySQL. Firstly, thank you so much Chris for this and your other sessions and thank you too to all those with questions and answers below which helped me immensely. I thought I’d submit pointers to others who might be stuck, showing where I got stuck and then fixed things. For clarity, I’m using XCODE 6.3 running on OS X 10.10.3, and and used MAMP 3.2.1 to setup php and mySQL. Here goes:

    I used MAMP and the linked myPHPAdmin to complete Part 1 – MAMP helps get the Apache server running locally, then provides the way in to create the database, the password and the user with the right privileges. All straightforward, but watch out for a couple of things – MAMP and MAMP pro share common htdocs folder, but difference databases, so they can’t be used interchangeably. I also accidentally deleted the htdocs folder, causing mayhem, as that is where MAMP and MAMP pro look, for various default positions. Recreating it solved problems. Final tip – If you are using MAMP (or pro) it comes with default ports set that will NOT cause a clash with any Apache server which you may have running already. When you are sure you don’t have any inbuilt Apache running, you need to switch the default ports to the suggested 80, 443, 3306.

    In part 2, I managed to introduce two-hours of misery! The symptoms did not appear until much later, but the cause was here: Please check the spelling and Capitalisation of the field names. I accidentally used name instead on Name, and so on. This caused me to think that my localhost settings were somehow wrong. I could get responses in part 4 using someone else’s database (thank you rv (below) for but not from my own database running on localhost! More follows.

    In part 3, the trick is to get the JSON text to appear in a browser window in step 3.2. Creating the service.php file can be tricky – I started using Apple’s TextEdit, but had problems with .txt extensions being amended or not displayed, so eventually switched to Xcode. Copying Chris’s code in from above does work, however, there are two potential gotchas: Some sites I found suggest that after line 9 in the code in part 3.1 the code ‘exit();’ should be inserted, as a failure should end the php code. The second one is that the download file for this code contains an additional line after line 35 in section 3.1 above (‘mysqli_close($result);’). This is not required, so you can comment it out with //. Finally, don’t forget to update the code in Line 4 of 3.1 to use your user, database and password from part 1.

    In part 4, I’m only up to 4.4, but wanted to share the point on ‘my code works on someone else’s php, but not mine on localhost’. The real clue was when I downloaded and tried Chris’s completed code. It worked (!) even though no words appeared in my cell. I tumbled it when I clicked on either of the first two cells on my table view controller (I had two entries in my database), it opens the map, and plotted a pin off the west coast of southern Africa (Lat and Long = 0). So I had two entries in the table – and nothing in the third cell. Tracing back to when I lost the valid data, it was in lines 54 to 57 in HomeModel.m in 4.3 above. The JSON conversion steps. I was using name in my database definition (and latitude vice Latitude) and so on, so there was no match, and the empty data followed through. I think the comment below: “Adding the line $con->set_charset(“utf8″) fixed it!” may avoid the problem, but not correct it, but I can’t be sure.

    Sorry for the length. I hope it’s of use to someone. Thank you once again Chris – I hope you find time for a Swift update sometime soon.

  2. Hello there! Your tutorials are great 🙂 I’ve had great success 🙂
    I’m stuck on 3.1 here. I cut-n-paste the php text, save it to a service.php file and so on. NOTHING shows up when I run the file via http://localhost/service.php. I threw in a standard line of text at the bottom of service.php, and THAT LINE OF TEXT shows up, but the php Stuff doesn’t do anything in my browser 🙁
    Any help? I’ve been trying to figure it out for days.

  3. Still struggling myself but I have not has time to review the link Chris sent a few weeks back. I am wondering if I am running it a limit in the array as I am pulling in more than 26,000 entries.

  4. Hi Chris, your explanations really have clicked and helped me. I am running into the problem getting the “while” statement in the PHP service to execute properly. The big problem for me is I am not getting any error response so I an not real sure where to look for the solution. As a novice to PHP and MySQL I am sure I am missing a simple component.


  5. Hi Chris, I really love all of your tutorials – super helpful and beginner friendly!
    Have you created the Swift Version of creating an app from a WordPress page?

  6. In line 50 of HomeModel.m, where the code is NSDirectory *jsonElement = jsonArray[i], I encounter an error even when copying and pasting the code directly. The error says “Subscript requires size of interface “NSArray” which is not constant in non-fragile ABI.” Has anyone else encountered this problem and does anyone know what I’m doing wrong?

  7. hey instead of the the data being shown when i tested the service.php. It showed the php code. By the way I am using xampp for this.

  8. hello chris thanks for your excellent guide. Would it be possible to send data from text fields in the app to the database using the web service?

  9. Hi Chris. At the risk of sounding repetitive, I must say your tutorial was one of the easiest to follow. The level of detail you went into is impressive and I can see how you get into a newbies mind and then do your tutorials. Keep up the good work.

    I am using your Model class to connect to the db and getting a list of items back. However once the user clicks on an item i would like to make a further database call to get details of that item. From the current code, it seems I cant leverage the same Model class and it is very specific in what it returns and parses, etc. Does this mean I have to write a Model class for each different type of db call that I make? Is there a more efficient way to reuse code?

    • Hey Murtaza, thanks for your kind words and i’m glad you enjoyed it. The model class would contain all of the various calls to the database. Just separating the responsibilities like that (between the model and the view controller) will go a long way for debugging or updating code in the future.

  10. Hi Chris, thanks for the tutorial. It was really helpful. I can now access and see the records on the iPhone screen. Can you please provide a hint on how to edit each record or add a new record?

    • Hey Reza, thanks for reading!
      In order to update or insert new records, you’ll have to create a php service to reads the request for the parameters to insert or update.
      Then from the iOS side, you need to include those parameters as part of the request to the service.

  11. Hmm never mind. I figured it out. Forgot to upper case the the first letter of the my database fields. All good now 🙂 Thanks again!

  12. HMM did my previous comment get deleted? probably cause I put a link in it. Anyways I build the app, then plugged in the location of web service and no locations show up on my build and no errors stop the build from happening.
    Then I used Chris’ source code and I get the same behavior. Anyone else having this issue?

  13. I also just tested my json through a linter and it came up as valid json. but no locations are showing up when i run the app. Anyone else having this issue? I just wish at least it would show me an error 🙂
    Thanks again for writing this tutorial.

  14. Hey Chris, I just tried running the app building it myself and using your source code. In both cases I am getting blank fields. I am using this data I have the service set up but I just want to troubleshoot the problem with the data not being pulled. Also, I am not getting any errors when it build. Is the json output correct?

  15. Thanks for the tutorial. I have a problem with my special chracters in database. I have set utf8 unicode but still getting question marks.. I think we should modify our php file, (encoding decoding problem?)

  16. Great tutorial Chris, it’s really helped me! Everything is working just as you said. Was just wondering how I would go about adding or editing locations? Because the results are in an array, I’m having a lot of trouble posting a change back to the MySQL database..

  17. Thanks for this tutorial, would love to see this in Swift.
    How do I make this more secure ? Now anyone can use the service and look into my database table.
    Also is there a limit to JSON ?
    With a lot of records the result is a blank page, only when using LIMIT in the SQL Query it shows the JSON result.

  18. Great tutorial Chris, Thanks so much.
    Just wondering if you had plans to update Objective-C code to Swift any time soon?

    Thank you.

  19. Hey Chris! Great tutorial.

    My question is: how can I make login screen using the informations from a database? Can you please help me?


  20. I had to create a Location.m file and put the code below in it. I could then compile just fine.

    #import “Location.h”
    @implementation Location

  21. Hi Chris, Brilliant and clear instructions but I’m obviously missing something basic. When I upload the service.php file and then try it in a browser, I’m getting “unexpected end of file”. From what I can see in the php file the “>” character in the while loop is matching up with the “<" at the start of the php file, or is it just my text editor fooling me. Any ideas?

  22. hello, thx for the tutorial.

    my cells doesn’t show anything…

    here’s my JSON result

    [ { “dede”: “Bienvenue” }, { “dede”: “Découverte : la Zumbatomic” }, { “dede”: “Jeux de mains, Jeux demain !…” }, { “dede”: “Allonne Kodokan club” }, { “dede”: “BRC : Les Beaux jours arrivent” } ]

    and my parts of modified code

    in location.h
    @property (nonatomic, strong) NSString *titre;
    in viewcontroller.m
    myCell.textLabel.text = item.titre;
    in homemodel.m
    newLocation.titre = jsonElement[@”dede”];

    is there any pb with that?


  23. Hello Chris,

    Thanks for the tutorial. I been following at your posts.

    In this one I got stucked pretty soon. I had previously a host in Godaddy. So I proceed to create the database. After that the service.php file and I uploaded by ftp. But when I try to look for it in the browser “” I cannot get thr right info, instead I received this error.

    Internal Server Error
    The server encountered an internal error or misconfiguration and was unable to complete your request.
    Please contact the server administrator to inform of the time the error occurred and of anything you might have done that may have caused the error.
    More information about this error may be available in the server error log.

    Do you know something about this?. How to deal with it.


    • Hey Naoa18, that’s most likely cause by an error in your PHP code. Godaddy is not showing you the actual error message and instead is telling you to check the server error log! I’d suggest contacting their support to see how to see the PHP error message or where the log is so you can check it. The error message will give you a hint on what’s wrong with the PHP code.

  24. // Create new HomeModel object and assign it to _homeModel variable

    _homeModel = [[HomeModel alloc] init];

    // Set this view controller object as the delegate for the home model object

    _homeModel.delegate = self;

    // Call the download items method of the home model object


    —-> [_homeModel downloadItems];

    • @ Maverick, look in your ViewController.h file and make sure there is a #import “HomeModel.h” near the top.
      Also, it looks like you misspelled _homeModel in the @interface ViewContorller () section.

  25. Hi Chris,
    I am following this tutorial in Xcode 6 and have now
    gotten to the point where you say that running the app should display
    the two addresses. When I open the app in the simulator, I get only a
    empty table. by means of putting Log statements throughout the code, it
    looks like the JSON is being downloaded properly, but then when it
    reaches the part at the end of connectionDidFinishLoading

    if (self.delegate)
    NSLog(@”Data is read”);
    [self.delegate itemsDownloaded:_locations];

    This part never gets performed and thus it appears the table view does not get refreshed with the downloaded data.

    Any suggestions?

      • aha! I missed this part:
        // Set this view controller object as the delegate for the home model object
        _homeModel.delegate = self;

        and the funny (in a sad way) is that I missed it twice (retyped out the code here twice to try to get a better understanding of what the pieces are doing)

        Thanks Chris!

  26. Hello Chris, Thank you so much for this great tutorial!!!! I have one question so I am making an app where instead of a map view it just shows a string of text in a UITextField such as like the name of the address or something but I cannot figure out how to do this. Any Help would be great thank you so much!

  27. Hi Chris, I try to use your php code to extract data from mysql and use it in xcode using swift. I keep getting error when trying to run in xcode and somehow I think the problem come from the NSJSONSerialization because if I comment it out, there is no no error and I could print out the content from the url. The funny thing is if i try to use some others json format site eg., I can get it working without any error! So now it looks like the site itself and I just couldn’t figure out what is wrong………please help……….

  28. Hi Chris. Longtime iOS front-end developer, learning back-end, came here to learn how to set up the PHP side of things. I set up your PHP script with the proper db name and user information, but when I navigate to the file on my web server I get the following message:

    Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in /home/amarkon/public_html/dbaccess.php on line 36

    Any ideas?

    Question 2 is how to customize the script so I can run a custom SQL query in the app?

  29. Hi Chris.
    Awesome tutorial, very clean and understandable!!!
    I have tried everything and it works perfect with me. My question is: how can i make login screen before the table view with different users, so that 2 or 3 different people can use the database?
    Best regards from Bulgaria

  30. Hi, Thanks for this great tutorial!

    I’m trying to follow every step of your tutorial except the json data. I don’t want to use location information, but a product information. I still use Location.h and Location as the structure, however I change the field names into mine. as below:


    @interface Location : NSObject

    @property (nonatomic, strong) NSString *ID;
    @property (nonatomic, strong) NSString *title;
    @property (nonatomic, strong) NSString *sub;
    @property (nonatomic, strong) NSString *price;


    Accordingly, I modified the scripts in HomeModel.m as below:

    for (int i = 0; i < jsonArray.count; i++)
    NSDictionary *jsonElement = jsonArray[i];

    // Create a new location object and set its props to JsonElement properties
    Location *newLocation = [[Location alloc] init];
    newLocation.ID = jsonElement[@"ID"];
    newLocation.title = jsonElement[@"title"];
    newLocation.sub = jsonElement[@"sub"];
    newLocation.price = jsonElement[@"price"];

    // Add this question to the locations array
    [_locations addObject:newLocation];


    Now, the problem is that I cannot build this program, the errors come as below:

    "_OBJC_CLASS_$_Location", referenced from:
    objc-class-ref in HomeModel.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    I have no clue what the errors talking, please help and advise!

  31. Thanks for this great tutorial!

    I’m trying to apply your code to my school project. Still, I have a problem with the tableview. My tableview is blank, although I have checked that the PHP file and database are OK. The JSON feed is valid and the cell identifier is also OK. I have also problems with the tableview object in the storyboard, I have to shrink it about 15 pixels from the right side, otherwise the row lines continue over the right edge of the screen. I had similar problems with my previous exercise, which was also about tableview. Is there any well-known solutions for issue like this?

Leave a Comment