Skip to main content

Advanced

Theming

The Loop Media SDK allows integrations to customize appearance and provide support for additional languages. SDK uses LMGTheme protocol to provide following resources:

  • Spacing between UI elements
  • Colors
  • Typography
  • Icons
  • Additional languages support
  • Custom decorations (rounded corners, dividers, etc)

Please see LMGTheme.h for complete list of all possible modifications in the SDK. When using the LMGUI SDK, you can build a completely custom theme using the protocol mentioned above, or use/modify the existing default theme (LMGDefaultTheme).

In order to use a custom theme, provide an instance of it to LMGThemeManager prior to SDK initialization using following code:

LMGThemeManager.apply(YOUR_INSTANCE_OF_LMGTheme);

// ... initialize SDK here ...

Icons

In order to change icons in the SDK one needs to provide a reference to a bundle inside of an instance of LMGTheme with all required assets.

Additional Languages

In order to add support for additional language translations, provide a reference to a bundle inside of an instance of LMGTheme with all 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;
}