Opciones avanzadas
Configuración avanzada y opcional del SDK de Singular para iOS. No es necesaria para una integración estándar.
Interfaz JavaScript
Descripción general
Habilita la funcionalidad del SDK de Singular desde código JavaScript en aplicaciones híbridas basadas en WKWebView usando la interfaz JavaScript.
Métodos compatibles:
- setCustomUserId: Establece un identificador de usuario personalizado
- unsetCustomUserId: Elimina el identificador de usuario personalizado
- event: Registra eventos con o sin atributos
- revenue: Registra ingresos
Configuración de la integración con WKWebView
Configura la interfaz JavaScript en el WKNavigationDelegate de tu controlador de vista para habilitar los métodos del SDK de Singular desde JavaScript.
Nota: A partir de iOS 8.0+, Apple recomienda usar WKWebView para agregar contenido web a tu app. No uses UIWebView ni WebView . Consulta la documentación de WKWebView de Apple para obtener más información.
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
Requisitos de configuración:
-
Incluye el archivo
Singular.jsen el bundle de tu aplicación - Establece tu controlador de vista como el delegado de navegación del WKWebView
-
Implementa el método delegado
decidePolicyForNavigationAction -
Llama a
processJSRequestWKpara procesar las solicitudes del SDK de Singular
Uso de JavaScript
Llama a los métodos de Singular desde código JavaScript que se ejecuta en tu WKWebView.
Registrar eventos
// 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
})
);
Registrar ingresos
// Track revenue in USD
Singular.revenue('USD', 9.99);
// Track revenue in other currencies
Singular.revenue('EUR', 8.50);
Administrar el ID de usuario personalizado
// Set custom user ID
Singular.setCustomUserId('user_12345');
// Remove custom user ID
Singular.unsetCustomUserId();
Notas de la API JavaScript:
-
Todos los métodos se llaman sobre el objeto global
Singular - Los atributos del evento deben pasarse como objetos serializados en JSON
-
Los nombres de los métodos usan camelCase (por ejemplo,
setCustomUserId) - La interfaz conecta automáticamente las llamadas de JavaScript con los métodos nativos del SDK
Funciones BETA
No disponible de forma general: Las funciones de esta sección están en BETA. Singular debe habilitarlas para tu cuenta antes de que funcionen, y su comportamiento puede cambiar. Habla con tu Customer Success Manager antes de desarrollar sobre ellas.
Callback de atribución
El callback de atribución entrega a tu app, en el dispositivo, el resultado de atribución de Singular para la instalación —como la red y la campaña que la generaron— durante la primera sesión del usuario después de instalar.
Se requiere habilitación: Esta función está desactivada de forma predeterminada. Si no se ha habilitado para tu cuenta, el callback nunca se ejecuta, aunque tu código sea correcto. Contacta a tu Customer Success Manager para solicitarla.
Cómo configurarlo
- Pide a tu Customer Success Manager que habilite el callback de atribución para tu cuenta.
- Registra tu handler en el objeto de configuración del SDK antes de inicializarlo. Para ver la firma y un ejemplo de código, consulta
deviceAttributionCallback. - Prueba en un dispositivo que no haya abierto la app antes. El callback solo se ejecuta en una primera sesión.
Qué esperar
- Solo en la primera sesión: El callback se ejecuta una vez, durante la primera sesión después de la instalación. No se llama en aperturas posteriores.
- Organic es un resultado, no una falla: Cuando no se encuentra ningún touchpoint, el callback igualmente se ejecuta e informa la red como "Organic". Si el callback no se ejecuta en absoluto, la causa es un problema de configuración y no de atribución.
- Una mejor estimación, no la atribución final: El resultado refleja el último touchpoint disponible en el momento en que se procesa la sesión. No siempre coincidirá con la atribución que se muestra en los reportes de Singular, que se decide después con más información.