Granify Mobile SDK

Details

This project houses a native iOS Framework intended to be utilized from within iOS applications to make it easy to communicate with Granify’s servers.

iOS 12 and later are currently supported.

Project Organization

The Granify class is the main interface for functions to be called by your application. See the documentation for each of these methods for details, as well as the quick start guide below for an overview of how each function fits into the API as a whole.

Installing the Granify SDK

Follow the Installation Checklist. The checklist includes a list of every step you might require, with details on exactly how to implement it. Make sure you implement all the Required steps, and as many optional steps as necessary for your case.

Objective-C Usage

The SDK has been developed in Swift, but was designed with Objective-C compatibility in mind. There are still some minor differences to be aware of when using the SDK within an Objective-C codebase.

Compilation

Configure your project to look for the Granify SDK framework header within the framework data. One option is to set the “Header Search Paths” project build setting to include GranifySDK.xcframework. Once that is done, import the header in your source file as follows:

#import "GranifySDK/GranifySDK-Swift.h"

API Differences

Per Apple’s recommendations, a prefix is applied to all public class and enumeration declarations in Objective-C. Names will all be the same as the Swift documentation shows, but with a GFY prefix. For example, GranifySDK.Product in Swift becomes GFYProduct.

The API has been designed to avoid unrepresentable data types in Objective-C (such as optional primitive types), but there are still some cases where the Swift and Objective-C APIs have necessarily diverged for compatibility reasons. This documentation is generated for the Swift API, but consulting the GranifySDK-Swift.h header will show any Objective-C specific differences (along with documentation) that need to be accounted for. You can find the header located at GranifySDK.xcframework/${architecture}/GranifySDK.framework/Headers/.

Expect that you may encounter:

  • Optional primitive type properties (in Swift) exposed as getProperty-style methods with nullable container types used instead (in Objective-C)
    • let prop: Int? for example, becomes - (NSNumber * _Nullable)getProp;
  • Optional primitive type parameters (in Swift) exposed using nullable container type parameters (in Objective-C)
    • func foo(param: Double?) { //... for example, becomes - (void)fooWithParam:(NSNumber * _Nonnull)param;

Hybrid Apps

Some apps are designed to use a combination of native rendering and rendering HTML pages in a webview. To make this work with Granify, it is important that the iOS SDK be used on all native pages, and that the JS SDK be used for each HTML page loaded into a webview. Furthermore, it is necessary to pass state from the app to the webview in order for both SDKs to work in the same session. See Hybrid Apps for details on how to implement this, and the limitations to the current system.

App Suspension

When the shopper returns after hiding or suspending the app, or returns after idling for long periods of time (greater than 30 minutes), communication with Granify’s servers may have ceased. In this case the shopping session has become inactive and a new session will be created.

On session start, the SDK will re-send its most recent cached information about the shopper (i.e. shopper id, cart, and wish list information) to the server to initialize the new session’s data. It is important however to call any of the Granify session tracking functions with updated information if it may have been changed while the app was idle or suspended. For example, if a shopper’s cart is synced with their account across multiple devices, changes made on other devices will require Granify.trackCart(...) to be called when the app becomes aware of the change to the cart.

Information specific to the shopper’s current session will not be cached and automatically sent to Granify’s servers on app resume. Therefore, it is important to call the appropriate API functions (Granify.trackPageView(...), Granify.trackProduct(...), and Granify.setCurrentProduct(...)) explicitly with the information for the app view that loads when resuming from a suspended state.

Error Handling

By design, Granify functions should never throw errors caused by internal errors or server communication errors, but may throw to indicate problems with provided argument data. Any exceptions encountered therefore should be reviewed and addressed to confirm correct API usage.

Privacy and Data Protection

Privacy and Data Protection is very important to Granify. We take every effort to make sure the data we collect is secure, and we never, ever sell the information to anyone else. Granify is fully compliant with GDPR, CCPA and other Data Protection legislation. If your app complies with any of these systems, your company’s contract with Granify will clearly define the roles played by both parties.

For the most part, Granify does not collect personally identifiable information about shoppers. We care about how many times they look at a product, or what they add to their cart, but we don’t want or need to know who they are. We don’t collect names, addresses, email addresses or any such information.

We do, however, link all the shoppers’ actions together using a shopperId that you give us. It is important that you refrain from using any personally identifiable data as the shopperId; don’t use the email address, for example. It should be impossible to identify who the shopper is from the ID. Ideally, this should not even be the unique primary key you use to identify the shopper either, but a new, unique code just for Granify.