참고 urls


들어가기 전 특징


  • Named routes는 더 이상 권장되지 않습니다.

  • 딥링크에는 URI Scheme, Universal Links, App Links의 세 가지 표준 기술 유형 존재

    • URI 스킴 방식 : 앱에 URI 스킴(scheme) 값을 등록하여 딥링크 사용

    • 앱링크(App Link) : Android 제공 - 도메인 주소를 이용한 딥링크 사용

    • 유니버셜 링크 (Universal Link) : iOS 제공 - 도메인 주소를 이용한 딥링크 사용

    고유한 웹사이트 주소(도메인)로 만들어지기 때문에 항상 유일합니다.
    도메인이 이 앱의 소유자라는 것을 인증해줘야 제대로 동작합니다.


github page로 웹 도메인 이용


웹 도메인을 소유해야하지만, 임시 솔루션으로 github 페이지를 이용해 링크를 생성해봅니다.

  • https://pages.github.com/ 를 참고해 그대로 따라가줍니다.

    꼭..! username.github.io 라는 이름으로 해주셔야 합니다. username과 정확히 일치하지않으면 작동하지 않는다고 합니다!


앱 내 라우터 설정


앱링크는 http 또는 https를 사용하는 일종의 딥링크 입니다.
그래서 특정 링크를 눌렀을 때 앱에서 특정 페이지를 오픈할려면 라우터 설정을 해줘야합니다.

1. go_router 패키지 추가

add dependency "go_router" (F1 커멘트팔레트 이용)


2. go_router 패키지 초기 설정

main.dart에서 라우팅 처리할 GoRouter 개체 생성 & 연결

full code는 example 코드 참고

void main() => runApp(const MyApp());

final GoRouter _router = GoRouter(
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return const HomeScreen();
      },
      routes: <RouteBase>[
        GoRoute(
          path: 'details',
          builder: (BuildContext context, GoRouterState state) {
            return const DetailsScreen();
          },
        ),
      ],
    ),
  ],
);

class MyApp extends StatelessWidget {
  /// Constructs a [MyApp]
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

1) _router 설정 선언

main.dart

final _router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomePage(),
      routes: <RouteBase>[
        GoRoute(
          path: 'products/:productId',
          builder: (context, state) => ShopDetailPage(
            productId: state.pathParameters['productId'] ?? '',
          ),
        ),
      ],
    ),
  ],
);

파라미터 없는 경우

GoRoute(
    path: '/page2',
    builder: (context, state) => const Page2Screen(),
  ),

쿼리 파라미터가 있는 경우 (? 뒤에)
query parameter

GoRoute(
  path: '/users',
  builder: (context, state) => const UsersScreen(filter: state.queryParameters['filter']),
),

경로에 파라미터 있는 경우
path parameter

GoRoute(
  path: '/users/:userId',
  builder: (context, state) => const UserScreen(id: state.pathParameters['userId']),
),

2) _router MaterialApp에 연결

main.dart 파일에 MyApp와 router 연결 후 routerConfig 설정

...

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
      ...
    );
  }

3. page 이동

route 설정할 땐 / 로 시작하지 않고
page 이동할 땐 /로 시작 하는 것..!

잊지말고 에러나면 요 부분을 자세히 봐보세요!

전달할 파라미터 없는 경우

context.go('/details');

전달할 파라미터가 있는 경우

Path Parameter:

context.go('/users/123'),
context.go('/users/$userId'),

Query Parameter:

context.go(Uri(path: '/users/123', queryParameters: {'filter': 'abc'}).toString());

pop

context.pop(true)

Android Applink 설정


android/app/src/main/AndroidManifest.xml

  • 다음 메타데이터 태그와 인텐트 필터를 <activity>태그 안에 추가
  • example.com자신의 웹 도메인으로 교체하세요!
 <meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
 <intent-filter android:autoVerify="true">
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
     <data android:scheme="http" android:host="example.com" />
     <data android:scheme="https" />
 </intent-filter>

예를들어 링크가 https://adbr-dev.github.io/ 와 같다면,
android:host="example.com" 부분을 작성할 땐
android:host="adbr-dev.github.io" 와 같이 작성해주세요!

(저것때문에.. 테스트할 때 삽질..을..ㅠㅠ 몇분이나..)


assetlinks.json 파일 호스팅


소유한 도메인이 있는 웹 서버를 사용하여 assetlinks.json 파일을 호스팅합니다

  • assetlinks.json 파일은 브라우저 대신 열어줄 안드로이드 앱을 모바일 브라우저에 알려주는 역할을 합니다.

  • 위 파일을 생성하려면, [Flutter 앱 패키지 이름][APK 빌드에 사용할 서명키 sha256 fingerprint]를 알아야 합니다.


준비물1: Package name

build.gradle 파일 내 namespace 확인해보면 됩니다.

android {
    namespace "ai.corca.webview_mock"

또는 MainActivity.kt 파일 내 package 다음을 확인해보세요

package ai.corca.webview_mock

준비물2: SHA-256 인증서 지문

구글플레이 앱 서명을 사용하거나 로컬 키 저장소를 사용하거나 두가지 방법이 있는데
저는 구글 플레이 앱 서명 방식을 사용할게요!

구글 개발자 계정이 없으신 분들은 로컬 키 저장소 사용 방법을 보고 sha256을 생성해 사용하세요!

Release> Setup > App Integrity> App Signing tab:
출시 > 설정 > 앱 무결성 > 앱 서명 탭

위 위치에서 SHA-256 인증서 지문을 찾을 수 있습니다!

assetlinks.json 이름으로 파일을 생성

구글플레이 앱 서명을 이용하시는 분들은
구글 플레이 콘솔에 적힌 "디지털 애샛 링크 JSON"을 바로 복사해서 쓰셔도 됩니다!

  • package_name값을 Android 애플리케이션 ID로 설정하십시오 .

  • sha256_cert_fingerprints를 이전 단계에서 얻은 값으로 설정합니다.

code:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.deeplink_cookbook",
    "sha256_cert_fingerprints":
    ["FF:2A:CF:7B:DD:CC:F1:03:3E:E8:B2:27:7C:A2:E3:3C:DE:13:DB:AC:8E:EB:3A:B9:72:A1:0E:26:8A:F5:EC:AF"]
  }
}]
  • 다음과 유사한 URL에서 파일을 호스팅합니다. <webdomain>/.well-known/assetlinks.json

  • 브라우저가 앱에 액세스할 수 있는지 확인


테스트


https://developer.android.com/training/app-links/verify-android-applinks?hl=ko#testing
안드로이드 공식문서에 적혀있는게 조금 더 많은 내용이 기입되어있는 것 같아 가져왔습니당


1. 앱 실행

flutter run --release                 

2. URL 인텐트 테스트

  • 앱과 연결된 웹사이트의 목록을 확인하고 호스팅되는 JSON 파일의 유효성을 확인하고 나면 기기에 앱을 설치합니다.
  • 비동기 인증 프로세스가 완료될 때까지 20초 이상 기다립니다.
  • 다음 명령어를 사용하여 시스템에서 앱이 인증되었는지, 올바른 링크 처리 정책이 설정되었는지 확인합니다.
  • 올바르게 호스팅 되어있는지 테스트 하지 않습니다.
adb shell 'am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://<web-domain>/details"' \
    <package name>

3. 앱에서 링크 테스트

.. 흠.. 실행이 안됨.. ㅠㅠ

.. ?? 왜 안되는지 잘 모르겠음.. 20분간 들여다 보고 있지만
여기까지 글 발행하고 iOS 셋팅 이어서 하고와서 보겠습니다.


💡 다음 iOS 유니버셜 링크 설정으로 이어집니다.
profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻

1개의 댓글

comment-user-thumbnail
2023년 12월 23일

안녕하세요! 혹시 안드로이드 딥링크 기능 이요!
핸드폰에서 딥링크가 안되는 부분 해결되셨나요?
저도 같은 증상이 나타나네요 ㅎㅎ

답글 달기