This series describes a simple Web 2.0 iPhone application that integrates the device with an IBM WebSphere CloudBurst Appliance. WebSphere CloudBurst provides a set of APIs based on REST, which the device uses to collaborate with the appliance. In the application, the device performs a request on the REST syndication, WebSphere CloudBurst receives the request, and then returns the data response in a JSON format. A full client application gives you a significant amount of flexibility in your user interface, as well as complete access to iPhone features.
Part 1 of this series provided a high level introduction to help you prepare your development environment for creating this integrated solution. Part 2 took the next steps toward building the sample application using the iPhone SDK, and defined the data elements that are used for retrieving and displaying JSON data from the back end. In Part 3, you created the application using a Cocoa framework based on a Model-View-Controller framework. You created a controller class to manage the view part that was created in the previous articles of this series.
This article describes how to extend a class to manage the HTTPS protocol, including security management. In the previous articles, you created the application that managed the navigation between the iPhone screen and a display, but you used a static file stored inside the application. You will now retrieve that file using an HTTPS syndication between the iPhone and WebSphere CloudBurst.
REST syndication is performed on the HTTPS protocol. You need to manage the certificate and the password used for authentication. For security reasons, you will not store the password inside the iPhone. Instead, you will store only the user and the server. You will catch the password using an Alert Prompt, retrieve it from the Alert View, and then use the password for the syndication.
As with the previous installments, this article series assumes a general familiarity with Web2.0 technologies including REST, ATOM, JSON, and Objective-C. The sample application described in these articles is realized using the Model-View-Controller (MVC) pattern in Objective-C using the Apple iPhone SDK 3.x, to be run on an iPhone (or iPod Touch) device with a 3.x firmware. Therefore, this development assumes some basic knowledge of the C programming language (Object-C inherits all of C's features). It is also important that you understand basic object-oriented paradigms, such as inheritance, class, interface, and so on.
Also, this exercise uses the Cocoa framework, which consists of a set of APIs, libraries, and run time code that forms the development layer for the iPhone SDK. Cocoa is implemented in Object-C and uses the MVC pattern to encapsulate views, application data, controllers and the class to mediate the management logic.
To perform the steps and run the examples from this article, you will need a computer with the Apple SDK 3.0 or higher installed, running a compatible version of Mac OS. You also need access to a WebSphere CloudBurst Appliance running in your environment. In liu of an actual iPhone or simiilar device for testing, you can use the iPhone emulator included with the iPhone SDK.
Creating an Alert Prompt class
The Alert View is a simple view provided by the Cocoa framework through the class named UIAlertView, and displays a message on the top of the application. The standard Alert View object is created with a title, a text message, and two buttons, typically Ok and Cancel. Listing 1 shows part of the code that creates an Alert View with the OK button, and Figure 1 shows the Alert View.
Listing 1. Open an Alert View
<![CDATA[
.
.
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"A title"
message:@"A message"
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
.
.
]]> |
Figure 1. Alert View
The problem is that you need to capture not only an action performed by the button clicked, but you also need to catch the text data: the user's password. To do this, you need to create a class that extends the standard Alert view class (UIAlertView). You also need to to improve it with the required objects and functions that manage them.
The class to implement the Alert Prompt is simple. The main part of the class is the constructor. You will realize a constructor in a similar way, such as the invoker of the standard Alert Prompt (see Listing 2).
Listing 2. AlertPrompt.h
<![CDATA[
//
// AlertPrompt.h
// WCA000
//
// Created by luca amato on 9/27/10.
//
#import <Foundation/Foundation.h>
@interface AlertPrompt : UIAlertView
{
UITextField *inputField;
}
@property (nonatomic, retain) UITextField *inputField;
@property (readonly) NSString *enteredText;
]]>
- (id)initWithTitle:(NSString *)title
message:(NSString *)message
delegate:(id)delegate
cancelButtonTitle:(NSString *)
cancelButtonTitle
okButtonTitle:(NSString *)okButtonTitle;
@end |
The first action that the constructor performs is a call to the constructor
of this superclass. If the constructor of the superclass works fine, then
you only need to add an inputField using the
UITextField class, which becomes the first
responder of the view. At the very least, you will create a behavior to
return to the caller the entered text (see Listing 3).
Listing 3. AlertPrompt.m
<![CDATA[
//
// AlertPrompt.m
// WCA000
//
// Created by luca amato on 9/27/10.
//
#import "AlertPrompt.h"
@implementation AlertPrompt
@synthesize inputField;
@synthesize enteredText;
- (id)initWithTitle:(NSString *)title
message:(NSString *)message
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
okButtonTitle:(NSString *)okayButtonTitle
{
if (self = [super initWithTitle:title
message:message
delegate:delegate
cancelButtonTitle:cancelButtonTitle o
therButtonTitles:okayButtonTitle,
nil])
{
UITextField *aTextField = [[UITextField alloc]
initWithFrame:CGRectMake(12.0, 45.0, 260.0, 25.0)];
[aTextField setBackgroundColor:[UIColor whiteColor]];
[self addSubview:aTextField];
self.inputField = aTextField;
[aTextField release];
CGAffineTransform translate = CGAffineTransformMakeTranslation
(0.0, 130.0);
[self setTransform:translate];
}
return self;
}
- (void)show
{
[inputField becomeFirstResponder];
[super show];
}
- (NSString *)enteredText
{
return inputField.text;
}
- (void)dealloc
{
[inputField release];
[super dealloc];
}
@end
]]> |
You can now call the Alert View in the buttonDownload method. Before calling
it, you need to close the keyboard. This assumes that the user inserts the
server name and the user ID in the fields. This action is performed with
the resignFirstResponder method. Listing 4
shows the complete buttonDownload method.
Listing 4. buttonDownload method
<![CDATA[
-(IBAction) buttonDownload
{
[field1 resignFirstResponder];
[field2 resignFirstResponder];
NSLog(@"buttonDownloadImage");
AlertPrompt *prompt = [AlertPrompt alloc];
prompt = [prompt initWithTitle:field1.text
message:@"Enter password"
delegate:self
cancelButtonTitle:@"Cancel"
okButtonTitle:@"Okay"];
[prompt show];
[prompt release];
}
]]> |
When you instantiate the Alert View, you delegate the caller class
(delegate:self). When the user closes the Alert
View using the OK or Cancel button, the framework invokes the
AlertView:willDismissWithButtonIndex: method.
With this method, you will prepare the correct REST URL and retrieve the
JSON file from WebSphere CloudBurst Appliance.
When the user pushes the button on the Alert View, the framework invokes
AlertView:willDismissWithButtonIndex: in the
class delegate. As you can see, when you instantiate the Alert View, you
define the OneViewController class as a
delegated class.
Next, you need to create the called method inside the class. The method will
receive a pointer to the called view and an index regarding the pushed
button. You can use these parameter to check which button has been pressed
by the user that left the view. You need to retrieve and use the inserted
password only when the user clicks on the OK button. If the
OK button is pressed, then use the received parameter from the
Alert View to retrieve the password from the enteredText field. Now
you have all the required information to create the
urlRequest string:
- protocol from the
PROTOCOL constant - serverUser from the entry field
field2 - password from
enteredTextof the Alert View - server from the entry field
field1 - REST invocation from the
APIconstant
Create a string that looks like this:
https://user:password@wcaserver/resources/virtualSystems |
The next step is to accept the HTTPS certificate from the server. To do
this, the Cocoa framework provides a method called
setAllowsAnyHTTPSCertificate:YES
forHost:.
Before you invoke the sendSynchronousRequest:
method from WebSphere CloudBurst Appliance, you must set the correct value
for User-Agent in the HTTP header communication. This value is important
because it is used by the server to identify which browser performs the
request. WebSphere CloudBurst Appliance manages only a subset of browsers.
In this case, it is not important which browser you will choose to
simulate because you manage the JSON server response with a specific code.
However, if the server does not understand the requester, so you may
receive a wrong or empty answer. The trick is to insert in the
User-Agent field the browser ID of a browser
that is managed by the server (see Listing 5). You will choose to simulate
a Firefox browser running with a Windows® OS. The
User-Agent value has to be set as
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6)
Gecko/20091201 Firefox/3.5.6 GTB5.
Listing 5. -(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
<![CDATA[
- (void)alertView:(UIAlertView *)alertView
willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == [alertView cancelButtonIndex])
{
return;
}
NSString *entered = [(AlertPrompt *)alertView enteredText];
NSString *server = field1.text;
NSString *serveruser = field2.text;
NSString *documentsDir = PROTOCOL;
documentsDir = [documentsDir stringByAppendingPathComponent:server];
NSString *uniquePath = [documentsDir stringByAppendingPathComponent:API];
NSString *urlString = [NSString stringWithFormat:
@"%@%@:%@@%@%@",PROTOCOL,serveruser,entered,server,API];
NSString *host = [NSString stringWithFormat:@"%@%@",PROTOCOL,server];
NSLog(@"uniquePath:%@",uniquePath);
[field1 resignFirstResponder]; // chiusura tastiera
description.text = @"loading....";
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:server];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:urlString]
cachePolicy:NSURLCacheStorageNotAllowed
timeoutInterval:30];
[urlRequest
setValue:@"Mozilla/5.0...." //set correct agent value
forHTTPHeaderField:@"User-Agent"];
NSURLResponse *response;
NSError *error;
NSData *returnData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
NSString *responseString = [[NSString alloc] initWithData:returnData
encoding:NSUTF8StringEncoding];
NSLog(@"responseString:%@",responseString);
[field1 resignFirstResponder]; // chiusura tastiera
description.text = responseString;
}
]]> |
You have created some objects to support your tests, such as the Test button and TextView in the OneView view. The best way to "clean" these objects is to hide them; you can then reactivate them when you have resolved your application problems. To do this, open OneView in the Interface builder. Select your object view (for example, a UiButton object). In the Object View Attribute, select the Hidden drawing option as shown in Figure 2.
Figure 2. Set Hidden draw option
Be sure to save all the files. Now you can test your application by selecting Build > Build and Go. If you find some errors, remove them and recompile the project. To test the application:
- Insert the server name in the Server WCA field.
- Insert the user ID in the User id field.
- Click the Load button.
- Insert the correct password in the Alert view.
- Click the OK button.
- Click the Next button.
- In the next view, you can see the list of the virtual systems running on your WebSphere CloudBurst Appliance cloud. If your cloud is empty, the display list will be empty.
The examples in this series were developed using iOS 3. If you want to try this application in your programming environment using the current iOS 4.x, you will need to change the Base SDK of the project. To do this, choose Project > Edit Project Settings. In the Base SDK for all Configuration drop down list, select iOS Simulator 4.1. Close the window and recompile the application.
You might notice that not all the code is working as it should under iOS 4. The
-(void)applicationWillTerminate method: is
never called because of the multitasking support introduced by the new iOS
version. The method is now
-(void)applicationDidEnterBackground:, so you
must rename the old method with the new one. You will also need to change
the application delegation action. You must insert in the ViewDidLoad
method the application delegate:
[[UIApplication sharedApplication] setDelegate: self]; |
Listing 6 shows the new ViewDidLoad method.
Listing 6. ViewDidLoad method
<![CDATA[
-(void)viewDidLoad {
self.title = @"WCA Server";
NSString *filePath = [self dataFilePathPersistence];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePathPersistence]];
NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
FourLines *fourLines = [unarch decodeObjectForKey:DATAKEY];
[unarch finishDecoding];
field1.text = fourLines.field1;
field2.text = fourLines.field2;
[unarch release];
[data release];
}
[[UIApplication sharedApplication] setDelegate:self];
[super viewDidLoad];
}]]> |
For the same reason, it is necessary to change the Alert View. You created an Alert view subclass. When you instantiate the Alert Prompt View, you performed a translation to locate the view in the correct position.
Change these coordinates:
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 130.0); |
to:
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 30.0); |
This conclusion of this four-part series described how to manage an iPhone application with secure HTTP communication. All the major parts of a client-server scenario were presented, based on the iPhone SDK: presentation, data management, network protocol (including secure protocol), and a simple test without communication (hide or un-hide properties). By using the REST syndication in read mode, you can use the same model to use all the functions offered by the REST protocol and to use a full control device for your environment.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code | 1105_amato2_WCAsample.zip | 2.1MB | HTTP |
Information about download methods
-
IBM WebSphere
Cloudburst Appliance product information
-
developerWorks cloud
computing zone
- Series: Managing your private cloud
- Series: Cloud computing for the enterprise
-
Enable C++ applications for Web service using XML-RPC
-
Apple Developer resources
-
Mac OS X
Cocoa Frameworks
-
iOS Dev
Center
-
JSON
-
Objective-C tutorial
-
developerWorks WebSphere Application Server zone
-
IBM developerWorks
WebSphere

Luca Amato is an IBM certified architect who has more than 15 years experience in software development. He has participated as a consultant and project leader in many projects based on web technology. Luca holds a degree in Information Technology from the University of Pisa, Italy, and teaches a language theory course at the University of Pavia for the Informatic department. Luca is an integration solution architect for WebSphere at IBM Italy in Milan, Italy. He works in the WebSphere group with many years of experience in SOA-based solutions. He is also a member of the OpenSource community in IBM.




