Installation Checklist

This page will list every step you need to take to fully integrate with Granify. Make sure you have applied every required step, and any optional steps that you need.

  1. [Required] Include the Granify Framework in your XCode project.
  2. [Required] Subscribe to the Group Assigned event.
  3. [Optional] Subscribe to the Message shown event.
  4. [Optional] Register a Group Assignment Provider.
  5. [Required] Activate Granify.
  6. [Optional] Set the Shopper ID.
  7. [Required] Implement the trackPageView method
  8. [Required] Implement the trackProduct method
  9. [Required] Implement the setCurrentProduct method.
  10. [Required] Implement the trackCart method.
  11. [Required] Implement the trackOrder method.
  12. [Optional] Implement the trackWishList method.
  13. [Optional] Implement the setRestrictionState method.
  14. [Optional] Pass state to webviews if necessary
  15. [Required] Implement the showConcept method.

Include the Granify Framework in your XCode project

[Required]

The GranifySDK is distributed as an XCFramework. You will be given the correct version of the SDK directly.

  • Create a “Frameworks” folder.
  • Import the GranifySDK XCFramework into that folder (either drag or “Add Files to…”).
  • Embed XCFramework in project’s target
    • In your project’s settings, in the general tab, find “Frameworks, Libraries, and Embedded Content”, and select “Embed and Sign” next to the GranifySDK.xcframework.
  • Link XCFramework with your project
    • In the “Build Phases” tab, find “Link Binary With Libraries”, and ensure that the GranifySDK.xcframework is Required.

See How to add XCFramework to Xcode project for more details.

Subscribe to the Group Assigned event

[Required]

As soon as Granify assigns a group to the current shopper (or you provide us with one using the Group Assignment Provider), Granify will publish this event. You can use this to log metrics in your chosen metric system. It is particularly important that this data point is stored because it allows your financial team to confirm all the numbers Granify is reporting (and billing against), and you can be confident that you are getting all the benefits from our partnership.

Call this method before you activate Granify.

Granify.subscribeGroupAssigned { group in
  // log the chosen group with your metrics provider
}

see Granify.subscribeGroupAssigned(handler:) for specific details.

Subscribe to the Message shown event

[Optional, Recommended]

Every time Granify shows a campaign to the shopper (or would have shown the campaign, depending on the group assigned), this event will be published. You can use this information to log or metric the event in your chosen logging or metric system.

Call this method before you activate Granify.

Granify.subscribeMessageShown { status in
  // log the event with your metrics provider
}

see Granify.subscribeMessageShown(handler:)

Register a Group Assignment Provider

[Optional]

In most cases, Granify will choose the group to which to assign each shopper, but some clients have requested that they be able to control this themselves. If this is you (your account manager will be able to tell you), then you will need to register a Group Assignment Provider. This is a method or closure that we will call when we need a group for the current shopper.

It is critical that this method be registered before you activate Granify.

Granify.registerGroupAssignment {
  // some code to choose which group to assign
  return MatchingGroup.granify // for example
}

see Granify.registerGroupAssignment(provider:) for more details

Activate Granify

[Required]

Granify doesn’t just act - we always wait for you, the app owner, to start the process. This gives you control to choose to disable Granify if you need to (by not activating it), without having to make extensive code changes.

When you activate Granify, you need to provide two important pieces of information:

  • information identifying your site.
  • information telling us how to direct shoppers to various parts of your app.

see Configuring Granify for more details on exactly what we need you to give us.

let deepLinks = [
  DeepLink(pageType: .cart, link: URL(string: "com.mycompany.MyApp://cart")!),
  ... // add links to all relevant page types
]
let config = GranifyConfiguration(forSite: SiteIdentifier(identifier: "AbXyZ")!,
                                  childSiteId: SiteIdentifier(identifier: "SdFgH"),
                                  deepLinks: deepLinks) { productId, sku in
      let path = "product?productId=\(productId)&sku=\(String(describing: sku))"
      return URL(string: "com.mycompany.MyApp://\(path)")
    }
try? Granify.activateGranify(with: config)

see Granify.activateGranify(with:) for more details

Set the Shopper ID

[Optional, Recommended]

It is not required, but we strongly recommend that you provide us with a unique identifier for the current shopper as soon after activation as you have it. If you have it at the time of activation, you can call this method immediately after activating Granify; if you need to wait for authentication or authorization before you gain access to a unique identifier, then provide it to us when you have it.

The Granify Brain will use this information to include this particular shopper’s previous activity in its decision making, allowing us to provide considerably more effective service.

See Privacy and Data Protection for details on what kinds of information cannot be used for shopper IDs, but please, no email addresses.

Granify.setShopperId(shopperId: "aSdeRtyUi%FghIrtFDer#dfTgDSe")

see Granify.setShopperId(shopperId:) for more details

Implement the trackPageView method

[Required]

One of the key pieces of information the Granify Brain uses to make its decisions is knowing when the shopper navigates from page to page within the app. In an app, our SDK cannot determine this information for itself - we need you to tell us every time the shopper navigates to a new page.

For more details on exactly how and why we track each page, see Tracking Pages.

You will be asked to provide three pieces of information:

  • the type of page that has been opened
  • the UIScrollView instance that represents the scrollable area of the current page
  • a closure which returns the margins within which a sliding campaign may be rendered. This closure may be called multiple times while the page is open, if the device is rotated, for example. Use this to ensure our campaigns do not render over your menu, or any other critical information.

Additionally, an optional parentView parameter be passed in if your application will be supporting inline campaigns. This will be the parent UIView on your page.

Granify.trackPageView(pageType: .cart, parentView: myParentView, mainScrollView: myDetailsScrollView) {
  return UIEdgeInsets(top: 0, left: 0, bottom: menu.height, right: 0)
}

see Granify.trackPageView(pageType:parentView:mainScrollView:getInsets:) for more details

Implement the trackProduct method

[Required]

It is critical for the Granify Brain to know which products the shopper is looking at, as well as which are actually being bought. The trackProduct method is one of two methods (along with setCurrentProduct) which are required to provide Granify with enough information to make good decisions.

For more details on exactly how we track products and shopper interest, see Tracking Products.

The trackProduct method must be called every time a new product page is viewed (even if the shopper has already seen this page). It provides the Granify Brain with the complete list of all possible variations of the current product. It does not tell us which variation (sku) is currently selected, though - that is the job of setCurrentProduct.

Granify.trackProduct(products: [
  Product(sku: "myprod_001",
          productId: "myprod",
          title: "My Product",
          price: 100.0,
          regularPrice: 100.01,
          image: URL(string: "path/to/image"),
          url: URL(string: "path/to/product"))
  ],
  ... // more variations of this product
  ) {
    // your code for adding this product to the cart...
    self.addProductToCart(id: "myprod")
  }

see Granify.trackProduct(products:currentProductCarterCallback:) for more details

Implement the setCurrentProduct method

[Required]

It is critical for the Granify Brain to know which products the shopper is looking at, as well as which are actually being bought. The setCurrentProduct method is one of two methods (along with trackProduct) which are required to provide Granify with enough information to make good decisions.

For more details on exactly how we track products and shopper interest, see Tracking Products.

The setCurrentProduct method must be called every time a new variation of a product is selected, including the first time the product is viewed. The trackProduct call will tell us all the variations available for the current product, and the setCurrentProduct method will tell us which variation of the product is currently selected. The product identified with setCurrentProduct must be one of those provided in the last trackProduct call.

Granify.setCurrentProduct(sku: "myprod_001", productId: "myprod")

see Granify.setCurrentProduct(sku:productId:) for more details

Implement the trackCart method

[Required]

It is critical to Granify’s effectiveness that the Brain knows the contents of the current shopper’s cart at all times. You can keep us to date by utilizing this method. The method should be called with the complete contents of the cart whenever those contents change. That could be when the shopper adds, removes or changes the type or quantity of an item, but it could also be when the app receives information about cart contents from a previous or parallel session.

You should also call this method when the app starts, even if the cart is empty.

Granify.trackCart(items: [
  product1: 1,
  product2: 4,
  product3: 2
])

see Granify.trackCart(items:) for more details

Implement the trackOrder method

[Required]

It is imperative that Granify know every time a shopper actually places an order. The whole purpose of Granify is to encourage your shoppers to do exactly this, and we need to know when we have been successful to allow the Granify Brain to learn and improve. Call this method when an order is confirmed as successful.

Granify.trackOrder(details: Order(orderNumber: "order123",
            currency: Currency.usd,
            lineItemsTotal: Price(amount: 100.00),
            subtotal: Price(amount: 100.00),
            totalTax: Price(amount: 10.00),
            totalShipping: Price(amount: 20.00),
            total: Price(amount: 130.00),
            lineItems: [
              product1: 1,
              product2: 4,
              product3: 2
            ],
            discountCodes: [],
            financialStatus: defaultFinancialStatus))

see Granify.trackOrder(details:) for more details

Implement the trackWishList method

[Optional]

Keeping track of shoppers’ favorite things helps the Granify Brain to make better decisions about which campaigns to offer, and when to offer them. Use the trackWishList method to let us know about all the various wishlists and favorites lists you maintain for your shoppers.

This method should be called as soon as the app opens, once for each wishlist. It should also be called whenever there is a change in a wishlist. You should call this method with the complete contents of the wishlist every time.

Granify.trackWishList(name: "My wish list", contents: [
  WishListItem(product: product1,
               dateAdded: Date.now,
               priceWhenAdded: Price(amount: 100.00),
               callToAction: URL(string: "path/to/product#product1"),
               productPage: URL(string: "path/to/product"))
])

see Granify.trackWishList(name:contents:) for more details

Implement the setRestrictionState method

[Optional]

This method is not required, but is often very useful. If your app has other popups, modals, or there are any times when you do not want a campaign to pop up, you can set the restricted state. When this state is on (.restricted), no campaigns will be shown. Switch it off to resume normal programming.

For example, if you have a promotional message that pops up when a shopper logs in, you might set the restricted state on while that popup is open, and then set if off again once the popup has been removed.

Please remember to always switch the restricted state off when you no longer require it.

Granify.setRestrictionState(to: .restricted)

see Granify.setRestrictionState(to:) for more details

Pass state to webviews if necessary

If your app is a hybrid app, you need to pass the current Granify state to the page loading in the webview every time a new page loads. Fetch the current state and pass that down to the webview. Exactly how you do that depends on which webview you use.

Granify.getCurrentState()

see Granify.getCurrentState()for more details.

Implement the showConcept method

[Required]

The showConcept method is necessary, but is only ever used for forcing a campaign to show. It is not necessary for you to call showConcept before a campaign will show. However, we need a way to be able to force-display campaigns that are not yet available for your shoppers. This allows us to test them in the context of your app, and get final design approval. Without this method, we cannot test a campaign without making it live in production first, and nobody wants that.

The standard way to implement this is to add a new field somewhere inside the app’s settings screen, where we can enter a four or five digit code and click a button. You would then pass that code to Granify by calling this method. Some clients hide this section in their settings behind “magic” gestures (eg: tap five times on the settings screen to reveal the “developer” options).

Granify.showConcept(conceptId: "1234")

see Granify.showConcept(conceptId:) for details of the method, and Testing for more information about testing in general.