- Print
- PDF
iOS SDK
- Print
- PDF
Available in Classic and VPC
It describes how to use the App Safer iOS SDK for the security of iOS apps. You can integrate App Safer by installing the SDK and configuring the environment.
As for the overall sample codes to which App Safer is applied, check the sample code.
Install SDK and configure environment
To use the features provided by App Safer, first install the iOS SDK and configure the environment. The library of App Safer for iOS apps consists of one framework and supports both the Bitcode Enable/Disable environment. The following describes how to configure it.
It is recommended to build in Xcode 8.0 or later environment.
- Decompress the downloaded SDK in an arbitrary directory.
- Check the project's Bitcode settings.
- Path: Build Settings > Build Options > Enable Bitcode
- Add the App Safer framework to the project.
- Path: File > Add Files to "Your Project"... > Options > select Copy items if needed > select AppSaferFramework.framework > click Add
- When using Swift, create a bridging header for compatibility with Objective-C.
- Create a header file: File > New File... > select Header File > Set filename "AppSaferFramework-Bridging-Header.h" at the project root
- Add a header file to build settings: Build Settings > Swift Compiler - General > Objective-C Bridging Header > Enter the following code inAppSaferFramework-Bridging-Header.h
#ifndef AppSaferFramework_Bridging_Header_h #define AppSaferFramework_Bridging_Header_h #import <AppSaferFramework/AppSaferFramework.h> #endif /* AppSaferFramework_Bridging_Header_h */
Apply the debugging prevention function
The anti-debugging feature is automatically applied when the SDK is installed. If debugging is required, use it with the App Safer SDK temporarily disabled.
Apply the capture blocking and detection function
You must call the API to apply the screen protection function during app preview screen protection, screenshot detection, recording and mirroring provided by the App Safer SDK.
- Older than iOS 13.0: call the App Safer API from AppDelegate according to the life cycle of the app
- iOS 13.0 or newer: call the APP Safer API from SceneDelegate according to the life cycle of the app
The following is an example of calling the API.
If you register selector
, you can receive a callback and perform the desired action when a capture event is detected.
AppDelegate (Swift)
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
@objc func didDetectCapture() -> Void {
print("[DETECT] Detected Screenshot in AppDelegate");
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AppSafer.registerScreenProtectionObserver(window, observer: self, selector: #selector(didDetectCapture))
return true
}
func applicationWillResignActive(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func applicationDidEnterBackground(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
func applicationWillEnterForeground(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func applicationDidBecomeActive(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
}
AppDelegate (Objective-C)
#import "AppDelegate.h"
#import <AppSaferFramework/AppSaferFramework.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (void)didDetectCapture {
NSLog(@"[DETECT] Detected Screenshot in AppDelegate");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
[AppSafer registerScreenProtectionObserver:_window observer:self selector:@selector(didDetectCapture)];
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:true];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:true];
}
@end
SceneDelegate (Swift)
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
@objc func didDetectCapture() -> Void {
print("[DETECT] Detected Screenshot in AppDelegate");
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
AppSafer.registerScreenProtectionObserver(window, observer: self, selector: #selector(didDetectCapture))
}
}
func sceneDidBecomeActive(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func sceneWillResignActive(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
func sceneWillEnterForeground(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func sceneDidEnterBackground(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
}
SceneDelegate (Objective-C)
#import "SceneDelegate.h"
#import <AppSaferFramework/AppSaferFramework.h>
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)didDetectCapture {
NSLog(@"[DETECT] Detected Screenshot in SceneDelegate");
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)) {
[AppSafer registerScreenProtectionObserver:_window observer:self selector:@selector(didDetectCapture)];
}
- (void)sceneWillEnterForeground:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)sceneDidBecomeActive:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)sceneWillResignActive:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:true];
}
- (void)sceneDidEnterBackground:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:true];
}
@end
Provided APIs
The App Safer API is provided in 2 packages, and the APIs that can be called from each package are as follows:
- AppSafer
Name | Description |
---|---|
initAppSafer | Initialize to use AppSafer |
checkTampering | Real-time security detection
|
setUserId | Set user identifier |
- AppSaferDelegate
- This is a callback function that operates asynchronously.
- Result handling is delegated through AppSaferDelegate.
- To receive scan results, you must implement AppSaferDelegate and register it using the initAppSafer function.
- When using Swift, you must implement it in
class
, notstruct
, and add both AppSaferDelegate and NSObject.
Name | Requirement status | Description |
---|---|---|
appSaferDidInitFinish | Required | Check the result of initializing App Safer |
appSaferDidCheckTamperingFinish | Required | Check the result of executing the checkTampering function |
appSaferDetectedJailbreak | Optional | Call it when the jailbreaking of the device is detected |
appSaferDetectedSimulator | Optional | Call it when it detects that the device is running in a virtual machine |
appSaferDetectedDebugging | Optional | Call it when debugging is detected |
appSaferDetectedMemoryTampered | Optional | Call it when alteration of the app memory is detected |
initAppSafer
You can use App Safer only when it is successfully initialized. To initialize App Safer, use the following code.
Information needed to send the log and variables used globally are initialized.
- You must implement AppSaferDelegate to receive notification of successful initialization.
func initAppSafer(_ delegate: AppSaferDelegate!, serviceCode: String!, key appsaferKey: String!) -> Int32
- (int) initAppSafer:(id<AppSaferDelegate>)delegate serviceCode:(NSString *)serviceCode key:(NSString *)appsaferKey
Parameters
Parameters Description delegate An instance in which AppSaferDelegate is implemented serviceCode The code for using App Safer
NAVER Cloud Platform users must pass "ncloud"appsaferKey The App Safer Key value created when an app is registered on the console Return value
Return value Description SUCCESS(0) Success FAIL(-1) Failure Example
struct ContentView: View { func initAppSaferExample() { // APP_SAFER_KEY generated when registering an app to the Console let result = AppSafer().initAppSafer(AppSaferDelegator.delegator, serviceCode: "ncloud", key: "<APP_SAFER_KEY>") NSLog("initAppSafer() result: %d", result); if(result == SUCCESS) { // init success } else if(result == FAIL) { // init fail } } var body: some View { Button("initAppSafer") { initAppSaferExample() } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)initAppSaferExample:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; int res = FAIL; if(appSafer != nil) { // APP_SAFER_KEY generated when registering an app to the Console res = [appSafer initAppSafer:self serviceCode:@"ncloud" key:@"<APP_SAFER_KEY>"]; NSLog(@"initAppSafer() result: %d", res); if(res == SUCCESS) { // init success } } }
checkTampering
To execute the real-time security detection function, use the following code.
func checkTampering()
- (int)checkTampering
Return value
Return value Description SUCCESS(0) Scan start succeeded FAIL(-1) Scan start failed BLOCK(2) Blocked for violating the security policy BEFOREINIT(3) App Safer is not initialized. Example
struct ContentView: View { func checkTamperingExample() { let result = AppSafer().checkTampering() switch(result) { case FAIL: print("Failed to check tampering") break case SUCCESS: print("Check Tampering Success") break case BLOCK: print("Device is blocked") break case BEFOREINIT: print("AppSafer is not initialized") break default: break } } var body: some View { Button("checkTampering") { checkTamperingExample() } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)checkAppSafer:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; if(appSafer != nil) { int res = [appSafer checkTampering]; switch(res) { case FAIL: NSLog(@"Failed to check tampering"); break; case SUCCESS: NSLog(@"Check Tampering Success"); break; case BLOCK: NSLog(@"Device is blocked"); break; case BEFOREINIT: NSLog(@"AppSafer is not initialized"); break; } } else { NSLog(@"AppSafer is nil"); } } @end
setUserId
Use the code below to include the user identifier in the log sent to the App Safer server when initialization and detection events occur.
func setUserId(_ userId: String!) -> Int32
- (int)setUserId:(NSString *)userId
Parameters
Parameters Description userId User identifier Return value
Return value Description SUCCESS(0) Setting succeeded FAIL(-1) Setting failed Example
struct ContentView: View { func setUserIdExample(_ userId: String) { print("setUserId(\(userId))") let result = AppSafer().setUserId(userId) switch(result) { case FAIL: print("Failed to set userId: \(userId)") break case SUCCESS: print("setUserId() Success: \(userId)") break default: break } } var body: some View { Button("setUserId") { setUserIdExample("ExampleUserId") } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)setUserId:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; if(appSafer != nil) { NSLog(@"setUserId(%@)", [self.useridText text]); int res = [appSafer setUserId:[self.useridText text]]; switch(res) { case FAIL: NSLog(@"Failed to set userId"); break; case SUCCESS: NSLog(@"setUserId Success"); break; } } else { NSLog(@"AppSafer is nil"); } }
appSaferDidInitFinish
After calling the initAppSafer function, the function below is called to pass the initialization result.
func appSaferDidInitFinish(_ result: Int32)
- (void)appSaferDidInitFinish:(int)result
Parameters
Parameters Description SUCCESS(0) Successfully initialized FAIL(-1) Initialization failed BLOCK(2) Blocked for violating the security policy Example
func appSaferDidInitFinish(_ result: Int32) { print("appSaferDidInitFinish result: \(result)"); if(result == BLOCK) { print("Device is blocked!"); // add to exit application logic } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDidInitFinish:(NSUInteger)result msg:(NSString *)message { NSLog(@"appSaferDidInitFinish result: %d", result); if(result == BLOCK) { NSLog(@"Device is blocked!"); // add to exit application logic } }
appSaferDidCheckTamperingFinish
The function below is called to pass the result of executing the checkTampering function.
func appSaferDidCheckTamperingFinish(_ result: Int32)
- (void)appSaferDidCheckTamperingFinish:(int)result
Parameters
Parameters Description FAIL(-1) Scan failed SAFE(0) The event is not detected. DETECT(1) The event is detected. BLOCK(2) Blocked Example
func appSaferDidCheckTamperingFinish(_ result: Int32) { print("appSaferDidCheckTamperingFinish result: " + ( result == FAIL ? "FAIL" : result == SAFE ? "SAFE" : result == DETECT ? "DETECT" : result == BLOCK ? "BLOCK": "UNKNOWN")) if(result == BLOCK) { print("Device is blocked!") // add to exit application logic } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDidCheckTamperingFinish:(int)result { NSLog(@"appSaferDidCheckTamperingFinish result: %@", result == FAIL ? @"FAIL" : result == SAFE ? @"SAFE" : result == DETECT ? @"DETECT" : result == BLOCK ? @"BLOCK": @"UNKNOWN"); if(result == BLOCK) { NSLog(@"Device is blocked!"); // add to exit application logic } }
appSaferDetectedJailbreak
When the jailbreaking of the device is detected, the following function is called. You can use it when you want to receive the result even if the operation of the checkTampering function is not completed.
func appSaferDetectedJailbreak()
- (void)appSaferDetectedJailbreak
Example
func appSaferDetectedJailbreak() { print("[DETECT] appSaferDetectedJailbreak"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedJailbreak { NSLog(@"[DETECT] appSaferDetectedJailbreak"); }
appSaferDetectedSimulator
The function below is called when it is detected that the app is running in a virtual machine. You can use it when you want to receive the result even if the operation of the checkTampering function is not completed.
func appSaferDetectedSimulator()
- (void)appSaferDetectedSimulator
Example
func appSaferDetectedSimulator() { print("[DETECT] appSaferDetectedSimulator"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedSimulator { NSLog(@"[DETECT] appSaferDetectedSimulator"); }
appSaferDetectedDebugging
When debugging is detected in the device, the following function is called. You can use it when you want to receive the result even if the operation of the checkTampering function is not completed.
func appSaferDetectedDebugging()
- (void)appSaferDetectedDebugging
Example
func appSaferDetectedDebugging() { print("[DETECT] appSaferDetectedDebugging"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedDebugging { NSLog(@"[DETECT] appSaferDetectedDebugging"); }
appSaferDetectedMemoryTampered
When memory alteration is detected, the following function is called. You can use it when you want to receive the result even if the operation of the checkTampering function is not completed.
func appSaferDetectedMemoryTampered()
- (void)appSaferDetectedMemoryTampered
Example
func appSaferDetectedMemoryTampered() { print("[DETECT] appSaferDetectedMemoryTampered"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedMemoryTampered { NSLog(@"[DETECT] appSaferDetectedMemoryTampered"); }