고급 옵션
WKWebView 기반 하이브리드 앱에 대한 세션 관리 및 JavaScript 연동을 포함한 고급 SDK 기능을 구성합니다.
세션 관리
자동 세션 관리
Singular SDK는 최신 iOS 앱에 대한 추가 구성 없이 세션 관리를 자동으로 처리합니다.
기본 동작:
앱이 60초 이상 백그라운드로 이동하면 SDK는 포그라운드로 돌아올 때 새 세션을 등록합니다.
세션 시간 제한 구성
앱의 사용 패턴에 맞게 세션 시간 초과 기간을 사용자 지정합니다.
메서드 서명:
+ (void)setSessionTimeout:(int)timeoutInSeconds;
// Initialize SDK configuration
guard let config = SingularConfig(
apiKey: "SDK_KEY",
andSecret: "SDK_SECRET"
) else {
return
}
// Set session timeout to 120 seconds (2 minutes)
Singular.setSessionTimeout(120)
// Start the SDK
Singular.start(config)
// Initialize SDK configuration
SingularConfig *config = [[SingularConfig alloc]
initWithApiKey:@"SDK_KEY"
andSecret:@"SDK_SECRET"];
// Set session timeout to 120 seconds (2 minutes)
[Singular setSessionTimeout:120];
// Start the SDK
[Singular start:config];
타임아웃 값:
- 기본값: 60초
- 최소값: 0초(배경/포그라운드 전환 시마다 새 세션 생성)
- 권장: 앱 사용 패턴에 따라 30-180초
모범 사례: Singular.start() 으로 전화하기 전에 setSessionTimeout으로 전화하여 첫 번째 세션부터 시간 초과 값이 적용되는지 확인하세요.
하이브리드 앱을 위한 자바Script 인터페이스
개요
자바Script 인터페이스를 사용하여 WKWebView 기반 하이브리드 앱의 자바Script 코드에서 Singular SDK 기능을 사용하도록 설정합니다.
지원되는 메서드
- setCustomUserId: 사용자 지정 사용자 식별자 설정
- unsetCustomUserId: 사용자 지정 사용자 식별자 제거
- 이벤트: 속성이 있든 없든 이벤트 추적
- 구매: 구매 추적
WKWebView 연동 설정
JavaScript에서 Singular SDK 메서드를 사용하도록 뷰 컨트롤러의 WKNavigationDelegate에서 JavaScript 인터페이스를 구성합니다.
참고: iOS 8.0 이상부터 Apple은 앱에 웹 콘텐츠를 추가할 때 WKWebView를 사용할 것을 권장합니다. UIWebView 또는 WebView를 사용하지 마십시오. 자세한 내용은 Apple의 WKWebView 설명서를참조하십시오.
import UIKit
import WebKit
class ViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Create WKWebView
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = self
view.addSubview(webView)
// Load web content
if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url)
}
}
}
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Check if Singular JavaScript interface exists
let js = "typeof(Singular)"
webView.evaluateJavaScript(js) { (result, error) -> Void in
if let resultString = result as? String {
if resultString == "undefined" {
// Load Singular JavaScript interface
do {
if let path = Bundle.main.path(forResource: "Singular", ofType: "js") {
let contents = try String(contentsOfFile: path)
webView.evaluateJavaScript(contents, completionHandler: nil)
}
} catch {
print("Error loading Singular.js: \(error)")
}
} else {
// Process Singular SDK request
Singular.processJSRequestWK(webView, withURL: navigationAction.request)
}
}
}
// Allow navigation
decisionHandler(.allow)
}
}
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import <Singular/Singular.h>
@interface ViewController () <WKNavigationDelegate>
@property (strong, nonatomic) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Create WKWebView
WKWebViewConfiguration *webConfiguration = [[WKWebViewConfiguration alloc] init];
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:webConfiguration];
self.webView.navigationDelegate = self;
[self.view addSubview:self.webView];
// Load web content
NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
if (url) {
[self.webView loadFileURL:url allowingReadAccessToURL:url];
}
}
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
// Check if Singular JavaScript interface exists
NSString *js = @"typeof(Singular)";
[webView evaluateJavaScript:js completionHandler:^(id result, NSError *error) {
if ([result isKindOfClass:[NSString class]]) {
NSString *resultString = (NSString *)result;
if ([resultString isEqualToString:@"undefined"]) {
// Load Singular JavaScript interface
NSString *path = [[NSBundle mainBundle] pathForResource:@"Singular" ofType:@"js"];
if (path) {
NSError *readError;
NSString *contents = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:&readError];
if (contents) {
[webView evaluateJavaScript:contents completionHandler:nil];
} else {
NSLog(@"Error loading Singular.js: %@", readError);
}
}
} else {
// Process Singular SDK request
[Singular processJSRequestWK:webView withURL:navigationAction.request];
}
}
}];
// Allow navigation
decisionHandler(WKNavigationActionPolicyAllow);
}
@end
설정 요구 사항:
-
앱 번들에
Singular.js파일을 포함합니다. - 보기 컨트롤러를 WKWebView의 탐색 델리게이트로 설정합니다.
-
decidePolicyForNavigationAction델리게이트 메서드 구현 -
processJSRequestWK을 호출하여 Singular SDK 요청 처리
자바Script 사용
WKWebView에서 실행 중인 JavaScript 코드에서 Singular 메서드를 호출합니다.
이벤트 추적
// Simple event without attributes
Singular.event('level_completed');
// Event with attributes (pass as JSON string)
Singular.event('purchase_attempt',
JSON.stringify({
"item_name": "sword",
"item_category": "weapons",
"item_price": 9.99
})
);
구매 추적
// Track revenue in USD
Singular.revenue('USD', 9.99);
// Track revenue in other currencies
Singular.revenue('EUR', 8.50);
사용자 지정 사용자 ID 관리
// Set custom user ID
Singular.setCustomUserId('user_12345');
// Remove custom user ID
Singular.unsetCustomUserId();
JavaScript API 참고 사항:
-
모든 메서드는 글로벌
Singular객체에서 호출됩니다. - 이벤트 속성은 JSON 문자열화된 객체로 전달되어야 합니다.
-
메소드 이름은 카멜케이스 사용(예:
setCustomUserId) - 인터페이스는 자바Script 호출을 네이티브 SDK 메소드에 자동으로 연결합니다.