setupDeeplink function
Implementation
Future<void> setupDeeplink({
String? domain,
String? scheme,
required bool isDryRun,
}) async {
print(
'${ColorsText.cyan}═══════════════════════════════════════════════════════════${ColorsText.reset}');
print(
'${ColorsText.cyan} Deep Linking Setup ${isDryRun ? '(DRY RUN)' : ''}${ColorsText.reset}');
print(
'${ColorsText.cyan}═══════════════════════════════════════════════════════════${ColorsText.reset}\n');
// Extract project information
final projectInfo = await extractProjectInfo();
// Display extracted information
print('${ColorsText.blue}🔍 Extracted Information:${ColorsText.reset}');
if (projectInfo.androidPackageName != null) {
print(
' ${ColorsText.green}✓${ColorsText.reset} Android Package: ${projectInfo.androidPackageName}');
}
if (projectInfo.iosBundleId != null) {
print(
' ${ColorsText.green}✓${ColorsText.reset} iOS Bundle ID: ${projectInfo.iosBundleId}');
}
if (projectInfo.iosTeamId != null) {
print(
' ${ColorsText.green}✓${ColorsText.reset} iOS Team ID: ${projectInfo.iosTeamId}');
} else {
print(
' ${ColorsText.yellow}⚠${ColorsText.reset} iOS Team ID: Not found in project');
}
if (projectInfo.debugSha256 != null) {
print(
' ${ColorsText.green}✓${ColorsText.reset} Debug SHA256: ${projectInfo.debugSha256}');
} else {
print(
' ${ColorsText.yellow}⚠${ColorsText.reset} Debug SHA256: Not found (keytool not available or keystore not found)');
}
print('');
// Display configuration
print('${ColorsText.blue}⚙️ Configuration:${ColorsText.reset}');
if (domain != null) {
print(' • Domain: $domain');
}
if (scheme != null) {
print(' • Custom Scheme: $scheme://');
}
print('');
// Plan what will be done
print(
'${ColorsText.blue}📝 Files to be created/modified:${ColorsText.reset}\n');
final List<String> fileChanges = [];
// Android changes
if (domain != null || scheme != null) {
fileChanges.add(
' 1. ${ColorsText.cyan}android/app/src/main/AndroidManifest.xml${ColorsText.reset}');
final intentDetails = <String>[];
if (domain != null) intentDetails.add('https://$domain');
if (scheme != null) intentDetails.add('$scheme://');
fileChanges
.add(' └─ Add intent-filter for: ${intentDetails.join(', ')}');
}
if (domain != null && projectInfo.androidPackageName != null) {
fileChanges.add('');
fileChanges.add(
' 2. ${ColorsText.cyan}android/.well-known/assetlinks.json${ColorsText.reset}');
fileChanges.add(' └─ New file with package & SHA256 fingerprint');
}
// iOS changes
if (domain != null && projectInfo.iosBundleId != null) {
fileChanges.add('');
fileChanges.add(
' 3. ${ColorsText.cyan}ios/.well-known/apple-app-site-association${ColorsText.reset}');
fileChanges.add(' └─ New file with Team ID & Bundle ID');
}
if (scheme != null) {
fileChanges.add('');
fileChanges
.add(' 4. ${ColorsText.cyan}ios/Runner/Info.plist${ColorsText.reset}');
fileChanges.add(' └─ Add CFBundleURLSchemes for: $scheme');
}
// Code changes
fileChanges.add('');
fileChanges.add(
' 5. ${ColorsText.cyan}lib/core/utils/deeplink_handler.dart${ColorsText.reset}');
fileChanges.add(' └─ New utility class for handling deep links');
fileChanges.add('');
fileChanges.add(' 6. ${ColorsText.cyan}lib/main.dart${ColorsText.reset}');
fileChanges.add(' └─ Add DeeplinkHandler initialization');
for (final change in fileChanges) {
print(change);
}
// Manual steps
print('\n${ColorsText.yellow}⚠️ Manual Steps Required:${ColorsText.reset}');
if (domain != null) {
print(' • iOS: Add Associated Domains capability in Xcode');
print(' └─ Add: applinks:$domain');
print(' • Upload .well-known files to https://$domain/');
}
if (projectInfo.iosTeamId == null && domain != null) {
print(' • iOS: Add your Team ID to apple-app-site-association file');
}
if (projectInfo.debugSha256 == null && domain != null) {
print(' • Android: Add SHA256 fingerprint to assetlinks.json');
}
if (isDryRun) {
print(
'\n${ColorsText.cyan}ℹ️ This was a dry run. No changes were made.${ColorsText.reset}');
print(
'${ColorsText.cyan} Run without --dry-run to apply changes.${ColorsText.reset}');
return;
}
// Ask for confirmation
print('\n${ColorsText.green}Continue with setup? (y/n):${ColorsText.reset} ');
final answer = stdin.readLineSync()?.toLowerCase();
if (answer != 'y' && answer != 'yes') {
print('${ColorsText.yellow}Setup cancelled.${ColorsText.reset}');
return;
}
print('\n${ColorsText.blue}🚀 Starting setup...${ColorsText.reset}\n');
// Install app_links package
print(
'${ColorsText.blue}📦 Installing app_links package...${ColorsText.reset}');
await installPackage('app_links');
print('');
// 1. Update AndroidManifest.xml
if (domain != null || scheme != null) {
await _updateAndroidManifest(domain: domain, scheme: scheme);
}
// 2. Create assetlinks.json
if (domain != null && projectInfo.androidPackageName != null) {
await _createAssetLinks(
packageName: projectInfo.androidPackageName!,
sha256: projectInfo.debugSha256,
);
}
// 3. Create apple-app-site-association
if (domain != null && projectInfo.iosBundleId != null) {
await _createAppleAppSiteAssociation(
teamId: projectInfo.iosTeamId,
bundleId: projectInfo.iosBundleId!,
);
}
// 4. Update Info.plist
if (scheme != null) {
await _updateInfoPlist(scheme: scheme);
}
// 5. Create deeplink_handler.dart
await _createDeeplinkHandler();
// 6. Show integration instructions
_showCompletionInstructions(
domain: domain,
scheme: scheme,
projectInfo: projectInfo,
);
}