Closed finnvoor closed 1 year ago
Yes to access anything on Superwall.shared
you need to run Superwall.configure
first, but understand you don't need to add that functionality in an app extension. Using isInitialized
for shared code seems the way to go here if you want to use shared code.
Thanks for the suggestions. We actually log Superwall has not been configured. Please call Superwall.configure()
to the console if you access Superwall.shared
before calling configure. But since you ifdef'd out all register calls that wouldn't have shown when debugging. It also creates an assertion failure (i.e. a crash during debug) immediately. We don't want to crash an app in production if we can help it and we assume that developers have tested their code before pushing to production. Ignoring register would lead to more confusion over why a paywall wasn't showing.
I would also advise against ifdefing core functionality like paywall code so that you don't get unexpected issues in production
We don't want to crash an app in production if we can help it
The issue is Superwall is crashing apps in production if you call registerEvent before configure, just with extremely confusing and difficult to debug issues. If you do not call configure, Superwall will slow down your app and randomly crash with misleading error messages. RevenueCat, on the other hand, will instantly fatalError with the obvious error message "Purchases has not been configured. Please call Purchases.configure()".
It seems to me like if an SDK is going to cause a crash in production, it might as well give an obvious error message with the crash. Yes it was developer error, but giving a more obvious error message will save debugging time. This could have been much harder to discover (and still occur if I hadn't ifdef'd superwall) if there was some kind of race condition where registerEvent is only occasionally called before configure.
We're gonna discuss this internally and get back to you!
Investigated this more – the errors you were receiving were due to a recursive call inside the SDK to initialise shared
when the app tried to log the error message. This shouldn't have been happening. This will be fixed in the next update and so only the error message Superwall has not been configured. Please call Superwall.configure()
will show in the logs – but the app won't crash in production. Thanks for spotting this and very sorry you experienced this issue!
We have an app with event tracking, and call
Superwall.shared.register
in a function that also sends the events to 3rd party analytics.We also have an app extension, which I added event tracking to by calling the same methods, but I did not call Superwall.configure because the extension does not need paywalls.
When testing this code from Xcode, no errors were thrown because all our paywall code is ifdef'd out behind #if DEBUG, because seeing the paywall was annoying when debugging. When running from TestFlight however, we were seeing very strange issues with the app crashing randomly, and some features just stalling/not working.
After debugging for days I realised this was due to calling
Superwall.shared.register
without callingSuperwall.configure
, resulting in thousands of various calls inside Superwall breaking.This is my mistake for not realising I was calling register, but I think it would be much better if the Superwall SDK ignored all register/other calls before configure is called, or even just immediately terminated the program to avoid these hard to debug issues. For now I have wrapped all register calls in
guard Superwall.isInitialized
.