Skip to content

Commit 9094725

Browse files
committed
Add Swift Package Manager support
1 parent 6eee661 commit 9094725

File tree

4 files changed

+345
-4
lines changed

4 files changed

+345
-4
lines changed

source/IOSResolver/IOSResolver.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<ItemGroup>
6969
<Compile Include="src\IOSResolver.cs" />
7070
<Compile Include="src\IOSResolverSettingsDialog.cs" />
71+
<Compile Include="src\SwiftPackageManager.cs" />
7172
<Compile Include="src\VersionNumber.cs" />
7273
<Compile Include="Properties\AssemblyInfo.cs" />
7374
</ItemGroup>

source/IOSResolver/src/IOSResolver.cs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ protected override bool Read(string filename, Logger logger) {
405405
private static SortedDictionary<string, Pod> pods =
406406
new SortedDictionary<string, Pod>();
407407

408+
// List of pods to ignore because they are replaced by Swift packages.
409+
private static HashSet<string> podsToIgnore = new HashSet<string>();
410+
408411
// Order of post processing operations.
409412
private const int BUILD_ORDER_REFRESH_DEPENDENCIES = 10;
410413
private const int BUILD_ORDER_CHECK_COCOAPODS_INSTALL = 20;
@@ -510,6 +513,10 @@ protected override bool Read(string filename, Logger logger) {
510513
private const string PREFERENCE_PODFILE_ALLOW_PODS_IN_MULTIPLE_TARGETS =
511514
PREFERENCE_NAMESPACE + "PodfileAllowPodsInMultipleTargets";
512515

516+
// Whether to use Swift Package Manager for dependency resolution.
517+
private const string PREFERENCE_SWIFT_PACKAGE_MANAGER_ENABLED =
518+
PREFERENCE_NAMESPACE + "SwiftPackageManagerEnabled";
519+
513520
// List of preference keys, used to restore default settings.
514521
private static string[] PREFERENCE_KEYS = new [] {
515522
PREFERENCE_COCOAPODS_INSTALL_ENABLED,
@@ -525,7 +532,8 @@ protected override bool Read(string filename, Logger logger) {
525532
PREFERENCE_SWIFT_FRAMEWORK_SUPPORT_WORKAROUND,
526533
PREFERENCE_SWIFT_LANGUAGE_VERSION,
527534
PREFERENCE_PODFILE_ALWAYS_ADD_MAIN_TARGET,
528-
PREFERENCE_PODFILE_ALLOW_PODS_IN_MULTIPLE_TARGETS
535+
PREFERENCE_PODFILE_ALLOW_PODS_IN_MULTIPLE_TARGETS,
536+
PREFERENCE_SWIFT_PACKAGE_MANAGER_ENABLED
529537
};
530538

531539
// Whether the xcode extension was successfully loaded.
@@ -605,6 +613,9 @@ protected override bool Read(string filename, Logger logger) {
605613
// Parses dependencies from XML dependency files.
606614
private static IOSXmlDependencies xmlDependencies = new IOSXmlDependencies();
607615

616+
// Parses SPM dependencies from XML dependency files.
617+
private static SwiftPackageManager spmDependencies = new SwiftPackageManager();
618+
608619
// Project level settings for this module.
609620
private static ProjectSettings settings = new ProjectSettings(PREFERENCE_NAMESPACE);
610621

@@ -1158,6 +1169,19 @@ public static bool PodfileAllowPodsInMultipleTargets {
11581169
}
11591170
}
11601171

1172+
/// <summary>
1173+
/// Whether to use Swift Package Manager for dependency resolution.
1174+
/// If enabled, the resolver will attempt to use SPM for packages that define SPM support,
1175+
/// falling back to Cocoapods if disabled or if the package does not support SPM.
1176+
/// </summary>
1177+
public static bool SwiftPackageManagerEnabled {
1178+
get { return settings.GetBool(PREFERENCE_SWIFT_PACKAGE_MANAGER_ENABLED,
1179+
defaultValue: true); }
1180+
set {
1181+
settings.SetBool(PREFERENCE_SWIFT_PACKAGE_MANAGER_ENABLED, value);
1182+
}
1183+
}
1184+
11611185

11621186
/// <summary>
11631187
/// Whether to use project level settings.
@@ -2148,14 +2172,25 @@ internal static void AddDummySwiftFile(
21482172
File.WriteAllText(pbxprojPath, project.WriteToString());
21492173
}
21502174

2175+
[PostProcessBuildAttribute(35)]
2176+
public static void OnPostProcessResolveSwiftPackages(BuildTarget buildTarget,
2177+
string pathToBuiltProject) {
2178+
if (!SwiftPackageManagerEnabled) {
2179+
return;
2180+
}
2181+
var resolvedPackages = SwiftPackageManager.Resolve(spmDependencies.SwiftPackages, logger);
2182+
SwiftPackageManager.AddPackagesToProject(resolvedPackages, pathToBuiltProject, logger);
2183+
podsToIgnore = SwiftPackageManager.GetReplacedPods(resolvedPackages);
2184+
}
2185+
21512186
/// <summary>
21522187
/// Post-processing build step to generate the podfile for ios.
21532188
/// </summary>
21542189
[PostProcessBuildAttribute(BUILD_ORDER_GEN_PODFILE)]
21552190
public static void OnPostProcessGenPodfile(BuildTarget buildTarget,
21562191
string pathToBuiltProject) {
21572192
if (!InjectDependencies() || !PodfileGenerationEnabled) return;
2158-
GenPodfile(buildTarget, pathToBuiltProject);
2193+
GenPodfile(buildTarget, pathToBuiltProject, podsToIgnore);
21592194
}
21602195

21612196
/// <summary>
@@ -2299,7 +2334,8 @@ private static string GeneratePodfileSourcesSection() {
22992334
// Mono runtime from loading the Xcode API before calling the post
23002335
// processing step.
23012336
public static void GenPodfile(BuildTarget buildTarget,
2302-
string pathToBuiltProject) {
2337+
string pathToBuiltProject,
2338+
HashSet<string> podsToIgnore = null) {
23032339
analytics.Report("generatepodfile", "Generate Podfile");
23042340
string podfilePath = GetPodfilePath(pathToBuiltProject);
23052341

@@ -2341,6 +2377,10 @@ public static void GenPodfile(BuildTarget buildTarget,
23412377
foreach (var target in XcodeTargetNames) {
23422378
file.WriteLine(String.Format("target '{0}' do", target));
23432379
foreach(var pod in pods.Values) {
2380+
if (podsToIgnore != null && podsToIgnore.Contains(pod.name)) {
2381+
Log(String.Format("Skipping pod {0} because it is replaced by a Swift Package.", pod.name), verbose: true);
2382+
continue;
2383+
}
23442384
file.WriteLine(String.Format(" {0}", pod.PodFilePodLine));
23452385
}
23462386
file.WriteLine("end");
@@ -2351,6 +2391,9 @@ public static void GenPodfile(BuildTarget buildTarget,
23512391
bool allowPodsInMultipleTargets = PodfileAllowPodsInMultipleTargets;
23522392
int podAdded = 0;
23532393
foreach(var pod in pods.Values) {
2394+
if (podsToIgnore != null && podsToIgnore.Contains(pod.name)) {
2395+
continue;
2396+
}
23542397
if (pod.addToAllTargets) {
23552398
file.WriteLine(String.Format(" {0}{1}",
23562399
allowPodsInMultipleTargets ? "" : "# ",
@@ -2908,10 +2951,14 @@ private static void RefreshXmlDependencies() {
29082951
foreach (var podName in podsToRemove) {
29092952
pods.Remove(podName);
29102953
}
2954+
spmDependencies.SwiftPackages.Clear();
2955+
podsToIgnore.Clear();
2956+
29112957
// Clear all sources (only can be set via XML config).
29122958
Pod.Sources = new List<KeyValuePair<string, string>>();
2913-
// Read pod specifications from XML dependencies.
2959+
// Read pod and spm specifications from XML dependencies.
29142960
xmlDependencies.ReadAll(logger);
2961+
spmDependencies.ReadAll(logger);
29152962
}
29162963
}
29172964

source/IOSResolver/src/IOSResolverSettingsDialog.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ private class Settings {
4343
internal string swiftLanguageVersion;
4444
internal bool podfileAlwaysAddMainTarget;
4545
internal bool podfileAllowPodsInMultipleTargets;
46+
internal bool swiftPackageManagerEnabled;
4647
internal bool useProjectSettings;
4748
internal EditorMeasurement.Settings analyticsSettings;
4849

@@ -64,6 +65,7 @@ internal Settings() {
6465
swiftLanguageVersion = IOSResolver.SwiftLanguageVersion;
6566
podfileAlwaysAddMainTarget = IOSResolver.PodfileAlwaysAddMainTarget;
6667
podfileAllowPodsInMultipleTargets = IOSResolver.PodfileAllowPodsInMultipleTargets;
68+
swiftPackageManagerEnabled = IOSResolver.SwiftPackageManagerEnabled;
6769
useProjectSettings = IOSResolver.UseProjectSettings;
6870
analyticsSettings = new EditorMeasurement.Settings(IOSResolver.analytics);
6971
}
@@ -86,6 +88,7 @@ internal void Save() {
8688
IOSResolver.SwiftLanguageVersion = swiftLanguageVersion;
8789
IOSResolver.PodfileAlwaysAddMainTarget = podfileAlwaysAddMainTarget;
8890
IOSResolver.PodfileAllowPodsInMultipleTargets = podfileAllowPodsInMultipleTargets;
91+
IOSResolver.SwiftPackageManagerEnabled = swiftPackageManagerEnabled;
8992
IOSResolver.UseProjectSettings = useProjectSettings;
9093
analyticsSettings.Save();
9194
}
@@ -149,6 +152,18 @@ public void OnGUI() {
149152

150153
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
151154

155+
GUILayout.BeginHorizontal();
156+
GUILayout.Label("Swift Package Manager Integration", EditorStyles.boldLabel);
157+
settings.swiftPackageManagerEnabled =
158+
EditorGUILayout.Toggle(settings.swiftPackageManagerEnabled);
159+
GUILayout.EndHorizontal();
160+
GUILayout.Label("Use Swift Package Manager to resolve dependencies that support it. " +
161+
"If this is enabled, the resolver will prioritize SPM packages and " +
162+
"fall back to Cocoapods for any dependencies that do not have an " +
163+
"SPM equivalent specified.");
164+
165+
GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
166+
152167
GUILayout.BeginHorizontal();
153168
GUILayout.Label("Podfile Generation", EditorStyles.boldLabel);
154169
settings.podfileGenerationEnabled =

0 commit comments

Comments
 (0)