@@ -56,8 +56,6 @@ Future<void> testWithNewIOSSimulator(
56
56
SimulatorFunction testFunction, {
57
57
String deviceTypeId = 'com.apple.CoreSimulator.SimDeviceType.iPhone-11' ,
58
58
}) async {
59
- // Xcode 11.4 simctl create makes the runtime argument optional, and defaults to latest.
60
- // TODO(jmagman): Remove runtime parsing when devicelab upgrades to Xcode 11.4 https://github.com/flutter/flutter/issues/54889
61
59
final String availableRuntimes = await eval (
62
60
'xcrun' ,
63
61
< String > [
@@ -68,11 +66,48 @@ Future<void> testWithNewIOSSimulator(
68
66
workingDirectory: flutterDirectory.path,
69
67
);
70
68
69
+ final String runtimesForSelectedXcode = await eval (
70
+ 'xcrun' ,
71
+ < String > [
72
+ 'simctl' ,
73
+ 'runtime' ,
74
+ 'match' ,
75
+ 'list' ,
76
+ '--json' ,
77
+ ],
78
+ workingDirectory: flutterDirectory.path,
79
+ );
80
+
81
+ // Get the preferred runtime build for the selected Xcode version. Preferred
82
+ // means the runtime was either bundled with Xcode, exactly matched your SDK
83
+ // version, or it's indicated a better match for your SDK.
84
+ final Map <String , Object ?> decodeResult = json.decode (runtimesForSelectedXcode) as Map <String , Object ?>;
85
+ final String ? iosKey = decodeResult.keys
86
+ .where ((String key) => key.contains ('iphoneos' ))
87
+ .firstOrNull;
88
+ final Object ? iosDetails = decodeResult[iosKey];
89
+ String ? runtimeBuildForSelectedXcode;
90
+ if (iosDetails != null && iosDetails is Map <String , Object ?>) {
91
+ final Object ? preferredBuild = iosDetails['preferredBuild' ];
92
+ if (preferredBuild is String ) {
93
+ runtimeBuildForSelectedXcode = preferredBuild;
94
+ }
95
+ }
96
+
71
97
String ? iOSSimRuntime;
72
98
73
99
final RegExp iOSRuntimePattern = RegExp (r'iOS .*\) - (.*)' );
74
100
101
+ // [availableRuntimes] may include runtime versions greater than the selected
102
+ // Xcode's greatest supported version. Use [runtimeBuildForSelectedXcode] when
103
+ // possible to pick which runtime to use.
104
+ // For example, iOS 17 (released with Xcode 15) may be available even if the
105
+ // selected Xcode version is 14.
75
106
for (final String runtime in LineSplitter .split (availableRuntimes)) {
107
+ if (runtimeBuildForSelectedXcode != null &&
108
+ ! runtime.contains (runtimeBuildForSelectedXcode)) {
109
+ continue ;
110
+ }
76
111
// These seem to be in order, so allow matching multiple lines so it grabs
77
112
// the last (hopefully latest) one.
78
113
final RegExpMatch ? iOSRuntimeMatch = iOSRuntimePattern.firstMatch (runtime);
@@ -82,7 +117,11 @@ Future<void> testWithNewIOSSimulator(
82
117
}
83
118
}
84
119
if (iOSSimRuntime == null ) {
85
- throw 'No iOS simulator runtime found. Available runtimes:\n $availableRuntimes ' ;
120
+ if (runtimeBuildForSelectedXcode != null ) {
121
+ throw 'iOS simulator runtime $runtimeBuildForSelectedXcode not found. Available runtimes:\n $availableRuntimes ' ;
122
+ } else {
123
+ throw 'No iOS simulator runtime found. Available runtimes:\n $availableRuntimes ' ;
124
+ }
86
125
}
87
126
88
127
final String deviceId = await eval (
0 commit comments