iOS SDK
    • PDF

    iOS SDK

    • PDF

    Article Summary

    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.

    Note

    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.

    Note

    It is recommended to build in Xcode 8.0 or later environment.

    1. Decompress the downloaded SDK in an arbitrary directory.
    2. Check the project's Bitcode settings.
      • Path: Build Settings > Build Options > Enable Bitcode
    3. 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
    4. 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
    NameDescription
    initAppSaferInitialize to use AppSafer
    checkTamperingReal-time security detection
    • Jailbreak detection
    • Simulator detection
    • Debugging detection
    • Memory Tampered detection
    • Unauthorized Signature detection
    setUserIdSet 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, not struct, and add both AppSaferDelegate and NSObject.
    NameRequirement statusDescription
    appSaferDidInitFinishRequiredCheck the result of initializing App Safer
    appSaferDidCheckTamperingFinishRequiredCheck the result of executing the checkTampering function
    appSaferDetectedJailbreakOptionalCall it when the jailbreaking of the device is detected
    appSaferDetectedSimulatorOptionalCall it when it detects that the device is running in a virtual machine
    appSaferDetectedDebuggingOptionalCall it when debugging is detected
    appSaferDetectedMemoryTamperedOptionalCall 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

      ParametersDescription
      delegateAn instance in which AppSaferDelegate is implemented
      serviceCodeThe code for using App Safer
      NAVER Cloud Platform users must pass "ncloud"
      appsaferKeyThe App Safer Key value created when an app is registered on the console
    • Return value

      Return valueDescription
      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 valueDescription
      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

      ParametersDescription
      userIdUser identifier
    • Return value

      Return valueDescription
      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

      ParametersDescription
      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

      ParametersDescription
      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");
      }
      

    Was this article helpful?

    What's Next
    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.