Connecting to a Curam REST API using Swift for Apple iOS
Connecting programmatically to a Cúram REST API resource depends on the programming language used. The following is an example using the Apple Swift Language for iOS.
Before you begin
Procedure
- Create a LoginService.swift class file in your project to handle the Cúram authentication code.
-
Define the following variables in the LoginService.swift class:
var username = "" var password = "" var data: NSMutableData = NSMutableData() // Used for Weblogic var WL_JSESSION_ID: String = "" var JSESSION_ID: String = "" // Used for Websphere struct LTPAToken { static var ltpaToken2:String = "" }
-
Define the invokeLoginService() function, which will eventually be called to initiate a login
request. The function takes three parameters:
- username
The user name to log in.
- password
The password to log in.
- loadTokenUrl
The full qualified URL for the login, that is, https://host:port/Rest/j_security_check
func invokeLoginService(username: String, password: String, loadTokenUrl: String) { let nsUrl = NSURL(string: loadTokenUrl as String ); self.username = username self.password = password NSLog(loadTokenUrl) let request = NSMutableURLRequest(URL:nsUrl!); request.HTTPMethod = "POST"; request.HTTPShouldHandleCookies = true request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") //set Referer for CSRF request.setValue("curam://foundational.app", forHTTPHeaderField: "Referer") let postString = "j_username=" + username + "&j_password=" + password ; request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding); //invoke login request var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)! connection.start() }
The delegate argument in the NSURLConnection object defines that the LoginService (self) class should handle the response from the login request. Next, define the following connection functions to support this.
- username
-
Define a connection function to handle when the connection request is completed. This function
sets the necessary cookies if the request was successful.
func connection(connection:NSURLConnection, didReceiveResponse response: NSURLResponse) { let status = (response as? NSHTTPURLResponse)?.statusCode ?? -1 NSLog("status code is \(status)") if ( status == 200 ) { //200 OK authentication successful, fetch the LTPAToken2 from response and set for future requests self.data = NSMutableData() let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage() let allCookies = cookieStorage.cookiesForURL(response.URL!) as! [NSHTTPCookie] var cookieProperties = [String: AnyObject]() for cookie in allCookies { cookieProperties[NSHTTPCookieName] = cookie.name cookieProperties[NSHTTPCookieValue] = cookie.value println("name: \(cookie.name) value: \(cookie.value)") if ( cookie.name == "LtpaToken2" ) { LTPAToken.ltpaToken2 = cookie.value! } } let success = [ 200, "Success"] return } else if ( status == ErrorCodeConstants.errAuthenticationFailure ) { //authentication error let error = [ 401, "LoginErrorMsg3"] return } else { let error = [ 600, "LoginErrorMsg2"] return } }
-
Define a connection function to handle the data that is returned by the request.
func connection(connection: NSURLConnection, didReceiveData connectionData: NSData) { // Append the received chunk of data to our data object self.data.appendData(connectionData) }
-
Define a connection function to handle an unsuccessful response.
func connection(connection: NSURLConnection, didFailWithError connectionData: NSError) { // Append the received chunk of data to our data object NSLog("didFailWithError ---> \(connectionData)") return }
-
Use the newly created LoginService.swift class within your project to initiate
authentication.
For example, from a view controller, use the following:
var username = “planner” var password = “password” var loginURL = “https://host:port/Rest/j_security_check let loginService = LoginService() loginService.invokeLoginService (username, password, loginURL)
-
In your project, use the following code to invoke the GET method of the Cúram persons REST API
resource. This code uses the previously defined loginService variable.
let url = NSURL(string: curamServerURI+"/v1/persons/101") let request = NSMutableURLRequest(URL:url!); request.HTTPMethod = "GET" let config = NSURLSessionConfiguration.defaultSessionConfiguration() //set the headers , this can be moved in a common method, when there are more apis to invoke var xHTTPAdditionalHeaders: [NSObject : AnyObject] = ["Content-Type": "application/json", "Accept": "application/json"] //set the headers for LTPAToken if it is for WAS else for WLS , you need to set the _WL_AUTHCOOKIE_JSESSIONID & JSESSIONID xHTTPAdditionalHeaders["Cookie"] = "LtpaToken2="+LoginService.LTPAToken.ltpaToken2+";" //set Referer for CSRF xHTTPAdditionalHeaders["Referer"] = "curam://foundational.app" config.HTTPAdditionalHeaders = xHTTPAdditionalHeaders let session = NSURLSession(configuration: config) var err: NSError? let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in let status = (response as? NSHTTPURLResponse)?.statusCode ?? -1 self.data = NSMutableData() if (status == 200) { //200 OK..request successful .... process response println("Response: \(response)") var strData = NSString(data: data, encoding: NSUTF8StringEncoding) println("Body: \(strData)") var err: NSError? if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary { if(err != nil) { // If there is an error parsing JSON, print it to the console println("JSON Error \(err!.localizedDescription)") } if let results: NSArray = jsonResult["relationships"] as? NSArray { dispatch_async(dispatch_get_main_queue(), { println("Person Relationship data :\(results)") }) } } } else { let error = [ 600, "Request failed"] println("Request failed Error \(self.data)") } }) //start the service request task.resume()