Skip to main content

Advanced

Theming

The GetintheLoop SDK allows integrations to customize the appearance of managed UIs and provide support for additional languages. The SDK uses a theme object to provide following customizations:

  • Spacing
  • Colors
  • Typography
  • Icons
  • Other UI-specifics, such as rounded corners, divider size, etc.

Setting a Custom Theme

A custom theme is, at the root, a dictionary of theme values that are applied to the SDK's UI components via NSAppearance.

Creating and applying a custom theme is straight forward:

  1. Create a new instance of LMGTheme, passing the custom theme properties as a dictionary during instantiation
  2. Apply the theme with the LMGThemeManager
// Create a new LMGTheme instance
let theme = LMGTheme.init([
"colors": [
"titleText": UIColor.black,
"headlineText": UIColor.black,
"subheadText": UIColor.black,
"bodyText": UIColor.black,
"captionText": UIColor.black,
"overlineText": UIColor.blue,
"primaryAction": [
":normal": UIColor.blue,
],
]
]);

// Set the theme for the SDKs
LMGThemeManager.apply(theme);

Supporting Additional Languages

The GetintheLoop SDKs provide first-party support for English, French, Spanish, and Dutch.

To add support for additional language translations, or to customize the existing translations, an integration can provide a reference to an NSBundle, via the LMGTheme instance, that contains the required localization keys.

Offers

Sent notification or direct link must have offer id or offer slug available.

Displaying offer details

@import LMGUI;

...

// Offer Details in no particular Location
UIViewController *offerDetailViewController = [LMGOfferDetailsWireframe viewControllerForOfferId:@"OFFER_ID__OR__SLUG"];
[self.navigationController pushViewController:offerDetailViewController animated:TRUE];

...

// Offer Details in one Location
UIViewController *offerDetailViewController = [LMGOfferDetailsWireframe viewControllerForOfferId:@"OFFER_ID__OR__SLUG" locationId:@"LOCATION_ID__OR__SLUG"];
[self.navigationController pushViewController:offerDetailViewController animated:TRUE];

Business or Location

Sent notification or direct link must have business id, business slug, location slug available.

Displaying business details

The Business Details screen displays the offers and locations available for a business. The locations and offers shown are based on what is available in the current geocontext area.

@import LMGUI;

...

UIViewController *businessDetailViewController = [LMGBusinessDetailsWireframe viewControllerForBusinessId:@"BUSINESS_ID__OR__SLUG"];
[self.navigationController pushViewController:businessDetailViewController animated:TRUE];

If location services are enabled, the locations displayed will be ordered based on distance from the device.

Displaying location details

@import LMGUI;

...

UIViewController *locationDetailViewController = [LMGLocationDetailsWireframe viewControllerForBusinessId:@"BUSINESS_ID__OR__SLUG" locationId:@"LOCATION_ID__OR__SLUG"];
[self.navigationController pushViewController:locationDetailViewController animated:TRUE];

Managing Navigation

Once an SDK view is initialized and presented, the SDK manages navigation to other views automatically. In some cases, this navigation behaviour needs to be customized for an integration. For example, if the integration provides custom business listing screens, it may want to override the default behaviour when a Business view is tapped.

The SDK allows an integration to intercept, stop, or otherwise customize internal navigation actions via a Navigation Delegate.

Navigation delegate is an object that implements the LMGClientNavigationDelegate protocol. LMGClientNavigationDelegate specifies one method, (UIViewController *)onPendingView:(UIViewController *)pending currentView:(UIViewController *)current data:(NSDictionary *)data.

This method allows you to inspect the pending ViewController and choose what to present

onPendingView is called before each navigation action initiated by an SDK managed view. It allows you to customize navigation by returning different values:

  • Return the pending UIViewController. This is the default navigation behaviour.
  • Return a custom UIViewController. This will navigate to your custom UIViewController using the standard transition for the current user interaction (most likely a push).
  • Return nil. This cancels navigation. Can be used to prevent certain views from being shown, or to fully customized the navigation behaviour of a custom UIViewController.

Screen Types

All of the SDK's ViewControllers have a screenType property that allows you to easily determine the type of screen that is pending navigation. LMGScreenTypes are:

  • Collection
  • OfferDetails
  • BusinessDetails
  • LocationDetails
  • LocationsList
  • MixedContent
  • Search
  • Map
  • Bookmarks
  • Rewards
  • InlineBrowser
  • EmailClient

Exceptions

While almost all SDK-initiated navigation is customizable via the Navigation Delegate, there are exceptions, primarily the Offer Redemption flow.

Offer Redemption is a complex process that potentially involves a number of different steps and screens. As these are all required to support all the different offer features and use-cases, observing, interrupting, or cancelling these screens via the Navigation Delegate is not permitted.

Example Implementation

Example of implementation onPendingView: currentView: data: delegate method:

func onPendingView(_ pending: UIViewController, currentView current: UIViewController, data: [AnyHashable : Any]) -> UIViewController? {
if (pending.responds(to: Selector(("screenType")))) {
let screenType = LMGScreenType(rawValue: pending.value(forKey: "screenType") as! UInt)

switch screenType! {
case LMGScreenType.LocationDetails:
// Prevent from any navigation when Location Details screen should be shown
return nil;
case LMGScreenType.Collection:
// Showing YourCustomViewController when Collection screen should be shown
return YourCustomViewController();
default:
// No changes for other screen types
return pending;
}
}
return pending;
}

SDK Configuration Options

SDK has some configurations that are optional for the integration:

  • Ability to save offers when user is identified (true/false or "VerifiedOnly")
  • Ability to share offers and businesses
  • Ability to add an attribution badge
  • Ability to enable/disable feedback links
  • Ability to customize feedback URL
  • Ability to set the minimum authentication level needed to redeem an offer ("None", "Identified" or "Verified")
  • Ability to enable/disable visual effects like confetti
<key>LMGConfig</key>
<dict>
<key>OfferBookmarkingEnabled</key>
<true/> // or <string>VerifiedOnly</string>
<key>OfferSharingEnabled</key>
<true/>
<key>BusinessSharingEnabled</key>
<true/>
<key>PoweredByGetintheLoopBadgeEnabled</key>
<true/>
<key>FeedbackLinksEnabled</key>
<true/>
<key>SupportEmail</key>
<string>support@loopmediagroup.com</string>
<key>RedemptionRequiresMinimumAudienceId</key>
<string>Identified</string>
<key>VisualEffectsEnabled</key>
<true/>
</dict>

Logging

The SDK comes with 5 built-in debug levels, from most detailed to most restricted logs: LMGDebugLoggerLevelVerbose, LMGDebugLoggerLevelDebug, LMGDebugLoggerLevelInfo, LMGDebugLoggerLevelWarning and LMGDebugLoggerLevelNone.

By default it is set to LMGDebugLoggerLevelNone.

@import LMGUI;

...

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

... your app init code ...

[[LMGClient shared] setLoggerLevel:LMGDebugLoggerLevelDebug];
return YES;
}