Skip to content

Commit b00f1c4

Browse files
authored
Adding vmservice to get iOS app settings (#123156)
fixes flutter/flutter#120405
1 parent 529b919 commit b00f1c4

File tree

16 files changed

+462
-189
lines changed

16 files changed

+462
-189
lines changed

packages/flutter_tools/lib/src/commands/build_ios.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,11 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
376376

377377
final Map<String, String?> xcodeProjectSettingsMap = <String, String?>{};
378378

379-
xcodeProjectSettingsMap['Version Number'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleShortVersionStringKey);
380-
xcodeProjectSettingsMap['Build Number'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleVersionKey);
381-
xcodeProjectSettingsMap['Display Name'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleDisplayNameKey);
382-
xcodeProjectSettingsMap['Deployment Target'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kMinimumOSVersionKey);
383-
xcodeProjectSettingsMap['Bundle Identifier'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleIdentifierKey);
379+
xcodeProjectSettingsMap['Version Number'] = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kCFBundleShortVersionStringKey);
380+
xcodeProjectSettingsMap['Build Number'] = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kCFBundleVersionKey);
381+
xcodeProjectSettingsMap['Display Name'] = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kCFBundleDisplayNameKey);
382+
xcodeProjectSettingsMap['Deployment Target'] = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kMinimumOSVersionKey);
383+
xcodeProjectSettingsMap['Bundle Identifier'] = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kCFBundleIdentifierKey);
384384

385385
final List<ValidationMessage> validationMessages = xcodeProjectSettingsMap.entries.map((MapEntry<String, String?> entry) {
386386
final String title = entry.key;

packages/flutter_tools/lib/src/intellij/intellij_validator.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
494494

495495
@override
496496
String get version {
497-
return _version ??= _plistParser.getStringValueFromFile(
497+
return _version ??= _plistParser.getValueFromFile<String>(
498498
plistFile,
499499
PlistParser.kCFBundleShortVersionStringKey,
500500
) ?? 'unknown';
@@ -508,7 +508,7 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
508508
}
509509

510510
final String? altLocation = _plistParser
511-
.getStringValueFromFile(plistFile, 'JetBrainsToolboxApp');
511+
.getValueFromFile<String>(plistFile, 'JetBrainsToolboxApp');
512512

513513
if (altLocation != null) {
514514
_pluginsPath = '$altLocation.plugins';

packages/flutter_tools/lib/src/ios/application_package.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ abstract class IOSApp extends ApplicationPackage {
5858
globals.printError('Invalid prebuilt iOS app. Does not contain Info.plist.');
5959
return null;
6060
}
61-
final String? id = globals.plistParser.getStringValueFromFile(
61+
final String? id = globals.plistParser.getValueFromFile<String>(
6262
plistPath,
6363
PlistParser.kCFBundleIdentifierKey,
6464
);

packages/flutter_tools/lib/src/ios/devices.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ class IOSDevice extends Device {
451451
_logger.printError('');
452452
return LaunchResult.failed();
453453
}
454-
packageId = buildResult.xcodeBuildExecution?.buildSettings['PRODUCT_BUNDLE_IDENTIFIER'];
454+
packageId = buildResult.xcodeBuildExecution?.buildSettings[IosProject.kProductBundleIdKey];
455455
}
456456

457457
packageId ??= package.id;

packages/flutter_tools/lib/src/ios/plist_parser.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class PlistParser {
2424
final Logger _logger;
2525
final ProcessUtils _processUtils;
2626

27+
// info.pList keys
2728
static const String kCFBundleIdentifierKey = 'CFBundleIdentifier';
2829
static const String kCFBundleShortVersionStringKey = 'CFBundleShortVersionString';
2930
static const String kCFBundleExecutableKey = 'CFBundleExecutable';
@@ -32,6 +33,9 @@ class PlistParser {
3233
static const String kMinimumOSVersionKey = 'MinimumOSVersion';
3334
static const String kNSPrincipalClassKey = 'NSPrincipalClass';
3435

36+
// entitlement file keys
37+
static const String kAssociatedDomainsKey = 'com.apple.developer.associated-domains';
38+
3539
static const String _plutilExecutable = '/usr/bin/plutil';
3640

3741
/// Returns the content, converted to XML, of the plist file located at
@@ -164,17 +168,17 @@ class PlistParser {
164168
return null;
165169
}
166170

167-
/// Parses the Plist file located at [plistFilePath] and returns the string
168-
/// value that's associated with the specified [key] within the property list.
171+
/// Parses the Plist file located at [plistFilePath] and returns the value
172+
/// that's associated with the specified [key] within the property list.
169173
///
170174
/// If [plistFilePath] points to a non-existent file or a file that's not a
171175
/// valid property list file, this will return null.
172176
///
173177
/// If [key] is not found in the property list, this will return null.
174178
///
175179
/// The [plistFilePath] and [key] arguments must not be null.
176-
String? getStringValueFromFile(String plistFilePath, String key) {
180+
T? getValueFromFile<T>(String plistFilePath, String key) {
177181
final Map<String, dynamic> parsed = parseFile(plistFilePath);
178-
return parsed[key] as String?;
182+
return parsed[key] as T?;
179183
}
180184
}

packages/flutter_tools/lib/src/ios/simulators.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ class IOSSimulator extends Device {
468468
// parsing the xcodeproj or configuration files.
469469
// See https://github.com/flutter/flutter/issues/31037 for more information.
470470
final String plistPath = globals.fs.path.join(package.simulatorBundlePath, 'Info.plist');
471-
final String? bundleIdentifier = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleIdentifierKey);
471+
final String? bundleIdentifier = globals.plistParser.getValueFromFile<String>(plistPath, PlistParser.kCFBundleIdentifierKey);
472472
if (bundleIdentifier == null) {
473473
globals.printError('Invalid prebuilt iOS app. Info.plist does not contain bundle identifier');
474474
return LaunchResult.failed();

packages/flutter_tools/lib/src/ios/xcodeproj.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class XcodeProjectInterpreter {
185185
final Status status = _logger.startSpinner();
186186
final String? scheme = buildContext.scheme;
187187
final String? configuration = buildContext.configuration;
188+
final String? target = buildContext.target;
188189
final String? deviceId = buildContext.deviceId;
189190
final List<String> showBuildSettingsCommand = <String>[
190191
...xcrunCommand(),
@@ -195,6 +196,8 @@ class XcodeProjectInterpreter {
195196
...<String>['-scheme', scheme],
196197
if (configuration != null)
197198
...<String>['-configuration', configuration],
199+
if (target != null)
200+
...<String>['-target', target],
198201
if (buildContext.environmentType == EnvironmentType.simulator)
199202
...<String>['-sdk', 'iphonesimulator'],
200203
'-destination',
@@ -380,17 +383,19 @@ class XcodeProjectBuildContext {
380383
this.configuration,
381384
this.environmentType = EnvironmentType.physical,
382385
this.deviceId,
386+
this.target,
383387
this.isWatch = false,
384388
});
385389

386390
final String? scheme;
387391
final String? configuration;
388392
final EnvironmentType environmentType;
389393
final String? deviceId;
394+
final String? target;
390395
final bool isWatch;
391396

392397
@override
393-
int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId);
398+
int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId, target);
394399

395400
@override
396401
bool operator ==(Object other) {
@@ -402,10 +407,26 @@ class XcodeProjectBuildContext {
402407
other.configuration == configuration &&
403408
other.deviceId == deviceId &&
404409
other.environmentType == environmentType &&
405-
other.isWatch == isWatch;
410+
other.isWatch == isWatch &&
411+
other.target == target;
406412
}
407413
}
408414

415+
/// The settings that are relevant for setting up universal links
416+
@immutable
417+
class XcodeUniversalLinkSettings {
418+
const XcodeUniversalLinkSettings({
419+
this.bundleIdentifier,
420+
this.teamIdentifier,
421+
this.associatedDomains = const <String>[],
422+
});
423+
424+
final String? bundleIdentifier;
425+
final String? teamIdentifier;
426+
final List<String> associatedDomains;
427+
}
428+
429+
409430
/// Information about an Xcode project.
410431
///
411432
/// Represents the output of `xcodebuild -list`.

packages/flutter_tools/lib/src/macos/migrations/flutter_application_migration.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class FlutterApplicationMigration extends ProjectMigrator {
2727
void migrate() {
2828
if (_infoPlistFile.existsSync()) {
2929
final String? principalClass =
30-
globals.plistParser.getStringValueFromFile(_infoPlistFile.path, PlistParser.kNSPrincipalClassKey);
30+
globals.plistParser.getValueFromFile<String>(_infoPlistFile.path, PlistParser.kNSPrincipalClassKey);
3131
if (principalClass == null || principalClass == 'NSApplication') {
3232
// No NSPrincipalClass defined, or already converted. No migration
3333
// needed.

packages/flutter_tools/lib/src/vmservice.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const String kFlutterMemoryInfoServiceName = 'flutterMemoryInfo';
4141
const String kFlutterGetSkSLServiceName = 'flutterGetSkSL';
4242
const String kFlutterGetIOSBuildOptionsServiceName = 'flutterGetIOSBuildOptions';
4343
const String kFlutterGetAndroidBuildVariantsServiceName = 'flutterGetAndroidBuildVariants';
44+
const String kFlutterGetIOSDeeplinkSettingsServiceName = 'flutterGetIOSDeeplinkSettings';
4445

4546
/// The error response code from an unrecoverable compilation failure.
4647
const int kIsolateReloadBarred = 1005;
@@ -337,6 +338,25 @@ Future<vm_service.VmService> setUpVmService({
337338
registrationRequests.add(
338339
vmService.registerService(kFlutterGetAndroidBuildVariantsServiceName, kFlutterToolAlias),
339340
);
341+
342+
vmService.registerServiceCallback(kFlutterGetIOSDeeplinkSettingsServiceName, (Map<String, Object?> params) async {
343+
final XcodeUniversalLinkSettings settings = await flutterProject.ios.universalLinkSettings(
344+
configuration: params['configuration']! as String,
345+
scheme: params['scheme']! as String,
346+
target: params['target']! as String,
347+
);
348+
return <String, Object>{
349+
'result': <String, Object>{
350+
kResultType: kResultTypeSuccess,
351+
'bundleIdentifier': settings.bundleIdentifier ?? '',
352+
'teamIdentifier': settings.teamIdentifier ?? '',
353+
'associatedDomains': settings.associatedDomains,
354+
},
355+
};
356+
});
357+
registrationRequests.add(
358+
vmService.registerService(kFlutterGetIOSDeeplinkSettingsServiceName, 'Flutter Tools'),
359+
);
340360
}
341361

342362
if (printStructuredErrorLogMethod != null) {

0 commit comments

Comments
 (0)