Create and display offers with Decision Management

Learn how to show offers from Journey Optimizer Decision Management in your mobile apps with Experience Platform Mobile SDK.

Journey Optimizer Decision Management helps you to deliver the best offer and experience to your customers across all touchpoints at the right time. Once designed, target your audience with personalized offers.

Architecture

Decision management makes personalization easy with a central library of marketing offers and a decision engine that applies rules and constraints to rich, real-time profiles created by Adobe Experience Platform. As a result, it enables you to send your customers the right offer at the right time. See About Decision Management for more information.

NOTE
This lesson is optional and only applies to Journey Optimizer users looking to use the Decision Management functionality to display offers in a mobile app.

Prerequisites

  • Successfully built and run app with SDKs installed and configured.
  • Set up the app for Adobe Experience Platform.
  • Access to Journey Optimizer - Decision Management with the proper permissions to manage offers and decisions as described here.

Learning objectives

In this lesson, you will

  • Update your Edge configuration for Decision Management.
  • Update your tag property with the Journey Optimizer - Decisioning extension.
  • Update your schema to capture proposition events.
  • Validate setup in Assurance.
  • Create an offer decision, based on offers in Journey Optimizer - Decision Management.
  • Update your app to register the Optimizer extension.
  • Implement offers from Decision Management in your app.

Setup

TIP
If you have set up your environment already as part of the Setup A/B tests with Target lesson, you might already have performed some of the steps in this setup section.

Update datastream configuration

To ensure data sent from your mobile app to Platform Edge Network is forwarded to Journey Optimizer - Decision Management, update your datastream.

  1. In the Data Collection UI, select Datastreams, and select your datastream, for example Luma Mobile App.

  2. Select More for Experience Platform and select Edit Edit from the context menu.

  3. In the Datastreams > Folder > Adobe Experience Platform screen, ensure Offer Decisioning, Edge Segmentation, and Adobe Journey Optimizer are selected. If you will do the Target lesson, select Personalization Destinations, too. See Adobe Experience Platform settings for more information.

  4. To save your datastream configuration, select Save .

    AEP datastream configuration

Install Journey Optimizer - Decisioning tags extension

  1. Navigate to Tags and find your mobile tag property and open the property.

  2. Select Extensions.

  3. Select Catalog.

  4. Search for the Adobe Journey Optimizer - Decisioning extension.

  5. Install the extension. The extension does not require additional configuration.

    Add Decisioning extension

Update your schema

  1. Navigate to Data Collection interface and select Schemas from the left rail.
  2. Select Browse from the top bar.
  3. Select your schema to open it.
  4. In the schema editor, select Add Add next to Field groups.
  5. In the Add fields groups dialog, Search search for proposition, select Experience Event - Proposition Interactions and select Add field groups. This field group collects the experience event data relevant to offers: what offer is presented, as part of which collection, decision, and other parameters (see later in this lesson). But also what is happening with the offer? Is it displayed, interacted with, dismissed, and so forth.
    Proposition
  6. Select Save to save the changes to your schema.

Validate setup in Assurance

To validate your setup in Assurance:

  1. Go to the Assurance UI.
  2. Select Configure in left rail and select Add next to Validate Setup underneath ADOBE JOURNEY OPTIMIZER DECISIONING.
  3. Select Save.
  4. Select Validate Setup in the left rail. Both datastream setup and the SDK setup in your application are validated.
    AJO Decisioning validation

Create placement

Before you can actually create offers, you have to define how and where these offers can be placed in the mobile app. In Decision Management, you define placements for this purpose and you will define a placement for the mobile channel that supports a JSON payload:

  1. In the Journey Optimizer UI, select Components Components from DECISION MANAGEMENT in the left rail.

  2. Select Placements from the top bar.

  3. If no placement with name Mobile JSON, Mobile as Channel type and JSON as Content type is listed, you must create a placement. Otherwise, continue to Create offers.

To create the Mobile JSON placement:

  1. Select Add Create placement.

    1. in the Details section, enter Mobile JSON as the Name, select Mobile from Channel type and JSON from Content type.
    2. Select Save to save the placement.

    Create placement

Create offers

  1. In the Journey Optimizer UI, select Offers Offers from DECISION MANAGEMENT in the left rail.

  2. In the Offers screen, select Browse to see the list of offers.

  3. Select Create offer.

  4. In the New offer dialog, select Personalized offer and click Next.

  5. In the Details step of Create new personalized offer:

    1. Enter a Name for the offer, for example Luma - Juno Jacket, and enter a Start date and time and an End date and time. Outside of these dates, the offer won’t be selected by the Decisioning engine.
    2. Select Next.
      Offers - Details
  6. In the Add representations step of Create new personalized offer:

    1. Select Mobile Mobile from Channel list, and select Mobile JSON from the Placement list.

    2. Select Custom for Content.

    3. Select Add content. In the Add personalization dialog:

      1. In case a Mode selector is available, ensure it is set to JSON.

      2. Enter the following JSON:

        code language-json
        {
            "title": "Juno Jacket",
            "text": "On colder-than-comfortable mornings, you'll love warming up in the Juno All-Ways Performance Jacket, designed to compete with wind and chill. Built-in Cocona™ technology aids evaporation, while a special zip placket and stand-up collar keep your neck protected.",
            "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/jackets/wj06-purple_main.jpg"
        }
        
      3. Select Save.
        Offers - Custom content

    4. Select Next.
      Offer Representations

  7. In the Add constraints step of the Create new personalized offer:

    1. Set Priority to 10.
    2. Toggle Include capping off.
    3. Select Next.
      Offers - Constraints
  8. In the Review step of Create new personalized offer:

    1. Review the offer, then select Finish.
    2. In the Save offer dialog, select Save and approve.
  9. Repeat steps 3 - 8 to create four more offers with different names and content. All other configuration values, for example Start date and time or Priority, are similar to the first offer you created. You can quickly create duplicate and edit offers.

    1. In Journey Optimizer UI, select Offers Offers from the left rail, then select Offers from the top bar.

    2. Select the row of the offer that you created.

    3. In the right pane, select More More actions and from the context menu select Duplicate Duplicate.

      Use the table below to define the four other offers.

      table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 layout-fixed
      Offer name Offer content in JSON
      Luma - Affirm Water Bottle { "title": "Affirm Water Bottle", "text": "You'll stay hydrated with ease with the Affirm Water Bottle by your side or in hand. Measurements on the outside help you keep track of how much you're drinking, while the screw-top lid prevents spills. A metal carabiner clip allows you to attach it to the outside of a backpack or bag for easy access.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/gear/fitness-equipment/ug06-lb-0.jpg" }
      Luma - Desiree Fitness Tee { "title": "Desiree Fitness Tee", "text": "When you're too far to turn back, thank yourself for choosing the Desiree Fitness Tee. Its ultra-lightweight, ultra-breathable fabric wicks sweat away from your body and helps keeps you cool for the distance.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/tees/ws05-yellow_main.jpg" }
      Luma - Adrienne Trek Jacket { "title": "Adrienne Trek Jacket", "text": "You're ready for a cross-country jog or a coffee on the patio in the Adrienne Trek Jacket. Its style is unique with stand collar and drawstrings, and it fits like a jacket should.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/women/tops/jackets/wj08-gray_main.jpg" }
      Luma - Aero Daily Fitness Tee { "title": "Aero Daily Fitness Tee", "text": "Need an everyday action tee that helps keep you dry? The Aero Daily Fitness Tee is made of 100% polyester wicking knit that funnels moisture away from your skin. Don't be fooled by its classic style; this tee hides premium performance technology beneath its unassuming look.", "image": "https://luma.enablementadobe.com/content/dam/luma/en/products/men/tops/tees/ms01-black_main.jpg" }
  10. As a final step you must create a fallback offer, which is an offer sent to customers if they are not eligible for other offers.

    1. Select Create offer.

    2. In the New offer dialog, select Personalized offer and select Next.

    3. In the Details step of Create new fallback offer, enter a Name for the offer, for example Luma - Fallback Offer, and select Next.

    4. In the Add representations step of Create new fallback offer:

      1. Select Mobile Mobile from Channel list, and select Mobile JSON from Placement list.

      2. Select Custom for Content.

      3. Select Add content.

      4. In the Add personalization dialog, enter the following JSON and select Save:

        code language-json
        {
           "title": "Luma",
           "text": "Your store for sports wear and equipment.",
           "image": "https://luma.enablementadobe.com/content/dam/luma/en/logos/Luma_Logo.png"
        }
        
      5. Select Next.

  11. In the Review step of Create new fallback offer:

    1. Review the offer, then select Finish.
    2. In the Save offer dialog, select Save and approve.

You should now have the following list of offers:
Offers list

Create a collection

To present an offer to your mobile app user, you must define an offer collection, consisting of one or more of the offers you created.

  1. In the Journey Optimizer UI, select Offers from the left rail.

  2. Select Collections from the top bar.

  3. Select Add Create collection.

  4. In the New collection dialog, enter a Name for your collection, for example Luma - Mobile App Collection, select Create static collection, and click Next.

  5. In Luma - Mobile App Collection, select the offers you want to include in the collection. For this tutorial, pick the five offers you created. You can easily filter the list using the search field, for example by typing Luma.

  6. Select Save.

    Offers - Collection

Create a decision

The final step is to define a decision, which is the combination of one or more decision scopes and your fallback offer.

A decision scope is a combination of a specific placement (for example HTML in an email, or JSON in a mobile app) and one or more evaluation criteria.

An evaluation criterium is the combination of

  • an offer collection,
  • eligibility rules: for example, is the offer only available for a specific audience,
  • a ranking method: when multiple offers are available to pick from, which method do you use to rank them (for example by offer priority, using a formula, or an AI model).

See Key steps to create and manage offers if you want to better understand how placements, rules, rankings, offers, representations, collections, decisions, and so on, interact and relate to each other. This lesson is solely focused on using the output of a decision rather than on the flexibility in defining decisions within Journey Optimizer - Decision Management.

  1. In the Journey Optimizer UI, select Offers from the left rail.

  2. Select Decisions from the top bar.

  3. Select Add Create decision.

  4. In the Details step of Create a new offer decision:

    1. Enter a Name for the decision, for example Luma - Mobile App Decision, enter Start date and time and End date and time.
    2. Select Next.
  5. In the Add decision scopes step of Create a new offer decision:

    1. Select Mobile JSON from Placement list.

    2. In the Evaluation Criteria tile, select Add Add.

      1. In the Add Offer Collection dialog, select your offer collection. For example, Luma - Mobile App Collection.
      2. Select Add.
        Decision - Select collection
    3. Ensure that None is selected for Eligibility, and Offer priority is selected as the Ranking method.

    4. Select Next.
      Decision scopes .

  6. In the Add fallback offer step of Create a new offer decision:

    1. Select your fallback offer, for example the Luma - Fallback offer.
    2. Select Next.
  7. In the Summary step of Create a new offer decision:

    1. Select Finish.
    2. In the Save offer decision dialog, select Save and activate.
    3. In the Decisions tab, you see your decision with status Live.

Your offer decision, consisting of a set of offers, is now ready for use. To use the decision in your app, you have to refer in your code to the decision scope.

  1. In the Journey Optimizer UI, select Offers.

  2. Select Decisions from the top bar.

  3. Select your decision, for example Luma - Mobile App Decision.

  4. In the Decision scopes tile, select Copy Copy.

  5. From the contextual menu, select Decision scope.
    Copy decision scope

  6. Use any text editor to paste the decision scope for later use. The decision scope has the following JSON format.

    code language-json
    {
        "xdm:activityId":"xcore:offer-activity:xxxxxxxxxxxxxxx",
        "xdm:placementId":"xcore:offer-placement:xxxxxxxxxxxxxxx"
    }
    

Implement offers in your app

As discussed in previous lessons, installing a mobile tag extension only provides the configuration. Next you must install and register the Optimize SDK. If these steps aren’t clear, review the Install SDKs section.

NOTE
If you completed the Install SDKs section, then the SDK is already installed and you can skip this step.
  1. In Xcode, ensure that AEP Optimize is added to the list of packages in Package Dependencies. See Swift Package Manager.

  2. Navigate to Luma > Luma > AppDelegate in the Xcode Project navigator.

  3. Ensure AEPOptimize is part of your list of imports.

    code language-swift
    import AEPOptimize
    
  4. Ensure Optimize.self is part of the array of extensions that you are registering.

    code language-swift
    let extensions = [
        AEPIdentity.Identity.self,
        Lifecycle.self,
        Signal.self,
        Edge.self,
        AEPEdgeIdentity.Identity.self,
        Consent.self,
        UserProfile.self,
        Places.self,
        Messaging.self,
        Optimize.self,
        Assurance.self
    ]
    
  5. Navigate to Luma > Luma > Model > Data > decisions in the Xcode Project navigator. Update the activityId and placementId values with the decision scope details you copied from the Journey Optimizer interface.

  6. Navigate to Luma > Luma > Utils > MobileSDK in the Xcode Project navigator. Find the func updatePropositionOD(ecid: String, activityId: String, placementId: String, itemCount: Int) async function. Add the following code:

    code language-swift
    // set up the XDM dictionary, define decision scope and call update proposition API
    Task {
       let ecid = ["ECID" : ["id" : ecid, "primary" : true] as [String : Any]]
       let identityMap = ["identityMap" : ecid]
       let xdmData = ["xdm" : identityMap]
       let decisionScope = DecisionScope(activityId: activityId, placementId: placementId, itemCount: UInt(itemCount))
       Optimize.clearCachedPropositions()
       Optimize.updatePropositions(for: [decisionScope], withXdm: xdmData)
    }
    

    This function:

    • sets up an XDM dictionary xdmData, containing the ECID to identify the profile for which you have to present the offers.

    • defines decisionScope, an object that is based on the decision you have defined in the Journey Optimizer - Decision Management interface and is defined using the copied decision scope from Create a decision. The Luma app uses a configuration file (decisions.json) that retrieves the scope parameters, based on the following JSON format:

      code language-swift
      "scopes": [
          {
              "name": "name of the scope",
              "activityId": "xcore:offer-activity:xxxxxxxxxxxxxxx",
              "placementId": "xcore:offer-placement:xxxxxxxxxxxxxxx",
              "itemCount": 2
          }
      ]
      

      However, you can use any kind of implementation to ensure the Optimize APIs get the proper parameters (activityId, placementId and, itemCount), to construct a valid DecisionScope object for your implementation.
      For your information: the other key-values in the decisions.json file are for future use and not relevant and used currently in this lesson and as as part of the tutorial.

    • calls two APIs: Optimize.clearCachePropositions and Optimize.updatePropositions. These functions clear any cached propositions and update the propositions for this profile.

  7. Navigate to Luma > Luma > Views > Personalization > EdgeOffersView in the Xcode Project navigator. Find the func onPropositionsUpdateOD(activityId: String, placementId: String, itemCount: Int) async function and inspect the code of this function. The most important part of this function is the Optimize.onPropositionsUpdate API call, which

    • retrieves the propositions for the current profile based on the decision scope (which you have defined in Journey Optimizer - Decision Management),
    • retrieves the offer from the proposition,
    • unwraps the content of the offer so it can be displayed properly in the app, and
    • triggers the displayed() action on the offer which sends an event back to the Edge Network informing the offer is displayed.
  8. Still in EdgeOffersView, add the following code to the .onFirstAppear modifier. This code ensures that the callback for updating the offers is registered only once.

    code language-swift
    // Invoke callback for offer updates
    Task {
        await self.onPropositionsUpdateOD(activityId: decision.activityId, placementId: decision.placementId, itemCount: decision.itemCount)
    }
    
  9. Still in EdgeOffersView, add the following code to the .task modifier. This code updates the offers when the view is refreshed.

    code language-swift
    // Clear and update offers
    await self.updatePropositionsOD(ecid: currentEcid, activityId: decision.activityId, placementId: decision.placementId, itemCount: decision.itemCount)
    

Validate using the app

  1. Rebuild and run the app in the simulator or on a physical device from Xcode, using Play .

  2. Go to the Personalisation tab.

  3. Select Edge Personalisation.

  4. Scroll to the top, and you see two random offers displayed from the collection that you have defined in the DECISION LUMA - MOBILE APP DECISION tile.

    {width="300"}

    The offers are random, as you have given all offers the same priority and the ranking for the decision is based on priority.

Validate implementation in Assurance

To validate the offers implementation in Assurance:

  1. Review the setup instructions section to connect your simulator or device to Assurance.

  2. Select Configure in left rail and select Add next to Review & Simulate underneath ADOBE JOURNEY OPTIMIZER DECISIONING.

  3. Select Save.

  4. Select Review & Simulate in the left rail. Both datastream setup is validated and the SDK setup in your application.

  5. Select Requests at the top bar. You see your Offers requests.
    AJO Decisioning validation

  6. You can explore Simulate and Event List tabs for further functionality, checking your setup of Journey Optimizer Decision Management.

Next steps

You should now have all the tools to start adding more functionality to your Journey Optimizer - Decision Management implementation. For example:

  • apply different parameters to your offers (for example, priority, capping)
  • collect profile attributes in the app (see Profile) and use these profile attributes to build audiences. Then use these audiences as part of the eligibility rules in your decision.
  • combine more than one decision scope.
SUCCESS
You have enabled the app to display offers using the Journey Optimizer - Decisioning extension for the Experience Platform Mobile SDK.
Thank you for investing your time in learning about Adobe Experience Platform Mobile SDK. If you have questions, want to share general feedback, or have suggestions on future content, share them on this Experience League Community discussion post.

Next: Perform A/B tests

recommendation-more-help
9fed61f5-c338-47ad-8005-0b89a5f4af8b