Antes de começar: Pré-requisitos do SDK
Problemas durante a integração? Consulte as perguntas frequentes abaixo.
Siga as etapas em Integração de um SDK Singular:Planejamento e pré-requisitos.
Essas etapas são pré-requisitos para qualquer integração do Singular SDK.
Instalar o SDK
Você pode instalar o SDK Singular usando CocoaPods, Swift Package Manager ou uma Biblioteca Estática.
- Baixe e instale a versão mais recente do CocoaPods.
-
Para criar um podfile, navegue até a pasta raiz do projeto no Terminal e digite:
pod init
-
Para adicionar a dependência do Singular SDK, adicione o seguinte ao Podfile do seu projeto:
pod 'Singular-SDK'
Por exemplo:
-
No Terminal, navegue até a pasta raiz do projeto e execute:
pod install
- Deste ponto em diante, abra o arquivo de espaço de trabalho do Xcode .xcworkspace para abrir o projeto, em vez do arquivo .xcodeproj.
- Crie um cabeçalho de ponte Swift de acordo com as instruções abaixo.
-
No Xcode, vá para Arquivo > Adicionar pacotes e insira o repositório Singular SDK do GitHub:
https://github.com/singular-labs/Singular-iOS-SDK
-
Atualize a versão do Singular SDK:
- Clique no botão Adicionar pacote.
-
Vá para Fases de construção > Vincular binário com bibliotecas e adicione a biblioteca AdServices.framework. Certifique-se de que a marca como Opcional, uma vez que só está disponível para dispositivos com iOS 14.3 e superior.
-
Vá para Configurações de compilação > Vinculação > Outros sinalizadores de vinculador e atualize Outros sinalizadores de vinculador com os seguintes itens:
$(inherited) -ObjC -l "sqlite3.0" -l "z" -framework "AdSupport" -framework "Security" -framework "Singular" -framework "StoreKit" -framework "SystemConfiguration" -framework "WebKit" -framework "iAd" - Crie um cabeçalho de ponte Swift de acordo com as instruções abaixo.
O download e a instalação do Singular Framework só são necessários se você NÃO estiver usando os métodos CocoaPods ou SPM acima.
Está a atualizar a partir do Singular SDK 12.3.2 ou inferior?
Siga as etapas abaixo para remover a Biblioteca estática antiga
- Navegue até os arquivos do projeto e remova a biblioteca estática Singular. Normalmente, deve haver uma pasta com o nome Singular-iOS-sdk-v12.3.2. Clique com o botão direito do mouse na pasta e exclua-a do projeto.
- Prossiga para a próxima secção para instalar a nova estrutura
Adicionando o Singular Framework pela primeira vez
-
Descarregue e descompacte a Estrutura SDK.
Selecione o Framework correto para sua implementação:
- Para o Xcode 12 e superior, use o .xcframework [BAIXE AQUI]
- Para o Xcode 11 e inferior, use o .framework [BAIXE AQUI]
-
Adicione a pasta descompactada a uma pasta no seu projeto do Xcode:
No Xcode, clique com o botão direito do mouse em Nome do seu aplicativo > Adicionar arquivos a [Nome do seu projeto]. Na caixa de diálogo que se abre, selecione Opções > Criar grupos e adicione a pasta onde descompactou o SDK.
O framework Singular agora deve estar no seu projeto -
Para adicionar as bibliotecas necessárias:
- No Xcode, selecione Fases de construção > Ligar o binário às bibliotecas.
-
Clique em + e adicione as seguintes bibliotecas:
Libsqlite3.0.tbd SystemConfiguration.framework Security.framework Libz.tbd AdSupport.framework WebKit.framework StoreKit.framework AdServices.framework (mark as Optional since it's only available for devices with iOS 14.3 and higher).
- Incorporar e assinar a estrutura Singular
- Navegue até Geral > Estruturas, bibliotecas e conteúdo incorporado
- Ajuste a Estrutura Singular para ser"Incorporar e assinar"
Se você instalou o SDK usando CocoaPods ou o Gerenciador de Pacotes Swift, é necessário criar um Cabeçalho de Ponte para que o Swift use as bibliotecas Obj-C do SDK Singular.
-
No seu projeto, crie um novo arquivo do tipo Header e nomeie-o YourProjectName-Bridging-Header.
-
Abra o arquivo e adicione o seguinte:
#import <Singular/Singular.h>
Por exemplo:
-
Vá para Configurações de construção > Cabeçalho de ponte Objective-C e adicione o caminho relativo do arquivo:
Integrar o SDK
Importante:
- Para usar o Swift, é necessário ter um Bridging Header (consulte o guia acima).
- Se você adicionou o SDK Singular usando o Swift Package Manager, certifique-se de atualizar Build Settings > Other Linker Flags conforme explicado acima.
Importando a biblioteca Singular
No SceneDelegate, AppDelegate ou em qualquer arquivo onde o Singular será usado, importe a biblioteca de classes do Singular para começar a usar o SDK do Singular.
// If installed with Cocoapods or Swift Package Manager
import Singular
// If installed manually in Objective-C (New Framework)
#import <Singular/Singular.h>
// If installed manually in Objective-C (Legacy)
#import "Singular.h"
Criando um objeto de configuração
Antes de inicializar a funcionalidade Singular em seu código, é necessário criar um objeto de configuração Singular e definir todas as suas opções de configuração. Esse bloco de código deve ser adicionado em SceneDelegate (ou, se você não estiver usando SceneDelegate, adicione-o a AppDelegate).
O exemplo de código seguinte cria um objeto de configuração e define algumas opções de configuração comuns, como ativar a SKAdNetwork em Managed Mode e definir um tempo limite para aguardar uma resposta ATT.
As secções seguintes fornecem mais detalhes sobre cada uma destas opções e sobre como as pode personalizar.
Exemplo: Criando um objeto de configuração com algumas opções comuns
func getConfig() -> SingularConfig? {
// Create the config object with the SDK Key and SDK Secret
guard let config = SingularConfig(apiKey: 'APIKEY', andSecret: 'SECRET') else {
return nil
}
// If you are using App Tracking Transparency:
// Set a 300 sec delay before initialization to wait for
// the user's ATT response.
// (Remove this if you are not displaying an ATT prompt!)
config.waitForTrackingAuthorizationWithTimeoutInterval = 300
// Support custom ESP domains
config.espDomains = ["links.your-website-domain.com"]
// Set a handler method for deep links
config.singularLinksHandler = { params in
self.handleDeeplink(params: params)
}
return config
}
- (SingularConfig *)getConfig {
NSLog(@"-- Scene Delegate getConfig");
// Create the config object with the SDK Key and SDK Secret
SingularConfig* config = [[SingularConfig alloc] initWithApiKey:APIKEY
andSecret:SECRET];
// If you are using App Tracking Transparency:
// Set a 300 sec delay before initialization to wait for
// the user's ATT response.
// (Remove this if you are not displaying an ATT prompt!)
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
// Support custom ESP domains
config.espDomains = @[@"links.your-website-domain.com"];
// Set a handler method for deep links
config.singularLinksHandler = ^(SingularLinkParams * params) {[self handleDeeplink:params];};
return config;
}
Nota: a partir da versão 12.0.6 do Singular iOS SDK, a SKAdNetwork é ativada por padrão.
Se você ainda estiver usando uma versão mais antiga do SDK, será necessário ativar a SKAdNetwork usando o seguinte código ao criar o objeto de configuração:
// Enable SKAdNetwork in Managed Mode
config.skAdNetworkEnabled = true
// Enable SKAdNetwork in Managed Mode
config.skAdNetworkEnabled = YES;
Personalizar as opções de SKAdNetwork
A SKAdNetwork é a estrutura da Apple para determinar a atribuição de instalações móveis sem comprometer a privacidade do utilizador final. A SKAdNetwork permite-lhe medir o desempenho das suas campanhas de marketing de aplicações sem partilhar as informações de identificação pessoal do utilizador.
Por padrão, SKAdNetwork é ativada no Modo Gerenciado, em que o valor da conversão é gerenciado diretamente pela Singular a partir do lado do servidor. Se utilizar o Managed Mode, não precisa de adicionar qualquer código à sua aplicação para lidar com SKAdNetwork.
Isso permite o máximo de flexibilidade, pois é possível definir e alterar os valores de conversão através da plataforma Singular sem modificar o código do lado do cliente.
Este modo gerido do lado do servidor também o ajuda a lidar com os temporizadores de SKAdNetwork. A SKAdNetwork permite-lhe atualizar o valor de conversão no prazo de 24 horas a partir do momento do registo na SKAdNetwork. Qualquer chamada para atualizar o valor de conversão prolonga o temporizador por mais 24 horas. Por conseguinte, ao escolher os seus eventos de conversão, terá de se certificar de que os eventos ocorrem dentro dessa janela de atualização. No modo gerido, pode alterar a configuração do evento de conversão em qualquer altura sem lançar uma nova versão da sua aplicação.
Usando SKAdNetwork no modo manual (avançado)
Se pretender atualizar o valor de conversão por si próprio utilizando o código da aplicação, tem primeiro de definir o sinalizador manualSkanConversionManagement na Singular Config. Isto permite-lhe utilizar vários métodos SDK para obter e atualizar o valor de conversão manualmente.
Para ativar o Modo Manual:
func getConfig() -> SingularConfig? {
// Singular Config Options
guard let config = SingularConfig(apiKey: Constants.APIKEY,
andSecret: Constants.SECRET) else {
return nil
}
//...
config.manualSkanConversionManagement = true
//...
return config
}
- (SingularConfig *)getConfig {
// Singular Config Options
SingularConfig* config = [[SingularConfig alloc] initWithApiKey:APIKEY
andSecret:SECRET];
//...
config.manualSkanConversionManagement = YES;
//...
return config;
}
Para atualizar o valor de conversão:
No Modo Manual, para atualizar o valor de conversão, é necessário utilizar o método skanUpdateConversionValue. Pode utilizá-lo sempre que necessário no ciclo de vida da sua aplicação.
Nota: O método skanUpdateConversionValue não funcionará se não tiver ativado manualSkanConversionManagement.
Método skanUpdateConversionValue | |
---|---|
Descrição | Actualiza manualmente o valor de conversão SKAdNetwork. |
Assinatura | (BOOL)skanUpdateConversionValue:(NSInteger)conversionValue; |
Exemplo de utilização |
|
Outros métodos SKAdNetwork:
Para obter o valor de conversão atual, utilize o método skanGetConversionValue ou conversionValueUpdatedCallback. Ambos funcionam em Managed Mode e Manual Mode.
Método skanGetConversionValue | |
---|---|
Descrição | Obtém o valor de conversão atual monitorizado pelo Singular SDK. |
Assinatura | (NSNumber *)skanGetConversionValue; |
Exemplo de utilização |
|
conversionValueUpdatedCallback Callback | |
Descrição | Obtém o valor de conversão atual monitorizado pelo Singular SDK. |
Assinatura | void(^conversionValueUpdatedCallback)(NSInteger); |
Exemplo de utilização |
|
Manipulação do consentimento ATT (definição de um atraso de inicialização)
Exibir um prompt ATT (Transparência de rastreamento de aplicativo)
A partir do iOS 14.5, as aplicações são obrigadas a pedir o consentimento do utilizador (utilizando a estrutura App Tracking Transparency) antes de poderem aceder e partilhar alguns dados do utilizador que são úteis para fins de rastreio, incluindo o IDFA do dispositivo.
A Singular beneficia muito de ter o IDFA para identificar dispositivos e efetuar a atribuição de instalações (embora existam formas de efetuar a atribuição sem o IDFA). Recomendamos vivamente que peça o consentimento do utilizador para obter o IDFA.
Atraso na inicialização para aguardar a resposta da ATT
Por padrão, o Singular SDK envia uma sessão de usuário quando é inicializado. Quando uma sessão é enviada de um novo dispositivo, ela aciona imediatamente o processo de atribuição do Singular - que é realizado com base apenas nos dados disponíveis para o Singular naquele momento. Portanto, é essencial solicitar o consentimento e recuperar o IDFA antes que o SDK do Singular envie a primeira sessão.
Para atrasar o disparo de uma sessão de usuário, inicialize o Singular SDK com a opção waitForTrackingAuthorizationWithTimeoutInterval no objeto Config. Essa opção já está incluída no exemplo de código em 2.2. Criando um Objeto de Configuração.
func getConfig() -> SingularConfig? {
guard let config = SingularConfig(apiKey: Constants.APIKEY,
andSecret: Constants.SECRET) else {
return nil
}
//...
config.waitForTrackingAuthorizationWithTimeoutInterval = 300
//...
return config
}
- (SingularConfig *)getConfig {
SingularConfig* config = [[SingularConfig alloc] initWithApiKey:APIKEY
andSecret:SECRET];
//...
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
//...
return config;
}
Dica: Quando você define um atraso de inicialização, o fluxo do aplicativo é o seguinte:
- Quando o aplicativo é aberto, o Singular SDK começa a gravar uma sessão e os eventos do usuário, mas ainda não os envia para o servidor Singular.
- Quando o consentimento do App Tracking Transparency é concedido/negado ou o tempo definido passa, o SDK envia a sessão e quaisquer eventos em fila para o servidor Singular (com ou sem o IDFA).
- O Singular então inicia o processo de atribuição, aproveitando o IDFA se ele estiver disponível.
A tabela a seguir resume os cenários possíveis usando essa integração:
Cenário | Disponibilidade do IDFA |
O utilizador vê a caixa de diálogo de consentimento e concede o consentimento antes de decorrido o tempo definido. | O IDFA está disponível |
O utilizador vê o diálogo de consentimento e recusa o consentimento antes do tempo definido. | IDFA não está disponível |
O tempo definido expira, o diálogo de consentimento é mostrado ao utilizador e este dá o seu consentimento. | O IDFA está disponível apenas para os eventos do utilizador que são comunicados após o consentimento ser concedido |
O tempo definido expira e, em seguida, é mostrado ao utilizador o diálogo de consentimento e o consentimento é negado. | O IDFA não está disponível |
É mostrada ao utilizador a caixa de diálogo de consentimento, este sai da aplicação sem tomar qualquer ação e, mais tarde, abre a aplicação e concede o consentimento após o tempo definido ter expirado. | Todos os eventos em fila de espera são enviados para o servidor Singular quando a aplicação é reaberta. O IDFA não está disponível para esses eventos. Quaisquer eventos rastreados após o consentimento ser concedido têm o IDFA associado a eles. |
É mostrada ao utilizador a caixa de diálogo de consentimento, este sai da aplicação sem tomar qualquer ação e, mais tarde, abre a aplicação e nega o consentimento. | Todos os eventos em fila são enviados para os servidores Singular quando o aplicativo é reaberto. O IDFA não está disponível para esses eventos ou para qualquer um dos eventos rastreados posteriormente. |
Inicializando o SDK do Singular
Dica: Antes de continuar, certifique-se de ter concluído as etapas abaixo!
- Adicionou a biblioteca Singular
- Se estiver usando swift: criou um cabeçalho de ponte Swift
- Adicionado código para criar o objeto Singular Config
- Adicionado um manipulador de deep link
- Activou a SKAdNetwork
- Se estiver a mostrar o ATT: adicionado waitForTrackingAuthorizationWithTimeoutInterval
- O teste construiu a aplicação com êxito (a aplicação deve ser construída sem erros nesta fase)
O Singular SDK deve ser inicializado sempre que seu aplicativo for aberto. Esse é um pré-requisito para todas as funcionalidades de atribuição do Singular e também envia uma nova sessão de usuário para o Singular (as sessões são usadas para calcular a retenção de usuários). O SDK é inicializado usando o objeto de configuração que você criou em Criando um objeto de configuração.
Onde adicionar o código de inicialização?
É necessário inicializar o SDK do Singular em todos os pontos de entrada do aplicativo:
-
Para o iOS 13+ usando a interface SwiftUI sem SceneDelegate ou AppDelegate, inicialize o Singular SDK nos seguintes códigos ContentView().onOpenURL() e .onChange(of: scenePhase) (veja o código abaixo para exemplo).
-
Para iOS 13+, inicialize o Singular SDK nas seguintes funções SceneDelegate: willConnectTo session, continue userActivity, openURLContexts URLContexts.
-
Para versões mais antigas do iOS que não suportam SceneDelegate, inicialize o SDK nas seguintes funções AppDelegate: didFinishLaunchingWithOptions, continueUserActivity, openURL.
Exemplos de código de inicialização
// INITIALIZE THE SDK IN THE FOLLOWING SCENEDELEGATE FUNCTIONS]
// willConnectTo session
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
let userActivity = connectionOptions.userActivities.first
// Print IDFV to Console for use in Singular SDK Console
print(Date(), "-- Scene Delegate IDFV:",
UIDevice().identifierForVendor!.uuidString as Any)
//Initialize the Singular SDK here:
if let config = self.getConfig() {
config.userActivity = userActivity
Singular.start(config)
}
}
// continue userActivity
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
// Starts a new Singular session on continueUserActivity
if let config = self.getConfig() {
config.userActivity = userActivity
Singular.start(config)
}
}
//openURLContexts URLContexts
func scene(_ scene: UIScene, openURLContexts URLContexts:
Set<UIOpenURLContext>) {
// Starts a new Singular session on cold start from deeplink scheme
if let config = self.getConfig() {
config.openUrl = openurlString
Singular.start(config)
}
// Add custom code here to Redirect to non-Singular deep links
//...
}
// INITIALIZE THE SDK IN THE FOLLOWING WINDOWGROUP FUNCTIONS
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL(perform: { url in
openURL = url
// Initialize Singular from an openURL
if let config = self.getConfig() {
config.openUrl = url
Singular.start(config)
}
})
}
.onChange(of: scenePhase) { oldValue, phase in
// The SwiftUI ScenePhases replaces the old SceneDelegate lifecycle events
switch phase {
case .background:
print("App Scene: backgrounded")
case .inactive:
print("App Scene: inactive")
case .active:
print("App Scene: active")
// Initialize Singular
if let config = self.getConfig() {
Singular.start(config)
}
@unknown default:
print("App Scene: unknown")
}
}
}
// INITIALIZE THE SDK IN THE FOLLOWING SCENEDELEGATE FUNCTIONS
// willConnectToSession
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions {
NSUserActivity* userActivity = [[[connectionOptions userActivities] allObjects]
firstObject];
// Print identifier for Vendor (IDFV) to Xcode Console for use in Singular SDK Console
NSLog(@"-- Scene Delegate IDFV: %@", [[[UIDevice currentDevice] identifierForVendor] UUIDString]);
// Start a new Singular session from a backgrounded app
SingularConfig *config = [self getConfig];
config.userActivity = userActivity;
[Singular start:config];
}
// continueUserActivity
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity{
// Starts a new Singular session from a backgrounded App
SingularConfig *config = [self getConfig];
config.userActivity = userActivity;
[Singular start:config];
}
// openURLContexts
- (void)scene:(UIScene *)scene openURLContexts:(nonnull NSSet *)URLContexts {
// Starts a new Singular session on cold start from deeplink scheme
SingularConfig *config = [self getConfig];
config.openUrl = url;
[Singular start:config];
// Add custom code here to Redirect to Non-Singular deep links
//...
}
// INITIALIZE THE SDK IN THE FOLLOWING APPDELEGATE FUNCTIONS
// didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Starts new session when user opens the app if session timeout passed/opened using Singular Link
SingularConfig *config = [self getConfig];
config.launchOptions = launchOptions;
[Singular start:config];
return YES;
}
// continueUserActivity
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id> *restorableObjects))restorationHandler {
// Starts a new session when the user opens the app using a Singular Link while it was in the background
SingularConfig *config = [self getConfig];
config.userActivity = userActivity;
[Singular start:config];
return YES;
}
// openURL
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
// Starts new session when user opens the app using a non-Singular link, like a traditional app scheme.
SingularConfig *config = [self getConfig];
config.openUrl = url;
[Singular start:config];
// Add custom code here to Redirect to non-Singular deep links
//...
return YES;
}
- O AppDelegate inicializará o Singular apenas para o iOS 12.4 ou anterior.
- Se o seu alvo são versões do iOS superiores a 12.4, você deve começar a usar as atividades SceneDelegate.
// INITIALIZE THE SDK IN THE FOLLOWING APPDELEGATE FUNCTIONS
// didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) - Bool {
// Print IDFV to Console for use in Singular SDK Console
print(Date(), "-- Scene Delegate IDFV:", UIDevice().identifierForVendor!.uuidString as Any)
//Initialize the Singular SDK here:
if let config = self.getConfig() {
config.launchOptions = launchOptions
Singular.start(config)
}
return true
}
// continue userActivity
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) - Void) - Bool {
//Initialize the Singular SDK here:
if let config = self.getConfig() {
config.userActivity = userActivity
Singular.start(config)
}
return true
}
// open url
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) - Bool {
//Initialize the Singular SDK here:
if let config = self.getConfig() {
config.openUrl = url
Singular.start(config)
}
return true
}
Observações:
- Ao criar o objeto de configuração, tenha o cuidado de passar a opção correta - userActivity ou openUrl. Veja o código de exemplo abaixo e consulte as aplicações de exemplo, se necessário.
- Lembre-se de cumprir as várias leis de privacidade promulgadas nas regiões em que realiza negócios, incluindo GDPR, CCPA e COPPA. Para obter mais informações, consulte Práticas de Opt-In e Opt-Out do SDK e analise as funções do Singular SDK que ajudam a cumprir as leis de privacidade de dados.
- Para inicializar o SDK, você precisa da Chave do SDK Singular e do Segredo do SDK. Você pode obtê-los na plataforma Singular em"Ferramentas de Desenvolvedor > Integração SDK > Chaves SDK".
Perguntas e problemas frequentes
Consulte esta secção se encontrar quaisquer problemas ou erros ao criar a sua aplicação de teste.
No Xcode 15, existe uma nova opção chamada "User Script Sandboxing" que desempenha um papel crucial na construção O objetivo é evitar que os scripts façam alterações não intencionais no sistema, aumentando assim a estabilidade e a segurança da construção. Quando ativado, o sistema de construção restringe os scripts do utilizador para não permitir dependências de entrada/saída não declaradas. Isso é problemático para o SDK Singular, pois ele precisa executar scripts para vincular dependências de forma dinâmica.
Para resolver o problema:
- Navegue até Configurações de compilação > Opções de compilação.
- Ajuste "User Script Sandboxing" para um valor "Não"
- Verifique se o cabeçalho de ponte foi criado.
- Valide se o arquivo Bridging Header está vinculado em Build Settings > Objective-C Bridging Header.
Em alguns casos, o Simulador iOS exige que arm64 seja excluído em Build Settings > Excluded Architectures.
As Propriedades globais não são exibidas atualmente no Console de teste. Elas serão adicionadas no futuro. Utilize os registos de exportação para validar esta funcionalidade.
Porque é que estou a receber um erro de registo?
Os seguintes erros de registo comuns podem ser ignorados:
- [logging] nome de coluna duplicado: singular_link em "ALTER TABLE sessions ADD COLUMN singular_link TEXT DEFAULT NULL"
- [logging] duplicate column name: payload in "ALTER TABLE sessions ADD COLUMN payload TEXT DEFAULT NULL"
- [logging] nome da coluna duplicado: sequence em "ALTER TABLE events ADD COLUMN sequence INTEGER DEFAULT -1"
- [logging] nome da coluna duplicado: payload em "ALTER TABLE events ADD COLUMN payload TEXT DEFAULT NULL"