DZone
Cloud Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Cloud Zone > Calling an OpenWhisk Action in Swift

Calling an OpenWhisk Action in Swift

OpenWhisk's Swift environment has methods built in to call actions. This guide will walk you through creating and invoking an action with Swift.

Rob Allen user avatar by
Rob Allen
·
Mar. 24, 17 · Cloud Zone · Tutorial
Like (8)
Save
Tweet
3.19K Views

Join the DZone community and get the full member experience.

Join For Free

As OpenWhisk is a Functions-as-a-Service system, it makes sense to create actions that do one thing and call other actions when they want other work done. As an example, in DrinksChooser, the choose action calls the incrementDrinkCount action, which increments the count of the recommended drink in Redis. This way,  choose doesn't have to know anything about Redis as that's not its job.

In OpenWhisk's Swift environment, there's the Whisk.invoke() method to do this. This is how we do it.

let env = ProcessInfo.processInfo.environment
let namespace : String = env["__OW_NAMESPACE"] ?? ""
let incrementAction = "/" + namespace + "/DC/incrementDrinkCount"
 
let invokeResult = Whisk.invoke(actionNamed: incrementAction,
        withParameters: ["name": drink])
let result = JSON(invokeResult)


The Action's Name

To invoke an action, we need it's fully qualified name. This is your OpenWhisk namespace concatenated with the action's name, including its package name if it has one.

Let's start with the namespace:

let env = ProcessInfo.processInfo.environment
let namespace : String = env["__OW_NAMESPACE"] ?? ""


Conveniently, the namespace is held in an environment variable called __OW_NAMESPACE. In Swift, we can retrieve environment variables from the ProcessInfo.processInfo.environment which will return an Optional String. As we're lazy, we convert the Optional to a concrete String using ?? "". In a proper application, we'd implement Swift's error handling and do it properly.

Note that the namespace doesn't start with a leading /, but our fully qualified action name does, so we create our action name like this:

let name = "/" + namespace + "/DC/incrementDrinkCount"


The action's name is incrementDrinkCount and it's in the DC package, so we add those in to create our action name.

Invoke the Action

Invoking the action is easy enough:

let p = ["name": "A nice hot cup of tea!"]
let result = Whisk.invoke(actionNamed: name, withParameters: p)


We call Whisk.invoke() with our action name and a dictionary of parameters if we have any. In our case, we pass in the name of the drink whose count we want to increment.

The action is executed and the result is returned as a dictionary of type [String:Any].

Data Returned From Whisk.invoke()

You get a dictionary back from Whisk.invoke() with lots of interesting information:

[
    "activationId": "f91ac41933274f8eb191082a834f70a4",
    "annotations": [
        [
            "key": "limits",
            "value": [
                "logs": 10,
                "memory": 256,
                "timeout": 60000
            ]
        ],
        [
            "key": "path",
            "value": "19FT_dev/DC/incrementDrinkCount"
        ]
    ],
    "duration": 40,
    "end": 1488230688926,
    "logs": [],
    "name": "incrementDrinkCount",
    "namespace": "19FT_dev",
    "publish": false,
    "response": [
        "result": [
            "drink": "A nice hot cup of tea!",
            "new_count": "24"
        ],
        "status": "success",
        "success": true
    ],
    "start": 1488230663040,
    "version": "0.0.3"
]


The interesting information is in the response dictionary, and the first thing to check is the success key, which is a boolean and thus is either true or false:

let response = result["response"] as! Dictionary<String, Any>
if response["success"] as! Bool == false {
    return ["error": "incrementDrinkCount failed"]
}


As you can see, we have to downcast a lot.

As the type of the dictionary is [String:Any], we have to downcast all the time!

To make this easier, we can use the SwiftyJSON library, which handles the casting for us:

let jsonResult = JSON(result)
if jsonResult["response"]["success"].boolValue == false {
    return ["error": "incrementDrinkCount failed"]
}


This becomes even more useful as we delve deeper into a nested dictionary!

Swift (programming language)

Published at DZone with permission of Rob Allen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 10 Programming Habits a Web Developer Should Embrace
  • Java Microservices: Code Examples, Tutorials, and More
  • Data Statistics and Analysis With Java and Python
  • Correlation Between Fast TTM and Containers

Comments

Cloud Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo