checkDomainAssociationStatus static method
Check domain association status using swcutil_ctl (iOS 16+) This is the proper way to check if a domain is associated with an app
Implementation
static Future<VerificationResult> checkDomainAssociationStatus(
String domain,
String? bundleIdentifier,
) async {
// Check if simulator is available
if (!await isSimulatorAvailable()) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.skipped,
message: 'iOS Simulator not available (xcrun simctl not found)',
fixSuggestion: 'Install Xcode and ensure xcrun is available',
);
}
// Check if a simulator is booted
final bootedSim = await getBootedSimulator();
if (bootedSim == null) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.skipped,
message: 'No booted iOS simulator found',
fixSuggestion: 'Boot an iOS simulator: xcrun simctl boot <device-id>',
);
}
if (bundleIdentifier == null || bundleIdentifier.isEmpty) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.skipped,
message: 'Bundle identifier not found',
fixSuggestion: 'Ensure bundle identifier is configured in Info.plist',
);
}
// Check if app is installed
final appInstalled = await isAppInstalled(bundleIdentifier, bootedSim);
if (!appInstalled) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.warning,
message: 'App not installed on simulator',
fixSuggestion: 'Install the app on the simulator first:\n'
' xcrun simctl install booted <path-to-app.app>\n'
'Or build and run the app from Xcode',
details: {'bundleIdentifier': bundleIdentifier, 'simulator': bootedSim},
);
}
try {
// Use swcutil_ctl to check domain association (iOS 16+)
// This command queries the system for domain association status
final result = await Process.run('xcrun', [
'simctl',
'spawn',
bootedSim,
'swcutil_ctl',
'status',
domain,
]);
if (result.exitCode == 0) {
final output = result.stdout as String;
// Parse output to check association status
if (output.contains('associated') ||
output.contains('accepted') ||
output.contains(bundleIdentifier)) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.success,
message: 'Domain is associated with app',
details: {
'domain': domain,
'bundleIdentifier': bundleIdentifier,
'simulator': bootedSim,
},
);
} else if (output.contains('denied') ||
output.contains('not associated')) {
return VerificationResult(
checkName: 'iOS Runtime Test - Domain Association',
status: VerificationStatus.error,
message: 'Domain association denied or not found',
fixSuggestion: 'Check that:\n'
' 1. AASA file is accessible: https://$domain/.well-known/apple-app-site-association\n'
' 2. App entitlements include the domain\n'
' 3. Domain is verified in ULink dashboard',
details: {
'domain': domain,
'bundleIdentifier': bundleIdentifier,
'output': output,
},
);
}
}
// Fallback: Check system logs for domain association
return await _checkDomainAssociationFromLogs(domain, bundleIdentifier);
} catch (e) {
// swcutil_ctl might not be available on older iOS versions
// Fall back to log checking
return await _checkDomainAssociationFromLogs(domain, bundleIdentifier);
}
}