Skip to main content

iOS SDK Guide

This document is written based on the latest version of the SDK.

SDK Information

SDK-supported version

  • Compilable iOS version: iOS 8.0 or higher

    • In iOS 8.0, the API call doesn't work.
  • Actual working iOS version: iOS 9.0 or higher

SDK application

"An API key is required to use loplat SDK."

To use the loplat SDK, you must obtain a valid ID and Secret key provided by loplat.
To get a valid Id And Secret Key, please fill out the following information and send it to business@loplat.com.

  • Name
  • Company
  • Purpose

Authority

Add Authority

To use loplat SDK, permission must be added. The required permissions are listed below.

  • Access WiFi Information : iOS 12 or above is used to get the currently connected Wi-Fi information. (iOS 13 or later, location permission is required to operate.)

  • Background Modes - Location Updates : It is used to receive location information in the background.

    Access WiFi Information
    Background Modes
    - Location Updates

Xcode Project > Capabilities Allow any permissions as shown below.

Allow Permissions in XCode


Request location permission from the user (required)

"For iOS 11 or above, you must provide feedback text to users to use location permissions."

Please specify the reason for using location permission according to the service scenario.
If the reason for using the location permission is poor, approval could be rejected in the App Store review.
Be sure to explain detailed reasons for use to the user.
Detailed reason for use must include a legitimate reason for using the location in the background.
Therefore, please write the text that informs which benefits users would have by allowing location information.

"Example :"

Required to provide location-based events and benefit.
When you enter an affiliated store, we provide a coupon issuance or offline benefit-finding service.
If you select Always Allow, you will benefit without using the app.


Add the values below to your project's info.plist file.

<?xml version="1.0" encoding="UTF-8">
<!DOCTYPE plist PUBLIC "=//OBJECTIVE-C//DTD PLIST 1.0//EN" "http://www.OBJECTIVE-C.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- skip -->
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Example: To get 'all benefits' provided by the app, select 'Always' Allow.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Example: To get 'all benefits' provided by the app, select 'Always' Allow.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Example: To get benefits provided by the app, select location information as 'while using the app' and select 'always'</string>
<!-- skip -->
</dict>
</plist>

If you look at the above code in Xcode, it looks like this:

Location Permission Message

"Please call Plengi.requestAlwaysLocationAuthorization() when requesting location permission from the user."

If you want to use the Core Location API according to the scenario of the app (ex: If you want to ask always permission in the foreground after login.) Please refer to the Core Location API documentation and make a request.


(void)Plengi.requestAlwaysLocationAuthorization;

Please call the above API when requesting location permission from the user according to your app's scenario.
Please refer to the example image below for scenarios where 'always' permission can be obtained for each iOS version.

ex1) Request for location permission on the first screen when the user initially installs the app
ex2) Request location permission when the user logs in


iOS 12 lower

The above screen is an example of the location permission request notification window (Prompt) in `iOS 12 or lower'.


iOS 13.0 ~ 13.3.1

The above screen is an example of the location permission request notification window (Prompt) in iOS 13.0 ~ 13.3.1.
When a user selects 'Allow while using app' in the foreground
When the SDK runs in the background, a notification window appears whether you want to change the location permission to 'always'.


iOS 13.4 ~ 13.7

The image above is an example of the location permission request notification window (Prompt) in iOS 13.4 ~ 13.7.
If the user selects 'Allow while using app', a notification window appears whether you want to change the location permission to 'always'.


iOS 14.0 or higher

The image above is an example screen of the location permission request notification window (Prompt) in iOS 14.0 or later.
If the user selects 'Allow while using app', a notification window appears whether you want to change the location permission to 'always'. With iOS 14.0, users can set 'On' or 'Off' for 'Precise Location'.



Request ATT(App Tracking Transparency) permission from users

"For iOS 14.5 or above, the user must grant permission to use IDFA (advertising ID)."

Please specify the reason for requesting permission according to the service scenario.

"Example phrases:"

‘If you allow it, you can receive appropriate information.’


Add the values below to your project's info.plist file. (Required) Even if the service scenario does not request permission, you must add it.

<?xml version="1.0" encoding="UTF-8">
<!DOCTYPE plist PUBLIC "=//OBJECTIVE-C//DTD PLIST 1.0//EN" "http://www.OBJECTIVE-C.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- skip -->
<key>NSUserTrackingUsageDescription</key>
<string>Example: If you allow, you can receive appropriate information.</string>
<!-- skip -->
</dict>
</plist>

App Tracking Transparency import

Import the App Tracking Transparency by adding the following statement to the file requesting permission.

#import <AppTrackingTransparency/AppTrackingTransparency.h>

Request 'ATT' permission

Depending on the scenario of the app, add the following code to request ‘ATT’ permission.

- (void)requestIDFA {
  [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    // Please write code according to your app scenario.
  }];
}

Below is an example image of a request.

IDFA can be used if the user selects ‘Allow ATT’.



Add loplat SDK to your project

Applying Cocoapod

"Are you already using Cocoapods for your project?"

Go to Add SDK

To use Cocoapods, install Cocoapod binaries on macOS.
Input the command below into the terminal.

$ sudo gem install cocoapods

If the installation is complete, activate the Cocoapod module in the project to which the loplat SDK will be applied.
Input the command below into the terminal.

$ cd $PROJECT_PATH
$ pod init

Add loplat SDK dependencies

loplat iOS SDK can be installed under the following prerequisites.

  • Xcode 12.2+ (Xcode 12.2 or higher are compatible.)
  • Cocoapod 1.9.0+
  • Swift 5.4+ (with objc)

If you open the Podfile in the project folder with the text editor, you will see the contents in the example format.

platform :ios, '8.0'
# use_frameworks!

target 'MyApp' do
pod 'AFNetworking', '~> 2.6'
pod 'ORStackView', '~> 3.0'
pod 'SwiftyJSON', '~> 2.3'
end

After entering the code below in the target tag of Podfile, save it.

pod 'MiniPlengi', '1.4.2'

Since the SDK uses Swift, uncomment # use_frameworks in the Podfile. (delete the #)

Then, apply the library by entering the command into the terminal.

$ pod update
$ pod install

loplat SDK has been added to the project.

"When I open an Xcode project, I get an error that all libraries cannot be found."

To open a project with Cocoapod applied, you must not open a file with an extension of .xcodeproj, but open a workspace file .xcworkspace file.

"When using Objective-C, be sure to include Swift Libraries."

As shown in the image below, you must include the Swift standard library. Otherwise, the app itself may not run due to the inability to include the SDK on some iOS versions.

Swift Library Always

SDK initialization

To import

AppDelegate.h (Objective-C) / AppDelegate.swift (Swift) Add to the file.

#import <MiniPlengi/MiniPlengi-Swift.h>

How to apply SDK

1. Initialize Plengi (required)
"Plengi.initialize() must be requested from AppDelegate."

SDK may not work if it is called from elsewhere.


Modify AppDelegate class declaration as follows.

@interface AppDelegate : UIResponder <UIApplicationDelegate, PlaceDelegate>

Then, add code to initialize the actual SDK to the AppDelegate class.

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ********** skip ********** //
if ([Plengi initializeWithClientID:@"Client ID issued by Loplat"
clientSecret:@"Client key issued by Loplat"
echoCode:@"A code that can identify users by customer company (Please be careful about personal information)"] == Result.SUCCESS) {
// init success
} else {
// init failed
}
// ********** skip ********** //
}
  • echoCode: ID for user identification (for management) and tracking in the app (ex, advertising id,id,....,etc.). If you do not want to manage echoCode, you can enter nil value.
"echoCode should not contain personal information."

Do not deliver personal information such as email and phone numbers.

2. Initialize Plengi - when the app comes alive in the background (very important)

This action is essential for the app to work automatically in the background. (Crash may occur if UI operation is entered into AppDelegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
[Plengi initializeWithClientID:@"Client ID issued by Loplat"
clientSecret:@"Client key issued by Loplat"
echoCode:@"A code that can identify users by customer company (Please be careful about personal information)"];
// If there is a history of starting after agreeing to user terms in MainViewController
if ([Plengi getEngineStatus] == EngineStatusSTARTED ) {
[Plengi start];
}
}

Register PlaceDelegate

Register PlaceDelegate to receive events when a place recognition event is received from the server or a loplat X advertisement is received.

After Plengi.init is called, call setDelegate.

if ([Plengi setDelegate:self] == ResultSUCCESS) {
// setDelegate registration success
} else {
// Failed to register setDelegate
}

After that, implement PlaceDelegate.

@implementation AppDelegate

- (void)responsePlaceEvent:(PlengiResponse *)plengiResponse {
if ([plengiResponse echoCode] != nil) {
// echoCode entered by the customer
}

if ([plengiResponse result] == ResultSUCCESS) {
// If you use the Lite plan, only advertisement information is provided according to the real-time location-based message sending function.
if ([plengiResponse advertisement] != nil) {
// When there is loplat X advertisement information,
// By default, the Plengi SDK handles advertising events as direct notifications.
// However, if the advertisement event is directly handled according to the setting value, the corresponding object is used.
}

// If you use the basic / premium plan, you can check the location recognition result data in addition to the features of the lite plan.
if ([plengiResponse place] != nil) {
if ([plengiResponse placeEvent] == PlaceEventENTER) {
// When a user enters a place
} else if ([plengiResponse placeEvent] == PlaceEventNEARBY) {
// When a user recognized as NEARBY
} else if ([plengiResponse placeEvent] == PlaceEventLEAVE) {
// When a user leaves a place
}
}

if ([plengiResponse complex] != nil) {
// When a complex is recognized
}

if ([plengiResponse area] != nil) {
// When commercial district are recognized
}

if ([plengiResponse geofence] != nil) {
// When geofence information is available
}

if ([plengiResponse location] != nil) {
// The latitude and longitude value of the device at the time of recognition
}

if ([plengiResponse district] != nil) {
// When there is district information
}
} else {
/* From here, it indicates error codes */
// [plengiResponse errorReason] contains location recognition failure/error reason

// FAIL : Location recognition Failed
// NETWORK_FAIL : Network Error
// ERROR_CLOUD_ACCESS : When the client ID/PW is incorrect or requested by an unauthenticated user
}
}

Running SDK

Start/Stop

  • You can start or stop monitoring users' place/store visits. Call start after the user agrees to the location terms and conditions.
"Every time the app starts or logs in, you must call start after checking whether the user agrees to the location terms and conditions."
"The SDK is designed not to be called Start / Stop redundantly."

Even if start/stop is called repeatedly, it is implemented to be called only once within the SDK.

"Stop should not be called for exceptional cases."

Do not call stop for exceptional cases. Call stop only when the user refuses to agree to the location agreement.

  • The user's location information will be delivered to PlaceDelegate.
  • Start and stop monitoring is declared as follows.
[Plengi start]; //Monitoring Start
[Plengi stop]; //Monitoring Stop

Place recognition result

  • Place recognition result value will be delivered as a PlengiResponse object.

Lite plan

  • Advertisement information is provided according to the real-time location-based message send function.

  • (Campaign result can be monitored on loplat X.)

    • Advertisement : Advertising (PlengiResponse.Advertisement Class, response.advertisement Result)

      @objc public let body: String                           // Ad content
      @objc public let campaign_id: Int // loplat X campaign id
      @objc public let img: String // Image URLs included in ads
      @objc public let intent: String // Ads event type (Url link or Deep link
      @objc public let msg_id: Int // loplat X Ads Id
      @objc public let target_pkg: String // The package name of the app corresponding to the advertisement
      @objc public let title: String // Ads Title
      @objc public let client_code: String // Ads Client Code

Basic / Premium Plan

  • In addition to the Lite plan, you can check the location recognition result.

    "Different information is available in the PlengiResponse object depending on the place recognition result."

    When recognizing a place, area (commercial district information) and complex (complex mall) information are additionally delivered according to the result of the recognized place. If only the commercial district is recognized, the place information will be provided as null, so please be careful when writing the code.

  • echoCode ( User identification code )

    @objc public var echoCode: String?                                  // User identification echoCode
    • echo_code will be delivered when init is executed.
  • result (Location recognition Success/Failure)

    @objc public var result: Result                                             // report results
    // Result.SUCCESS // Successful acquisition of requested location information
    // Result.FAIL // Fail
  • When location recognition fails

    • errorReason : Location recognition failure reason

      @objc public var errorReason: String                            // Reason when result is FAIL
    • Failed to get current location: Location Acquisition Fail

    • client authentication failed: Not Allowed Client

  • If location recognition is successful

    • type : location request type

      @objc public var type: ResponseType                                     // request type
      // ResponseType.PLACE // As a test, when refreshPlace() is requested
      // ResponseType.PLACE_EVENT // Upon request, according to the set cycle
    • placeEvent : Recognized place event types (ENTER, NEARBY, LEAVE)

      @objc public var placeEvent: PlaceEvent                         // Recognized Place event types
      // PlaceEvent.NOT_AVAILABLE // No Place information, not related to Area, Complex, or Geofence
      // PlaceEvent.ENTER // Entered the place
      // PlaceEvent.LEAVE // Left the Place
      // PlaceEvent.NEARBY // Located near Place
    • place : Location information (PlengiResponse.Place class, response.place can be obtained)

      @objc public let loplat_id: Int                                 // place ID
      @objc public let name: String // place name
      @objc public let tags: String? // tags related to places (Nullable)
      @objc public let floor: Int // floor information
      @objc public let lat: Double // latitude of place
      @objc public let lng: Double // longitude of place
      @objc public let accuracy: Double // Accuracy (accuracy > threshold comparison required)
      @objc public let threshold: Double // Threshold
      @objc public let client_code: String? // Customer Code (Nullable)
      @objc public let category: String // place category
      @objc public let category_code: String // Place category code
      @objc public let address: String? // Place (Old) Address (Nullable)
      @objc public let address_road: String? // Place (Street Name) Address (Nullable)
      @objc public let post: String? // Location Postal Code (Nullable)
      • accuracy > threshold: If the user is placed inside of the current location
      • Elsewhere: If the user is placed nearby the current location
    • Area : commercial district information (PlengiResponse.Area class, response.area can be obtained with)

      • If the request is within the commercial district, it will be delivered along with the recognition result.

      • Latitude and longitude are delivered under the following conditions.

        • If there is a place recognition result value -> Recognized place latitude/longitude
        • If there is no place recognition result -> latitude/longitude of the device
      @objc public let id: Int                                                // commercial district ID
      @objc public let name: String // commercial district name
      @objc public let tag: String // commercial district tag
      @objc public let lat: Double // commercial district Latitude
      @objc public let lng: Double // commercial district Longitude
    • Complex : Complex(Complex mall) Information (PlengiResponse.Complex class, response.complex can be obtained)

      • If the recognized place is within a complex, its information will also be delivered.
      @objc public let id: Int                        // Complex mall ID
      @objc public let name: String // Complex mall name
      @objc public let branch_name: String // Complex mall branch
      @objc public let category: String // Complex mall category title
      @objc public let category_code: String // Complex mall category code
    • GeoFence : Geofence & Fence (PlengiResponse.Geofence class, response.geofence delivery of results), fence information will be delivered in the geofence

      class GeoFence {
      @objc public let lat: Double // Geofence Latitude
      @objc public let lng: Double // Geofence Longitude
      @objc public let fences: Array<Fence> // List of child fences
      }

      class Fence {
      @objc public let gfid: Int // fence ID
      @objc public let name: String // fence name
      @objc public let dist: Double // fence distance between center coordinates and user position
      @objc public let client_code: String // Client Code for Fences
      }
    • District : administrative district (PlengiResponse.District class, response.district delivers results)

      class District {
      @objc public let lv0_code: String // Country code, supported code only
      @objc public let lv1_code: String // si, do
      @objc public let lv1_name: String //
      @objc public let lv2_code: String // si, gu, goon
      @objc public let lv2_name: String //
      @objc public let lv3_code: String // eup, dong, myeon
      @objc public let lv3_name: String //
      }

Integrating loplat X

"Registration is required to use loplat X."

Registration is required to use this service. For more detailed information, please get in touch with the loplat Business Team.

  • To receive local notifications (not push messages using APNs) (advertisement and notification messages) through loplat X, the marketing notification setting and the code below must be written before Plengi.initialize.
  • If you want to use Notification implemented yourself (refer to the code below), check Advertisement(response.advertisement) in the place recognition result for the advertisement information value.

When marketing notification setting is On - Enable loplat X

Call function to use loplat X in the SDK.

enableNotidetermines which advertising information will be processed.
If TRUE, the SDK notifies advertisement information the user directly through iOS notification (default)
If FALSE, advertisement notifications are managed directly in the client app and not be handled by SDK.

loplat X setting - Process advertising information directly from the client app

[Plengi enableAdNetwork:YES enableNoti:NO];

loplat X setting - Processing advertising information in the SDK

[Plengi enableAdNetwork:YES enableNoti:YES];

Marketing notifications setting is off - disable loplat X

If you do not allow to receive advertisements under certain scenarios, such as when the user does not agree to push notifications, Stop using loplat X by adding the code below.

[Plengi enableAdNetwork:NO enableNoti:NO];

After notification permission is granted, events must be registered on the system to enable loplat X ad reception in the SDK.

Add the application_handleActionWithIdentifier event to the AppDelegate class and add the code below.

if (@available(iOS 10.0, *)) {
UNUserNotificationCenter.currentNotificationCenter.delegate = self;
}
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forLocalNotification:(UILocalNotification *)notification
completionHandler:(void (^)())completionHandler {
[Plengi processLoplatAdvertisement:application
handleActionWithIdentifier:identifier
for:notification
completionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))
completionHandler API_AVAILABLE(ios(10.0)) {
completionHandler(UNNotificationPresentationOptionAlert |
UNNotificationPresentationOptionBadge |
UNNotificationPresentationOptionSound);
// allows notifications to be raised in the foreground, even on iOS 10 or higher
// (Badges, sounds, and warnings are used in the guide, but these options can be omitted depending on development conditions)
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0)) {
[Plengi processLoplatAdvertisement:center
didReceive:response
withCompletionHandler:completionHandler];
completionHandler();
// loplat SDK to handle user notification tracking (Click, Dismiss)
}

sample app