SDK do Unreal Engine - Suporte a links diretos

Documento

Adição de suporte para Deep Linking

Os linksdirecionam os usuários para um conteúdo específico dentro do seu aplicativo. Quando os usuários tocam em um link direto em um dispositivo com seu aplicativo instalado, o aplicativo é aberto diretamente para o conteúdo pretendido, como uma página de produto ou uma experiência específica.

Os links de rastreamento singulares suportam links diretos padrão (para aplicativos instalados) e links diretos adiados (para novas instalações). Para obter informações abrangentes, consulte as Perguntas frequentes sobre links diretose as Perguntas frequentes sobre links singulares.


Requisitos

Pré-requisitos

Preencha os Pré-requisitos de Links singularespara habilitar links diretos para plataformas iOS e Android.

Observações:

  • Este guia pressupõe que sua organização está usando Singular Links- a tecnologia de link de rastreamento da Singular lançada em 2019. Os clientes mais antigos podem estar usando links de rastreamento herdados.
  • Os destinos de link direto do seu aplicativo precisam ser configurados na página Aplicativos no Singular (consulte Configurando URLs de link direto).

Configuração do SDK

Implementar o manipulador de links Singular

O SDK Singular fornece um mecanismo de manipulador baseado em delegado para recuperar parâmetros de deep link, deferred deep link e passthrough de links de rastreamento Singular quando seu aplicativo é aberto.

Parâmetros disponíveis:

  • Deeplink: O URL de destino dentro do seu aplicativo para usuários que clicam no link (configurado na página Gerenciar links).
  • Passthrough: Dados personalizados passados através do link de rastreamento para contexto adicional ou metadados de campanha.
  • IsDeferred: Indica se o link é um link direto diferido (verdadeiro para novas instalações, falso para instalações existentes).

Adicionar o manipulador de deep link ao seu aplicativo

Configure o manipulador de deep link para processar dados de deep link recebidos quando seu aplicativo for iniciado. Isso deve ser feito antes de inicializar o SDK Singular.

Etapas de implementação

  1. Adicione as inclusões necessárias do Singular ao arquivo de cabeçalho da sua classe.
  2. Implemente um método para manipular o retorno de chamada OnSingularLinksResolved.
  3. Crie e registre o objeto USingularDelegates antes da inicialização do SDK.
  4. Registre seu método handler usando OnSingularLinksResolved.AddDynamic().
  5. Processe os parâmetros de deep link no seu método manipulador.
C++
// Add to the include section of your class header
#include "SingularLinkParams.h"
#include "SingularDelegates.h"

// In your class header, declare the handler method
UFUNCTION()
void OnSingularLinksResolved(const FSingularLinkParams& LinkParams);

// In your class implementation file, implement the handler method
void UYourGameInstance::OnSingularLinksResolved(const FSingularLinkParams& LinkParams)
{
    // Extract parameters from the tracking link
    const FString Deeplink = LinkParams.SingularLinksParams["deeplink"];
    const FString Passthrough = LinkParams.SingularLinksParams["passthrough"];
    const bool IsDeferred = LinkParams.SingularLinksParams["isDeferred"] == "true";

    // Log the parameters
    UE_LOG(LogTemp, Log, TEXT("Deep Link Resolved"));
    UE_LOG(LogTemp, Log, TEXT("Deeplink: %s"), *Deeplink);
    UE_LOG(LogTemp, Log, TEXT("Passthrough: %s"), *Passthrough);
    UE_LOG(LogTemp, Log, TEXT("Is Deferred: %s"), IsDeferred ? TEXT("true") : TEXT("false"));

    // Handle deep link routing
    if (!Deeplink.IsEmpty())
    {
        HandleDeepLinkNavigation(Deeplink, IsDeferred);
    }
}

void UYourGameInstance::HandleDeepLinkNavigation(const FString& Url, bool IsDeferred)
{
    // Your deep link routing logic
    UE_LOG(LogTemp, Log, TEXT("Routing to: %s (Deferred: %s)"), 
           *Url, IsDeferred ? TEXT("true") : TEXT("false"));

    // Example: Parse the URL and navigate to appropriate content
    if (Url.Contains(TEXT("product")))
    {
        NavigateToProduct(Url);
    }
    else if (Url.Contains(TEXT("promo")))
    {
        NavigateToPromotion(Url);
    }
    else
    {
        NavigateToHome();
    }
}

// Register the delegate BEFORE initializing the Singular SDK
void UYourGameInstance::InitializeSingular()
{
    // Create the delegates object
    USingularDelegates* SingularDelegates = 
        CreateDefaultSubobject<USingularDelegates>(TEXT("SingularLinksHandler"));

    // Register the deep link handler
    SingularDelegates->OnSingularLinksResolved.AddDynamic(
        this, 
        &UYourGameInstance::OnSingularLinksResolved
    );

    UE_LOG(LogTemp, Log, TEXT("Singular Link Handler registered"));

    // Now initialize the SDK
    bool Success = USingularSDKBPLibrary::Initialize(
        TEXT("YOUR_SDK_KEY"),
        TEXT("YOUR_SDK_SECRET"),
        60,    // Session timeout
        TEXT(""),    // Custom user ID
        true,  // Enable SKAdNetwork
        false, // Manual SKAN management
        0,     // Wait for tracking authorization
        false, // OAID collection
        true,  // Enable logging
        3,     // Log level
        false, // Clipboard attribution
        TEXT(""),    // Facebook App ID
        TEXT("")     // Custom SDID
    );

    if (Success)
    {
        UE_LOG(LogTemp, Log, TEXT("Singular SDK initialized successfully"));
    }
}

Importante: O delegado deve ser registado antes de chamar USingularSDKBPLibrary::Initialize(). Se você registrar o manipulador após a inicialização, ele não receberá retornos de chamada do deep link.


Comportamento do manipulador

Entendendo a resolução de deep link

O manipulador de deep link se comporta de maneira diferente, dependendo se o aplicativo foi instalado recentemente ou se já está instalado quando o usuário toca em um Singular Link.

Instalação recente (Deep Link diferido)

Em uma instalação recente, não existe uma URL aberta quando o aplicativo é iniciado. A Singular completa a atribuição para determinar se o link de rastreamento contém um valor de deep link.

Fluxo de Deep Link Diferido:

  1. O usuário clica em um link de rastreamento da Singular configurado com um valor de deep link.
  2. O usuário instala e abre o aplicativo pela primeira vez.
  3. O Singular SDK envia a primeira sessão para os servidores Singular.
  4. A atribuição é concluída e identifica o deep link a partir do link de rastreamento.
  5. O valor do deep link retorna para o manipulador com IsDeferred = true.

Testando Deep Links Diferidos:

  1. Desinstale o aplicativo do dispositivo de teste (se estiver instalado no momento).
  2. iOS: Redefina seu IDFA. Android:Redefina seu Google Advertising ID (GAID).
  3. Clique no link de rastreamento Singular do dispositivo (verifique se ele está configurado com um valor de link profundo).
  4. Instale e abra o aplicativo.

A atribuição deve ser concluída com êxito e o valor diferido do deep link será passado para o seu manipulador.

Dica de teste de desenvolvimento: Ao testar links diretos com uma compilação de desenvolvimento usando um nome de pacote ou ID de pacote diferente, configure o link de rastreamento especificamente para o identificador do aplicativo de desenvolvimento. Depois de clicar no link de teste, instale a compilação de desenvolvimento diretamente no dispositivo através do Unreal Engine ou de ferramentas específicas da plataforma, em vez de transferir a aplicação de produção a partir da loja de aplicações.


Já instalado (link direto imediato)

Quando o aplicativo já está instalado, clicar em um link singular abre o aplicativo imediatamente usando a tecnologia Universal Links (iOS) ou Android App Links.

Fluxo imediato do Deep Link:

  1. O usuário clica em um link de rastreamento Singular.
  2. O sistema operacional fornece uma URL aberta contendo todo o link de rastreamento Singular.
  3. Durante a inicialização do SDK, a Singular analisa a URL.
  4. O Singular extrai os valores deeplink e passthrough.
  5. Os valores retornam através do manipulador com IsDeferred = false.

Parâmetros de passagem

Capture dados adicionais do clique no link de rastreamento usando parâmetros de passagem para metadados de campanha, segmentação de usuários ou informações personalizadas.

Se um parâmetro passthrough (_p) for incluído no link de rastreamento, o parâmetro Passthrough do manipulador conterá os dados correspondentes.

C++
void UYourGameInstance::OnSingularLinksResolved(const FSingularLinkParams& LinkParams)
{
    // Extract passthrough data
    const FString PassthroughData = LinkParams.SingularLinksParams["passthrough"];

    if (!PassthroughData.IsEmpty())
    {
        // Parse JSON passthrough data
        TSharedPtr<FJsonObject> JsonObject;
        TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(PassthroughData);

        if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
        {
            // Extract campaign metadata
            FString CampaignId;
            if (JsonObject->TryGetStringField(TEXT("campaign_id"), CampaignId))
            {
                UE_LOG(LogTemp, Log, TEXT("Campaign ID: %s"), *CampaignId);
            }

            FString UserSegment;
            if (JsonObject->TryGetStringField(TEXT("segment"), UserSegment))
            {
                UE_LOG(LogTemp, Log, TEXT("User Segment: %s"), *UserSegment);
            }

            FString PromoCode;
            if (JsonObject->TryGetStringField(TEXT("promo_code"), PromoCode))
            {
                UE_LOG(LogTemp, Log, TEXT("Promo Code: %s"), *PromoCode);
                ApplyPromoCode(PromoCode);
            }

            // Use the data in your app
            ApplyCampaignSettings(CampaignId, UserSegment);
        }
        else
        {
            UE_LOG(LogTemp, Warning, TEXT("Failed to parse passthrough data"));
        }
    }
}

void UYourGameInstance::ApplyCampaignSettings(const FString& CampaignId, const FString& Segment)
{
    // Your campaign-specific logic
    UE_LOG(LogTemp, Log, TEXT("Applying campaign settings for: %s (Segment: %s)"), 
           *CampaignId, *Segment);
}

Exemplo de URL de passagem:
https://yourapp.sng.link/A1b2c/abc123?_dl=myapp://product/123&_p={"campaign_id":"summer2025","segment":"premium","promo_code":"SAVE20"}

O manipulador receberá o parâmetro passthrough que contém a cadeia de caracteres JSON com metadados da campanha.


Referência de FSingularLinkParams

Detalhes do parâmetro

O objeto FSingularLinkParams contém detalhes do link de rastreamento passados para o manipulador de deep link.

Parâmetro Tipo de parâmetro Descrição
deeplink FString O URL de destino do deep link, conforme configurado na página Gerenciar links no Singular. Esse valor direciona os usuários para um conteúdo in-app específico.
passthrough FString Parâmetros de passagem adicionados ao link de rastreamento, normalmente usados para metadados de campanha, segmentação de usuários ou dados personalizados que seu aplicativo precisa processar.
isDeferred bool Indica se o link está configurado como um link profundo diferido. Retorna true para novas instalações (diferidas), false para instalações existentes (imediatas).

Assinatura do método

C++
// Callback method signature for Singular Links
void OnSingularLinksResolved(const FSingularLinkParams& linkParams)

// Access parameters using the SingularLinksParams map:
const FString Deeplink = linkParams.SingularLinksParams["deeplink"];
const FString Passthrough = linkParams.SingularLinksParams["passthrough"];
const bool IsDeferred = linkParams.SingularLinksParams["isDeferred"] == "true";

Implementação de roteamento de deep link

Criando um roteador de deep link

Implemente um sistema de roteamento de deep link centralizado para navegar os usuários para conteúdo específico com base na estrutura de URL do deep link.

C++
// Deep Link Router class implementation
class UDeepLinkRouter : public UObject
{
public:
    void RouteDeepLink(const FString& DeepLinkUrl, bool IsDeferred)
    {
        UE_LOG(LogTemp, Log, TEXT("Routing deep link: %s (Deferred: %s)"), 
               *DeepLinkUrl, IsDeferred ? TEXT("true") : TEXT("false"));

        // Parse the URL scheme
        if (DeepLinkUrl.StartsWith(TEXT("myapp://product/")))
        {
            FString ProductId = ExtractParameter(DeepLinkUrl, TEXT("myapp://product/"));
            NavigateToProduct(ProductId);
        }
        else if (DeepLinkUrl.StartsWith(TEXT("myapp://category/")))
        {
            FString CategoryName = ExtractParameter(DeepLinkUrl, TEXT("myapp://category/"));
            NavigateToCategory(CategoryName);
        }
        else if (DeepLinkUrl.StartsWith(TEXT("myapp://promo")))
        {
            NavigateToPromotions();
        }
        else if (DeepLinkUrl.StartsWith(TEXT("myapp://profile")))
        {
            NavigateToUserProfile();
        }
        else
        {
            // Default fallback
            UE_LOG(LogTemp, Warning, TEXT("Unknown deep link format, navigating to home"));
            NavigateToHome();
        }

        // Track deep link usage
        TrackDeepLinkEvent(DeepLinkUrl, IsDeferred);
    }

private:
    FString ExtractParameter(const FString& Url, const FString& Prefix)
    {
        FString Param;
        if (Url.Split(Prefix, nullptr, &Param))
        {
            // Remove query parameters if present
            FString CleanParam;
            if (Param.Split(TEXT("?"), &CleanParam, nullptr))
            {
                return CleanParam;
            }
            return Param;
        }
        return FString();
    }

    void NavigateToProduct(const FString& ProductId)
    {
        UE_LOG(LogTemp, Log, TEXT("Navigating to product: %s"), *ProductId);
        // Your product screen navigation logic
    }

    void NavigateToCategory(const FString& CategoryName)
    {
        UE_LOG(LogTemp, Log, TEXT("Navigating to category: %s"), *CategoryName);
        // Your category screen navigation logic
    }

    void NavigateToPromotions()
    {
        UE_LOG(LogTemp, Log, TEXT("Navigating to promotions"));
        // Your promotions screen navigation logic
    }

    void NavigateToUserProfile()
    {
        UE_LOG(LogTemp, Log, TEXT("Navigating to user profile"));
        // Your profile screen navigation logic
    }

    void NavigateToHome()
    {
        UE_LOG(LogTemp, Log, TEXT("Navigating to home screen"));
        // Your home screen navigation logic
    }

    void TrackDeepLinkEvent(const FString& DeepLink, bool IsDeferred)
    {
        // Track deep link usage with Singular
        TMap<FString, FString> EventAttributes;
        EventAttributes.Add(TEXT("deep_link_url"), DeepLink);
        EventAttributes.Add(TEXT("is_deferred"), IsDeferred ? TEXT("true") : TEXT("false"));

        USingularSDKBPLibrary::EventWithAttributes(
            TEXT("deep_link_opened"), 
            EventAttributes
        );
    }
};

Prática recomendada: Rastreie as aberturas de deep link como eventos personalizados no Singular para medir a eficácia de suas campanhas de deep link e entender qual conteúdo gera mais engajamento.


Considerações importantes

Notas de implementação

  • Tempo de registro: Sempre registre o manipulador de deep link antes de inicializar o SDK do Singular. O manipulador deve estar no lugar antes que o SDK processe o link de rastreamento.
  • Segurança de thread: A chamada de retorno do manipulador pode ser executada em uma thread em segundo plano. Certifique-se de que qualquer atualização da interface do usuário ou lógica de navegação seja enviada para o thread do jogo usando os mecanismos thread-safe do Unreal Engine.
  • Esquemas de URL: Projete esquemas de URL consistentes para seus links profundos (por exemplo, myapp://product/, myapp://category/) para simplificar a lógica de roteamento e a manutenção.
  • Tratamento de fallback: Implemente sempre uma navegação de retorno (normalmente para o ecrã inicial) para deep links não reconhecidos ou malformados para evitar falhas na aplicação ou uma má experiência do utilizador.
  • Teste de ambos os fluxos: Teste tanto os deep links imediatos (aplicativo instalado) quanto os diferidos (nova instalação) para garantir o tratamento adequado em todos os cenários.
  • Validação de parâmetros: Valide todos os parâmetros extraídos de deep links antes de usá-los para evitar problemas de segurança ou falhas de URLs maliciosos ou malformados.
  • Configuração de plataforma: Configuração completa específica da plataforma (iOS Universal Links, Android App Links) conforme documentado no guia Singular Links Prerequisites.

Lista de verificação de produção: Antes de lançar campanhas de links diretos, verifique: (1) O manipulador foi registrado antes da inicialização do SDK, (2) A configuração específica da plataforma foi concluída, (3) Os links diretos foram configurados no painel do Singular, (4) A lógica de roteamento lida com todos os padrões de URL esperados, (5) Os fluxos imediatos e diferidos foram testados com êxito.


Recursos adicionais