Udostępnij za pośrednictwem


Linki uniwersalne firmy Apple

Często pożądane jest połączenie witryny internetowej i aplikacji mobilnej, aby linki w witrynie internetowej uruchamiały aplikację mobilną i wyświetlały zawartość w aplikacji mobilnej. Łączenie aplikacji, nazywane również łączeniem głębokim, jest techniką umożliwiającą urządzeniu przenośnemu odpowiadanie na adres URL i uruchamianie zawartości w aplikacji mobilnej reprezentowanej przez adres URL.

Na platformach Firmy Apple linki głębokie są nazywane uniwersalnymi linkami. Gdy użytkownik naciśnie link uniwersalny, system przekierowuje link bezpośrednio do aplikacji bez routingu za pośrednictwem przeglądarki Safari lub witryny internetowej. Te linki mogą być oparte na schemacie niestandardowym, takim jak myappname://, lub mogą używać schematu HTTP lub HTTPS. Na przykład kliknięcie linku w witrynie internetowej przepis spowoduje otwarcie aplikacji mobilnej skojarzonej z tą witryną internetową, a następnie wyświetlenie określonego przepisu dla użytkownika. Użytkownicy, którzy nie mają zainstalowanej aplikacji, zostaną przekierowani do zawartości w witrynie internetowej. Ten artykuł koncentruje się na linkach uniwersalnych korzystających ze schematu HTTPS.

Aplikacje .NET MAUI dla systemu iOS obsługują linki uniwersalne. Wymaga to hostowania pliku JSON zasobów cyfrowych w domenie, który opisuje relację z aplikacją. Dzięki temu firma Apple może sprawdzić, czy aplikacja próbująca obsłużyć adres URL ma własność domeny adresów URL, aby zapobiec przechwyceniu linków aplikacji przez złośliwe aplikacje.

Proces obsługi linków uniwersalnych firmy Apple w aplikacji .NET MAUI dla systemu iOS lub Mac Catalyst jest następujący:

Aby uzyskać więcej informacji, zobacz Zezwalanie aplikacjom i witrynom internetowym na łączenie się z zawartością w developer.apple.com. Aby uzyskać informacje na temat definiowania niestandardowego schematu adresów URL dla aplikacji, zobacz Definiowanie niestandardowego schematu adresów URL dla aplikacji w developer.apple.com.

Tworzenie i hostowanie skojarzonego pliku domen

Aby skojarzyć witrynę internetową z aplikacją, musisz hostować skojarzony plik domeny w witrynie internetowej. Skojarzony plik domeny jest plikiem JSON, który musi być hostowany w domenie w następującej lokalizacji: https://domain.name/.well-known/apple-app-site-association.

Poniższy kod JSON przedstawia zawartość typowego skojarzonego pliku domen:

{
    "activitycontinuation": {
        "apps": [ "85HMA3YHJX.com.companyname.myrecipeapp" ]
    },
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "85HMA3YHJX.com.companyname.myrecipeapp",
                "paths": [ "*", "/*" ]
            }
        ]
    }
}

Klucze apps i appID powinny określać identyfikatory aplikacji dla aplikacji, które są dostępne do użycia w witrynie internetowej. Wartości tych kluczy składają się z prefiksu identyfikatora aplikacji i identyfikatora pakietu.

Ważne

Skojarzony plik domeny musi być hostowany przy użyciu https prawidłowego certyfikatu i bez przekierowań.

Aby uzyskać więcej informacji, zobacz Obsługa skojarzonych domen w developer.apple.com.

Dodawanie uprawnień skojarzonych domen do aplikacji

Po hostaniu skojarzonego pliku domeny w domenie należy dodać skojarzone domeny uprawnienia do aplikacji. Gdy użytkownik zainstaluje aplikację, system iOS próbuje pobrać skojarzony plik domeny i zweryfikować domeny z uprawnieniami.

Skojarzone uprawnienia domen określają listę domen, z którymi jest skojarzona aplikacja. To uprawnienie należy dodać do pliku Entitlements.plist w aplikacji. Aby uzyskać więcej informacji na temat dodawania uprawnień w systemie iOS, zobacz Uprawnienia. Aby uzyskać więcej informacji na temat dodawania uprawnień na komputerze Mac Catalyst, zobacz Uprawnienia.

Uprawnienie jest definiowane com.apple.developer.associated-domains przy użyciu klucza typu ArrayString:

<key>com.apple.developer.associated-domains</key>
<array>
  <string>applinks:recipe-app.com</string>
</array>

Aby uzyskać więcej informacji na temat tego uprawnienia, zobacz Uprawnienia skojarzone domen w developer.apple.com.

Alternatywnie możesz zmodyfikować plik projektu (csproj), aby dodać uprawnienie w elemecie <ItemGroup> :

<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' Or $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">

    <!-- For debugging, use '?mode=developer' for debug to bypass apple's CDN cache -->
    <CustomEntitlements
        Condition="$(Configuration) == 'Debug'"
        Include="com.apple.developer.associated-domains"
        Type="StringArray"
        Value="applinks:recipe-app.com?mode=developer" />

    <!-- Non-debugging, use normal applinks:url value -->
    <CustomEntitlements
        Condition="$(Configuration) != 'Debug'"
        Include="com.apple.developer.associated-domains"
        Type="StringArray"
        Value="applinks:recipe-app.com" />

</ItemGroup>

W tym przykładzie zastąp wartość applinks:recipe-app.com poprawną dla domeny. Upewnij się, że uwzględnisz tylko żądaną domenę podrzędną i domenę najwyższego poziomu. Nie dołączaj składników ścieżki i zapytania ani ukośnika końcowego (/).

Uwaga

W systemach iOS 14+ i macOS 11 lub nowszych aplikacje nie wysyłają już żądań dotyczących apple-app-site-association plików bezpośrednio do serwera internetowego. Zamiast tego wysyłają żądania do zarządzanej przez firmę Apple sieci dostarczania zawartości (CDN) dedykowanej skojarzonym domenom.

Dodawanie możliwości skojarzonych domen do identyfikatora aplikacji

Po dodaniu uprawnień skojarzonych domen do aplikacji należy dodać możliwości skojarzonych domen do identyfikatora aplikacji dla aplikacji na koncie dewelopera firmy Apple. Jest to wymagane, ponieważ wszystkie uprawnienia zdefiniowane w aplikacji również muszą zostać dodane jako funkcje identyfikatora aplikacji dla aplikacji na koncie dewelopera firmy Apple.

Aby dodać możliwości skojarzonych domen do identyfikatora aplikacji:

  1. W przeglądarce internetowej zaloguj się do konta dewelopera firmy Apple i przejdź do strony Certyfikaty, identyfikatory i profile.

  2. Na stronie Certyfikaty, Identyfikatory i profile wybierz kartę Identyfikatory .

  3. Na stronie Identyfikatory wybierz identyfikator aplikacji, który odpowiada aplikacji.

  4. Na stronie Edytowanie konfiguracji identyfikatora aplikacji włącz funkcję Skojarzone domeny, a następnie wybierz przycisk Zapisz:

    Screenshot of enabling the associated domains capability in the Apple Developer Portal.

  5. W oknie dialogowym Modyfikowanie możliwości aplikacji wybierz przycisk Potwierdź.

Po zaktualizowaniu identyfikatora aplikacji należy wygenerować i pobrać zaktualizowany profil aprowizacji.

Uwaga

Jeśli później usuniesz uprawnienia skojarzonych domen z aplikacji, musisz zaktualizować konfigurację identyfikatora aplikacji na koncie dewelopera firmy Apple.

Gdy użytkownik aktywuje link uniwersalny, system iOS i Mac Catalyst uruchomi aplikację i wyśle do niej NSUserActivity obiekt. Ten obiekt może być odpytywane, aby określić sposób uruchamiania aplikacji i określić, jakie działania należy podjąć. Powinno to być wykonywane w FinishedLaunching delegatach cyklu życia i ContinueUserActivity . Delegat FinishedLaunching jest wywoływany, gdy aplikacja została uruchomiona, a ContinueUserActivity delegat jest wywoływany, gdy aplikacja jest uruchomiona lub zawieszona. Aby uzyskać więcej informacji na temat delegatów cyklu życia, zobacz Zdarzenia cyklu życia platformy.

Aby odpowiedzieć na wywoływany delegat cyklu życia systemu iOS, wywołaj metodę ConfigureLifecycleEvents w MauiAppBuilder obiekcie w CreateMauiapp metodzie MauiProgram klasy. Następnie w obiekcie wywołaj ILifecycleBuilder metodę AddiOS i określ Action program obsługi dla wymaganego delegata:

using Microsoft.Maui.LifecycleEvents;
using Microsoft.Extensions.Logging;

namespace MyNamespace;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            })
            .ConfigureLifecycleEvents(lifecycle =>
            {
#if IOS || MACCATALYST
                lifecycle.AddiOS(ios =>
                {
                    // Universal link delivered to FinishedLaunching after app launch.
                    ios.FinishedLaunching((app, data) => HandleAppLink(app.UserActivity));

                    // Universal link delivered to ContinueUserActivity when the app is running or suspended.
                    ios.ContinueUserActivity((app, userActivity, handler) => HandleAppLink(userActivity));

                    // Only required if using Scenes for multi-window support.
                    if (OperatingSystem.IsIOSVersionAtLeast(13) || OperatingSystem.IsMacCatalystVersionAtLeast(13))
                    {
                        // Universal link delivered to SceneWillConnect after app launch
                        ios.SceneWillConnect((scene, sceneSession, sceneConnectionOptions)
                            => HandleAppLink(sceneConnectionOptions.UserActivities.ToArray()
                                .FirstOrDefault(a => a.ActivityType == Foundation.NSUserActivityType.BrowsingWeb)));

                        // Universal link delivered to SceneContinueUserActivity when the app is running or suspended
                        ios.SceneContinueUserActivity((scene, userActivity) => HandleAppLink(userActivity));
                    }
                });
#endif
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }

#if IOS || MACCATALYST
    static bool HandleAppLink(Foundation.NSUserActivity? userActivity)
    {
        if (userActivity is not null && userActivity.ActivityType == Foundation.NSUserActivityType.BrowsingWeb && userActivity.WebPageUrl is not null)
        {
            HandleAppLink(userActivity.WebPageUrl.ToString());
            return true;
        }
        return false;
    }
#endif

    static void HandleAppLink(string url)
    {
        if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
            App.Current?.SendOnAppLinkRequestReceived(uri);
    }
}

Gdy system iOS otworzy aplikację w wyniku linku uniwersalnego, NSUserActivity obiekt będzie miał ActivityType właściwość o wartości BrowsingWeb. Właściwość obiektu WebPageUrl działania będzie zawierać adres URL, do którego użytkownik chce uzyskać dostęp. Adres URL można przekazać do App klasy za pomocą SendOnAppLinkRequestReceived metody .

Uwaga

Jeśli nie używasz scen w aplikacji do obsługi wielu okien, możesz pominąć procedury obsługi cyklu życia dla metod Sceny.

App W klasie zastąpij metodę odbierania OnAppLinkRequestReceived i przetwarzania adresu URL:

namespace MyNamespace;

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }

    protected override async void OnAppLinkRequestReceived(Uri uri)
    {
        base.OnAppLinkRequestReceived(uri);

        // Show an alert to test that the app link was received.
        await Dispatcher.DispatchAsync(async () =>
        {
            await Windows[0].Page!.DisplayAlert("App link received", uri.ToString(), "OK");
        });

        Console.WriteLine("App link: " + uri.ToString());
    }
}

W powyższym przykładzie OnAppLinkRequestReceived przesłonięcia są wyświetlane adres URL linku aplikacji. W praktyce link aplikacji powinien prowadzić użytkowników bezpośrednio do zawartości reprezentowanej przez adres URL bez żadnych monitów, logowań lub innych przerw. W związku z tym przesłonięcia to lokalizacja, OnAppLinkRequestReceived z której ma być wywoływana nawigacja do zawartości reprezentowanej przez adres URL.

Ostrzeżenie

Linki uniwersalne oferują potencjalny wektor ataku do aplikacji, dlatego upewnij się, że wszystkie parametry adresu URL są weryfikowane i odrzucane źle sformułowane adresy URL.

Aby uzyskać więcej informacji, zobacz Obsługa linków uniwersalnych w aplikacji w developer.apple.com.

Ważne

W systemie iOS linki uniwersalne powinny być testowane na urządzeniu, a nie na symulatorze.

Aby przetestować link uniwersalny, wklej link do aplikacji Notes i naciśnij go długo (w systemie iOS) lub kliknij go za pomocą kontrolki (w systemie macOS), aby odnaleźć wybrane opcje, aby przejść do linku. Jeśli linki uniwersalne zostały poprawnie skonfigurowane, zostanie wyświetlony wybór otwierania w aplikacji i w przeglądarce Safari. Wybór spowoduje ustawienie domyślnego zachowania na urządzeniu podczas wykonywania linków uniwersalnych z tej domeny. Aby zmienić ten wybór domyślny, powtórz kroki i dokonaj innego wyboru.

Uwaga

Wprowadzenie adresu URL do przeglądarki Safari nigdy nie spowoduje otwarcia aplikacji. Zamiast tego przeglądarka Safari zaakceptuje tę akcję jako nawigację bezpośrednią. Pod warunkiem, że użytkownik znajduje się w domenie bezpośrednio, witryna wyświetli baner umożliwiający otwarcie aplikacji.

W systemie iOS można przetestować linki uniwersalne przy użyciu skojarzonych domen testów diagnostycznych w ustawieniach dewelopera:

  1. Włącz tryb dewelopera w Ustawienia. Aby uzyskać więcej informacji, zobacz Włączanie trybu dewelopera na urządzeniu na developer.apple.com.
  2. W Ustawienia > Developer przewiń do linków uniwersalnych i włącz tworzenie skojarzonych domen.
  3. Otwórz diagnostykę i wpisz adres URL. Następnie otrzymasz opinię na temat tego, czy link jest prawidłowy dla zainstalowanej aplikacji.

Często nieprawidłowe linki uniwersalne są wynikiem nieprawidłowej applinks konfiguracji.

Aby uzyskać porady dotyczące rozwiązywania problemów, zobacz Debugowanie linków uniwersalnych w developer.apple.com.