4. Integrating Actions in Your App

🚧

Before you begin, make sure you’ve completed the following steps:

To submit details on customers’ actions, you’ll need to create API methods. For more information, please refer to the API integrations section.

Mindbox’s SDK offers the following 2 methods to call API methods from a mobile app:

  • executeAsyncOperation to send data to the system;
  • executeSyncOperation to receive data from the system.

Use the OperationBodyRequest constructor to create a request body when calling an API method.

Integration specifications

In this guide, we’ll demonstrate an example of how to call the SDK’s API to transmit data.

To submit data to Mindbox, relevant API methods must be set up. These must be configured separately for each project.

Your customer success manager is responsible for setting up and documenting these API methods.

❗️

You’ll need to have a document detailing all the required API methods before you proceed to the steps below.

Below you will find examples of how you can integrate some requests from a mobile app.

Please note that if you copy the code from these examples, your integration will not work.

Authentication example (for tests only)

Expected results:

  • You can find a customer in Mindbox by searching using their phone number.
  • This customer’s profile contains mobile app details.
private func auth() {
    let body = OperationBodyRequest();
    
    body.customer = .init(
        mobilePhone: "12025550159"
    )
    
    Mindbox.shared.executeAsyncOperation(
        operationSystemName: "CheckGuide.auth",
        operationBody: body
    )
}

Submitting Product and Category View actions

Expected result:

  • Customers that can be found by their deviceUUID will have product and category view actions displayed in the Actions tab of their profiles.
private func viewProduct() {
    let body = OperationBodyRequest();
    
    body.viewProduct = .init(
        product: .init(ids: ["website": "123"])
    )
    
    Mindbox.shared.executeAsyncOperation(
        operationSystemName: "CheckGuide.viewProduct",
        operationBody: body
    )
}

private func viewCategary() {
    let body = OperationBodyRequest();
    
    body.viewProductCategory = .init(
        productCategory: .init(ids: ["website": "123"])
    )
    
    Mindbox.shared.executeAsyncOperation(
        operationSystemName: "CheckGuide.viewCategory",
        operationBody: body
    )
}

Submitting Added to / Deleted from Cart actions

Mindbox offers 2 methods to handle product lists:

  • Add / delete individual products;
  • Set up a list by a single request.

Popular product lists: Cart and Favorites.

Expected result:

  • Customers that can be found by their deviceUUID will have "product added to cart" and "product deleted from cart" actions displayed in the Actions tab of their profiles.
private func addProductToCart() {
    let body = OperationBodyRequest();
    
    body.addProductToList = .init(product: .init(ids: ["website": "123"]), pricePerItem: 100)
    Mindbox.shared.executeAsyncOperation(
        operationSystemName: "CheckGuide.addProductToCart",
        operationBody: body
    )
}

private func setUpCart() {
    let body = OperationBodyRequest();
    
    body.productListItems = [
        .init(
            product: .init(ids: ["website": "123"]),
            count: 1,
            priceOfLine: 100
        ),
        .init(
            product: .init(ids: ["website": "321"]),
            count: 1,
            priceOfLine: 100
        )
    ]
    
    Mindbox.shared.executeAsyncOperation(
        operationSystemName: "CheckGuide.setUpCart",
        operationBody: body
    )
}

Checking customer in segment: example

Run this request to check whether a customer belongs to a specific segment.

Expected result:

  • Xcode displays Mindbox’s response.
private func checkSegment() {
    let body = OperationBodyRequest()
    
    Mindbox.shared.executeSyncOperation(
        operationSystemName: "CheckGuide.checkSegment",
        operationBody: body) {
            result in
            switch result {
            case let .success(response):
                print(response.createJSON())
            case let .failure(error):
                print(error.errorDescription)
            }
        }
}

Receiving personal recommendations: example

Run this request to return a personalized list of products compiled using one of the product recommendation algorithms.

Expected result:

  • Xcode displays Mindbox’s response.
private func getReco() {
    let body = OperationBodyRequest()
    
    body.recommendation = .init(limit: 3)
    
    Mindbox.shared.executeSyncOperation(
        operationSystemName: "CheckGuide.getReco",
        operationBody: body) {
            result in
            switch result {
            case let .success(response):
                print(response.createJSON())
            case let .failure(error):
                print(error.errorDescription)
            }
        }
}

Submitting async data to Mindbox

Run the Mindbox.shared.executeAsyncOperation SDK method to submit async data to Mindbox.

This SDK method receives:

  • the system name of the operation;
  • the body of the request to Mindbox.

Method description

executeAsyncOperation<T: OperationBodyRequestType>(
  operationSystemName: String, 
  operationBody: T
)

Call example

let body = OperationBodyRequest()

body.customer =  .init(
  email: "<Email>",
  mobilePhone: "<Mobile phone>",
  ids:  ["websiteid": "<Website ID>"],
  subscriptions: [
    .init(
      brand: "<System name of the customer's subscription brand>",
      pointOfContact: .sms,
      topic: "<External ID of the subscription topic>",
      isSubscribed: true
    )
  ]

)

Mindbox.shared.executeAsyncOperation(
  operationSystemName: "Mobile.AuthorizeCustomer",
  operationBody:body
)

👍

Check your results:

  1. Create an API method in your Mindbox project;
  2. Integrate Mindbox.shared.executeAsyncOperation so that it is called in your app (for example, by tapping a button);
  3. Start the app and run the target action;
  4. Find the customer profile in the system and check that their profile displays the expected entry on the Actions tab.

For information on how to debug common errors, refer to the SDK Integration Checklist.

Submitting and receiving synced data from Mindbox

Run Mindbox.shared.executeSyncOperation to execute synced operations.

This SDK method receives as parameters:

  • the system name of the operation;
  • the body of the request to Mindbox;
  • the callback for successful operations;
  • the callback for unsuccessful operations.

A type object is passed to such callbacks, which includes the parsed Mindbox response.

You can also create your own class to process Mindbox’s responses if processing cannot be carried out using the SDK’s structures.

This class will be passed to the function call as an individual parameter.

Using a predefined class

Method description

public func executeSyncOperation<T>(
  operationSystemName: String,
  operationBody: T,
  completion: @escaping (Result<OperationResponse, MindboxError>) -> Void
) where T: OperationBodyRequestType {}

Use the operationSystemName and operationBody parameters to make a request.

The request response is the Result<OperationResponse, MindboxError> entity.

Example:

// Create body
let body = OperationBodyRequest()
body.productListItems = ... // fill with data

// Call method
Mindbox.shared.executeSyncOperation(
 operationSystemName: "OperationName",
 operationBody: body
) { result in
  switch result {
    case let .success(response):
      // Handle response here
    case let .failure(error):
      print(error.errorDescription)
  }
}

Using your own class in response

Use the operationSystemName and operationBody parameters to make a request.

You can also use the customResponseType parameter that should implement the OperationResponseType protocol.

The response will be the Result<P, MindboxError> entity.

Method description

public func executeSyncOperation<T, P>(
  operationSystemName: String,
  operationBody: T,
  customResponseType: P.Type,
  completion: @escaping (Result<P, MindboxError>) -> Void
) where T: OperationBodyRequestType, P: OperationResponseType {}

Example:

// Create a new struct/class wich implements OperationResponseType 
struct MyResponse: OperationResponseType {
  var status: Status

  // provide custom fields here
}

...

// Create body
let body = OperationBodyRequest()
body.productListItems = ... // fill with data

// Call method
Mindbox.shared.executeSyncOperation(
  operationSystemName: "OperationName",
  operationBody: body,
  customResponseType: MyResponse.self // type of your custom response model
) { result in
   switch result {
     case let .success(response):
     // handle response here
     // response is type of MyResponse
     case let .failure(error):
     print(error.errorDescription)
   }
  }

Response definitions

OperationResponse is a model listing all the fields that a server might return. All these fields are optional.

MindboxError is an error model that Mindbox returns.

Server errors could be:

  • validationError that contains the ValidationError model. This refers to fields with incorrect values;
  • protocolError that contains the ProtocolError model, returned for server responses with a 4XX status or for certain 5XX errors;
  • serverError that is returned for a 5ХХ status response without data from the server;
  • connectionError that is a request error due to a connection failure;
  • invalidResponse that is returned for an invalid server response;
  • internalError that refers to Mindbox’s configuration errors, response decoding errors, etc.;
  • unknown that is returned for unexpected behavior when the nested type is Error.

Use the errorDescription parameter for debugging.