Skip to content

Commit 51a6790

Browse files
author
Stewart Miles
committed
Fixed VersionHandler and IOSResolver compatibility with Unity 4.
Unity 4 doesn't have the UnityEngine.PluginImporter class and stores the Xcode DLL in a yet another location. Since the PluginImporter is not available in Unity 4, VersionHandler targetting is disabled as it's not possible - without hacking .meta files - to enable / disable targeting for plugins (DLLs). As the Mono distribution is slightly different, the IOSResolver has been modified to only call methods that use the Xcode plugin in separate methods after the workaround for loading the plugin has been installed. In addition, since the Xcode DLL seemingly moves with each Unity OSX release, a brute force file search is now used to search for the Xcode DLL if it isn't in the default location. BUG=31336359 Change-Id: Ia45055abd460b10a018f3a1623833a558283e646
1 parent 352175b commit 51a6790

File tree

7 files changed

+97
-51
lines changed

7 files changed

+97
-51
lines changed
Binary file not shown.

exploded/Assets/PlayServicesResolver/Editor/Google.IOSResolver_v1.2.1.0.dll.meta

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Binary file not shown.

exploded/Assets/PlayServicesResolver/Editor/Google.VersionHandler_v1.2.1.0.dll.meta

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
328 Bytes
Binary file not shown.

source/IOSResolver/src/IOSResolver.cs

Lines changed: 72 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
using System.Collections.Generic;
2323
using System.IO;
2424
using System.Reflection;
25-
using UnityEditor.iOS.Xcode;
2625
using UnityEditor;
2726
using UnityEditor.Callbacks;
2827
using UnityEngine;
@@ -186,27 +185,27 @@ public static SortedDictionary<int, List<string>>
186185
private static string IOS_PLAYBACK_ENGINES_PATH =
187186
Path.Combine("PlaybackEngines", "iOSSupport");
188187

189-
// Search for a directory up to a maximum search depth stopping the
190-
// depth first search each time the specified directory is found.
191-
private static List<string> FindDirectory(
192-
string searchPath, string directoryToFind, int maxDepth,
188+
// Search for a file up to a maximum search depth stopping the
189+
// depth first search each time the specified file is found.
190+
private static List<string> FindFile(
191+
string searchPath, string fileToFind, int maxDepth,
193192
int currentDepth = 0) {
194-
if (Path.GetFileName(searchPath) == directoryToFind) {
193+
if (Path.GetFileName(searchPath) == fileToFind) {
195194
return new List<string> { searchPath };
196195
} else if (maxDepth == currentDepth) {
197196
return new List<string>();
198197
}
199-
var foundDirs = new List<string>();
200-
foreach (var dir in Directory.GetDirectories(searchPath)) {
201-
if (Path.GetFileName(dir) == directoryToFind) {
202-
foundDirs.Add(dir);
203-
} else {
204-
foundDirs.AddRange(FindDirectory(
205-
dir, directoryToFind, maxDepth,
206-
currentDepth: currentDepth + 1));
198+
var foundFiles = new List<string>();
199+
foreach (var file in Directory.GetFiles(searchPath)) {
200+
if (Path.GetFileName(file) == fileToFind) {
201+
foundFiles.Add(file);
207202
}
208203
}
209-
return foundDirs;
204+
foreach (var dir in Directory.GetDirectories(searchPath)) {
205+
foundFiles.AddRange(FindFile(dir, fileToFind, maxDepth,
206+
currentDepth: currentDepth + 1));
207+
}
208+
return foundFiles;
210209
}
211210

212211
// Try to load the Xcode editor extension.
@@ -218,47 +217,55 @@ private static Assembly ResolveUnityEditoriOSXcodeExtension(
218217
// Unity.iOS.Extensions.Xcode. Catch this and redirect the load to
219218
// the UnityEditor.iOS.Extensions.Xcode.
220219
string assemblyName = (new AssemblyName(args.Name)).Name;
221-
if (!assemblyName.Equals("Unity.iOS.Extensions.Xcode")) {
220+
if (!(assemblyName.Equals("Unity.iOS.Extensions.Xcode") ||
221+
assemblyName.Equals("UnityEditor.iOS.Extensions.Xcode"))) {
222222
return null;
223223
}
224+
Log("Trying to load assembly: " + assemblyName, verbose: true);
224225
iOSXcodeExtensionLoaded = false;
225226
string fixedAssemblyName =
226227
assemblyName.Replace("Unity.", "UnityEditor.") + ".dll";
228+
Log("Redirecting to assembly name: " + fixedAssemblyName,
229+
verbose: true);
227230

228-
// Find the playback engines folder.
231+
// Get the managed DLLs folder.
229232
string folderPath = Path.GetDirectoryName(
230233
Assembly.GetAssembly(
231234
typeof(UnityEditor.AssetPostprocessor)).Location);
232-
if (UnityEngine.RuntimePlatform.OSXEditor ==
233-
UnityEngine.Application.platform) {
234-
// Unity likes to move their DLLs around between releases to keep
235-
// us on our toes, so search for the PlaybackEngines folder under
236-
// the package path.
235+
// Try searching a common install location.
236+
folderPath = Path.Combine(
237+
(new DirectoryInfo(folderPath)).Parent.FullName,
238+
IOS_PLAYBACK_ENGINES_PATH);
239+
string assemblyPath = Path.Combine(folderPath, fixedAssemblyName);
240+
if (!File.Exists(assemblyPath)) {
237241
string searchPath = (new DirectoryInfo(folderPath)).FullName;
238-
searchPath = Path.GetDirectoryName(
239-
searchPath.Substring(0, searchPath.LastIndexOf(".app")));
240-
foreach (var directory in
241-
FindDirectory(
242-
searchPath,
243-
Path.GetFileName(IOS_PLAYBACK_ENGINES_PATH), 3)) {
244-
if (File.Exists(Path.Combine(directory, fixedAssemblyName))) {
245-
folderPath = directory;
246-
break;
247-
}
242+
if (UnityEngine.RuntimePlatform.OSXEditor ==
243+
UnityEngine.Application.platform) {
244+
// Unity likes to move their DLLs around between releases to
245+
// keep us on our toes, so search for the DLL under the
246+
// package path.
247+
searchPath = Path.GetDirectoryName(
248+
searchPath.Substring(0, searchPath.LastIndexOf(".app")));
249+
} else {
250+
// Search under the Data directory.
251+
searchPath = Path.GetDirectoryName(
252+
searchPath.Substring(
253+
0, searchPath.LastIndexOf(
254+
"Data" + Path.DirectorySeparatorChar.ToString())));
248255
}
249-
} else {
250-
folderPath = Path.Combine(
251-
(new DirectoryInfo(folderPath)).Parent.FullName,
252-
IOS_PLAYBACK_ENGINES_PATH);
256+
Log("Searching for assembly under " + searchPath, verbose: true);
257+
var files = FindFile(searchPath, fixedAssemblyName, 5);
258+
if (files.Count > 0) assemblyPath = files.ToArray()[0];
253259
}
254-
255260
// Try to load the assembly.
256-
string assemblyPath = Path.Combine(folderPath, fixedAssemblyName);
257261
if (!File.Exists(assemblyPath)) {
258-
return null;
262+
Log(assemblyPath + " does not exist", verbose: true);
263+
return null;
259264
}
265+
Log("Loading " + assemblyPath, verbose: true);
260266
Assembly assembly = Assembly.LoadFrom(assemblyPath);
261267
if (assembly != null) {
268+
Log("Load succeeded from " + assemblyPath, verbose: true);
262269
iOSXcodeExtensionLoaded = true;
263270
}
264271
return assembly;
@@ -268,10 +275,22 @@ private static Assembly ResolveUnityEditoriOSXcodeExtension(
268275
/// Initialize the module.
269276
/// </summary>
270277
static IOSResolver() {
278+
// NOTE: We can't reference the UnityEditor.iOS.Xcode module in this
279+
// method as the Mono runtime in Unity 4 and below requires all
280+
// dependencies of a method are loaded before the method is executed
281+
// so we install the DLL loader first then try using the Xcode module.
271282
RemapXcodeExtension();
283+
InitializeTargetName();
284+
}
285+
286+
/// <summary>
287+
/// Initialize the TARGET_NAME property.
288+
/// </summary>
289+
private static void InitializeTargetName() {
272290
try {
273-
TARGET_NAME = PBXProject.GetUnityTargetName();
291+
TARGET_NAME = UnityEditor.iOS.Xcode.PBXProject.GetUnityTargetName();
274292
} catch (Exception exception) {
293+
Debug.Log("Failed: " + exception.ToString());
275294
if (exception is FileNotFoundException ||
276295
exception is TypeInitializationException ||
277296
exception is TargetInvocationException) {
@@ -561,10 +580,9 @@ public static void OnPostProcessPatchProject(BuildTarget buildTarget,
561580
String.Join(", ", podsWithoutBitcode.ToArray()) + ")",
562581
level: LogLevel.Warning);
563582
}
564-
565583
// Configure project settings for Cocoapods.
566584
string pbxprojPath = GetProjectPath(pathToBuiltProject);
567-
PBXProject project = new PBXProject();
585+
var project = new UnityEditor.iOS.Xcode.PBXProject();
568586
project.ReadFromString(File.ReadAllText(pbxprojPath));
569587
string target = project.TargetGuidByName(TARGET_NAME);
570588
project.SetBuildProperty(target, "CLANG_ENABLE_MODULES", "YES");
@@ -680,7 +698,7 @@ public static void OnPostProcessUpdateProjectDeps(
680698
"Resources"));
681699

682700
string pbxprojPath = GetProjectPath(pathToBuiltProject);
683-
PBXProject project = new PBXProject();
701+
var project = new UnityEditor.iOS.Xcode.PBXProject();
684702
project.ReadFromString(File.ReadAllText(pbxprojPath));
685703
string target = project.TargetGuidByName(TARGET_NAME);
686704

@@ -707,10 +725,11 @@ public static void OnPostProcessUpdateProjectDeps(
707725
PlayServicesSupport.DeleteExistingFileOrDirectory(
708726
destFrameworkFullPath);
709727
Directory.Move(frameworkFullPath, destFrameworkFullPath);
710-
project.AddFileToBuild(target,
711-
project.AddFile(destFrameworkPath,
712-
destFrameworkPath,
713-
PBXSourceTree.Source));
728+
project.AddFileToBuild(
729+
target,
730+
project.AddFile(destFrameworkPath,
731+
destFrameworkPath,
732+
UnityEditor.iOS.Xcode.PBXSourceTree.Source));
714733

715734
string moduleMapPath =
716735
Path.Combine(Path.Combine(destFrameworkFullPath, "Modules"),
@@ -752,8 +771,9 @@ public static void OnPostProcessUpdateProjectDeps(
752771
File.Copy(resFile, Path.Combine(pathToBuiltProject,
753772
destFile), true);
754773
project.AddFileToBuild(
755-
target, project.AddFile(destFile, destFile,
756-
PBXSourceTree.Source));
774+
target, project.AddFile(
775+
destFile, destFile,
776+
UnityEditor.iOS.Xcode.PBXSourceTree.Source));
757777
}
758778
foreach (var resFolder in resFolders) {
759779
string destFolder =
@@ -765,8 +785,9 @@ public static void OnPostProcessUpdateProjectDeps(
765785
destFolderFullPath);
766786
Directory.Move(resFolder, destFolderFullPath);
767787
project.AddFileToBuild(
768-
target, project.AddFile(destFolder, destFolder,
769-
PBXSourceTree.Source));
788+
target, project.AddFile(
789+
destFolder, destFolder,
790+
UnityEditor.iOS.Xcode.PBXSourceTree.Source));
770791
}
771792
}
772793
}

source/VersionHandler/src/VersionHandler.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,18 @@ public FileMetadata this[long version] {
437437
}
438438
}
439439

440+
/// <summary>
441+
/// Determine whether the PluginImporter class is available in
442+
/// UnityEditor. Unity 4 does not have this class in which case we
443+
/// can't - without potentially dangerously - modify the .meta yaml
444+
/// files to enable / disable plugin targeting.
445+
/// </summary>
446+
internal static bool PluginImporterAvailable {
447+
get {
448+
return FindClass("UnityEditor", "UnityEditor.PluginImporter") != null;
449+
}
450+
}
451+
440452
/// <summary>
441453
/// Construct an instance.
442454
/// </summary>
@@ -635,6 +647,11 @@ public void Add(FileMetadata metadata) {
635647
/// AssetDatabase.Refresh(), false otherwise.</return>
636648
public bool EnableMostRecentPlugins() {
637649
bool modified = false;
650+
651+
// If PluginImporter isn't available it's not possible
652+
// to enable / disable targeting.
653+
if (!FileMetadataByVersion.PluginImporterAvailable) return false;
654+
638655
foreach (var metadataByVersion in
639656
metadataByCanonicalFilename.Values) {
640657
modified |= metadataByVersion.EnableMostRecentPlugins();

0 commit comments

Comments
 (0)