diff --git a/CHANGELOG.md b/CHANGELOG.md index eb469c4..204d74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,21 @@ # Changelog All notable changes to this package will be documented in this file. -## [Unreleased] +## [0.4.1] ### Enhancements * Android: subscription replacement. When a paywall's Purchase action is set to replace an existing subscription, a custom purchase controller now receives the subscription being replaced through a new `IPurchaseController.PurchaseFromGooglePlay(productId, basePlanId, offerId, ProductReplacement replacement, completion)` overload. Pass `replacement.OldPurchaseToken` and `replacement.Mode` to the billing flow's `SubscriptionUpdateParams` to upgrade, downgrade or switch the user's subscription instead of buying a second one. The overload has a default implementation that calls the existing four-argument method, so existing controllers compile and behave as before. Purchases without a custom controller handle the replacement automatically. +* `EventType` gains the events SuperwallKit 4.18 and superwall-android 2.10 added: `TeleportOpen` and `TeleportReturn` (iOS), and `CustomerCenterOpen`, `CustomerCenterClose`, `CustomerCenterAction`, `CustomerCenterSurveyResponse` and `CustomerCenterRefundRequest`. Before, they reached `HandleSuperwallEvent` with a warning and the default `EventType`. + +### iOS +* SuperwallKit 4.18 and later need iOS 15. If Target minimum iOS Version is lower, the generated Podfile now uses iOS 15 so `pod install` succeeds, and the build logs a warning to raise the game's own target. + +### Android +* `LogScope.StoreKitManager` now enables the Android SDK's `billing` log scope, which replaces the deprecated `storeKitManager`. Android billing logs reach `SuperwallDelegate.HandleLog` with the scope `"billing"` instead of `"storeKitManager"`. ### Dependencies -* Android: pins the native SDK to 2.9.0 (was `2.8.7`). [View Android SDK release notes](https://github.com/superwall/Superwall-Android/releases/tag/2.9.0). +* Android: pins the native SDK to 2.10.0 (was `2.8.7`). View the Android SDK release notes for [2.9.0](https://github.com/superwall/Superwall-Android/releases/tag/2.9.0) and [2.10.0](https://github.com/superwall/Superwall-Android/releases/tag/2.10.0). +* iOS: pins the native SDK to 4.19.1. The generated Podfile already requires SuperwallKit `>= 4.19.1, < 5.0`; the CI harness now builds the bridge against exactly 4.19.1 (was `from: 4.12.10`). [View iOS SDK release notes](https://github.com/superwall/Superwall-iOS/releases/tag/4.19.1). ## [0.4.0] @@ -21,8 +29,11 @@ All notable changes to this package will be documented in this file. ### Android * Custom callbacks need the default in-window presentation. With `AndroidPaywallPresentation.Activity`, Unity is paused while the paywall is open, so each callback fails straight away and logs an error instead of leaving the paywall waiting. +### Fixes +* iOS paywalls now follow the orientations the game allows through `Screen.autorotateTo*` and `Screen.orientation`. Before, a landscape-only game could be rotated to portrait while a paywall was open, and stayed in portrait after it closed. + ### Dependencies -* iOS: the generated Podfile now requires SuperwallKit `>= 4.12.10, < 5.0`, the first versions with the custom callback API. A Podfile kept by an Append build is updated. +* iOS: the generated Podfile now requires SuperwallKit `>= 4.19.1, < 5.0`. 4.12.10 added the custom callback API and 4.19.1 keeps paywalls to the game's orientations. A Podfile kept by an Append build is updated, unless you changed the SuperwallKit requirement by hand. ## [0.3.0] diff --git a/Editor/SuperwallPostBuildProcessor.cs b/Editor/SuperwallPostBuildProcessor.cs index 725871a..2ea8a9e 100644 --- a/Editor/SuperwallPostBuildProcessor.cs +++ b/Editor/SuperwallPostBuildProcessor.cs @@ -13,6 +13,41 @@ public class SuperwallPostBuildProcessor : IPostprocessBuildWithReport { public int callbackOrder => 99; + // 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'"; + + // 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 = + { + "'~> 4.0'", + "'>= 4.12.10', '< 5.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. + /// + public static string UpdateSuperwallKitRequirement(string podfileContent) + { + foreach (string requirement in PreviousSuperwallKitRequirements) + { + string previousPod = "pod 'SuperwallKit', " + requirement; + if (previousPod != SuperwallKitPod) + { + podfileContent = podfileContent.Replace(previousPod, SuperwallKitPod); + } + } + return podfileContent; + } + public void OnPostprocessBuild(BuildReport report) { #if UNITY_IOS @@ -24,19 +59,22 @@ public void OnPostprocessBuild(BuildReport report) } #if UNITY_IOS - // 4.12.10 added the custom callback API the bridge calls. - private const string SuperwallKitPod = "pod 'SuperwallKit', '>= 4.12.10', '< 5.0'"; - private const string LegacySuperwallKitPod = "pod 'SuperwallKit', '~> 4.0'"; - 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.x supports iOS 13+, so anything Unity allows is fine. + // 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. string iosTarget = PlayerSettings.iOS.targetOSVersionString; - if (string.IsNullOrEmpty(iosTarget)) iosTarget = "15.0"; + if (string.IsNullOrEmpty(iosTarget)) iosTarget = MinimumIOSVersion; + if (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; + } if (!File.Exists(podfilePath)) { @@ -84,12 +122,16 @@ private static void PostProcessIOS(string buildPath) File.WriteAllText(podfilePath, podfileContent); Debug.Log("[Superwall] Added SuperwallKit pod to existing Podfile"); } - else if (podfileContent.Contains(LegacySuperwallKitPod)) + else { // An Append build keeps the Podfile from the last export. Without this, its old - // requirement lets Podfile.lock hold a SuperwallKit the bridge can't compile against. - File.WriteAllText(podfilePath, podfileContent.Replace(LegacySuperwallKitPod, SuperwallKitPod)); - Debug.Log("[Superwall] Updated the SuperwallKit requirement in the existing Podfile"); + // 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"); + } } } diff --git a/Plugins/Android/SuperwallSDK.androidlib/build.gradle b/Plugins/Android/SuperwallSDK.androidlib/build.gradle index e3d8c7a..f9475dd 100644 --- a/Plugins/Android/SuperwallSDK.androidlib/build.gradle +++ b/Plugins/Android/SuperwallSDK.androidlib/build.gradle @@ -21,7 +21,7 @@ if (agpMajor < 9) { // Follow the host project's compile SDK (Unity writes unity.compileSdkVersion // into the exported project's gradle.properties from Player Settings) so this -// module never pins consumers to a stale SDK. superwall-android 2.9.0 pulls +// module never pins consumers to a stale SDK. superwall-android 2.10.0 pulls // androidx.activity 1.10.1, which requires compileSdk >= 35 — hence the fallback. def unityCompileSdk = (findProperty('unity.compileSdkVersion') ?: '35') as int @@ -43,7 +43,7 @@ android { dependencies { // Pinned exactly: a floating range (2.+) lets a Maven-side release break // consumer builds overnight. Bump deliberately with each Unity SDK release. - api 'com.superwall.sdk:superwall-android:2.9.0' + api 'com.superwall.sdk:superwall-android:2.10.0' api 'com.android.billingclient:billing:9.1.0' implementation 'com.google.android.material:material:1.12.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0' diff --git a/Plugins/Android/SuperwallSDK.androidlib/src/main/kotlin/com/superwall/sdk/unity/SuperwallUnityBridge.kt b/Plugins/Android/SuperwallSDK.androidlib/src/main/kotlin/com/superwall/sdk/unity/SuperwallUnityBridge.kt index cd766dd..5b438ed 100644 --- a/Plugins/Android/SuperwallSDK.androidlib/src/main/kotlin/com/superwall/sdk/unity/SuperwallUnityBridge.kt +++ b/Plugins/Android/SuperwallSDK.androidlib/src/main/kotlin/com/superwall/sdk/unity/SuperwallUnityBridge.kt @@ -1093,7 +1093,7 @@ class SuperwallUnityBridge { "configmanager" -> LogScope.configManager "identitymanager" -> LogScope.identityManager "localizationmanager" -> LogScope.localizationManager - "storekitmanager" -> LogScope.storeKitManager + "storekitmanager", "billing" -> LogScope.billing "bouncebutton" -> LogScope.bounceButton "device" -> LogScope.device else -> null diff --git a/Runtime/Models/Enums.cs b/Runtime/Models/Enums.cs index 3d165a8..0f808d9 100644 --- a/Runtime/Models/Enums.cs +++ b/Runtime/Models/Enums.cs @@ -292,7 +292,15 @@ public enum EventType StripeCheckoutStart, StripeCheckoutSubmit, StripeCheckoutComplete, - StripeCheckoutFail + StripeCheckoutFail, + // SuperwallKit 4.18 / superwall-android 2.10 (teleport events are iOS only). + TeleportOpen, + TeleportReturn, + CustomerCenterOpen, + CustomerCenterClose, + CustomerCenterAction, + CustomerCenterSurveyResponse, + CustomerCenterRefundRequest } [Serializable] diff --git a/Tests/Editor/PodfileRequirementTests.cs b/Tests/Editor/PodfileRequirementTests.cs new file mode 100644 index 0000000..4da606a --- /dev/null +++ b/Tests/Editor/PodfileRequirementTests.cs @@ -0,0 +1,42 @@ +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/PodfileRequirementTests.cs.meta b/Tests/Editor/PodfileRequirementTests.cs.meta new file mode 100644 index 0000000..058c79e --- /dev/null +++ b/Tests/Editor/PodfileRequirementTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 475dada1ffcc4deabb158715b5904d53 \ No newline at end of file diff --git a/ci~/ios-harness/Package.swift b/ci~/ios-harness/Package.swift index 3e1ff53..ac68ec8 100644 --- a/ci~/ios-harness/Package.swift +++ b/ci~/ios-harness/Package.swift @@ -11,7 +11,7 @@ let package = Package( .library(name: "SuperwallBridge", targets: ["SuperwallBridge"]) ], dependencies: [ - .package(url: "https://github.com/superwall/Superwall-iOS", from: "4.12.10") + .package(url: "https://github.com/superwall/Superwall-iOS", exact: "4.19.1") ], targets: [ .target( diff --git a/package.json b/package.json index 6bb4db9..26611b4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.superwall.sdk", "displayName": "Superwall SDK", - "version": "0.4.0", + "version": "0.4.1", "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": {},