Mobile SDK
IBM Cloud® Functions is deprecated. Existing Functions entities such as actions, triggers, or sequences will continue to run, but as of 28 December 2023, you can’t create new Functions entities. Existing Functions entities are supported until October 2024. Any Functions entities that still exist on that date will be deleted. For more information, see Deprecation overview.
IBM Cloud® Functions provides a mobile SDK for iOS
and watchOS
devices that enables mobile apps to fire remote triggers and invoke remote actions. A version for Android is not available, so Android developers can use
the OpenWhisk REST API directly. The mobile SDK is written in Swift 4 and supports iOS 11 and later releases. You can build the mobile SDK by using Xcode 9.
The mobile SDK is not supported for IAM-based namespaces. Use a Cloud Foundry-based namespace instead.
Add the SDK to your app
You can install the mobile SDK by using CocoaPods, Carthage, or from the source directory.
Install mobile SDK with CocoaPods
The IBM Cloud® Functions SDK for mobile is available for public distribution through CocoaPods. Assuming CocoaPods is installed, put the following lines into a file called Podfile
inside the starter app project directory.
install! 'cocoapods', :deterministic_uuids => false
use_frameworks!
target 'MyApp' do
pod 'OpenWhisk', :git => 'https://github.com/apache/incubator-openwhisk-client-swift.git', :tag => '0.3.0'
end
target 'MyApp WatchKit Extension' do
pod 'OpenWhisk', :git => 'https://github.com/apache/incubator-openwhisk-client-swift.git', :tag => '0.3.0'
end
From the command line, type pod install
. This command installs the SDK for an iOS app with a watchOS
extension. Use the workspace file CocoaPods
creates for your app to open the project in Xcode
.
After installation, open your project workspace. You might get the following warning when building:
Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.
This is caused if CocoaPods does not update the Swift version in the Pods project. To fix, select the Pods project and the IBM Cloud® Functions target. Go to Build Settings and change the setting Use Legacy Swift Language Version
to no
. Alternatively, you can add the following post installation instructions at the end of you Podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.0'
end
end
end
Install mobile SDK with Carthage
Create a file in the project directory for your app and name it Cartfile
. Put the following line in the file:
github "openwhisk/openwhisk-client-swift.git" ~> 0.3.0 # Or latest version
From the command line, type carthage update --platform ios
. Carthage downloads and builds the SDK, creates a directory that is called Carthage in the project directory for your app, and puts an OpenWhisk.framework
file inside Carthage/build/iOS.
You must then add OpenWhisk.framework
file to the embedded frameworks in your Xcode project
Install mobile SDK from source code
- Download the source code.
- Open the project by using the
OpenWhisk.xcodeproj
with Xcode. The project contains two schemes: "OpenWhisk" (targeted for iOS) and "OpenWhiskWatch" (targeted forwatchOS
2). - Build the project for the targets that you need and add the resulting frameworks to your app (usually in
~/Library/Developer/Xcode/DerivedData/your-app-name
).
Install the starter app example for mobile SDK
You can use the Cloud Functions CLI to download example code that embeds the Cloud Functions SDK framework.
To install the starter app example, enter the following command:
ibmcloud fn sdk install iOS
This command downloads a compressed file that contains the starter app. The project directory contains a Podfile.
To install the SDK, enter the following command:
pod install
Getting started with mobile SDK
To get up and running quickly, create a WhiskCredentials
object with your Cloud Functions API credentials and create a Cloud Functions instance from the object.
For example, use the following example code to create a credentials object:
let credentialsConfiguration = WhiskCredentials(accessKey: "myKey", accessToken: "myToken")
let whisk = Whisk(credentials: credentialsConfiguration!)
In previous example, you pass in the myKey
and myToken
that you get from Cloud Functions. You can retrieve the key and token with the following CLI command:
ibmcloud fn property get --auth
Example output
whisk auth kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk:tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
The string before the colon is your key, and the string after the colon is your token.
Invoke a mobile SDK action
To invoke a remote action, you can call invokeAction
with the action name. Use a dictionary to pass parameters to the action as needed.
Example
// In this example, we are invoking an action to print a message to the IBM Cloud Functions Console
var params = Dictionary<String, String>()
params["payload"] = "Hi from mobile"
do {
try whisk.invokeAction(name: "helloConsole", package: "mypackage", namespace: "mynamespace", parameters: params, hasResult: false, callback: {(reply, error) -> Void in
if let error = error {
//do something
print("Error invoking Action \(error.localizedDescription)")
} else {
print("Action invoked!")
}
})
} catch {
print("Error \(error)")
}
Fire a mobile SDK trigger
To fire a remote trigger, you can call the fireTrigger
method, and pass in parameters as needed by using a dictionary.
// In this example we are firing a trigger when our location has changed by a certain amount
var locationParams = Dictionary<String, String>()
locationParams["payload"] = "{\"lat\":41.27093, \"lon\":-73.77763}"
do {
try whisk.fireTrigger(name: "locationChanged", package: "mypackage", namespace: "mynamespace", parameters: locationParams, callback: {(reply, error) -> Void in
if let error = error {
print("Error firing trigger \(error.localizedDescription)")
} else {
print("Trigger fired!")
}
})
} catch {
print("Error \(error)")
}
In the previous example, you are firing a trigger that is called locationChanged
.
Use mobile SDK actions that return a result
If the action returns a result, set hasResult
to true in the invokeAction
call. The result of the action is returned in the reply dictionary, for example:
do {
try whisk.invokeAction(name: "actionWithResult", package: "mypackage", namespace: "mynamespace", parameters: params, hasResult: true, callback: {(reply, error) -> Void in
if let error = error {
//do something
print("Error invoking Action \(error.localizedDescription)")
} else {
var result = reply["result"]
print("Got result \(result)")
}
})
} catch {
print("Error \(error)")
}
By default, the SDK returns only the activation ID and any result that is produced by the invoked action. To get metadata of the entire response object, which includes the HTTP response status code, use the following setting:
whisk.verboseReplies = true
Configuring the mobile SDK
You can configure the SDK to work with different installations of Cloud Functions by using the baseURL
parameter. For instance:
whisk.baseURL = "http://localhost:8080"
In this example, you use an installation that is running at http://localhost:8080
. If you do not specify the baseURL
, the mobile SDK uses the instance that is running at https://us-south.functions.cloud.ibm.com.
You can pass in a custom NSURLSession in case you require special network handling. For example, you might have your own Cloud Functions installation that uses self-signed certificates:
// create a network delegate that trusts everything
class NetworkUtilsDelegate: NSObject, NSURLSessionDelegate {
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))
}
}
// create an NSURLSession that uses the trusting delegate
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: NetworkUtilsDelegate(), delegateQueue:NSOperationQueue.mainQueue())
// set the SDK to use this urlSession instead of the default shared one
whisk.urlSession = session
Support for qualified names with mobile SDK
All actions and triggers have a fully qualified name that is made up of a namespace, a package, and an action or trigger name. The SDK can accept these elements as parameters when you are invoking an action or Firing a trigger. The SDK also
provides a function that accepts a fully qualified name that looks like /mynamespace/mypackage/nameOfActionOrTrigger
. The qualified name string supports unnamed default values for namespaces and packages that all Cloud Functions
users have, so the following parsing rules apply:
qName = "foo"
results innamespace = default
,package = default
,action/trrigger = "foo"
qName = "mypackage/foo"
results innamespace = default
,package = mypackage
,action/trigger = "foo"
qName = "/mynamespace/foo"
results innamespace = mynamespace
,package = default
,action/trigger = "foo"
qName = "/mynamespace/mypackage/foo"
results innamespace = mynamespace
,package = mypackage
,action/trigger = "foo"
All other combinations issue a WhiskError.QualifiedName
error. Therefore, when you are using qualified names, you must wrap the call in a "do/try/catch
" construct.