Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

Swift Networking Tutorial Index: Building a Swift App to Query a Custom API

Our tutorial series on networking in Swift provides a detailed, practical overview of the topic from the back-end API to the end user application. The series is broken up into two major parts. In the first part, we build a custom web service in PHP which provides access to a RESTful API that serves inventory content from a hypothetical plumbing supply shop. Knowing how to create a simple API is useful for delivering mock content during your app development cycle, and provides application developers with more knowledge on precisely how such a service is constructed. In the second part, we use table views to create a Swift application to query our custom API and deliver the contents of the service to the end user of the application. Use the index below to navigate the tutorial.

Introduction
Introduction and Overview: From the Back End API to the End User Application

The Web API
Building a RESTful API in PHP, Part 1
Building a RESTful API in PHP, Part 2

The Swift Client App
Networking in Swift: Building the Swift Client, Part 1
Networking in Swift: Building the Swift Client, Part 2
Networking in Swift: Building the Swift Client, Part 3
Networking in Swift: Building the Swift Client, Part 4
Networking in Swift: Building the Swift Client, Part 5
 


This tutorial was authored by Stefan Agapie, a Senior iOS Software Engineer, and adapted for the present piece.

Networking in Swift: Building the Swift Client, Part 3

This is part three in the tutorial segment on building a Swift client application to query a RESTful web API, from our series of articles on networking in Swift. In the first segment, we created a custom RESTful API in PHP that serves up the inventory of our hypothetical plumbing supply shop.

In this segment, we have been building a Swift client which queries this API and delivers that inventory content to our end user. In part one, we got our Swift application up and running. In part two of building the Swift client, we created our basic data model, hooked up the segues to our inventory views, and successfully handled raw responses from the server by printing them to the Xcode console.

In the present article, we'll create model objects from the JSON dictionary returned by the server (at the end of part two), and display our inventory item lists in their respective table view controllers.

Model Objects
When we left off in part two, we were filling out the requestInventory method in our PlumbingSupplyInventoryTableViewController. Currently, that method simply prints the returned JSON dictionary to the Xcode console. We'll now create model objects from this dictionary by factoring out the relevant code from the requestInventory method and placing them in a separate method to handle this logic. In your PlumbingSupplyInventoryTableViewController file, add the following method below the requestInventory function that we were working on in the previous article:

Notice that in the last line we do not print out the jsonResult dictionary object but instead wrap it in an array and return it to the caller. In the requestInventory method, replace the three lines of code we factored out into the new inventoryItems method with the following two lines of code:

If you run the app and select one of the two inventory item categories, you should see the same response as before in your console, but wrapped in an array. We'll now refine the raw JSON data. Replace the return [jsonResult] line of code in the inventoryItems method with the following snippet:


Let's take a closer look at this. The first line gets the raw data dictionary object from the JSON results container. The second line defines a container that will hold model objects that are built from the raw data dictionary objects from line one. Inside the for loop we iterate through the raw data dictionary objects and build an array of refined data objects. And in our last line we simply return the array of model objects.

If you now run the app again, you'll see the difference in the Xcode console output, which now returns a tidy array mapping individual inventory items to their memory locations. Let's display these inventory lists in their respective views.

Displaying Our Inventory Item List
Return to the main storyboard. Locate and select one of the table view cells from our PlumbingSupplyInventoryTableViewController scene. In the Attributes Inspector, locate the Style drop down menu and select the option “Basic.” Locate the Identifier field and type in “Cell”. Finally, locate the Accessory drop down menu and select the option “Disclosure Indicator.” Do the same for the other cell as well.

Now open the file PlumbingSupplyInventoryTableViewController.swift file. Inside and toward the top of the class, add the following property:

This data source property will supply our dynamic table view cells with the information to display on screen. The number of items in our data source will always be equal to the number of items from a single plumbing supply inventory category. In the same class  replace the default boilerplate code for the three methods below with the following snippets:

These data source methods are called by the system to query this controller on how to proceed when building our table view and displaying content within it. In the first method we simply tell the system that our table view will display only one section. The second method says that the number of items in our single table view section is equal to the number of items in our data source.

The last method does several things to build a table view cell. In the first line (line 12 in the snippet above) it dequeues a reusable cell. When scrolling a table view, table view cells that scroll off the screen are placed on a queue for reuse and cells that scroll onto the screen are removed from this queue and reused. This process helps speed up table view performance which makes possible the smooth table view scrolling with which we are all familiar. On the second line (line 13) we utilize the indexPath object to get the row number of the cell that is next to become visible in our table view; the row number corresponds to a unique item in our data source. There is a one-to-one correspondence between the cells and the items in our data source. The following line gets the name of an inventory item and assigns it to the label of the next cell to become visible. The last line simply returns that cell.

Let's jump back to where we defined our requestInventory function. In this method, replace this line of code that reads println(inventoryItems) with the following snippet:

What's going on here? In line 1, we capture a reference to the data source that is received from the self.inventoryItems(data) method call. The next segment is a C level API call to a dispatch system, on a queue of our choice, which executes code that we place inside its block/closure. The code inside the closure performs updates to our UI elements.

According to Apple's documentation, any code that updates UI elements must be executed on the main queue—which is what we do. The first line within the closure asks our table view to reload since we have assigned items to its data source. The second line hides the web activity indicator spinner, since our request for web content has terminated. Run the app and select on of the two plumbing supply categories. Once the content downloads you should see a table view similar to the one depicted below:


Success! We've successfully displayed the list of inventory items returned by the web API. Notice, however, that we did not use the callback responseHandler( error: nil, items: nil) closure but instead updated our UI in the method from above. We leave this as an exercise for the reader to implement. If you are not sure how to go about implementing this, don't worry, we wrote another method on a different controller that uses the closure to update its UI elements after an update. We do this towards the end of this tutorial.

This project can be found on GitHub.

We're almost done! In the next article, we'll display thumbnail images alongside each of the items in our inventory list above. And then in the final tutorial, we'll build our item description scene for each item in the inventory that displays the full image along with the extended description supplied by our API.

Index
Introduction
Introduction and Overview: From the Back End API to the End User Application

The Web API
Building a RESTful API in PHP, Part 1
Building a RESTful API in PHP, Part 2

The Swift Client App
Networking in Swift: Building the Swift Client, Part 1
Networking in Swift: Building the Swift Client, Part 2
Networking in Swift: Building the Swift Client, Part 3
Networking in Swift: Building the Swift Client, Part 4
Networking in Swift: Building the Swift Client, Part 5


This tutorial was authored by Stefan Agapie, a Senior iOS Software Engineer, and adapted for the present piece. 

Networking in Swift: Building the Swift Client, Part 1

If you've been following along from the beginning of this tutorial series on networking in Swift, you're now running a local web server and have created a simple RESTful API in PHP that serves up the inventory for our hypothetical Super PHPlumbing Bros. project. In this segment of the series, we'll build the iOS Swift client to bring that content to our end user. In the present article, we'll start our Swift project from scratch and create a single view application using a table view controller that will serve as the primary interface to our inventory of plumbing tools and supplies.

In the Beginning . . . 
Download and install the latest version of Xcode, if you haven't already, and fire it up. From the Xcode menu bar (or the Welcome screen) select File->New->Project. A window will appear with various options to choose from. In the left hand panel, under iOS, choose 'Application'. And in the main panel select 'Single View Application'. Then go ahead and click 'Next' as shown below.

On the following window you will be asked to name your application. Name it what ever you like. Under the Language section select Swift from the drop down menu. Make sure that the build is for iPhone in the 'Devices' menu, and then click 'Next' again.

You'll then be prompted to choose a location to house your project and will be given the option to place the project under source control. If you know how to use git for source control, then by all means use it! Otherwise, uncheck the box if it is already checked and click 'Create' to start up the project.

Displaying the Available Services
In our Swift application, we want to present the user with all the available services that our supply shop has to offer. Our custom API provides an interface to our inventory of Plumbing Tools as well as our inventory of Copper Pipes and Fittings. To present these options to the end user we are going to use a table view. So let's jump in. In the navigator panel (the left panel) of Xcode, locate and select the file named Main.storyboard.

Once the main storyboard loads, scroll to the pre-loaded Single View Controller and select it. When properly selected its border will turn blue, as seen here:

As we are going to use a table view, we can safely discard this default view controller. Delete the single View Controller by pressing the delete key on your keyboard, while the controller is selected. In the Utilities Panel on the right side of the Xcode interface, locate the Object Library submenu. Select a Table View Controller, and drag and drop it inside the main storyboard. 

While the new controller is selected, point your mouse toward Xcode's menu bar and select: Editor->Embed In->Navigation Controller. This embeds our selected Table View Controller into, you guessed it, a Navigation Controller.



A Navigation Controller is a stack for managing the presentation order of our view controllers. Select the Table View situated inside the Table View Controller, and then select the Attributes Inspector from the Utilities Panel. Locate the 'Content' field and select 'Static Cells' from its drop down menu.


You should see three cells appear inside the Table View. We only need two such cells, as this is where the user will be presented with the option to browse either the Plumbing Tools inventory or the Copper Pipes and Fittings inventory. Delete the bottom cell by first selecting it, and then pressing the delete key on your keyboard. Now let's name our two primary interfaces. For each of the two remaining cells, select the cell, and then locate the 'Style' field in the Attributes Inspector panel. From the 'Style' drop down menu select 'Basic'.


Both table view cells should now display a label that reads 'Title'. Two clicks in rapid succession on a label will place it into edit mode. Modify the titles so that they read from top to bottom, 'Plumbing Tools' and 'Copper Pipes and Fittings', respectively.

In order for the application to run, we need to specify the initial view controller that we want to load when the application first boots up. In the main storyboard, select the Navigation Controller. Then, in the Attributes Inspector menu, locate the check box that reads, 'Is Initial View Controller' and select it as shown below:

In the top left corner of Xcode make sure that the active scheme is set, and click the play button to build and run the application. Once the iOS simulator starts up, your app should look like this:

This project can be found on GitHub.

Success! We've built the primary view that will be presented to the end user when they open our iOS application. In part two of this segment, we'll begin building our data models. You can find part two in the tutorial on building the Swift client at the link.

Index
Introduction
Introduction and Overview: From the Back End API to the End User Application

The Web API
Building a RESTful API in PHP, Part 1
Building a RESTful API in PHP, Part 2

The Swift Client App
Networking in Swift: Building the Swift Client, Part 1
Networking in Swift: Building the Swift Client, Part 2
Networking in Swift: Building the Swift Client, Part 3
Networking in Swift: Building the Swift Client, Part 4
Networking in Swift: Building the Swift Client, Part 5

This tutorial was authored by Stefan Agapie, a Senior iOS Software Engineer, and adapted for the present piece. 

Networking in Swift: Building a RESTful API in PHP, Part 2

This is the third post in our tutorial series on networking in Swift. In the introductory article, we provided an overview of the project and set up our local server. In the next piece, we began building out our RESTful API in PHP, which will serve the inventory for our hypothetical Super PHPlumbing Bros. supply company to the custom Swift client we will construct in the final segment of the series.

If you've been following along thus far, you've set up your local server and completed building the first half of the API, which serves the inventory for the shop's supplies. In this article, we will complete our API by adding the necessary code to serve the content of our plumbing tools inventory.

Building the Plumbing Tools Interface
In creating the API for our plumbing tools interface, we will follow pretty much the same series of steps we took while building the plumbing supplies interface, continuing to add the necessary code to the bare bones API we started with in part one. Our skeletal structure now has some real meat on it. Your PlumbingAPI.php file should now look like this:

Jumping In . . .
Once again, let's begin toward the bottom, in the final else if block in the script, the plumbing tools API call, which begins at line 263 above. Replace the echo command in line 264 with the following code block, which contains the relevant response logic:
// build payload //
$response['code'] = 1;
$response['api_version'] = '1.0.0';
$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
   
// if an 'item_id' was provided then return details for that item //
if ( $_GET['item_id'] ) {
    $response['item_id'] = strtoupper($_GET['item_id']);
    $response['data'] = plumbing_tool_item_details(strtoupper($_GET['item_id']));
}
// else return our entire inventory of plumbing tools //
else {
    $response['data'] = plumbing_tools_inventory_without_description();
}
Save your PlumbingAPI.php file and point your browser to this url, http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&format=json. The response will appear as follows in your web browser:
Plumbing Tools Inventory without Descriptions.
Plumbing Tools Inventory.
{ "code": 1, "status": 200, "data": null, "api_version": "1.0.0" }
Now let's add in our plumbing tools inventory. The relevant function begins at line 132 above (function plumbing_tools_inventory()). Replace the echo command with the following associative array:

As in part one, this array constitutes the actual content of the relevant inventory, including item ids, names, image locations, and descriptions. Let's now write the necessary code to serve up our tools inventory without the lengthy descriptions. Appropriately, this will be placed in the plumbing_tools_inventory_without_description() function, located at line 140 in the full script file above. Replace the two lines of placeholder code in that function (lines 141 and 142) with the following snippet:

// pull our entire inventory of plumbing tools //
$inventory = plumbing_tools_inventory();
   
// container for plumbing tools inventory with omitted description //
$inventory_without_details = array();
   
// iterate over the array, duplicate the inventory without descriptions//
foreach ($inventory as $key=>$value) {
    if (is_array($value)) {
        $inventory_item = array();
        foreach ($value as $subkey=>$subvalue) {
            if ( strcasecmp($subkey,'description') != 0 )
                $inventory_item[$subkey] = $subvalue;
        }
        $inventory_without_details[$key] = $inventory_item;
    }
}
return $inventory_without_details;
Save your file and point your browser to this endpoint: http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&format=json. You should see a json response for our entire inventory of plumbing tools.

Now we'll work on serving individual plumbing tools along with their descriptions. Find the plumbing_tools_item_details($item_id) function at line 176 in the script above, and replace the place-holder code in lines 177 and 178 with the following block:
// pull our entire inventory of plumbing tools //
$inventory = plumbing_tools_inventory();
   
// container for item matching the provided item_id //
$inventory_item = array();
   
// iterate through our inventory and find the requested item //
foreach ($inventory as $key=>$value) {
    if (is_array($value) && strcasecmp($value['id'], $item_id) == 0) {
        foreach ($value as $subkey=>$subvalue) {
                $inventory_item[$subkey] = $subvalue;
        }
        break;
    }
}
return $inventory_item;
Save your php file and point your browser to this url:http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&item_id=PT12010&format=json. This is an endpoint to the first item from our json inventory response for plumbing tools. You should see the following response in your browser:
{
    "code": 1,
    "status": 200,
    "data": {
        "id": "PT12010",
        "name": "Plunger.",
        "image": "http://localhost:8888/assets/plunger.png",
        "description": "Super-pliable industrial-rubber cup with tiered ridges forms ultra-tight seal on any size drain. The heavy-duty steel handle allows for maximum pressure forced down drain to source of clog. Designed to work effectively at any angle for hard-to-reach, low-clearance applications."
    },
    "api_version": "1.0.0",
    "item_id": "PT12010"
}
Our API is almost complete! Besides json, you will typically encounter web APIs that support multiple formats. Let's have our API also support XML and HTML responses. Find the deliver_response($format, $api_response) function at line 23 in the API script above, and locate the "XML Response" else if block that begins at line 49. Currently, it only has a place holder comment indicating that this is where we will our XML response logic will live. Add the following code to that block:
// Set HTTP Response Content Type //
header('Content-Type: application/xml; charset=utf-8');
       
// initializing or creating array //
$data = $api_response['data'];

// Format data into an XML response //
$xml = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
arrayToXml($data, $xml);
       
// Deliver formatted data //
echo $xml;
This is the next line. Notice that the HTML response logic is in the final else block of the same function. Replace the place-holder "// HTML Response //" comment with the following snippet:
// Set HTTP Response Content Type //
header('Content-Type: text/html; charset=utf-8');

// initializing ro creating array //
$data = $api_response['data'];
       
$payload = '';
$html = '';
if (is_array($data)) {
    arrayToHTML($data, $html);
    $payload = $html;
}
else {
    $payload = $data;
}
       
// Deliver formatted data //
echo $payload;
Finally, we have to fill out the arrayToXml($data, $xml) and arrayToHTML($data, $html) functions referenced in these two snippets. Find the empty arrayToXml function at line 214 in the PHP script above, and add the following to its body:
// wrap XML with $wrap TAG //
if ($wrap != null) {
    $xml .= "<$wrap>\n";
}
// main loop //
foreach ($array as $key=>$value) {
  
    if(is_array($value)) {
        // recursive call //
        arrayToXml($value, $xml,'ITEM');
    } else {
        // set tags in uppercase if needed //
        if ($upper == true) {
              $key = strtoupper($key);
            }
            // append to XML string //
            $xml .= "<$key>" . htmlspecialchars(trim($value)) . "</$key>";
    }
}
// close tag if needed //
if ($wrap != null) {
    $xml .= "</$wrap>\n";
}
Now locate the arrayToHTML function, located at line 224 in our PHP script above. Like its XML counterpart, it is currently empty. Add the following code to the body of the function:
// wrap html with $tag //
if ($tag != null) {
    $html .= "<HTML>\n";
}
// main loop //
foreach ($array as $key=>$value) {
   
    if(is_array($value)) {
        // recursive call //
        arrayToHTML($value, $html,'h1');
    } else {
        // set tags in uppercase if needed //
        if ($upper == true) {
            $key = strtoupper($key);
        }
        // append to XML string //
        $html .= "<$key>" . strtoupper($key) . ' : ' . htmlspecialchars(trim($value)) . "</$key><br>";
    }
}
// close tag if needed //
if ($tag != null) {
    $html .= "</HTML>\n";
}
Save your file and point your browser to this endpoint: http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&item_id=PT12010&format=json . You should see a json response for our entire inventory of plumbing tools. If you type in xml instead of json, in the url, you should see an xml response. Also, typing in html will result in an html response. 

Rejoice! We have completed what is arguably the hardest part of this tutorial!

Clean URLs
Although our URLs up to now were well-formed for the task, you will at times be restricted to use what is known as clean URLs to query a web service. Clean URLs are structured in such a way that the query portion of the URLs that we have been using thus far are instead inserted within the URL path. Simply put, instead of using this url, http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&format=json, to access our inventory of plumbing, we will setup a mechanism that supports this type, http://localhost:8888/api/v1/plumbing_tools.json, of URL as well.

For this, we will add some code to the .htaccess file created in the introductory article to this series. Remember, using .htaccess files is not recommended for production environments, but it will serve us just fine for the purposes of our testing our Swift app. In your usual text editor, type in the following lines of code to the .htaccess file:
# Turn on the rewrite engine
RewriteEngine on

# Rewrite Rules for version 1.0.0 api
# ###################################
# Access to a single inventory item
RewriteRule ^api/v1/([^\/]*)[/]([^\/]*)[//.](html|json|xml) /v1/PlumbingAPI.php?method=$1&item_id=$2&format=$3 [L]
# Access to entire inventory
RewriteRule ^api/v1/([^\/]*)[//.](html|json|xml) /v1/PlumbingAPI.php?method=$1&format=$2 [L]
Any text after a pound character (#) is ignored by the interpreter of this file—it indicates a comment. The first non-comment line of code notifies the interpreter that we will be using rewrite rules. The other lines of code translate our clean url into a standard url that our web service can understand.

The syntax for the rewrite rule is as follows: RewriteRule Pattern Substitution [flags]. For the pattern argument we provided a regular expression (regex) to conduct the translation for us, as we would like to make it as generic as possible—in order to support multiple API signatures. The first RewriteRule interprets the single item with description inventory request for both copper pipes and fittings as well as plumbing tools. The second RewriteRule addresses requests for entire inventories. See this guide (.pdf) for more on regular expressions.

In the same file but just below the our last line, we'll now create the rewrite rules for version two of our API. Here are the rewrite rules for version two of our web service:

# Rewrite Rules for version 2.0.0 api
# ###################################
# Access to a single inventory item
RewriteRule ^api/v2/([^\/]*)[/]([^\/]*)[//.](html|json|xml) /v2/PlumbingAPI.php?method=$1&item_id=$2&format=$3 [L]
# Access to entire inventory
RewriteRule ^api/v2/([^\/]*)[//.](html|json|xml) /v2/PlumbingAPI.php?method=$1&format=$2 [L]
Save your .htaccess file and point your browser to the following url: http://localhost:8888/api/v1/plumbing_tools.json. The web service should respond by sending you the entire inventory of plumbing tools.

This url will also work: http://localhost:8888/api/v1/plumbing_tools/json. You can replace the json path with any other supported format.

Now point your browser here: http://localhost:8888/api/v1/plumbing_tools/pt12010.json. PT12010 is an item id value. This last web service request will respond by transmitting the relevant information along with description for the item matching the provided id.


Versioning
Placing web services with expanded or modified functionality into a separate folder is arguably the simplest versioning scheme to implement. There are other more complicated, and necessary, versioning schemes in use today. In our scheme, folder v1 is the earliest web service and v2 is the most recent. A number of arguments speak in favor of this implementation: there is no ambiguity about which web service version you are talking to, backward compatibility is maintained and you don't have to worry about creating dependency issues because each versioning folder contains the complete set of services.


Moving Forward
With that, we have completed our Super PHPlumbing Bros inventory API. Next week, we will move on to the final segment of this tutorial series and begin building the Swift client application that we will use to query the API and serve the content up to the end user. As always, comments, questions and suggestions are welcome below.



This project can be found on GitHub.

Index
Introduction
Introduction and Overview: From the Back End API to the End User Application

The Web API
Building a RESTful API in PHP, Part 1
Building a RESTful API in PHP, Part 2

The Swift Client App
Networking in Swift: Building the Swift Client, Part 1
Networking in Swift: Building the Swift Client, Part 2
Networking in Swift: Building the Swift Client, Part 3
Networking in Swift: Building the Swift Client, Part 4
Networking in Swift: Building the Swift Client, Part 5


This tutorial was authored by Stefan Agapie, a Senior iOS Software Engineer, and adapted for the present piece.

Networking in Swift: Building a RESTful API in PHP, Part 1

This is the second post in our tutorial series on networking in Swift. If you followed along in the introductory article, you have installed MAMP on your local machine, created an .htaccess file and set up the basic file structure for the project. In this tutorial, we'll begin building the API for our Super PHPlumbing Bros web service.

This RESTful API in PHP will serve content to the Swift-based iOS client application we'll create in the final part of the series. Our API will perform five distinct tasks when queried. It will provide: 1) inventory items response logic for our Plumbing Tools; 2) inventory items response logic for Plumbing Supplies; 3) inventory item response logic for Plumbing Tool with Description; 4) Inventory item response logic for Plumbing Supply with Description; 5) Error response logic.

In this article, we will cover the structure of our API queries, provide a simple bare bones interface for the service, and then build the first half of our custom API to serve up our plumbing supplies inventory.

API Queries
Our application will communicate with the web api through a simple url scheme. If you are not familiar with url schemes, take a brief detour through the linked Wikipedia page to learn about how they work (simply memorizing the components of a url scheme outright will save you lots of needless lookups later).

Our first stab at a url scheme looks crude. Here is the URL scheme that we will use to access our entire inventory of plumbing tools: http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&format=json.

Let's take a closer look at this scheme. Any text in a URL that comes after the question mark (?) is known as the URL query component. Each key/value pair that follows is logically separated by an ampersand (&). In this example the query string contains two key/value pairs. These key/value pairs will get passed along to our PlumbingAPI.php script via an associative array known as $_GET[]. Within our PHP script we will access the values for the 'method' and 'format' keys as follows: $_GET['method'] and $_GET['format'] would return 'copper_pipes_and_fittings' and 'json', respectively, in the crude example above. We use these values to determine what was requested of our API.

A Bare Bones API
Let's get down to it. Using your text editor, open PlumbingAPI.php for both versioning folders, v1 and v2. Until further noted, we'll be entering the same code in both versions. For the skeletal structure of our API, we are going to adapt the code from Mark Roland's helpful tutorial on "How to Build a RESTful API Web Service in PHP." We'll explain each component as we add flesh to our bare-bones script. Here's a Gist of the script:


After reading through the code, copy it into the PlumbingAPI.php file in your v1 folder. Using the URL scheme from above, point your web browser at http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&format=json, and you will see the API's response to the given method and format:

Simple API call to bare bones script


If you now navigate to http://localhost:8888/v1/PlumbingAPI.php?method=plumbing_tools&format=json, you'll see the response from the plumbing_tools method:

Second API call to bare bones script
  
If this is not working for you, then go back and make sure that you followed all the steps. If you do see a response in your web browser, then congratulations! You've successfully built and deployed your locally hosted web service. The various responses from our api are made possible by the following conditional code structure, from line 120 to the end of the file above:
// Copper Pipes and Fittings API //
if( strcasecmp($_GET['method'],'copper_pipes_and_fittings') == 0){
    echo 'Copper Pipes and Fittings API Call. <br>';
}

// Plumbing Tools API //
else if( strcasecmp($_GET['method'],'plumbing_tools') == 0){
    echo 'Plumbing Tools API Call. <br>';
}

// ** Deliver Response ** //
// Return Response to browser //
deliver_response($_GET['format'], $response);
With the exception of the function definitions, our script is executed from top to bottom. Notice the conditional if else if structure here. In our first API call we passed in the value 'copper_pipes_and_fittings' for the 'method' key. Recall that the parameters of a query string are passed in to the $_GET[] global array, which we read from in our first conditional if check. Since it evaluates to true in the first API call, we fall in that conditional block and therefore echo "Copper Pipes and Fittings API Call", followed by the function call: deliver_response($_GET['format'], $response). This last function call is what prints out the second line in the browser.

In our second api call, we passed in the value 'plumbing_tools' for the 'method' key in the URL. With this query, we fell into the conditional else-if check above. This gave us our alternate response. That's all there is to it!

Moving forward, we'll build on top of this primitive structure of conditional checks followed with a response using the echo call.  For explanations of built-in methods such as  strcasecmp() and echo, check out php.net and search for those calls to get documentation along with code samples on how to use them.

Building the Supplies Interface
We'll now begin building out the control flow for the various tasks our API will perform. In the first if conditional control flow replace the code at line 122 (echo 'Copper Pipes and Fittings API Call. <br>';) with the following:
// build payload //
$response['code'] = 1;
$response['api_version'] = '1.0.0';
$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
   
// if an 'item_id' was provided then return details for that item //
if ( $_GET['item_id'] ) {
    $response['item_id'] = strtoupper($_GET['item_id']);
    $response['data'] = copper_pipe_or_fitting_item_details(strtoupper($_GET['item_id']));
}
// else return our entire inventory of copper pipes and fittings //
else {
    $response['data'] = copper_pipes_and_fittings_inventory_without_description();
}
Save your PlumbingAPI.php file and point your browser to this URL: http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&format=json. The response will appear as follows in your web browser:
Copper Pipes and Fittings Inventory without Descriptions.
Copper Pipes and Fittings Inventory.
Delivering Response. $api_response = Array, format = json
Your are seeing this response because our first if check did not fall through as we did not provide an 'item_id' key with an associated value pair as parameters in the query part of our URL. In other words, a parameter with this format, '&item_id=<some item id>', was not appended to the above URL. This resulted in our conditional control flow to fall through the else path. In this else block we call a method that we defined earlier: copper_pipes_and_fittings_inventory_without_description(). In our definition of this method, notice that we call another method: copper_pipes_and_fittings_inventory(). This last method is responsible for fetching our entire inventory of copper pipes and fittings along with all item details. Go to this method, found in lines 27 -33 above, and replace line 32 (echo 'Copper Pipes and Fittings Inventory. <br>';)<code> with the following:


This is an associative array of sub-arrays. Each sub-array contains all the information of one inventory item. There are twelve items in our hypothetical Copper Pipes and Fittings category, the information for which was cobbled together from online sources. In a real world scenario, this or a similar method would normally pull this data from a data store like a database. But for the sake of brevity we will skip this part. Now go to where we defined the method copper_pipes_and_fittings_inventory_without_description() (line 56 in the bare bones files above), and replace lines 57 and 58 with the following: 
return copper_pipes_and_fittings_inventory();
For now we'll simply return our entire inventory with descriptions. We will revisit this method later and write code to omit item descriptions. Now navigate to our response delivery function (function deliver_response($format, $api_response)), line 23 in the bare bones code, and replace its echo command in line 24 with the following:


The response to our API query gets processed here. If a parameter of 'format=json' is provided in the query part of the URL, then our script would fall through our first if check. This parameter informs our API that one of three available formatted responses was requested. We support three formats in this example: json, xml and html. 

Let's now write the code to process json format requests. In the first conditional if-check block (line 14) replace the comment (// JSON Response //) with the following code:
// Set HTTP Response Content Type //
header('Content-Type: application/json; charset=utf-8');

// Format data into a JSON response //
$json_response = json_encode($api_response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);

// Deliver formatted data //
echo $json_response;
Save your PlumbingAPI.php file and point your browser to this url, http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&format=json. The response will appear as follows in your web browser:
{
    "code": 1,
    "status": 200,
    "data": [
        {
            "id": "CP12010",
            "name": "1 inch copper pipe.",
            "image": "http://localhost:8888/assets/1_inch_copper_pipe.png",
            "description": "1 in. x 10 ft. Copper Type M Hard Temper Straight Pipe for a multitude of plumbing and heating purposes. It is NSF and ANSI Standard 61 certified. Made of hard-temper ASTM - B88 copper. For general plumbing and heating purposes. Alloy C12200 (DHP) meets industry standards and is NSF and ANSI Standard 61 certified. Meets or exceeds industry standards to deliver a high quality flow product. Plumbing and mechanical codes govern what types of products may be used for applications. Local codes should always be consulted for minimum requirements"
        },
        {
            "id": "CP12020",
            "name": "1 1/4 inch copper pipe.",
            "image": "http://localhost:8888/assets/1_1_4_inch_copper_pipe.png",
            "description": "1 1/4 in. x 10 ft. Copper Type M Hard Temper Straight Pipe for a multitude of plumbing and heating purposes. It is NSF and ANSI Standard 61 certified. Made of hard-temper ASTM - B88 copper. For general plumbing and heating purposes. Alloy C12200 (DHP) meets industry standards and is NSF and ANSI Standard 61 certified. Meets or exceeds industry standards to deliver a high quality flow product. Plumbing and mechanical codes govern what types of products may be used for applications. Local codes should always be consulted for minimum requirements"
        },
    .
    .
    .
    .
        {
            "id": "CP14040",
            "name": "1 1/2 inch copper elbow fitting.",
            "image": "http://localhost:8888/assets/1_1_2_inch_copper_elbow_fitting.png",
            "description": "1 1/3 in. Copper Type M Hard Temper Straight Pipe for a multitude of plumbing and heating purposes. It is NSF and ANSI Standard 61 certified. Made of hard-temper ASTM - B88 copper. For general plumbing and heating purposes. Alloy C12200 (DHP) meets industry standards and is NSF and ANSI Standard 61 certified. Meets or exceeds industry standards to deliver a high quality flow product. Plumbing and mechanical codes govern what types of products may be used for applications. Local codes should always be consulted for minimum requirements"
        }
    ],
    "api_version": "1.0.0"
}
The vertical ellipses indicate that we trimmed the actual response. You should see a lot more data in your browser. The problem with this response is that the copper pipes and fittings inventory response contains too much data. In our next step we'll trim the response so that item descriptions are omitted. 

It is not good practice to submit details of items when requesting them in bulk. In a real-world scenario, internet access is often spotty and unreliable. And serving up too much data could negatively impact your users' experience. And since users are often not aware that your application is not to blame for a given issue, but rather their connectivity to the network, they will associate this bad experience with your application. So, in an effort to mitigate connectivity issues, we should always prefer to send the least amount of data as possible over a network. Also, it is very unlikely that you can fit all this data for one item onto a screen when presenting the user with a list of items.

To omit item details, navigate to where we defined the method copper_pipes_and_fittings_inventory_without_description(), and replace our return command (return copper_pipes_and_fittings_inventory();) with this chunk of code:
    // pull our entire inventory of copper pipes and fittings //
    $inventory = copper_pipes_and_fittings_inventory();
   
    // container for inventory minus descriptions//
    $inventory_without_details = array();
   
    // iterate through inventory and duplicate all attributes except descriptions //
    foreach ($inventory as $key=>$value) {
        if (is_array($value)) {
            $inventory_item = array();
            foreach ($value as $subkey=>$subvalue) {
                if ( strcasecmp($subkey,'description') != 0 )
                    $inventory_item[$subkey] = $subvalue;
            }
            $inventory_without_details[$key] = $inventory_item;
        }
    }
    return $inventory_without_details;    
This code is straight forward. It iterates through the json objects and all the items into another container with the exception of key value pairs that are associated with a key name of 'description.' Save your PlumbingAPI.php file and point your browser to this url, http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&format=json. The response will appear as follows in your web browser:
{
    "code": 1,
    "status": 200,
    "data": [
        {
            "id": "CP12010",
            "name": "1 inch copper pipe.",
            "image": "http://localhost:8888/assets/1_inch_copper_pipe.png"
        },
        {
            "id": "CP12020",
            "name": "1 1/4 inch copper pipe.",
            "image": "http://localhost:8888/assets/1_1_4_inch_copper_pipe.png"
        },
          .
    .
    .
    .
        {
            "id": "CP14040",
            "name": "1 1/2 inch copper elbow fitting.",
            "image": "http://localhost:8888/assets/1_1_2_inch_copper_elbow_fitting.png"
        }
    ],
    "api_version": "1.0.0"
}
Again, the vertical ellipses indicate that we trimmed the actual response. Notice that the descriptions have been omitted from the response. 

We will now write code to serve an individual copper pipe or fitting with a description. Find where the method function copper_pipe_or_fitting_item_details($item_id) is defined (line 66 in our bare bones API) and replace the two lines filling out the function (i.e. 67 and 68), with the following:
// pull our entire inventory of copper pipes and fittings //
$inventory = copper_pipes_and_fittings_inventory();
   
// container for item matching the provided item_id //
$inventory_item = array();
   
// iterate through our inventory and find the requested item //
foreach ($inventory as $key=>$value) {
    if (is_array($value) && strcasecmp($value['id'], $item_id) == 0) {
        foreach ($value as $subkey=>$subvalue) {
                $inventory_item[$subkey] = $subvalue;
        }
        break;
    }
}
return $inventory_item;
Save your php file and point your browser to this URL: http://localhost:8888/v1/PlumbingAPI.php?method=copper_pipes_and_fittings&item_id=CP12010&format=json. This is an endpoint to the first item from our json inventory response above. You should see the response below:
{
    "code": 1,
    "status": 200,
    "data": {
        "id": "CP12010",
        "name": "1 inch copper pipe.",
        "image": "http://localhost:8888/assets/1_inch_copper_pipe.png",
        "description": "1 in. x 10 ft. Copper Type M Hard Temper Straight Pipe for a multitude of plumbing and heating purposes. It is NSF and ANSI Standard 61 certified. Made of hard-temper ASTM - B88 copper. For general plumbing and heating purposes. Alloy C12200 (DHP) meets industry standards and is NSF and ANSI Standard 61 certified. Meets or exceeds industry standards to deliver a high quality flow product. Plumbing and mechanical codes govern what types of products may be used for applications. Local codes should always be consulted for minimum requirements"
    },
    "api_version": "1.0.0",
    "item_id": "CP12010"
}

Congratulations! We have completed the first half of our web API, serving up content for our copper pipes and fittings inventory. In the next article in the series, we'll complete the API to serve up our inventory of plumbing tools, and then begin building our Swift application to bring that content to our end user. Follow the line for part two on building a RESTful API in PHP.

This project can be found on GitHub.

As always, comments, questions, and suggestions are welcome below!

Index
Introduction
Introduction and Overview: From the Back End API to the End User Application

The Web API
Building a RESTful API in PHP, Part 1
Building a RESTful API in PHP, Part 2

The Swift Client App
Networking in Swift: Building the Swift Client, Part 1
Networking in Swift: Building the Swift Client, Part 2
Networking in Swift: Building the Swift Client, Part 3
Networking in Swift: Building the Swift Client, Part 4
Networking in Swift: Building the Swift Client, Part 5


This tutorial was authored by Stefan Agapie, a Senior iOS Software Engineer, and adapted for the present piece. 

Networking in Swift: From the Backend API to the End User App

Introduction
In this tutorial series, we will create an iOS application that will leverage Swift's networking layer to query a custom-built web service. First, we'll build a RESTful API in PHP from the bottom up and host it on our local machine. Then we'll craft an iOS Swift application to consume the content provided by the service, and present it to the end user in a collection view. The series is intended for people who have some degree of programming experience, but who have not yet obtained much practical knowhow on building an everyday, real-world, user-facing, mobile application. 

A typical use case for mobile applications requires the consumption of content that is hosted on a web server. For successful mobile app development, this means that you not only need to know how to build an application that consumes web content, but also to have a high level understanding (at the very least!) of how a web service actually delivers content to your mobile application.

This is important because you will encounter network related errors during your development cycle. And if you don't have at least a basic understanding of the web service that your are trying to communicate with, then you cannot be sure where the errors are originating from. In addition, you will likely also be asked, at work or by your own clients, to begin writing a mobile application that relies on a web service that has not been built yet! (This actually happens way too often!) In such cases, you can write your own temporary web service that delivers mock data to your application, if you know how to build one. Although there are other ways of delivering such mock data, this can be just as useful. 

In this article, we'll provide an overview of the project, and then work through the preliminary steps for running the web service on our local machine. In the following articles, we'll build out the PHP script that will execute the API, and finally construct our Swift application to query the service and return the relevant data to the end user.

The ABCs of APIs
What is an API and how will our Swift application interface with it? API stands for Application Programming Interface. A simple web search for 'API' will return many definitions with various types of descriptions and creative examples. I like to think of an API as a real object. 
Source

Since the internet is a series of pipes and tubes, our API will provide an interface to a plumbing supply inventory. Let's call our API the Mario Interface. Mario works at the front desk of a plumbing supply house called Super PHPlumbing Bros Inc. Mr. Swift is a plumber who needs some supplies to rescue a local potentate's daughter from the clutches of an invading warlord.

Mr. Swift finds PHPlumbing and walks up to the counter where he encounters Mario. Mr. Swift tells Mario that he would like some piping, mushrooms and a wrench. Mario says, "No problem, but first I need you to know exactly what you need," and hands Mr. Swift two forms.

Each form is titled with the company's name. Below the title, there are several check boxes, but only one may be checked per form. The relevant check boxes are: Piping/Fittings and Plumbing Tools. Below that is a description field for the requested items along with their quantity. 

Once completed, Mr. Swift hands the forms to Mario, who then passes them along to his employees, local Toads from the Mushroom Kingdom, who are tasked to assist him. The Toads find the relevant items, bring them out and place them on the counter. 

If at any point during this process there was a problem retrieving Mr. Swift's supplies, the Toads are responsible for reporting these errors up the chain of command, from the assistants up to Mario and terminating at Mr. Swift.

In our analogy, Mr. Swift is the client (our iOS application) in need of content or plumbing supplies. Super PHPlumbing Bros Inc. is the store or website that has the supplies or content that Mr. Swift is looking for. The form for getting supplies is the actual url (location of content) that is used to find and retrieve the content. And Mario, along with the Toads, comprise the API. 

APIs, and people like Mario, are needed to maintain a system of flow control structures that are necessary to efficiently run the business logic of the operation. Can you imagine a plumbing supply house that had no control structures like forms and employees to manage its everyday workflow? The princess would be doomed.

In this tutorial series, we'll construct a RESTful API in PHP to serve up an inventory of plumbing tools and supplies, and then build a custom Swift app to interface with the API and serve that inventory to the end user. For now, let's get our local server up and running. 

Setting Up the Local Server
Unfortunately, the PHP file that will serve our API will not execute on its own. A service is required to interpret and execute our PHP script. We therefore need to set up a place on our local machine to host our Super PHPlumbing Bros. supply house. One of the easiest ways to get a server up and running on a Mac is with MAMP. Once you've downloaded MAMP, you can run the package by double clicking it.

After the package mounts, follow the instructions to install the software. 

Once installed, navigate to your Applications folder and start MAMP. You will be prompted with several initialization screens. Once MAMP is installed, start the server my clicking the START button in the top right corner of the application window. 


The tiny box to the right of the word Apache should turn green if everything went smoothly. This means that your server is up and running! Now start a new session of Safari, and in the url field type the following address: http://localhost:8888 You should see a similar screen to the following, which indicates that all is in working order:

.htaccess
A .htaccess file provides directory level configuration on how a web server handles requests to resources that are in the same directory as the .htaccess file itself. Note that using .htaccess is discouraged for production environments, but for the purposes of our tutorial, it should work just fine. Using your favorite text editor, create a new file and name it .htaccess. In the screen capture above, notice the directory path next to the text, “Document root:”. Mine reads: "Document root: /Applications/MAMP/htdocs." This is where your PHP file, along with all related resources will live. Place your .htaccess file in this folder.

Remember, any file name that begins with a period “.” is a system file and is hidden by default. To view hidden files, you can use the "ls -a" command in a terminal. To view hidden files in Finder, you can follow the instructions here.

File Structure 
Navigate to the folder that contains your .htaccess file. For me, it's /Applications/MAMP/htdocs, and create three folders with the following names: v1, v2, assets. More on these folders later, but for now, your folder structure should more or less look like the following:

Using your text editor create a new file and call it PlumbingAPI.php. This file models the Mario Interface, our counter guy. Place a single copy in folder v1 and v2. The v1 and v2 folder will be used for version control. The earlier versions of an API would typically reside in folders with a smaller number while the most recent API edition would live in the folder with the largest number.

Moving Forward  
With that, we're all set to go! In the next segment of the tutorial we'll build our RESTful API in PHP, so let's take the plunge. Or, if you want to skip ahead, follow the link to the tutorial segment on building our Swift client application.