diff --git a/.github/workflows/native-sdk-bump.yml b/.github/workflows/native-sdk-bump.yml index 4677b57..2021812 100644 --- a/.github/workflows/native-sdk-bump.yml +++ b/.github/workflows/native-sdk-bump.yml @@ -12,9 +12,10 @@ # implements the Unity side and pushes it onto the same PR. # # Android is pinned exactly in Plugins/Android/.../build.gradle. iOS is pinned -# in two places that this workflow keeps identical: the Podfile lines written -# by Editor/SuperwallPostBuildProcessor.cs, and the SPM requirement in -# ci~/ios-harness/Package.swift. A floating requirement (`~> 4.0`, `from:`) is +# in two places that this workflow keeps identical: SuperwallKitMinimumVersion +# in Editor/SuperwallPostBuildProcessor.cs (the Swift package requirement added +# to the exported Xcode project, up to the next major), and the SPM requirement +# in ci~/ios-harness/Package.swift. A floating harness requirement (`from:`) is # replaced with an exact version on the first bump. # # Secrets: @@ -123,11 +124,11 @@ jobs: if [ "$PLATFORM" = android ]; then CURRENT="$(sed -nE "s/.*com\.superwall\.sdk:superwall-android:([^']+)'.*/\1/p" Plugins/Android/SuperwallSDK.androidlib/build.gradle)" else - # Exact SPM pin once one exists; otherwise the Podfile requirement, - # which starts out as a floating range (`~> 4.0`). + # Exact SPM pin in the harness once one exists; otherwise the + # minimum version the post-build processor requires. CURRENT="$(sed -nE 's/.*Superwall-iOS", exact: "([^"]+)".*/\1/p' ci~/ios-harness/Package.swift)" if [ -z "$CURRENT" ]; then - CURRENT="$(sed -nE "s/.*pod 'SuperwallKit', '([^']+)'.*/\1/p" Editor/SuperwallPostBuildProcessor.cs | head -1)" + CURRENT="$(sed -nE 's/.*SuperwallKitMinimumVersion = "([^"]+)".*/\1/p' Editor/SuperwallPostBuildProcessor.cs | head -1)" fi fi [ -n "$CURRENT" ] || { echo "::error::Could not read the current $PLATFORM pin"; exit 1; } @@ -178,9 +179,9 @@ jobs: sed -i -E "s/superwall-android $CURRENT/superwall-android $VERSION/" \ Plugins/Android/SuperwallSDK.androidlib/build.gradle else - # Podfile text (three copies) and the SPM harness must name the - # same version. `from:` becomes `exact:` the first time. - sed -i -E "s/(pod 'SuperwallKit', ')[^']+'/\1$VERSION'/" \ + # The exported project's package requirement and the SPM harness + # must name the same version. `from:` becomes `exact:` the first time. + sed -i -E "s/(SuperwallKitMinimumVersion = \")[^\"]+\"/\1$VERSION\"/" \ Editor/SuperwallPostBuildProcessor.cs sed -i -E "s#(Superwall-iOS\", )(from|exact): \"[^\"]+\"#\1exact: \"$VERSION\"#" \ ci~/ios-harness/Package.swift @@ -242,7 +243,7 @@ jobs: if [ "$PLATFORM" = android ]; then PLATFORM_NOTES="The Android bridge is Plugins/Android/SuperwallSDK.androidlib (Kotlin). Compile it with \`(cd ci~/android-harness && gradle :SuperwallSDK:assembleRelease -PagpVersion=8.5.2 --no-daemon)\`. C# cannot be compiled on this runner (no Unity); say so in the PR description." else - PLATFORM_NOTES="The iOS bridge is Plugins/iOS/SuperwallUnityBridge.swift. The Podfile lines live in Editor/SuperwallPostBuildProcessor.cs and the SPM pin in ci~/ios-harness/Package.swift; keep them on the same version. This runner is Linux: Swift cannot be compiled here, and neither can C# (no Unity). Be careful and precise, and say in the PR description that iOS was not compiled locally." + PLATFORM_NOTES="The iOS bridge is Plugins/iOS/SuperwallUnityBridge.swift. The Swift package requirement of the exported Xcode project is SuperwallKitMinimumVersion in Editor/SuperwallPostBuildProcessor.cs (asserted by Tests/Editor/SwiftPackageRequirementTests.cs) and the harness pin is in ci~/ios-harness/Package.swift; keep them on the same version. This runner is Linux: Swift cannot be compiled here, and neither can C# (no Unity). Be careful and precise, and say in the PR description that iOS was not compiled locally." fi DELIM="PROMPT_$(openssl rand -hex 8)" { diff --git a/CHANGELOG.md b/CHANGELOG.md index e3e7481..d436989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ # Changelog All notable changes to this package will be documented in this file. +## [0.6.0] + +### Breaking Changes +* iOS: SuperwallKit now comes from Swift Package Manager instead of CocoaPods. The post-build processor adds the `https://github.com/superwall/Superwall-iOS` package (from 4.19.1 up to the next major version) to the exported Xcode project, links `SuperwallKit` to `UnityFramework` and copies SuperwallKit's resource bundle into it. It no longer writes a Podfile, so CocoaPods is no longer required. Open `Unity-iPhone.xcodeproj`; Xcode resolves the package on first open or build. Projects that use other pods (for example through External Dependency Manager) keep their Podfile and workspace as before. +* iOS: a Target minimum iOS Version below 15.0 is no longer raised for SuperwallKit, because Swift packages build for the app's own deployment target. The build still logs a warning; raise the target to 15.0 or the Xcode build fails to link SuperwallKit. + +### Fixes +* iOS: 0.4.1 and 0.5.0 required SuperwallKit 4.19.1 from CocoaPods, but SuperwallKit 4.19.0 and later aren't published there (the newest pod is 4.18.3), so `pod install` failed with `None of your spec sources contain a spec satisfying the dependency: SuperwallKit (< 5.0, >= 4.19.1)` and the Xcode build couldn't link SuperwallKit. Getting it from Swift Package Manager fixes this. + +### Migration +* A Replace build needs no changes. An Append build over an iOS project exported by an earlier version keeps the old Podfile: the post-build processor removes its SuperwallKit pod and runs `pod install`, so the workspace doesn't link SuperwallKit from both the pod and the Swift package. If `pod install` can't run, the build logs a warning with the command to run yourself, or make a Replace build. + ## [0.5.0] ### Enhancements diff --git a/Editor/SuperwallPostBuildProcessor.cs b/Editor/SuperwallPostBuildProcessor.cs index 2ea8a9e..ef8c98c 100644 --- a/Editor/SuperwallPostBuildProcessor.cs +++ b/Editor/SuperwallPostBuildProcessor.cs @@ -6,6 +6,7 @@ using UnityEditor.iOS.Xcode; #endif using System.IO; +using System.Text.RegularExpressions; namespace Superwall.Editor { @@ -13,39 +14,67 @@ public class SuperwallPostBuildProcessor : IPostprocessBuildWithReport { public int callbackOrder => 99; + public const string SuperwallKitPackageUrl = "https://github.com/superwall/Superwall-iOS"; + public const string SuperwallKitProduct = "SuperwallKit"; + + // The resource bundle SPM builds for SuperwallKit's SuperwallKit target. + public const string SuperwallKitResourceBundle = "SuperwallKit_SuperwallKit.bundle"; + + // The exported Xcode project requires SuperwallKit from this version up to the next major. // 4.12.10 added the custom callback API the bridge calls. 4.19.1 keeps a paywall to the // orientations the game allows (Screen.autorotateTo*), and stops it leaving the game - // rotated after it closes. - public const string SuperwallKitPod = "pod 'SuperwallKit', '>= 4.19.1', '< 5.0'"; + // rotated after it closes. native-sdk-bump.yml rewrites this line. + public const string SuperwallKitMinimumVersion = "4.19.1"; // SuperwallKit 4.18.0 raised its deployment target from iOS 13 to iOS 15. private const string MinimumIOSVersion = "15.0"; - // Requirements earlier versions of this package wrote. A Podfile still naming one of these - // is moved to SuperwallKitPod; any other requirement was set by hand and is kept. Only the - // version part is spelled out here so native-sdk-bump.yml's rewrite of SuperwallKitPod - // leaves these alone. - private static readonly string[] PreviousSuperwallKitRequirements = + // A SuperwallKit pod line, whatever its requirement. Versions before 0.6.0 got SuperwallKit + // from CocoaPods; linking it from the pod and the Swift package would duplicate every class. + private static readonly Regex SuperwallKitPodLine = + new Regex(@"^[ \t]*pod[ \t]+['""]SuperwallKit['""][^\n]*\n?", RegexOptions.Multiline); + + // The minimumVersion of the XCRemoteSwiftPackageReference for SuperwallKit. pbxproj keys + // are sorted, so repositoryURL comes before requirement, and kind before minimumVersion. + private static readonly Regex SuperwallKitPackageMinimumVersion = new Regex( + @"(repositoryURL\s*=\s*""?https://github\.com/superwall/Superwall-iOS(?:\.git)?/?""?;\s*requirement\s*=\s*\{[^}]*?minimumVersion\s*=\s*)""?([^;""\s]+)""?;", + RegexOptions.IgnoreCase); + + /// + /// Whether the Xcode project (the text of project.pbxproj) already references the + /// SuperwallKit Swift package, as it does after an Append build. + /// + public static bool ContainsSuperwallKitPackage(string pbxprojContent) { - "'~> 4.0'", - "'>= 4.12.10', '< 5.0'", - }; + return pbxprojContent.IndexOf("github.com/superwall/Superwall-iOS", + System.StringComparison.OrdinalIgnoreCase) >= 0; + } /// - /// Moves a SuperwallKit requirement written by an earlier version of this package to the - /// current one. Returns the Podfile unchanged if it has none. + /// Raises the SuperwallKit package's minimum version in project.pbxproj to + /// SuperwallKitMinimumVersion. A newer minimum, set by hand, is kept. Returns the content + /// unchanged if it has no SuperwallKit package with a minimum version. /// - public static string UpdateSuperwallKitRequirement(string podfileContent) + public static string RaiseSuperwallKitPackageRequirement(string pbxprojContent) { - foreach (string requirement in PreviousSuperwallKitRequirements) + var required = System.Version.Parse(SuperwallKitMinimumVersion); + return SuperwallKitPackageMinimumVersion.Replace(pbxprojContent, match => { - string previousPod = "pod 'SuperwallKit', " + requirement; - if (previousPod != SuperwallKitPod) + if (System.Version.TryParse(match.Groups[2].Value, out var current) && current >= required) { - podfileContent = podfileContent.Replace(previousPod, SuperwallKitPod); + return match.Value; } - } - return podfileContent; + return match.Groups[1].Value + SuperwallKitMinimumVersion + ";"; + }); + } + + /// + /// Removes every SuperwallKit pod line from a Podfile. Returns the Podfile unchanged if it + /// has none. + /// + public static string RemoveSuperwallKitPod(string podfileContent) + { + return SuperwallKitPodLine.Replace(podfileContent, ""); } public void OnPostprocessBuild(BuildReport report) @@ -61,88 +90,48 @@ public void OnPostprocessBuild(BuildReport report) #if UNITY_IOS private static void PostProcessIOS(string buildPath) { - string podfilePath = Path.Combine(buildPath, "Podfile"); - - // Honor the deployment target Unity is set to (PlayerSettings → Other Settings → Target minimum iOS Version) - // so the Pods build for the same iOS version as the host app — otherwise older sims/devices vanish - // from Xcode's destination list. SuperwallKit 4.18+ requires iOS 15, so a lower target is raised - // for the Pods (pod install would fail otherwise) and the game is told to raise its own. + // SuperwallKit 4.18+ requires iOS 15. Xcode refuses to link the package into a target + // with a lower deployment target (PlayerSettings → Other Settings → Target minimum iOS Version). string iosTarget = PlayerSettings.iOS.targetOSVersionString; - if (string.IsNullOrEmpty(iosTarget)) iosTarget = MinimumIOSVersion; - if (System.Version.TryParse(iosTarget.Contains(".") ? iosTarget : iosTarget + ".0", out var target) + if (!string.IsNullOrEmpty(iosTarget) + && System.Version.TryParse(iosTarget.Contains(".") ? iosTarget : iosTarget + ".0", out var target) && target < System.Version.Parse(MinimumIOSVersion)) { - Debug.LogWarning($"[Superwall] SuperwallKit requires iOS {MinimumIOSVersion} or later, but Target minimum iOS Version is {iosTarget}. Raise it in Player Settings → Other Settings, or the Xcode build will fail to import SuperwallKit."); - iosTarget = MinimumIOSVersion; + Debug.LogWarning($"[Superwall] SuperwallKit requires iOS {MinimumIOSVersion} or later, but Target minimum iOS Version is {iosTarget}. Raise it in Player Settings → Other Settings, or the Xcode build will fail to link SuperwallKit."); } - if (!File.Exists(podfilePath)) - { - string podfileContent = $@"platform :ios, '{iosTarget}' -use_frameworks! - -target 'UnityFramework' do - {SuperwallKitPod} -end + RemovePodFromAppendedBuild(buildPath); -target 'Unity-iPhone' do -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '{iosTarget}' - end - end -end -"; - File.WriteAllText(podfilePath, podfileContent); - Debug.Log("[Superwall] Created Podfile with SuperwallKit dependency"); - } - else - { - string podfileContent = File.ReadAllText(podfilePath); - if (!podfileContent.Contains("SuperwallKit")) - { - int targetIndex = podfileContent.IndexOf("target 'UnityFramework'"); - if (targetIndex >= 0) - { - int doIndex = podfileContent.IndexOf("do", targetIndex); - if (doIndex >= 0) - { - int insertIndex = podfileContent.IndexOf('\n', doIndex) + 1; - podfileContent = podfileContent.Insert(insertIndex, $" {SuperwallKitPod}\n"); - } - } - else - { - podfileContent += $"\ntarget 'UnityFramework' do\n {SuperwallKitPod}\nend\n"; - } - - File.WriteAllText(podfilePath, podfileContent); - Debug.Log("[Superwall] Added SuperwallKit pod to existing Podfile"); - } - else - { - // An Append build keeps the Podfile from the last export. Without this, its old - // requirement lets Podfile.lock hold a SuperwallKit older than the bridge needs. - string updated = UpdateSuperwallKitRequirement(podfileContent); - if (updated != podfileContent) - { - File.WriteAllText(podfilePath, updated); - Debug.Log("[Superwall] Updated the SuperwallKit requirement in the existing Podfile"); - } - } - } - - // Modify the Xcode project to enable Swift string projPath = PBXProject.GetPBXProjectPath(buildPath); + bool hasPackage = ContainsSuperwallKitPackage(File.ReadAllText(projPath)); + var project = new PBXProject(); project.ReadFromFile(projPath); string unityFrameworkGuid = project.GetUnityFrameworkTargetGuid(); string mainTargetGuid = project.GetUnityMainTargetGuid(); + // An Append build keeps the package reference from the last export; adding it again + // would duplicate it. + if (!hasPackage) + { + string packageGuid = project.AddRemotePackageReferenceAtVersionUpToNextMajor( + SuperwallKitPackageUrl, SuperwallKitMinimumVersion); + project.AddRemotePackageFrameworkToProject(unityFrameworkGuid, SuperwallKitProduct, packageGuid, false); + Debug.Log($"[Superwall] Added the SuperwallKit Swift package (from {SuperwallKitMinimumVersion} up to the next major version) to UnityFramework"); + } + + // Xcode builds SuperwallKit's resource bundle (Core Data model, receipt certificates, + // images, localizations, privacy manifest) but doesn't copy it into UnityFramework, and + // SuperwallKit stops with "unable to find bundle named SuperwallKit_SuperwallKit" when + // it configures. Copy it in, where Bundle.module looks for a package linked into a + // framework. Not in the app target: Unity as a Library apps don't have it. + if (!project.ContainsFileByProjectPath(SuperwallKitResourceBundle)) + { + string bundleGuid = project.AddFile(SuperwallKitResourceBundle, SuperwallKitResourceBundle, PBXSourceTree.Build); + project.AddFileToBuild(unityFrameworkGuid, bundleGuid); + } + // Enable modules and Swift for the framework target project.SetBuildProperty(unityFrameworkGuid, "CLANG_ENABLE_MODULES", "YES"); project.SetBuildProperty(unityFrameworkGuid, "SWIFT_VERSION", "5.0"); @@ -156,25 +145,57 @@ private static void PostProcessIOS(string buildPath) project.WriteToFile(projPath); - RunPodInstall(buildPath); + if (hasPackage) + { + // Without this, the kept requirement lets Package.resolved hold a SuperwallKit + // older than the bridge needs. + string content = File.ReadAllText(projPath); + string updated = RaiseSuperwallKitPackageRequirement(content); + if (updated != content) + { + File.WriteAllText(projPath, updated); + Debug.Log($"[Superwall] Raised the SuperwallKit package requirement to {SuperwallKitMinimumVersion}"); + } + } } - private static void RunPodInstall(string buildPath) + // An Append build over an export from a version that used CocoaPods keeps its Podfile and + // Pods integration. Drop SuperwallKit from it and reinstall the pods, or the workspace still + // builds the old SuperwallKit pod and links it next to the Swift package: Xcode reports no + // error, and the app gets two copies of every SuperwallKit class. + // Runs before the processor opens project.pbxproj, because pod install rewrites it. + private static void RemovePodFromAppendedBuild(string buildPath) { - string podPath = LocatePodExecutable(); - if (podPath == null) + string podfilePath = Path.Combine(buildPath, "Podfile"); + if (!File.Exists(podfilePath)) return; + + string podfile = File.ReadAllText(podfilePath); + string updated = RemoveSuperwallKitPod(podfile); + if (updated == podfile) return; + + File.WriteAllText(podfilePath, updated); + Debug.Log("[Superwall] SuperwallKit now comes from Swift Package Manager, so its pod was removed from the Podfile this Append build kept. Running pod install to update the Pods integration."); + + string failure = RunPodInstall(buildPath); + if (failure != null) { Debug.LogWarning( - "[Superwall] Could not locate the CocoaPods 'pod' executable. " + - $"Run manually:\n\n cd \"{buildPath}\" && pod install\n\n" + - "If you don't have CocoaPods installed: 'sudo gem install cocoapods' " + - "or 'brew install cocoapods'."); - return; + $"[Superwall] {failure} Until the Pods integration is updated, Unity-iPhone.xcworkspace still links " + + "the old SuperwallKit pod next to the Swift package. Run:\n\n" + + $" cd \"{buildPath}\" && pod install\n\n" + + "or make a Replace build."); } + } + + // Returns null on success, or why pod install didn't run or failed. + private static string RunPodInstall(string buildPath) + { + string podPath = LocatePodExecutable(); + if (podPath == null) return "Could not find the CocoaPods 'pod' executable."; var process = new System.Diagnostics.Process(); process.StartInfo.FileName = "/bin/bash"; - // Login shell so user PATH from ~/.zshrc / ~/.bash_profile is loaded (rbenv/asdf shims, Homebrew). + // Login shell so the user's PATH from ~/.zshrc / ~/.bash_profile is loaded (rbenv/asdf shims, Homebrew). process.StartInfo.Arguments = $"-l -c \"cd '{buildPath}' && '{podPath}' install\""; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; @@ -184,7 +205,7 @@ private static void RunPodInstall(string buildPath) process.StartInfo.EnvironmentVariables.Remove("MONO_CFG_DIR"); process.StartInfo.EnvironmentVariables.Remove("DYLD_FALLBACK_LIBRARY_PATH"); process.StartInfo.EnvironmentVariables.Remove("DYLD_LIBRARY_PATH"); - // CocoaPods crashes with Encoding::CompatibilityError under non-UTF-8 locales — + // CocoaPods crashes with Encoding::CompatibilityError under non-UTF-8 locales; // Unity launched from Finder inherits launchd's empty LANG. process.StartInfo.EnvironmentVariables["LANG"] = "en_US.UTF-8"; process.StartInfo.EnvironmentVariables["LC_ALL"] = "en_US.UTF-8"; @@ -195,23 +216,16 @@ private static void RunPodInstall(string buildPath) string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); - if (process.ExitCode == 0) { - Debug.Log($"[Superwall] pod install completed successfully.\n{output}"); - } - else - { - Debug.LogWarning( - $"[Superwall] pod install failed (exit code {process.ExitCode}). " + - $"Run manually:\n\n cd \"{buildPath}\" && pod install\n\n{error}"); + Debug.Log($"[Superwall] pod install completed.\n{output}"); + return null; } + return $"pod install failed (exit code {process.ExitCode}):\n{error}{output}\n"; } catch (System.Exception e) { - Debug.LogWarning( - $"[Superwall] Could not run pod install automatically ({e.Message}). " + - $"Run manually:\n\n cd \"{buildPath}\" && pod install"); + return $"Could not run pod install ({e.Message})."; } } @@ -231,7 +245,7 @@ private static string LocatePodExecutable() if (!string.IsNullOrEmpty(path) && File.Exists(path)) return path; } - // Fall back to `which pod` under a login shell. + // Fall back to `command -v pod` under a login shell. try { var which = new System.Diagnostics.Process(); diff --git a/README.md b/README.md index 49c4e98..67eb0d1 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ https://github.com/superwall/Superwall-Unity.git ### Platform Dependencies -**iOS** — The post-build processor automatically creates a Podfile and runs `pod install`. Requires [CocoaPods](https://cocoapods.org/). +**iOS** — No CocoaPods needed. The post-build processor adds [SuperwallKit](https://github.com/superwall/Superwall-iOS) to the exported Xcode project as a Swift package (Swift Package Manager), linked to the `UnityFramework` target. Xcode resolves it the first time you open or build `Unity-iPhone.xcodeproj`. Requires Xcode 26 and a Target minimum iOS Version of 15.0 or later. **Android** — No manual setup needed. The package includes a Gradle library module that automatically pulls the Superwall Android SDK (pinned per release) and billing dependencies from Maven. The module inherits the compile SDK from your Player Settings and builds under both AGP 8.x (Unity 6000.3) and AGP 9+ (Unity 6000.4+). diff --git a/Tests/Editor/PodfileRequirementTests.cs b/Tests/Editor/PodfileRequirementTests.cs deleted file mode 100644 index 4da606a..0000000 --- a/Tests/Editor/PodfileRequirementTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -using NUnit.Framework; -using Superwall.Editor; - -namespace Superwall.Editor.Tests -{ - class PodfileRequirementTests - { - private static string Podfile(string pod) => - "platform :ios, '15.0'\nuse_frameworks!\n\ntarget 'UnityFramework' do\n " + pod + "\nend\n"; - - [Test] - public void SuperwallKitPod_RequiresTheVersionThatKeepsPaywallsToTheGamesOrientations() - { - Assert.AreEqual("pod 'SuperwallKit', '>= 4.19.1', '< 5.0'", SuperwallPostBuildProcessor.SuperwallKitPod); - } - - [TestCase("pod 'SuperwallKit', '~> 4.0'")] - [TestCase("pod 'SuperwallKit', '>= 4.12.10', '< 5.0'")] - public void UpdateSuperwallKitRequirement_MovesRequirementsThisPackageWroteBefore(string previousPod) - { - string updated = SuperwallPostBuildProcessor.UpdateSuperwallKitRequirement(Podfile(previousPod)); - - Assert.AreEqual(Podfile(SuperwallPostBuildProcessor.SuperwallKitPod), updated); - } - - [Test] - public void UpdateSuperwallKitRequirement_LeavesTheCurrentRequirementAlone() - { - string podfile = Podfile(SuperwallPostBuildProcessor.SuperwallKitPod); - - Assert.AreEqual(podfile, SuperwallPostBuildProcessor.UpdateSuperwallKitRequirement(podfile)); - } - - [Test] - public void UpdateSuperwallKitRequirement_KeepsARequirementSetByHand() - { - string podfile = Podfile("pod 'SuperwallKit', '4.19.3'"); - - Assert.AreEqual(podfile, SuperwallPostBuildProcessor.UpdateSuperwallKitRequirement(podfile)); - } - } -} diff --git a/Tests/Editor/SwiftPackageRequirementTests.cs b/Tests/Editor/SwiftPackageRequirementTests.cs new file mode 100644 index 0000000..fa0a7dd --- /dev/null +++ b/Tests/Editor/SwiftPackageRequirementTests.cs @@ -0,0 +1,88 @@ +using NUnit.Framework; +using Superwall.Editor; + +namespace Superwall.Editor.Tests +{ + class SwiftPackageRequirementTests + { + // An XCRemoteSwiftPackageReference as it appears in project.pbxproj. + private static string Pbxproj(string url, string minimumVersion) => + "\t\tA1B2C3 /* XCRemoteSwiftPackageReference */ = {\n" + + "\t\t\tisa = XCRemoteSwiftPackageReference;\n" + + "\t\t\trepositoryURL = \"" + url + "\";\n" + + "\t\t\trequirement = {\n" + + "\t\t\t\tkind = upToNextMajorVersion;\n" + + "\t\t\t\tminimumVersion = " + minimumVersion + ";\n" + + "\t\t\t};\n" + + "\t\t};\n"; + + private static string Podfile(string pods) => + "platform :ios, '15.0'\nuse_frameworks!\n\ntarget 'UnityFramework' do\n" + pods + "end\n"; + + [Test] + public void SuperwallKitMinimumVersion_IncludesTheFixThatKeepsPaywallsToTheGamesOrientations() + { + var minimum = System.Version.Parse(SuperwallPostBuildProcessor.SuperwallKitMinimumVersion); + + Assert.GreaterOrEqual(minimum, new System.Version(4, 19, 1)); + Assert.Less(minimum, new System.Version(5, 0, 0)); + } + + [Test] + public void ContainsSuperwallKitPackage_FindsTheReference() + { + Assert.IsTrue(SuperwallPostBuildProcessor.ContainsSuperwallKitPackage( + Pbxproj(SuperwallPostBuildProcessor.SuperwallKitPackageUrl, "4.19.1"))); + Assert.IsFalse(SuperwallPostBuildProcessor.ContainsSuperwallKitPackage( + Pbxproj("https://github.com/apple/swift-system.git", "1.0.0"))); + } + + [TestCase("4.12.10")] + [TestCase("\"4.0.0\"")] + public void RaiseSuperwallKitPackageRequirement_RaisesAnOlderMinimum(string minimum) + { + string url = SuperwallPostBuildProcessor.SuperwallKitPackageUrl; + + Assert.AreEqual( + Pbxproj(url, SuperwallPostBuildProcessor.SuperwallKitMinimumVersion), + SuperwallPostBuildProcessor.RaiseSuperwallKitPackageRequirement(Pbxproj(url, minimum))); + } + + [TestCase("4.19.1")] + [TestCase("9.0.0")] + public void RaiseSuperwallKitPackageRequirement_KeepsTheCurrentOrANewerMinimum(string minimum) + { + string pbxproj = Pbxproj(SuperwallPostBuildProcessor.SuperwallKitPackageUrl, minimum); + + Assert.AreEqual(pbxproj, SuperwallPostBuildProcessor.RaiseSuperwallKitPackageRequirement(pbxproj)); + } + + [Test] + public void RaiseSuperwallKitPackageRequirement_LeavesOtherPackagesAlone() + { + string pbxproj = Pbxproj("https://github.com/apple/swift-system.git", "1.0.0"); + + Assert.AreEqual(pbxproj, SuperwallPostBuildProcessor.RaiseSuperwallKitPackageRequirement(pbxproj)); + } + + [TestCase(" pod 'SuperwallKit', '~> 4.0'\n")] + [TestCase(" pod 'SuperwallKit', '>= 4.19.1', '< 5.0'\n")] + [TestCase(" pod \"SuperwallKit\", \"4.19.3\"\n")] + public void RemoveSuperwallKitPod_RemovesThePodAndKeepsOthers(string superwallPod) + { + string otherPod = " pod 'Firebase/Analytics'\n"; + + Assert.AreEqual( + Podfile(otherPod), + SuperwallPostBuildProcessor.RemoveSuperwallKitPod(Podfile(superwallPod + otherPod))); + } + + [Test] + public void RemoveSuperwallKitPod_LeavesAPodfileWithoutItAlone() + { + string podfile = Podfile(" pod 'Firebase/Analytics'\n"); + + Assert.AreEqual(podfile, SuperwallPostBuildProcessor.RemoveSuperwallKitPod(podfile)); + } + } +} diff --git a/Tests/Editor/PodfileRequirementTests.cs.meta b/Tests/Editor/SwiftPackageRequirementTests.cs.meta similarity index 100% rename from Tests/Editor/PodfileRequirementTests.cs.meta rename to Tests/Editor/SwiftPackageRequirementTests.cs.meta diff --git a/package.json b/package.json index 0c6ce62..eb7b28e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.superwall.sdk", "displayName": "Superwall SDK", - "version": "0.5.0", + "version": "0.6.0", "unity": "6000.3", "description": "Superwall SDK for Unity. Remotely configure paywalls, run paywall A/B tests, and more — all without shipping an app update.", "dependencies": {},