Advanced
Theming
The GetintheLoop 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:
- Swift
- Objective-C
LMGThemeManager.apply(YOUR_INSTANCE_OF_LMGTheme);
// ... initialize SDK here ...
[LMGThemeManager applyTheme: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.
Notifications & Direct Links
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
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:
- Swift
- Objective-C
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;
}
- (UIViewController *)onPendingView:(UIViewController *)pending currentView:(UIViewController *)current data:(NSDictionary *)data {
if([pending respondsToSelector:@selector(screenType)]) {
// Getting screen type
LMGScreenType type = (LMGScreenType) [[pending valueForKey:@"screenType"] integerValue];
switch (type) {
case LocationDetails:
// Prevent from any navigation when Location Details screen should be shown
return nil;
case Collection:
// Showing YourCustomViewController when Collection screen should be shown
return [YourCustomViewController new];
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;
}