How To Write A Simple PHP/MySQL Web Service for an iOS App

A tutorial on how to write a simple PHP/MYSQL based web service that you can communicate with from an iOS app. By Ray Wenderlich.

Leave a rating/review
Save for later
Share

Web Services Rule!

Web Services Rule!

As an iPhone/iPad developer, it can be really useful to be able to write your own simple web services that integrate with your apps.

For example, you may wish to display some news updates that come from your web server, and display it on startup. Or perhaps store some user data “in the cloud”. Your imagination is the only limit!

In this first tutorial in this two-part series, you’ll go step-by-step through the process of creating a simple web service, based on a promo code system I included in my latest app, Wild Fables. In the next part of this series, you’ll write an iOS app that integrates with this web service!

To run through all of the steps on this tutorial, you’ll need a web server with MySQL and PHP. If you do not have a web server already, you have three options:

  • If you want to enable Apache/MySQL/PHP directly on your Mac (for free), there are lots of good guides out there, here’s one I found with a quick Google search.
  • If you want to rent a web server online (usually for $$), there are many good choices out there, but the one I personally use (and enjoy) is Linode – check this tutorial for more information.
  • And if you’re just too lazy to do either of the above, you can just read through the steps below, and use the web service I’ve already made in part 2 of series :]

You don’t necessarily need to know PHP or MySQL to go through this tutorial (although it will be helpful!), as the tutorial includes all of the code you’ll need.

What You’ll Make

As you might know already if you’ve added In-App Purchases into your app, there is no built-in system provided by Apple to give out promo codes for your in-app purchases.

However, it can be extremely helpful to build your own promo code system for your in-app purchases, for several reasons:

  1. First, it’s great to be able to give out promo codes for in-app purchase content to professional app reviewers.
  2. Second, it’s also nice to be able to give out promo codes to your friends so they can check out your app.
  3. Finally, if you build your system right, it also provides a great way to track out which of your marketing vectors pay off (and which don’t) – more on this in the second part of the series!

So in this tutorial, we’re going to build a system where you can enter a code into your app, and it will connect to a web service to see if the code is valid or not. If it’s valid, the app will then “unlock” some content.

Don’t worry if you have no plans on adding this particular system into your app – you’ll learn the general technique of developing a web service and integrating it with an iPhone app as well!

Creating the Database

The first step of this project is to create the database tables you’ll need. For the purposes of this tutorial, you’ll need three database tables:

  • rw_app: A table to keep track of the apps we’re using the promo code system for. This way, you can use the same database tables for multiple apps.
    • id: Unique id for the app.
    • app_id: Unique string identifying the app (mainly for your own purposes).
  • rw_promo_code: A table to keep track of what promo codes are available.
    • id: Unique id for the code.
    • rw_app_id: The app id this code is for (from rw_app).
    • code: Alphanumeric code that the user types in to unlock something.
    • unlock_code: Alphanumeric string you’ll pass back to the app so it can know what to unlock.
    • uses_remaining: You’ll set things up so that codes can be used more than once – this way you can give out the same code to all of our friends on Twitter, for example. You’ll use this field to specify how many uses the code should have, and every time it is used this will be decremented by one. When iti hits 0, the code is no longer valid.
  • rw_promo_code_redeemed: A table to keep track some info each time a promo code that is redeemed. This will help us prevent one device from redeeming the same code multiple times (if it’s a multi-use code), by simply checking to see if the device has already used the code.
    • id: Unique id for the app.
    • rw_promo_code_id: The id of the promo code redeemed (from rw_promo_code).
    • device_id: The device identifier of the redeemer.
    • redeemed_time: A timestamp of when the code was redeemed.
  • id: Unique id for the app.
  • app_id: Unique string identifying the app (mainly for your own purposes).
  • id: Unique id for the code.
  • rw_app_id: The app id this code is for (from rw_app).
  • code: Alphanumeric code that the user types in to unlock something.
  • unlock_code: Alphanumeric string you’ll pass back to the app so it can know what to unlock.
  • uses_remaining: You’ll set things up so that codes can be used more than once – this way you can give out the same code to all of our friends on Twitter, for example. You’ll use this field to specify how many uses the code should have, and every time it is used this will be decremented by one. When iti hits 0, the code is no longer valid.
  • id: Unique id for the app.
  • rw_promo_code_id: The id of the promo code redeemed (from rw_promo_code).
  • device_id: The device identifier of the redeemer.
  • redeemed_time: A timestamp of when the code was redeemed.

Here are the MySQL statements you’ll need to create these tables:

DROP TABLE IF EXISTS rw_promo_code;
DROP TABLE IF EXISTS rw_app;
DROP TABLE IF EXISTS rw_promo_code_redeemed;

CREATE TABLE rw_promo_code (
    id mediumint NOT NULL AUTO_INCREMENT PRIMARY KEY,	
    rw_app_id tinyint NOT NULL, 
    code varchar(255) NOT NULL,
    unlock_code varchar(255) NOT NULL,
    uses_remaining smallint NOT NULL
);

CREATE TABLE rw_app (
    id mediumint NOT NULL AUTO_INCREMENT PRIMARY KEY,	
    app_id varchar(255) NOT NULL
);

CREATE TABLE rw_promo_code_redeemed (
    id mediumint NOT NULL AUTO_INCREMENT PRIMARY KEY,	
    rw_promo_code_id mediumint NOT NULL,
    device_id varchar(255) NOT NULL,
    redeemed_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

On your web server, you need to create a MySQL database and create the three tables as specified above. The way you do this varies depending on your web host, but just in case it’s useful I’ll tell you the steps I use on my web host, where I have full command-line access.

I save all of the above SQL statements to a file called create.sql, then I create and populate a new database with the following commands:

rwenderlich@kermit:~$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1286
Server version: 5.1.37-1ubuntu5.1-log (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database promos;
Query OK, 1 row affected (0.00 sec)

mysql> use promos;
Database changed
mysql> grant all privileges on promos.* to 'username'@'localhost' identified by 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye

rwenderlich@kermit:~$ mysql -u username -p promos < create.sql
Enter password: 
rwenderlich@kermit:~$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1417
Server version: 5.1.37-1ubuntu5.1-log (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use promos;
Database changed
mysql> show tables ;
+------------------------+
| Tables_in_promos       |
+------------------------+
| rw_app                 | 
| rw_promo_code          | 
| rw_promo_code_redeemed | 
+------------------------+
3 rows in set (0.00 sec)

Now you should have three empty database tables in a new database. Next, go ahead and add a test app and a test code with the following statements:

INSERT INTO rw_app VALUES(1, 'com.razeware.test');
INSERT INTO rw_promo_code VALUES(1, 1, 'test', 'com.razeware.test.unlock.cake', 10000);

OK! Now that the database is connected and populated, on to writing the PHP web service!