Apple 유니버설 링크

웹 사이트의 링크가 모바일 앱을 시작하고 모바일 앱에 콘텐츠를 표시하도록 웹 사이트와 모바일 앱을 연결하는 것이 바람직한 경우가 많습니다. 딥 링크라고도 하는 앱 연결은 모바일 디바이스가 URL에 응답하고 URL로 표시되는 모바일 앱에서 콘텐츠를 시작할 수 있도록 하는 기술입니다.

Apple 플랫폼에서 딥 링크는 유니버설 링크라고 합니다. 사용자가 범용 링크를 탭하면 시스템에서 Safari 또는 웹 사이트를 통해 라우팅하지 않고 앱으로 직접 링크를 리디렉션합니다. 이러한 링크는 사용자 지정 스키마(예: myappname://사용자 지정 체계)를 기반으로 하거나 HTTP 또는 HTTPS 스키마를 사용할 수 있습니다. 예를 들어 레시피 웹 사이트에서 링크를 클릭하면 해당 웹 사이트와 연결된 모바일 앱이 열리고 사용자에게 특정 레시피가 표시됩니다. 앱이 설치되지 않은 사용자는 웹 사이트의 콘텐츠로 이동합니다. 이 문서에서는 HTTPS 체계를 사용하는 범용 링크에 중점을 둡니다.

.NET MAUI iOS 앱은 유니버설 링크를 지원합니다. 이렇게 하려면 앱과의 관계를 설명하는 do기본 JSON 파일을 연결하는 디지털 자산을 호스팅해야 합니다. 이를 통해 Apple은 URL을 처리하려는 앱에 URL 소유권이 있는지 확인할 수 있습니다기본 악의적인 앱이 앱 링크를 가로채는 것을 방지할 수 있습니다.

.NET MAUI iOS 또는 Mac Catalyst 앱에서 Apple 유니버설 링크를 처리하는 프로세스는 다음과 같습니다.

  • 웹 사이트에서 연결된 do기본s 파일을 만들고 호스트합니다. 자세한 내용은 연결된 do기본s 파일 만들기 및 호스트를 참조하세요.
  • 연결된 do기본s 권한을 앱에 추가합니다. 자세한 내용은 에 연결된 do기본s 권한 추가를 참조하세요.
  • Apple 개발자 계정의 앱 ID에 연결된 do기본s 기능을 추가합니다. 자세한 내용은 앱 ID에 연결된 do기본s 기능 추가를 참조하세요.
  • 유니버설 링크가 앱으로 라우팅할 때 시스템에서 제공하는 사용자 활동 개체에 응답하도록 앱을 업데이트합니다. 자세한 내용은 범용 링크에 대한 응답을 참조 하세요.

자세한 내용은 앱 및 웹 사이트가 developer.apple.com 콘텐츠 에 연결하도록 허용을 참조하세요. 앱에 대한 사용자 지정 URL 체계를 정의하는 방법에 대한 자세한 내용은 developer.apple.com 앱 에 대한 사용자 지정 URL 체계 정의를 참조하세요.

연결된 do기본s 파일 만들기 및 호스트

웹 사이트를 앱과 연결하려면 웹 사이트에서 연결된 do기본 파일을 호스트해야 합니다. 연결된 do기본 파일은 다음 위치에서 https://domain.name/.well-known/apple-app-site-association기본 호스트해야 하는 JSON 파일입니다.

다음 JSON은 일반적인 연결된 do기본s 파일의 내용을 보여 줍니다.

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

키와 appID 키는 apps 웹 사이트에서 사용할 수 있는 앱의 앱 식별자를 지정해야 합니다. 이러한 키의 값은 앱 식별자 접두사 및 번들 식별자로 구성됩니다.

Important

연결된 do기본 파일은 유효한 인증서와 리디렉션 없이 호스트 https 되어야 합니다.

자세한 내용은 developer.apple.com 관련 do기본s 지원을 참조하세요.

앱에 연결된 do기본s 권한 추가

할 일에 연결된 do기본 파일을 호스팅한 후기본 연결된 do기본s 권한을 앱에 추가해야 합니다. 사용자가 앱을 설치하면 iOS는 연결된 do기본 파일을 다운로드하고 자격에서 할 일기본 확인하려고 시도합니다.

연결된 do기본s 권한은 앱이 연결된 할 일기본 목록을 지정합니다. 이 자격은 앱의 Entitlements.plist 파일에 추가되어야 합니다. iOS에서 자격을 추가하는 방법에 대한 자세한 내용은 자격을 참조 하세요. Mac Catalyst에서 자격을 추가하는 방법에 대한 자세한 내용은 자격을 참조 하세요.

자격은 다음 형식 ArrayStringcom.apple.developer.associated-domains 키를 사용하여 정의됩니다.

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

이 자격에 대한 자세한 내용은 developer.apple.com 관련 do기본s 권한을 참조하세요.

또는 프로젝트 파일(.csproj)을 수정하여 요소에 <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>

이 예제에서는 할 일의 applinks:recipe-app.com 올바른 값으로 바꿉기본. 원하는 subdo기본 및 최상위 do기본만 포함해야 합니다. 경로 및 쿼리 구성 요소 또는 후행 슬래시(/)를 포함하지 마세요.

참고 항목

iOS 14 이상 및 macOS 11 이상에서는 앱이 더 이상 파일에 대한 apple-app-site-association 요청을 웹 서버로 직접 보내지 않습니다. 대신 연결된 do기본 전용 Apple 관리 CDN(콘텐츠 배달 네트워크)에 요청을 보냅니다.

연결된 do기본s 기능을 앱 ID에 추가합니다.

앱에 연결된 do기본s 권한을 추가한 후 Apple 개발자 계정에서 앱의 앱 ID에 연결된 do기본s 기능을 추가해야 합니다. 앱에 정의된 모든 자격도 Apple 개발자 계정에서 앱의 앱 ID에 기능으로 추가해야 하기 때문에 이 작업이 필요합니다.

연결된 do기본s 기능을 앱 ID에 추가하려면 다음을 수행합니다.

  1. 웹 브라우저에서 Apple 개발자 계정에 로그인하고 인증서, ID 및 프로필 페이지로 이동합니다.

  2. 인증서, 식별자 및 프로필 페이지에서 식별자 탭을 선택합니다.

  3. 식별자 페이지에서 앱에 해당하는 앱 ID를 선택합니다.

  4. 앱 ID 구성 편집 페이지에서 연결된 Do기본s 기능을 사용하도록 설정한 다음 저장 단추를 선택합니다.

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

  5. 앱 기능 수정 대화 상자에서 확인 단추를 선택합니다.

앱의 앱 ID를 업데이트한 후 업데이트된 프로비저닝 프로필을 생성하고 다운로드해야 합니다.

참고 항목

나중에 앱에서 연결된 do기본s 권한을 제거하는 경우 Apple 개발자 계정에서 앱 ID의 구성을 업데이트해야 합니다.

사용자가 유니버설 링크를 활성화하면 iOS 및 Mac Catalyst가 앱을 시작하고 개체를 NSUserActivity 보냅니다. 이 개체를 쿼리하여 앱이 시작된 방법을 확인하고 수행할 작업을 결정할 수 있습니다. 이 작업은 수명 주기 대리자 및 ContinueUserActivity 수명 주기에서 FinishedLaunching 수행해야 합니다. FinishedLaunching 앱이 시작되면 대리자가 호출되고 ContinueUserActivity 앱이 실행 중이거나 일시 중단될 때 대리자가 호출됩니다. 수명 주기 대리자에 대한 자세한 내용은 플랫폼 수명 주기 이벤트를 참조 하세요.

호출되는 iOS 수명 주기 대리자를 응답하려면 클래스의 메서드에서 MauiAppBuilder 개체의 메서드를 CreateMauiapp 호출 ConfigureLifecycleEvents 합니다MauiProgram. 그런 다음 개체에서 ILifecycleBuilder 메서드를 AddiOS 호출하고 필요한 대리자의 처리기를 등록하는 메서드를 지정 Action 합니다.

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);
    }
}

iOS가 유니버설 링크 NSUserActivity 의 결과로 앱을 열면 개체에 값BrowsingWeb이 있는 ActivityType 속성이 있습니다. 활동 개체의 WebPageUrl 속성에는 사용자가 액세스하려는 URL이 포함됩니다. URL은 메서드를 사용하여 클래스 SendOnAppLinkRequestReceivedApp 전달될 수 있습니다.

참고 항목

다중 창 지원을 위해 앱의 장면을 사용하지 않는 경우 장면 메서드에 대한 수명 주기 처리기를 생략할 수 있습니다.

App 클래스에서 URL을 OnAppLinkRequestReceived 수신하고 처리하도록 메서드를 재정의합니다.

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());
    }
}

위의 예제에서 재정의는 OnAppLinkRequestReceived 앱 링크 URL을 표시합니다. 실제로 앱 링크는 프롬프트, 로그인 또는 기타 중단 없이 URL이 나타내는 콘텐츠로 사용자를 직접 가져와야 합니다. 따라서 재정의 OnAppLinkRequestReceived 는 URL이 나타내는 콘텐츠에 대한 탐색을 호출할 위치입니다.

Warning

유니버설 링크는 앱에 잠재적인 공격 벡터를 제공하므로 모든 URL 매개 변수의 유효성을 검사하고 잘못된 형식의 URL을 카드 합니다.

자세한 내용은 developer.apple.com 앱에서 유니버설 링크 지원을 참조하세요.

Important

iOS에서 유니버설 링크는 시뮬레이터가 아닌 디바이스에서 테스트해야 합니다.

범용 링크를 테스트하려면 노트 앱에 링크를 붙여넣고(iOS에서) 길게 누르거나(macOS에서) 컨트롤을 클릭하여 링크를 팔로우하기 위한 선택 사항을 검색합니다. 범용 링크가 올바르게 구성된 경우 앱 및 Safari에서 열 선택 항목이 표시됩니다. 이 작업에서 범용 링크를 따르면 디바이스에서 기본 동작이 설정됩니다기본. 이 기본 선택을 변경하려면 단계를 반복하고 다른 선택을 합니다.

참고 항목

Safari에 URL을 입력하면 앱이 열리지 않습니다. 대신 Safari는 이 작업을 직접 탐색으로 수락합니다. 사용자가 직접 탐색한 후 기본 경우 사이트에서 앱을 여는 배너를 표시합니다.

iOS에서는 개발자 설정에서 연결된 do기본s 진단 테스트를 사용하여 유니버설 링크를 테스트할 수 있습니다.

  1. 설정 개발자 모드를 사용하도록 설정합니다. 자세한 내용은 developer.apple.com 디바이스에서 개발자 모드 사용 설정을 참조하세요.
  2. 설정 개발자에서 유니버설 링크로 스크롤하여 연결된 Do기본s Development를 사용하도록 설정합니다.>
  3. 진단을 열고 URL을 입력합니다. 그러면 링크가 설치된 앱에 유효한지 여부에 대한 피드백을 받게 됩니다.

잘못된 범용 링크가 잘못 구성된 결과인 경우가 applinks 많습니다.

문제 해결 조언은 developer.apple.com 유니버설 링크 디버깅을 참조하세요.