Categories
Articles

XCode IPhone Client Server Echo Hello Example Using PHP


This is a basic IPhone client server example using PHP. This is a duplication of a Titanium example I created February 27th: see Titanium IPhone Client Server Echo Hello Example Using PHP.

This XCode example like the Titanium version simply sends text entered on the phone and returns it with the word “Hello” prefixed. It uses HTTP and the POST protocol. The server app is a simple PHP script.

First Launch

This is the IPhone screen when the application first runs.

The text input will show the keyboard when typing. The send button closes the keyboard and starts the HTTP session. There is no error handling should the connection fail or the server fail.

This is an asynchronous example. So other operations could occur while the request to server is in process. For example the send button can be pressed over and over. So an activity indicator would be a nice improvement.

Source Download
XCode 4 Project

I used the IOS “View-based Application” when creating a new project in XCode. All the coding is in the AnimatedDieFaceViewController UIViewController.

NSUrlClientServerURLVariablesEx01ViewController.h

This sets out the interface for the view controller.

Line 2 contains a constant for the PHP script that received the name and returns the response. You need to replace the YOURDOMAIN and the PATH_IF_ANY_TO/ for your project. The php script is included in the download and is also listed at the end of this post.

The responseTextView is updated with the response from test02.php.

The receivedData NSMutableData object handles the byte data that will come from the server.
[ad name=”Google Adsense”]
The two IBOutlet variables for the controller to access UI components. The controller needs to read the user input from nameTextField and needs to update responseTextView with data received from the server.

The one IBAction method kicks off the client server process with the send button.

#import <UIKit/UIKit.h>
#define kTextUrl @"http://www.YOURDOMAIN.com/PATH_IF_ANY_TO/echo_hello.php"

@interface NSUrlClientServerURLVariablesEx01ViewController : UIViewController {
    UITextField     *nameTextField;
    UITextView      *responseTextView;
    NSMutableData   *receivedData;
}
@property (nonatomic, retain) IBOutlet UITextField *nameTextField;
@property (nonatomic, retain) IBOutlet UITextView *responseTextView;
@property (nonatomic, retain) NSMutableData *receivedData;

- (IBAction)makeRequest;

@end

NSUrlClientServerURLVariablesEx01ViewController.m

This sets out the interface for the view controller. Five methods are used to handle the request to and response from the server.

The makeRequest method initiates the request to the server is on line 10.

First Launch

Four methods on lines 91, 99, 106 and 127 are required because line 27 makes this controller the delegate for NSURLConnection.

The makeRequest method on line 10 is fired from the send button. It performs two tasks. One is assembling the parts of the nsMutableURLRequest object such as the protocol and name value pair parameter. The POST protocol is set on line 18 and line 20 creates the name=whatever_the_user_enters name value pair needed for the server script. The second task is making NSURLConnection and testing if it can work.

Lines 91 – 97 contains the connection didReceiveResponse method. This is needed to clear the data received because of the nature of multiple times it can be called.

The connection didReceiveData method on line 99 – 104 starts collecting the byte data received over the network.

If there is a problem with the connection the connection didFailWithError method occupying lines 106 to 125 is called. Here you can create a better UIAlertView and perhaps relegate the error codes to a trace log.

Finally should everything go well and all the data is received, the connectionDidFinishLoading method on lines 127 – 139 updates the UITextView with our results.

//
#import "NSUrlClientServerURLVariablesEx01ViewController.h"

@implementation NSUrlClientServerURLVariablesEx01ViewController
@synthesize nameTextField;
@synthesize responseTextView;
@synthesize receivedData;

// Send button Touch Up Inside
- (IBAction)makeRequest
{
    NSLog(@"%s", __FUNCTION__);
    //Allocate NSURL object
    NSURL *nsURL = [[NSURL alloc] initWithString:kTextUrl];
    // Allocate NSMutableURLRequest
	NSMutableURLRequest *nsMutableURLRequest = [[NSMutableURLRequest alloc] initWithURL:nsURL];
    // Set HTTP method to POST
	[nsMutableURLRequest setHTTPMethod:@"POST"];
    // Set up the parameters to send.
    NSString *paramDataString = [NSString stringWithFormat:@"%@=%@", @"name", nameTextField.text];
    NSLog(@"%s - paramDataString: %@", __FUNCTION__, paramDataString);
    // Encode the parameters to default for NSMutableURLRequest.
	NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
    // Set the NSMutableURLRequest body data.
	[nsMutableURLRequest setHTTPBody: paramData];	
    // Create NSURLConnection and start the request.
    NSURLConnection *nsUrlConnection=[[NSURLConnection alloc]
                                    initWithRequest:nsMutableURLRequest 
                                    delegate:self];
    // Successful connection.
    if (nsUrlConnection) {
        NSMutableData *data = [[NSMutableData alloc] init];
        self.receivedData=data;
        [data release];
    } 
    // Unsuccessful connection.
    else {
        responseTextView.text =  [NSString stringWithFormat :@"Unable to make connection!"] ;
    }  
    // Clean up
	[nsURL release];
	[nsMutableURLRequest release];
    // Close keypad.
    [nameTextField resignFirstResponder];
    

}
- (void)dealloc
{
    [nameTextField release];
    [responseTextView release];
    [receivedData release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
}
*/

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    self.nameTextField = nil;
    self.responseTextView = nil;
    self.receivedData = nil;
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark NSURLConnection Callbacks
// Connection response.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{
    NSLog(@"%s - Response Code: %d\n", __FUNCTION__, [(NSHTTPURLResponse *)response statusCode]);
    NSLog(@"%s - Content-Type: %@\n",  __FUNCTION__, [[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:@"Content-Type"]);
    // Clear the NSMutableData receivedData.
    [receivedData setLength:0];
}
// You got data.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
    NSLog(@"%s", __FUNCTION__);
    // Append the data to our NSMutableData receivedData.
    [receivedData appendData:data];
}
// Sorry Dude, connection failed gloriously.
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{
    NSLog(@"%s", __FUNCTION__);
    
    // Create noxious error message.
    NSString *errorMessage = [[NSString alloc]initWithFormat: @"Connection failed! Error - %@ (URL: %@)", [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]];
    // Throw up a noxious error message.
    UIAlertView *alert = [[UIAlertView alloc] 
                        initWithTitle:@"Sorry Dude!"
                        message:errorMessage 
                        delegate:self
                        cancelButtonTitle:@"Close"
                        otherButtonTitles:nil];
    [alert show];
    // Clean up
    [connection release];
    self.receivedData = nil; 
    [alert release];
    [errorMessage release];
}
// Finally the data is completely loaded.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"%s", __FUNCTION__);
    // Encode received data to NSUTF8StringEncoding
    NSString *receviedDataAsString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
    NSLog(@"%s - receviedDataAsString: %@", __FUNCTION__, receviedDataAsString);
    // Show received data in the responseTextView.
    responseTextView.text = receviedDataAsString;
    // Clean up.
    [receviedDataAsString release];
    [connection release];
    self.receivedData = nil;
}
@end

[ad name=”Google Adsense”]

NSUrlClientServerURLVariablesEx01ViewController.xib

UIView

This is the layout of the interface.

There is another UIView behind the UILabel, UITextField and UIButton. The UIView background is set to a light gray to give a panel effect.

The UITextField is preloaded with a value.

Below the UIView at the top is a UITextView. It is also preloaded with a message on how to use the app.

 
 
 
 
 
 
 
 
 
 
 
NSUrlClientServerURLVariablesEx01ViewController IBOutlets and IBActions

The IBOutlets are for the UITextField and the UITextView so their properties in the controller code can be read or changed. The UITextField is read on line 20. The UITextView is changed on line 134.

The view outlet was set when I choose the IOS View-based Application to create the XCode project.

The IBActions are for the one UIButton when the Touch Up Inside event is initiated. You can see the method makeRequestlinked to the UIButton.

[ad name=”Google Adsense”]
echo_hello.php – Server Script
Very simple echo script. The name identifier on line 20 of NSUrlClientServerURLVariablesEx01ViewController.m is picked up in the PHP $_REQUEST object as you might expect. The value of $_REQUEST[‘name’] is appended to ‘Hello’ plus a space and returned without any data markup. Nothing very fancy.

<?php
echo "Hello " . $_REQUEST['name'] . "!";
?>