From 1a43f0bcc8758029df7fd1f0f660ef1656df8982 Mon Sep 17 00:00:00 2001 From: Hamlet Jiang Su <30667958+hjiangsu@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:15:47 -0800 Subject: [PATCH] Add app links support for https://thunderapp.dev (#1644) * feat: add app-link support for thunderapp.dev * feat: add support for ios universal links * feat: add support for universal links on macOS * misc: revert back minor snackbar change --- android/app/src/main/AndroidManifest.xml | 8 +++++ ios/Runner.xcodeproj/project.pbxproj | 6 ++++ ios/Runner/Runner.entitlements | 4 +++ lib/thunder/pages/thunder_page.dart | 6 ++-- macos/Podfile.lock | 41 ++++++++++++++---------- macos/Runner.xcodeproj/project.pbxproj | 12 +++++++ macos/Runner/AppDelegate.swift | 13 +++++++- macos/Runner/DebugProfile.entitlements | 8 +++-- macos/Runner/Info.plist | 11 +++++++ macos/Runner/Release.entitlements | 4 +++ 10 files changed, 91 insertions(+), 22 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 4e1b27e78..d9d371bc3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -60,6 +60,14 @@ + + + + + + + + diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index d10f779a8..a818221ac 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -631,6 +631,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-production"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; @@ -819,6 +820,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-production"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; @@ -845,6 +847,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-production"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; @@ -925,6 +928,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-development"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; @@ -1067,6 +1071,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-development"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; @@ -1201,6 +1206,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-development"; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = L7P596HY6P; ENABLE_BITCODE = NO; diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 903def2af..70ae49689 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -4,5 +4,9 @@ aps-environment development + com.apple.developer.associated-domains + + applinks:thunderapp.dev + diff --git a/lib/thunder/pages/thunder_page.dart b/lib/thunder/pages/thunder_page.dart index d53b5b536..3f01410c7 100644 --- a/lib/thunder/pages/thunder_page.dart +++ b/lib/thunder/pages/thunder_page.dart @@ -109,9 +109,11 @@ class _ThunderState extends State { } WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - handleSharedFilesAndText(); - if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) { + handleSharedFilesAndText(); + } + + if (!kIsWeb && (Platform.isAndroid || Platform.isIOS || Platform.isMacOS)) { BlocProvider.of(context).initialize(); BlocProvider.of(context).handleNotifications(); } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index f30ae4ff5..3067f1251 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - app_links (1.0.0): + - FlutterMacOS - connectivity_plus (0.0.1): - Flutter - FlutterMacOS @@ -29,20 +31,21 @@ PODS: - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - - sqlite3 (3.47.0): - - sqlite3/common (= 3.47.0) - - sqlite3/common (3.47.0) - - sqlite3/dbstatvtab (3.47.0): + - sqlite3 (3.47.1): + - sqlite3/common (= 3.47.1) + - sqlite3/common (3.47.1) + - sqlite3/dbstatvtab (3.47.1): - sqlite3/common - - sqlite3/fts5 (3.47.0): + - sqlite3/fts5 (3.47.1): - sqlite3/common - - sqlite3/perf-threadsafe (3.47.0): + - sqlite3/perf-threadsafe (3.47.1): - sqlite3/common - - sqlite3/rtree (3.47.0): + - sqlite3/rtree (3.47.1): - sqlite3/common - sqlite3_flutter_libs (0.0.1): + - Flutter - FlutterMacOS - - sqlite3 (~> 3.47.0) + - sqlite3 (~> 3.47.1) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe @@ -57,6 +60,7 @@ PODS: - FlutterMacOS DEPENDENCIES: + - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`) @@ -69,7 +73,7 @@ DEPENDENCIES: - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos`) + - sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`) - webview_flutter_wkwebview (from `Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin`) @@ -80,6 +84,8 @@ SPEC REPOS: - sqlite3 EXTERNAL SOURCES: + app_links: + :path: Flutter/ephemeral/.symlinks/plugins/app_links/macos connectivity_plus: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin device_info_plus: @@ -105,7 +111,7 @@ EXTERNAL SOURCES: sqflite_darwin: :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin sqlite3_flutter_libs: - :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/macos + :path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos video_player_avfoundation: @@ -114,25 +120,26 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin SPEC CHECKSUMS: + app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a connectivity_plus: 4c41c08fc6d7c91f63bc7aec70ffe3730b04f563 - device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 + device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b - flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4 + flutter_local_notifications: 7062189aabf7f50938a7b8b6614ffa97656eb0bf FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - share_plus: fd717ef89a2801d3491e737630112b80c310640e + share_plus: 1fa619de8392a4398bfaf176d441853922614e89 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - sqflite_darwin: a553b1fd6fe66f53bbb0fe5b4f5bab93f08d7a13 - sqlite3: 0aa20658a9b238a3b1ff7175eb7bdd863b0ab4fd - sqlite3_flutter_libs: f0b7a85544d8bac7b8bac12eac7d05bcfdd786d0 + sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d + sqlite3: 1e522f0938463e44b7faf50393b40bdc1e1e456d + sqlite3_flutter_libs: 1b4e98da20ebd4e9b1240269b78cdcf492dbe9f3 url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4 PODFILE CHECKSUM: c2e95c8c0fe03c5c57e438583cae4cc732296009 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 00b2861cc..a96ec62ce 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -592,8 +592,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -719,8 +721,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -740,8 +744,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -829,8 +835,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -920,8 +928,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1010,8 +1020,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = L7P596HY6P; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index 8e02df288..0862bf038 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -1,9 +1,20 @@ import Cocoa import FlutterMacOS +import app_links @main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } -} + + public override func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any NSUserActivityRestoring]) -> Void) -> Bool { + guard let url = AppLinks.shared.getUniversalLink(userActivity) else { + return false + } + + AppLinks.shared.handleLink(link: url.absoluteString) + + return false + } +} \ No newline at end of file diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements index 08c3ab17c..0c35a690e 100644 --- a/macos/Runner/DebugProfile.entitlements +++ b/macos/Runner/DebugProfile.entitlements @@ -2,13 +2,17 @@ + com.apple.developer.associated-domains + + applinks:thunderapp.dev + com.apple.security.app-sandbox com.apple.security.cs.allow-jit - com.apple.security.network.server - com.apple.security.network.client + com.apple.security.network.server + diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist index cf58f69b3..67c68c376 100644 --- a/macos/Runner/Info.plist +++ b/macos/Runner/Info.plist @@ -30,5 +30,16 @@ MainMenu NSPrincipalClass NSApplication + CFBundleURLTypes + + + CFBundleURLName + com.hjiangsu.thunder + CFBundleURLSchemes + + thunder + + + diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index ee95ab7e5..6bcf1e311 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -2,6 +2,10 @@ + com.apple.developer.associated-domains + + applinks:thunderapp.dev + com.apple.security.app-sandbox com.apple.security.network.client