checkDomainAssociationStatus static method

Future<VerificationResult> checkDomainAssociationStatus(
  1. String domain,
  2. String? bundleIdentifier
)

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