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

You must have a MacBook with Xcode installed, and an existing project created.

Procedure

  1. Create a LoginService.swift class file in your project to handle the Cúram authentication code.
  2. 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 = ""
    }
    
  3. 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.

  4. 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
            }
    }
    
    
  5. 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)
        }
    
  6. 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
        }
    
  7. 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)
    
  8. 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()