Skip to content

Commit 780aef4

Browse files
author
Stewart Miles
committed
Fixed iOS target SDK version check.
Fixed the iOS target SDK version check for Cocoapods to validate the target SDK is greater than or equal to the maximum required SDK for all Cocoapods included in a project. This also, modifies the iOS resolver to load the pod configuration when the plugin starts up, if dependency configuration files change and adds validation to the iOS SDK build setting. Bug: 134614506 Change-Id: Ia43d62a7e2c073b91040840e3b6bf08f59d60163
1 parent ce2adb2 commit 780aef4

File tree

3 files changed

+110
-58
lines changed

3 files changed

+110
-58
lines changed

source/IOSResolver/src/IOSResolver.cs

Lines changed: 93 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,12 @@ protected override bool Read(string filename, Logger logger) {
538538
// Project level settings for this module.
539539
private static ProjectSettings settings = new ProjectSettings(PREFERENCE_NAMESPACE);
540540

541+
/// <summary>
542+
/// Polls for changes to TargetSdk.
543+
/// </summary>
544+
private static PlayServicesResolver.PropertyPoller<string> targetSdkPoller =
545+
new PlayServicesResolver.PropertyPoller<string>("iOS Target SDK");
546+
541547
// Search for a file up to a maximum search depth stopping the
542548
// depth first search each time the specified file is found.
543549
private static List<string> FindFile(
@@ -676,7 +682,12 @@ exception is TypeInitializationException ||
676682
!ExecutionEnvironment.InBatchMode) {
677683
RunOnMainThread.Run(() => { AutoInstallCocoapods(); }, runNow: false);
678684
}
679-
685+
// Install / remove target SDK property poller.
686+
SetEnablePollTargetSdk(PodfileGenerationEnabled);
687+
// Load XML dependencies on the next editor update.
688+
if (PodfileGenerationEnabled) {
689+
RunOnMainThread.Run(RefreshXmlDependencies, runNow: false);
690+
}
680691

681692
// Prompt the user to use workspaces if they aren't at least using project level
682693
// integration.
@@ -826,7 +837,21 @@ private static bool LegacyCocoapodsInstallEnabled {
826837
public static bool PodfileGenerationEnabled {
827838
get { return settings.GetBool(PREFERENCE_PODFILE_GENERATION_ENABLED,
828839
defaultValue: true); }
829-
set { settings.SetBool(PREFERENCE_PODFILE_GENERATION_ENABLED, value); }
840+
set {
841+
settings.SetBool(PREFERENCE_PODFILE_GENERATION_ENABLED, value);
842+
SetEnablePollTargetSdk(value);
843+
}
844+
}
845+
846+
/// <summary>
847+
/// Enable / disable target SDK polling.
848+
/// </summary>
849+
private static void SetEnablePollTargetSdk(bool enable) {
850+
if (enable && EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS) {
851+
RunOnMainThread.OnUpdate += PollTargetSdk;
852+
} else {
853+
RunOnMainThread.OnUpdate -= PollTargetSdk;
854+
}
830855
}
831856

832857
/// <summary>
@@ -1104,41 +1129,38 @@ private static void AddPodInternal(string podName,
11041129
return;
11051130
}
11061131
pods[podName] = pod;
1132+
ScheduleCheckTargetSdk();
1133+
}
11071134

1108-
UpdateTargetSdk(pod);
1135+
/// <summary>
1136+
/// Determine whether the target SDK has changed.
1137+
/// </summary>
1138+
private static void PollTargetSdk() {
1139+
targetSdkPoller.Poll(() => TargetSdk,
1140+
(previousValue, currentValue) => { ScheduleCheckTargetSdk(); });
11091141
}
11101142

1143+
// ID of the job which checks that the target SDK is correct for the currently selected set of
1144+
// Cocoapods.
1145+
private static int checkTargetSdkJobId = 0;
1146+
11111147
/// <summary>
1112-
/// Update the iOS target SDK if it's lower than the minimum SDK
1113-
/// version specified by the pod.
1148+
/// Schedule a check to ensure target SDK is configured correctly given the set of selected
1149+
/// Cocoapods.
11141150
/// </summary>
1115-
/// <param name="pod">Pod to query for the minimum supported version.
1116-
/// </param>
1117-
/// <param name="notifyUser">Whether to write to the log to notify the
1118-
/// user of a build setting change.</param>
1119-
/// <returns>true if the SDK version was changed, false
1120-
/// otherwise.</returns>
1121-
private static bool UpdateTargetSdk(Pod pod,
1122-
bool notifyUser = true) {
1123-
int currentVersion = TargetSdkVersion;
1124-
int minVersion = pod.MinTargetSdkToVersion();
1125-
if (currentVersion >= minVersion) {
1126-
return false;
1127-
}
1128-
if (notifyUser) {
1129-
string oldSdk = TargetSdk;
1130-
TargetSdkVersion = minVersion;
1131-
Log("iOS Target SDK changed from " + oldSdk + " to " +
1132-
TargetSdk + " required by the " + pod.name + " pod");
1133-
}
1134-
return true;
1151+
private static void ScheduleCheckTargetSdk() {
1152+
RunOnMainThread.Cancel(checkTargetSdkJobId);
1153+
checkTargetSdkJobId = RunOnMainThread.Schedule(() => {
1154+
UpdateTargetSdk(false);
1155+
}, 500.0 /* delay in milliseconds before running the check */);
11351156
}
11361157

11371158
/// <summary>
11381159
/// Update the target SDK if it's required.
11391160
/// </summary>
1161+
/// <param name="runningBuild">Whether the build is being processed.</param>
11401162
/// <returns>true if the SDK was updated, false otherwise.</returns>
1141-
public static bool UpdateTargetSdk() {
1163+
public static bool UpdateTargetSdk(bool runningBuild) {
11421164
var minVersionAndPodNames = TargetSdkNeedsUpdate();
11431165
if (minVersionAndPodNames.Value != null) {
11441166
var minVersionString =
@@ -1157,12 +1179,14 @@ public static bool UpdateTargetSdk() {
11571179
"Yes", cancel: "No");
11581180
if (update) {
11591181
TargetSdkVersion = minVersionAndPodNames.Key;
1160-
string errorString = (
1161-
"Target SDK has been updated from " + TargetSdk +
1162-
" to " + minVersionString + ". You must restart the " +
1163-
"build for this change to take effect.");
1164-
EditorUtility.DisplayDialog(
1165-
"Target SDK updated.", errorString, "OK");
1182+
if (runningBuild) {
1183+
string errorString = (
1184+
"Target SDK has been updated from " + TargetSdk +
1185+
" to " + minVersionString + ". You must restart the " +
1186+
"build for this change to take effect.");
1187+
EditorUtility.DisplayDialog(
1188+
"Target SDK updated.", errorString, "OK");
1189+
}
11661190
return true;
11671191
}
11681192
}
@@ -1173,26 +1197,24 @@ public static bool UpdateTargetSdk() {
11731197
/// Determine whether the target SDK needs to be updated based upon pod
11741198
/// dependencies.
11751199
/// </summary>
1176-
/// <returns>Key value pair of minimum SDK version (key) and
1200+
/// <returns>Key value pair of maximum of the minimum SDK versions (key) and
11771201
/// a list of pod names that require it (value) if the currently
11781202
/// selected target SDK version does not satisfy pod requirements, the list
11791203
/// (value) is null otherwise.</returns>
11801204
private static KeyValuePair<int, List<string>> TargetSdkNeedsUpdate() {
1181-
var kvpair = new KeyValuePair<int, List<string>>(0, null);
1182-
var podListsByVersion = Pod.BucketByMinSdkVersion(pods.Values);
1183-
if (podListsByVersion.Count == 0) {
1184-
return kvpair;
1185-
}
1186-
KeyValuePair<int, List<string>> minVersionAndPodName = kvpair;
1187-
foreach (var versionAndPodList in podListsByVersion) {
1188-
minVersionAndPodName = versionAndPodList;
1189-
break;
1190-
}
1191-
int currentVersion = TargetSdkVersion;
1192-
if (currentVersion >= minVersionAndPodName.Key) {
1193-
return kvpair;
1205+
var emptyVersionAndPodNames = new KeyValuePair<int, List<string>>(0, null);
1206+
var minVersionAndPodNames = emptyVersionAndPodNames;
1207+
int maxOfMinRequiredVersions = 0;
1208+
foreach (var versionAndPodList in Pod.BucketByMinSdkVersion(pods.Values)) {
1209+
if (versionAndPodList.Key > maxOfMinRequiredVersions) {
1210+
maxOfMinRequiredVersions = versionAndPodList.Key;
1211+
minVersionAndPodNames = versionAndPodList;
1212+
}
11941213
}
1195-
return minVersionAndPodName;
1214+
// If the target SDK version exceeds the minimum required version return an empty tuple
1215+
// otherwise return the minimum required SDK version and the set of pods that need it.
1216+
return TargetSdkVersion >= maxOfMinRequiredVersions ? emptyVersionAndPodNames :
1217+
minVersionAndPodNames;
11961218
}
11971219

11981220
// Get the path of an xcode project relative to the specified directory.
@@ -1527,6 +1549,29 @@ public static void InstallCocoapods(bool interactive, string workingDirectory,
15271549
if (!interactive) complete.WaitOne();
15281550
}
15291551

1552+
/// <summary>
1553+
/// Called by Unity when all assets have been updated. This refreshes the Pods loaded from
1554+
/// XML files.
1555+
/// </summary>
1556+
/// <param name="importedAssets">Imported assets. (unused)</param>
1557+
/// <param name="deletedAssets">Deleted assets. (unused)</param>
1558+
/// <param name="movedAssets">Moved assets. (unused)</param>
1559+
/// <param name="movedFromAssetPaths">Moved from asset paths. (unused)</param>
1560+
private static void OnPostprocessAllAssets(string[] importedAssets,
1561+
string[] deletedAssets,
1562+
string[] movedAssets,
1563+
string[] movedFromAssetPaths) {
1564+
if (!CocoapodsIntegrationEnabled) return;
1565+
bool dependencyFileChanged = false;
1566+
var changedAssets = new List<string>(importedAssets);
1567+
changedAssets.AddRange(deletedAssets);
1568+
foreach (var asset in changedAssets) {
1569+
dependencyFileChanged = xmlDependencies.IsDependenciesFile(asset);
1570+
if (dependencyFileChanged) break;
1571+
}
1572+
if (dependencyFileChanged) RefreshXmlDependencies();
1573+
}
1574+
15301575
/// <summary>
15311576
/// Refresh XML dependencies if the plugin is enabled.
15321577
/// </summary>
@@ -2150,7 +2195,7 @@ private static CommandLine.Result RunPodCommand(
21502195
public static void OnPostProcessInstallPods(BuildTarget buildTarget,
21512196
string pathToBuiltProject) {
21522197
if (!InjectDependencies() || !PodfileGenerationEnabled) return;
2153-
if (UpdateTargetSdk()) return;
2198+
if (UpdateTargetSdk(true)) return;
21542199
if (!CocoapodsIntegrationEnabled || !cocoapodsToolsInstallPresent) {
21552200
Log(String.Format(
21562201
"Cocoapod installation is disabled.\n" +

source/PlayServicesResolver/src/PlayServicesResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public override string ToString() {
285285
/// Polls a value and signals a callback with the change after the specified delay
286286
/// time.
287287
/// </summary>
288-
private class PropertyPoller<T> {
288+
internal class PropertyPoller<T> {
289289
/// <summary>
290290
/// Delegate that is called when a value changes.
291291
/// </summary>

source/PlayServicesResolver/src/XmlDependencies.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,29 @@ internal class XmlDependencies {
4141
/// </summary>
4242
protected string dependencyType = "dependencies";
4343

44+
/// <summary>
45+
/// Determines whether a filename matches an XML dependencies file.
46+
/// </summary>
47+
/// <param name="filename"></param>
48+
/// <returns>true if it is a match, false otherwise.</returns>
49+
internal bool IsDependenciesFile(string filename) {
50+
foreach (var regex in fileRegularExpressions) {
51+
if (regex.Match(filename).Success) {
52+
return true;
53+
}
54+
}
55+
return false;
56+
}
57+
4458
/// <summary>
4559
/// Find all XML declared dependency files.
4660
/// </summary>
4761
/// <returns>List of XML dependency filenames in the project.</returns>
4862
private List<string> FindFiles() {
4963
return new List<string>(
5064
VersionHandlerImpl.SearchAssetDatabase(
51-
"Dependencies t:TextAsset",
52-
(string filename) => {
53-
foreach (var regex in fileRegularExpressions) {
54-
if (regex.Match(filename).Success) {
55-
return true;
56-
}
57-
}
58-
return false;
59-
}, new [] { "Assets", "Packages"}));
65+
"Dependencies t:TextAsset", IsDependenciesFile,
66+
new [] { "Assets", "Packages"}));
6067
}
6168

6269
/// <summary>

0 commit comments

Comments
 (0)