Releases: superwall/Superwall-iOS
Releases · superwall/Superwall-iOS
3.0.1
3.0.0
Welcome to SuperwallKit
v3.0, the framework formally known as Paywall
!
This update is a major release, containing lots of breaking changes, enhancements and bug fixes. We're excited for you to use it!
We understand that transitions between major SDK releases can become frustrating, so we've made a migration guide to make your life easier. We've also updated our example apps to v3, including RevenueCat+SuperwallKit and Objective-C apps. Finally, we recommend you check out our updated docs.
Breaking Changes
- Renames the package from
Paywall
toSuperwallKit
. - Renames the primary static class for integrating Superwall from
Paywall
toSuperwall
. - Sets the minimum iOS version to iOS 13.
- Moves all functions and variables to the
shared
instance for consistency. - Renames
preloadPaywalls(forTriggers:)
topreloadPaywalls(forEvents:)
- Renames
configure(apiKey:userId:delegate:options:)
toconfigure(apiKey:purchaseController:options:completion:)
. You can use the completion block to know when Superwall has finished configuring. - Removes delegate from
configure
. You now set the delegate viaSuperwall.shared.delegate
. - Changes
PaywallOptions
toSuperwallOptions
. This now clearly defines which of the options are explicit to paywalls vs other configuration options within the SDK. - Makes
Superwall.shared.options
internal so that options must be set inconfigure
. - Removes
Superwall.trigger(event:)
and replaces with register(event:params:handler:feature). This is Superwall's most powerful feature yet. Wrap your features with this method to conditionally show paywalls, lock features and more. - Renames
Paywall.EventName
toSuperwallEvent
and removes.manualPresent
as aSuperwallEvent
. - Renames
PaywallDelegate
toSuperwallDelegate
. - Superwall now automatically handles all subscription-related logic. However, if you'd still like control (e.g. if you're using RevenueCat), you'll need to implement a
PurchaseController
and setSuperwall.shared.subscriptionStatus
yourself whenever the subscription status of the user changes. You pass yourPurchaseController
toconfigure(apiKey:purchaseController:options:completion:)
. - Removes
isUserSubscribed()
from the delegate and replaces this with a published instance variablesubscriptionStatus
. This is enum that defaults to.unknown
on first install and the cached value on subsequent app opens. If you're using aPurchaseController
to handle subscription-related logic, you must setsubscriptionStatus
every time the user's subscription status changes. If you're letting Superwall handle subscription-related logic, this value will be updated with the device receipt. - For Objective-C users, this changes the
SWKPurchaseController
methodpurchase(product:)
topurchase(product:completion:)
. You call the completion block with the result of the user attempting to purchase a product, making sure you handle all cases ofSWKPurchaseResult
:.purchased
,.cancelled
,.pending
,failed
. When you have a purchasing error, you need to call the completion block with the.failed
case along with the error. - Changes
restorePurchases()
to an async function that returns a boolean instead of having a completion block. - Removes
Paywall.load(identifier:)
. This was being used to preload a paywall by identifier. - Removes
.triggerPaywall()
for SwiftUI apps. Instead, SwiftUI users should now use the UIKit functionSuperwall.register()
. - Changes the
period
andperiodly
attributes for 2, 3 and 6 month products. Previously, theperiod
would be "month", and theperiodly
would be "monthly" for all three. Now theperiod
returns "2 months", "quarter", "6 months" and theperiodly
returns "every 2 months", "quarterly", and "every 6 months". - Removes
localizationOverride(localeIdentifier:)
and replaces it with theSuperwallOption
localeIdentifier
. You set this on configure. - Removes ASN1Swift as a package dependency.
- Changes free trial logic. Previously we'd look at just the primary product. However, we determing free trial eligibility based on the first product in the paywall that has a free trial available.
- Changes Objective-C method
setUserAttributesDictionary(_:)
tosetUserAttributes(_:)
. - Adds
PaywallInfo
toSuperwallDelegate
methodsWillPresentPaywall(withInfo:)
,didPresentPaywall(withInfo:)
,willDismissPaywall(withInfo:)
anddidDismissPaywall(withInfo:)
. - Renames
SuperwallDelegate
methoddidTrackSuperwallEventInfo(_:SuperwallEventInfo)
tohandleSuperwallEvent(withInfo eventInfo: SuperwallEventInfo)
for clarity. - Renames
SuperwallDelegate
methodswillOpenURL(url:)
andwillOpenDeepLink(url:)
topaywallWillOpenURL(url:)
andpaywallWillOpenDeepLink(url:)
respectively. - Changes the
logLevel
to be non-optional and introduces anone
case to turn off logging. - Removes all guides from the SDK documentation. From now on, our online docs provide guides and the SDK documentation is only there as a technical reference.
- Changes the return type of
PurchaseController.restorePurchases()
fromBool
toRestorationResult
. - Changes
DismissState
toPaywallResult
. - Renamed the
PaywallResult
caseclosed
todeclined
. - Removes .error(Error) from
PaywallSkippedReason
in favor of a newPaywallState
case.presentationError(Error)
. - Exposes the
transactionBackgroundView
PaywallOption
to Objective-C by making it non-optional and adding anone
case in place of setting it tonil
.
Enhancements
- Adds
getPaywall(forEvent:params:paywallOverrides:delegate:)
! You can use this to request thePaywallViewController
to present however you like. Please read our docs to learn more about how to use this. - Adds paywall caching. This is enabled on all paywalls by default, however it can be turned off on a case by case basis via the dashboard. With this enhancement, your paywalls will load lightning fast and will reduce network load of your app.
- You can now pass an
IdentityOptions
object toidentify(userId:options)
. This should only be used in advanced use cases. By setting therestorePaywallAssignments
property ofIdentityOptions
totrue
, it prevents paywalls from showing until after paywall assignments have been restored. If you expect users of your app to switch accounts or delete/reinstall a lot, you'd set this when identifying an existing account. - Adds
Superwall.shared.isLoggedIn
to check whether the user is logged in to the SDK or not. This will be true if you've previously calledidentify(userId:options:)
. This is added to user properties, which means you can create a rule based on whether the user is logged in vs. whether they're anonymous. - Adds a new example app, UIKit+RevenueCat, which shows you how to use Superwall with RevenueCat.
- Adds a new Objective-C example app UIKit-Objc.
- Adds an Objective-C-only function
removeUserAttributes(_:)
to remove user attributes. In Swift, to remove attributes you can pass innil
for a specific attribute insetUserAttributes(_:)
. - Adds
getPresentationResult(forEvent:params:)
. This returns aPresentationResult
, which preemptively gets the result of registering an event. This helps you determine whether a particular event will present a paywall in the future. - Logs when products fail to load with a link to help diagnose the cause.
- Adds a published property
isConfigured
. This is a boolean which you can use to check whether Superwall is configured and ready to present paywalls. - Adds
isFreeTrialAvailable
toPaywallInfo
. - Adds
subscriptionStatusDidChange(to:)
delegate function. If you're letting Superwall handle subscription logic you can use this to receive a callback whenever the user's internal subscription status changes. You can also listen to the publishedsubscriptionStatus
variable. - Adds a completion handler to
Superwall.configure(...)
that lets you know when Superwall has finished configuring. You can also listen to the publishedisConfigured
variable. - If you let Superwall handle your subscription-related logic, we now assume that a non-consumable product on your paywall is a lifetime subscription. If not, you'll need to return a
SubscriptionController
from the delegate. handleDeepLink(_:)
now returns a discardableBool
indicating whether the deep link was handled. If you're usingapplication(_:open:options:)
you can return its value there.- Adds
togglePaywallSpinner(isHidden:)
to arbitrarily toggle the loading spinner on and off. This is particularly useful when you're doing async work when performing a custom action inhandleCustomPaywallAction(withName:)
. - Adds a new event
SubscriptionStatusDidChange
which is logged on the dashboard whenever the user's subscription status changes. - You can now target
device.isSandbox
in rules. - Tweaks the loading indicator UI.
- Prevents the registering of events that have the same name as internally tracked
SuperwallEvents
likepaywall_open
. - Adds a drawer display option which displays the paywall at 70% screen height on iOS 16 iPhones.
- Adds
$is_feature_gatable
standard property to register calls. - Cleans up and reformats SDK logs.
- If you're using SwiftUI, you can now call
Superwall.configure
in theinit()
of yourApp
file. This means you don't need to have aUIApplicationDelegate
. - You can access
device.subscriptionStatus
in a rule, which is a string that's eitherACTIVE
,INACTIVE
, orUNKNOWN
. - You no longer need to have swiftlint installed to run our example apps.
- Adds static variable
Superwall.isInitialized
which istrue
when initialization is complete andSuperwall.shared
can be accessed. - Adds
transaction_abandon
,transaction_fail
and `paywall...
3.0.0-rc.7
Breaking Changes
- Exposes the
transactionBackgroundView
PaywallOption
to Objective-C by making it non-optional and adding anone
case in place of setting it tonil
. - Renames
getPaywallViewController
togetPaywall
. - Renames
paywallStatePublisher
property onPaywallViewController
tostatePublisher
. - Changes the presentation error domain code from
SWPresentationError
toSWKPresentationError
.
Enhancements
- Adds paywall caching. This is disabled by default but we'll roll this out to users accounts remotely. With this enhancement, your paywalls will load lightning fast and will reduce network load of your app.
- Exposes
Logging
SuperwallOption
to Objective C. - Exposes
info
on thePaywallViewController
. - Adds
rawTrialPeriodPrice
,trialPeriodPrice
,trialPeriodDailyPrice
,trialPeriodWeeklyPrice
,trialPeriodMonthlyPrice
,trialPeriodYearlyPrice
.
Fixes
- Fixes issue where a crash would occur if storage was full and a persistent container couldn't be created.
- Fixes thread safety issue when using a lazy variable to retrieve products.
- If the internet is offline when trying to present a paywall, the paywall configuration hasn't been retrieved, and the user is not subscribed, it now throws a presentationError. If the internet reconnects future paywalls will show.
- Fixes retry logic for requests.
- Fixes crash when handling a deep link.
- Creates a strong reference to the purchase controller as it was getting deallocated if you didn't keep a hold on it.
3.0.0-rc.6
Breaking Changes
- Adds a
PaywallViewControllerDelegate
to thegetPaywallViewController
functions. This is mandatory and is how you control what happens after a paywall is dismissed. - The completion block of
getPaywallViewController(forEvent:params:paywallOverrides:delegate:completion:)
now accepts an optionalPaywallViewController
, an optionalPaywallSkippedReason
and an optionalError
. This makes it easier to understand when the paywall was skipped vs when a real error occurred. - Renamed the
PaywallResult
caseclosed
todeclined
.
Enhancements
- Exposes
PaywallOverrides
andPaywallViewController
to Objective-C. - Adds Objective-C convenience methods to
PaywallOverrides
. - Adds a
device.isFirstAppOpen
property that you can use in paywall rules. This istrue
for the very first time a user opens the app. When the user closes and reopens the app, this will befalse
. - Removes the need to tell us when you're going to present/have presented a
PaywallViewController
that has been retrieved usinggetPaywallViewController(...)
. - Adds
isInspectable
to the paywall web view if running on iOS 16.4+. - Exposes
PaywallViewControllerDelegate
to be used withgetPaywallViewController(...)
Fixes
- Fixes various memory related crashes.
- Fixes a crash when calling
reset()
when a paywall is displayed.
3.0.0-rc.5
Fixes
- Fixes bug where
Superwall.shared.register
's feature handler would not be called if the user is subscribed.
3.0.0-rc.4
Breaking Changes
- Changes
DismissState
toPaywallResult
. - Removes the
closedForNextPaywall
case fromPaywallResult
in favor of a newPaywallInfo
property calledcloseReason
, which can either benil
,.systemLogic
, or.forNextPaywall
. - Changes the
PaywallPresentationHandler
variables to functions. - Removes
Superwall.shared.track
. We're going all in onSuperwall.shared.register
baby! - Removes .error(Error) from
PaywallSkippedReason
in favor of a newPaywallState
case.presentationError(Error)
. - Removes
PaywallPresentationHandler
completion block variables removed in favor of function calls with the same names. - Changes
.onError
ofPaywallPresentationHandler
to no longer be called when a paywall is intentionally not shown (i.e. user is subscribed, user is in holdout, no rule match, event not configured) - Adds
.onSkip(reason:)
toPaywallPresentationHandler
to handle cases where paywall isn't shown because user is subscribed, user is in holdout, no rules match, event not configured
Enhancements
- Adds
getPaywallViewController
! You can no request an actual view controller to present however you like. Check function documentation in Xcode for instructions – follow directions closely. - Changes default logging level to
INFO
. - Adds new automatically tracked
paywall_decline
event that can be used to present a new paywall when a user dismisses a paywall. - Allows
transaction_abandon
to trigger new paywalls when added to a campaign – called when a user abandons checkout (did you know 75% of the time, users abandon checkout when Apple's payment sheet comes up?!). - Adds
.onSkip
toPaywallPresentationHandler
which is passed aPaywallSkippedReason
when a paywall is not supposed to show. - Adds logging at
INFO
level, mansplaining exactly why a paywall is not shown when callingregister
orgetPaywallViewController
. - Adds new automatically tracked event
presentation_request
that gets sent with properties explaining why a paywall was or was not shown.
Fixes
- Paywalls will now show even if you are missing products.
3.0.0-rc.3
Breaking Changes
- Changes the
logLevel
to be non-optional and introduces anone
case to turn off logging. - Removes all guides from the SDK documentation. From now on, our online docs provide guides and the SDK documentation is only there as a technical reference.
- Changes
TrackResultObjc
toPresentationResultObjc
- Removes convenience methods for creating PaywallPresentationHandlers because they were a bit confusing
- Changes the return type of
PurchaseController.restorePurchases()
frombool
toRestorationResult
Enhancements
- If you're using SwiftUI, you can now call
Superwall.configure
in theinit()
of yourApp
file. This means you don't need to have aUIApplicationDelegate
. - Prevents validation of restorations and purchases if you're using a
PurchaseController
- it's now all on you! - Updates Objective-C sample app to use
Superwall.register
and removes legacy StoreKit code. - Simplifies SwiftUI and RevenueCat example app.
- You can now access
device.subscriptionStatus
in a rule, which is a string that's eitherACTIVE
,INACTIVE
, orUNKNOWN
. - You no longer need to have swiftlint installed to run our example apps.
- If you're not using a
PurchaseController
and a user comes across the "You're already subscribed to this product" popup, we will now correctly identify this as a restoration and not a purchase. This can happen when testing in sandbox if you purchase a product -> delete and reinstall the app -> open a paywall and purchase. - Adds static variable
Superwall.isInitialized
which istrue
when initialization is complete andSuperwall.shared
can be accessed. - Adds
transaction_abandon
andtransaction_fail
as potential triggers. This comes with a newDismissState
caseclosedForNextPaywall
, which is returned when dismissing one paywall for another.
Fixes
- Fixes issue where an invalid URL provided for an "Open URL" click behavior would result in a crash.
- Exposes
PaywallPresentationHandler
asSWKPaywallPresentationHandler
for Objective-C. - Fixes issue #127, where calling identify with the same userId would prevent paywalls from showing.
3.0.0-rc.2
Enhancements
- Simplifies Superwall-UIKit-Swift exmaple project
Fixes
- Fixes bug where calling Superwall.shared prior to Superwall.configure would result in a recursive loop
3.0.0-rc.1
Breaking Changes
- Adds
PaywallInfo
toSuperwallDelegate
methodspaywallWillPresent(withInfo:)
,paywallDidPresent(withInfo:)
,paywallWillDismiss(withInfo:)
andpaywallDidDismiss(withInfo:)
. - Renames
SuperwallDelegate
methoddidTrackSuperwallEventInfo(_:SuperwallEventInfo)
tohandleSuperwallEvent(withInfo eventInfo: SuperwallEventInfo)
for clarity - Renames
SuperwallDelegate
methodswillOpenURL(url:)
andwillOpenDeepLink(url:)
topaywallWillOpenURL(url:)
andpaywallWillOpenDeepLink(url:)
respectively - Decouples associated value of
.dismissed
inSuperwall.shared.track()
closure toPaywallInfo
andDismissState
. - Changes
subscription_status_did_change
tosubscriptionStatus_didChange
. - Renames
TrackResult
toPresentationResult
Enhancements
- Introducing
Superwall.shared.register(event:params:handler:feature)
, Superwall's most powerful feature yet. Wrap your features with this method to conditionally show paywalls, lock features and more. - Adds a drawer display option which displays the paywall at 70% screen height on iOS 16 iPhones.
- Adds warning if setting subscription status without passing through a PurchaseController during config.
- Adds
$is_feature_gatable
standard property to register and track calls - Cleans up and reformats SDK logs
Fixes
- Fixes a long term bug where tracking an event to show a paywall and tracking an event that results in noRuleMatch would interfere with each other and cause the trigger session to be set to
nil
. This resulted in some paywall data being incorrect on the dashboard.
3.0.0-beta.8
Enhancements
- Prevents the tracking of events that have the same name as internally tracked
SuperwallEvents
likepaywall_open
.
Fixes
- Fixes an issue with reporting in the dashboard due to a mismatch of keys between client and server.