Figure 1: Adobe Experience Platform Logo
The latest generation of the Adobe Experience Platform Mobile SDK was built from the ground up to be modular and extensible. Extensions allow partners and customers to augment, customize and extend the capabilities of the Adobe Experience Platform SDKs with their own code. This includes listening for and dispatching any mobile engagement event, reading the shared state of any registered extension, and sharing the state of the current extension. The value of extensions for both customer and partners include:
By utilizing an Adobe Experience Platform extension vs. implementing a native SDK integration, there is less work on the customer’s part to install and initialize third party solutions and fewer API calls they need to implement.
Extensions that integrate with the Adobe Launch rules engine provide customers additional capabilities in constructing complex use case workflows across multiple solutions.
Extensions are managed within the Adobe Launch portal and can be dynamically updated with configuration changes without requiring a customer rebuild or resubmit their application. In this lab we will create a new mobile extension that will retrieve weather conditions based on zip code and will post back requested weather conditions to a slack channel. Each request will also register a data point on our combined weather map report.
By the end of this lab, participants should have a good understanding of:
Client-side native iOS extension code examples will utilize Apple Xcode v10.x with and iPhone Simulator running iOS 10+.
Customers and Partners should have access to Adobe Launch, along with the ability to create and manage mobile properties.
If you cannot create a mobile property, or do not have access to Adobe Launch, reach out to someone in your organization that can grant you access rights through the Adobe Admin Console. See this guide for more information: Assigning User Permissions.
Node.js 5.2.0 or greater is required for this lab. If it is not installed, the latest version can be found here.
Optional - create an Adobe I/O integration.
Beyond this Adobe SUMMIT lab, we are continuously updating our example projects. Visit or bookmark the following Github projects below to see our latest progress:
Figure 2: Adobe Experience Platform Mobile extension components
Each Adobe Experience Platform SDK extension is comprised of two components, a client-side native extension that is implemented inside the application, and a Launch UI extension that is uploaded into the Launch extension catalog and can be used to set configuration values. Beyond capturing configuration values, the Launch UI extension can expose events, conditions and actions that can be used in the Launch rules engine for workflow automation.
Figure 3: Adobe Experience Platform Mobile SDK Core event hub
Looking at the Mobile SDK Core event hub process flow you can see that as users engage with the mobile application, events are received by the Mobile Core event hub and are then simultaneously dispatched to all extensions that have registered event listeners.
As part of this lesson, a new mobile extension will be implemented in order to retrieve the weather conditions from a server based on a zip code. Adobe Mobile SDK team has provided sample code which can be used for this lesson.
Implement an iOS mobile extension for retrieving the weather conditions for a zip code.
Open the project in Xcode: Navigate to the resources/module-1/ACPWeatherExample
directory and double click on ACPWeatherExample.xcworkspace
. The ACPWeatherExample project should open in Xcode.
Hint: From the Project navigator you will see two projects, ACPWeatherExample and Pods. The ACPWeatherExample project contains the implementation for the weather extension and a test application for this lesson. Pods project contains the installed Cocoapod dependencies for this project: ACPCore representing the Mobile SDK Core extension and ACPAnalytics which is the Adobe Analytics mobile extension.
Figure 4: ACPWeatherExample Xcode project structure
Once the project is opened in Xcode, search for the keyword TODO
in the project in order to see all the steps for this lab exercise. It is recommended to implement these steps in incremental order. Each step has a number which is associated with the exercise number (module#.lesson#.exercise#).
Click on the search magnifier and in the text filed type TODO
.
Figure 5: Find the steps to be implemented
One of the required methods to override in a Mobile extension is the "name" method. This method should return the extension name. This name is used by the Mobile SDK Core as the extension's shared state name and also can be used for logging purposes. Multiple extensions can be registered at the same time with the Mobile SDK event hub, so the extension should have a unique name in order to avoid name conflicts. For the weather extension the following name should be set (Step 1.1.3.):
Next, the extension needs to register an event listener in order to receive events from the event hub with a particular event type and event source. The WeatherExtensionListener
class should be provided as parameter (Step 1.1.4.):
Implement the WeatherExtensionListener
class by first queueing the received event and then start processing the existing events. Introduce the following two lines where indicated (Step 1.1.5.):
Hint: We are queuing the received event in order fetch the latest Configuration shared state for current event. If at the time of processing the event the Configuration shared state is not updated (for example is nil because the remote download is not completed yet), we are keeping the event in the queue until a shared state update event is received from the event hub when we will retry to process this event.
When processing the event, after extracting the zip code from the request event, a network call is made to request the weather conditions. The following line needs to be uncommented where indicated (Step 1.1.6.):
Updating extension's shared state allows other extensions to access the latest weather conditions and these values can be used as data elements when rules are triggered, as it will be exemplified later in this lab.
After the weather conditions are received, also send a response event. You can create an event by using ACPExtensionEvent
as follow (Step 1.1.7.):
Once the event is created, it should be dispatched to the event hub using
ACPCore dispatchResponseEvent:requestEvent:error:
API. This API dispatches a response event for the associated request event (the trigger for this response). Uncomment the following line (Step 1.1.8):
Read more about this here: Dispatch paired events
The following 3 steps implement the two public APIs for the Weather extension that the mobile application developer will be interacting with.
First, let's implement the registerExtension
API. When this API is called the internal extension (WeatherExtensionInternal
class) should be registered with the event hub. Calling ACPCore registerExtension
API allows the event hub to register the extension. Uncomment the following line (Step 1.1.9.):
The second public API getWeatherByZipCode:callback:
receives the zip code as parameter from the mobile application developer and has a response callback function for the weather conditions. In order to send the zip code to the WeatherExtension create a request event with the same event type and source as the registered WeatherExtensionListener (see Step 4) and attach the zip code as event data as follows (Step 1.1.10.):
Dispatch the getWeatherEvent
to the event hub and implement the response callback to return the weather conditions back to the mobile application.
The ACPCore dispatchEventWithResponseCallback:responseCallback:.
API allows you to dispatch an event to your extension and wait for a response event in return. Uncomment the following line (Step 1.1.11.):
[ACPCore dispatchEventWithResponseCallback:getWeatherEvent
responseCallback:^(ACPExtensionEvent * _Nonnull responseEvent) {
NSLog(@"In response callback for event '%@', event data returned: %@", responseEvent.eventName, responseEvent.eventData);
callback([self extractWeatherData:responseEvent]);
} error:&dispatchError];
Last step, build the project. If everything was implemented correctly, there shouldn't be any compilation errors.
To Build the Weather Extension, from the Xcode top bar select the ACPWeatherExample
target and an iPhone simulator
, for e.g. iPhone XR (the selected iPhone should have iOS version 10+), then click on the Run button (play button) or press ⌘B.
Figure 6: Build the ACPWeatherExample
For this lesson the provided TestApp will be used to test the Weather Extension implemented in Lesson 1.
Note: If for some reason you were not able to finish the exercise in Lesson 1, you can use the finished project located at
resources/module-1/ACPWeatherExample-finished
. Close the current Xcode project and then double click onACPWeatherExample.xcworkspace
.
In this exercise, you will run the iOS TestApp in order to see the Weather extension dispatching events through the event hub, fetching response events and displaying the weather conditions in the mobile application. This application is an example of how an Adobe Mobile SDK customer can integrate Adobe and partner extensions in the same application, and how the Weather Extension will be used by the application developer.
For this exercise we are going to work with the TestApp folder in the Xcode project. In the project structure on the left side of your Xcode, click on TestApp to see the sources.
Figure 7: Test application sources
As you can see in Figure 7, the TestApp has sources and headers for AppDelegate and ViewController.
Check the AppDelegate.m
source code (in the left tab, click on this file). The following method - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
will be called when the application is initialized/booted.
The first step is to configure the Adobe Mobile SDK by using ACPCore configureWithAppId:
API and providing the Launch configuration ID for the environment that you are using (production, staging, development). This is a unique identifier that Launch UI provides for a mobile property, which will be used by the Adobe Mobile SDK to download the remote configuration and the rules configured for this property.
// Use ACPCPre configureWithAppId: API when you have a mobile property defined
// in Launch and have a remote configuration published.
// Read more about this: https://aep-sdks.gitbook.io/docs/using-mobile-extensions/mobile-core/configuration-reference#launch-environment-id
[ACPCore configureWithAppId:@"staging/launch-ENb44c5c8eb4ac4c5b8c89b6afffc167f7-development"];
After that, all the extensions are registered with the event hub as follows:
// register the Weather extension
[WeatherExtension registerExtension];
// register Adobe core extensions
[ACPIdentity registerExtension];
[ACPLifecycle registerExtension];
[ACPSignal registerExtension];
// register Adobe Analytics extension
[ACPAnalytics registerExtension];
Finally, ACPCore start method is called in order to start processing the events:
Note: It is important to register the extensions before calling ACPCore start API in order to receive all the events. Since the system is asynchronous, registering the extension after ACPCore start call may result in some events being dispatched before the extension is registered.
Check the ViewController.m
source code (in the left tab, click on this file), it contains two on click button actions associated with the two buttons in the app.
The first one, getWeather
calls the WeatherExtension getWeatherByZipCode:callback:
public API that was implemented in Lesson 1, Exercise 1.1 and updates the UI of the mobile application with the returned weather conditions.
The second one, getWeatherByTriggeringRules
calls the ACPCore trackAction
API with current zip code value. The event generated by this API call will be used by the Adobe Analytics mobile extension in order to track the click button action and it can be used for triggering new rules configured in Launch UI for this mobile property.
In order to run the test application, from the Xcode top bar select the TestApp
target and any iPhone simulator
, for e.g. iPhone XR (the selected iPhone should have iOS version 10+), then click on the Run button or press ⌘B.
Figure 8: Run the TestApp which uses the Weather Extension
Once the iOS mobile application is installed and opened on the selected iOS simulator, write the preferred US zip code and click on the Get weather
button. The results should looks as in the image below:
Figure 9: Test Application running
Every Adobe Experience Platform Mobile SDK extension has both a client-side component and a Launch UI extension component. The Launch UI extension is used to capture configuration values necessary to allow the client-side extension to work. Additionally, the Launch UI extension can be developed to expose events, conditions and actions specific to the extension. When defined, these actions can be used in the Launch rules engine.
Local sandbox testing is recommended for any Launch UI extension before uploading it to the Adobe Launch private or public catalog.
In this exercise we will startup the local Launch sandbox environment and view the Launch weather extension.
Launch Terminal
from the application dock, or by navigating to Applications/Utilities/Terminal.app
Open the folder: /resources/module-2/
In Terminal type cd
weather-extension
directory from /resources/module-2/
path.
Figure 10: Navigating to the weather-extension directory
If you type pwd
and return you should see in terminal that you are now located inside the weather-extension folder.
$ pwd
On a new line in Terminal type: npx @adobe/reactor-sandbox
and hit return:
$ npx @adobe/reactor-sandbox
You should see a message saying: 'Extension sandbox running at http://localhost:3000 and at https://localhost:4000'
Launch Chrome from the application dock and type in http://localhost:3000. You should now see the Weather Extension running in sandbox mode.
In the Select View drop-down make sure that Extension Configuration
is selected.
Notice that the sandbox shows a Timeout field. Type in a value i.e. 200.
Figure 11: Running Launch Weather Extension in Sandbox
On the right side of the window, select the tab named Get Settings
and hit the Get Settings
button. This should show the Timeout value that you typed into the field.
At the bottom of the Get Settings
window you can also click the Copy Settings to Init Panel
button.
Click back on the Init
window and see that "weather.timeout"
has a value equal to what was entered into the field.
Hint: the sandbox can be used to see how the Launch extension custom views will look like in Adobe Launch dashboard and what will be the returned values for the provided callbacks: init(), getSettings() and validate() before publishing the extension. These methods will be detailed in Lesson 2.
Now that we have seen how the Launch local sandbox can be used to preview and test your Launch UI extension, it's time to add an additional configuration field to the Weather extension.
In this exercise we will add an API key field to the Weather extension and then preview the changes in Launch Sandbox mode.
From the Finder navigate to the folder:
/resources/module-2/weather-extension/src/view/configuration
Find the configuration.html
file and drag and drop this file over the Brackets
application.
To Add a new configuration key, add a new label in the
. Un-comment out lines 11-18 by removing the "" HTML comments (Step 2.2.3):Add your key in the init
function to populate the view with info.settings which will exist if the user is editing something that was previously saved.
Further down in the same file on line 36 remove the "//" comment (Step 2.2.4):
init: function(info) {
if (info.settings) {
// TODO: Step 2.2.4. Add your key in the init function to populate the view with info.settings which will
// exist if the user is editing something that was previously saved.
document.getElementById('apiKey').value = info.settings['weather.apiKey'];
document.getElementById('timeout').value = info.settings['weather.timeout'];
} else {
document.getElementById('timeout').value = 0;
}
},
Next, add your key in the return of the getSettings
function. These keys should contain the values added by the user. The same keys can be used when the remote configuration is downloaded by the Adobe Mobile SDK when the application is launched and handled in the mobile extension.
Also remove the "//" comments on lines 47 and 50 (Step 2.2.5):
getSettings: function() {
// TODO: Step 2.2.5 Add a configuration key for the api key and collect current value
// Hint: The getSettings method is used to return the extension keys with the associated value enetered by the user
var key = document.getElementById('apiKey').value;
var timeout = Number(document.getElementById('timeout').value);
return {
'weather.apiKey': key,
'weather.timeout': timeout
};
},
Last, update the validate
function with some restrictions for the new key. This will guide the user to configure the extension properly.
Remove the "//" comments on lines 63-66 (Step 2.2.6):
validate: function() {
var timeoutField = document.getElementById('timeout');
var timeout = Number(timeoutField.value);
timeoutField.invalid = isNaN(timeout) || timeout < 0;
// TODO: Step 2.2.6. Update the validate function with some restrictions for your new key.
// Hint: The field validation is used to guide the user to configure the extension properly.
var keyField = document.getElementById('apiKey');
var key = keyField.value;
keyField.invalid = !key;
return !timeoutField.invalid && !keyField.invalid;
}
Save and close this file.
Click back on the Chrome browser and refresh the Launch Sandbox at http://localhost:3000.
If you accidentally stopped the Sandbox, then go back and repeat the steps in the previous Lesson 1 to launch the Weather extension in Sandbox mode.
You should now see the API Key field in the extension configuration view as in the image below:
Figure 12: Weather Extension API Key in Sandbox
Beyond the baseline extension created in this lab, take some time to explore the Launch UI extension further to see how we were able to define Data Elements, Events, Conditions and Actions that are all used in the Launch rules engine.
When you are ready to upload your extension to the Adobe Launch catalogue, you will first need an Adobe I/O integration created. See this documentation for how to create the integration here.
There is a great deal of information available to learn more about the Adobe Experience Platform Mobile SDK and Launch. Below are some resources that may be helpful: