Integrating WebSphere CloudBurst capabilities in an iPhone solution, Part 4: Extending classes to manage HTTPS syndication

This series of articles walks you through the process of creating a full client application for an Apple® iPhone® device that collaborates with an IBM® WebSphere® CloudBurst™ Appliance using a REST API. Using the vast REST-based APIs provided, WebSphere CloudBurst offers many integration opportunities for a Web 2.0 environment, such as with a smartphone. Building on the previous articles, Part 4 concludes this series showing how you can extend a class to manage the HTTPS protocol, including security management. This content is part of the IBM WebSphere Developer Technical Journal.

Share:

Luca Amato (lucaamato@it.ibm.com), Senior IT Architect, IBM

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



22 June 2011

Also available in

The series so far

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.

Prerequisites

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

Alert Prompt class

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.

HTTPS REST invocation

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 enteredText of the Alert View
  • server from the entry field field1
  • REST invocation from the API constant

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;
}
]]>

Removing the test object

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
fig2

Save and test

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:

  1. Insert the server name in the Server WCA field.
  2. Insert the user ID in the User id field.
  3. Click the Load button.
  4. Insert the correct password in the Alert view.
  5. Click the OK button.
  6. Click the Next button.
  7. 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.

Changing the SDK

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.

Troubleshooting

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.


Download

DescriptionNameSize
Sample code1105_amato2_WCAsample.zip2.1MB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Web development
ArticleID=656643
ArticleTitle=Integrating WebSphere CloudBurst capabilities in an iPhone solution, Part 4: Extending classes to manage HTTPS syndication
publish-date=06222011