用于混合应用的 JavaScript 接口
概述
使用 JavaScript 接口,从基于 WKWebView 的混合应用中的 JavaScript 代码启用 Singular SDK 功能。
支持的方法:
- setCustomUserId: 设置自定义用户标识符
- unsetCustomUserId: 移除自定义用户标识符
- event: 跟踪带或不带归因的事件
- revenue: 跟踪收入
设置 WKWebView 集成
在视图控制器的 WKNavigationDelegate 中配置 JavaScript 接口,以便从 JavaScript 中调用 Singular SDK 方法。
注意: 从 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 请求
JavaScript 用法
从在 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 字符串化的对象传递
-
方法名使用 camelCase(例如,
setCustomUserId) - 该接口会自动将 JavaScript 调用桥接到原生 SDK 方法