Skip to content

Commit

Permalink
Merge pull request #188 from superwall-me/develop
Browse files Browse the repository at this point in the history
v3.4.5
  • Loading branch information
yusuftor committed Dec 11, 2023
2 parents 331a71f + 8873560 commit f1f2b0b
Show file tree
Hide file tree
Showing 48 changed files with 565 additions and 369 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,18 @@

The changelog for `SuperwallKit`. Also see the [releases](https://github.com/superwall-me/Superwall-iOS/releases) on GitHub.

## 3.4.5

### Enhancements

- Adds internal feature flag to disable verbose events like `paywallResponseLoad_start`.
- Tracks a Superwall Event `reset` whenever `Superwall.shared.reset()` is called.

### Fixes

- Fixes issue where holdouts were still matching even if the limit set for their corresponding rules were exceeded.
- Fixes potential crash if the free trial notification delay was set to zero seconds.

## 3.4.4

### Enhancements
Expand Down
Expand Up @@ -170,6 +170,12 @@ enum InternalSuperwallEvent {
func getSuperwallParameters() async -> [String: Any] { [:] }
}

struct Reset: TrackableSuperwallEvent {
let superwallEvent: SuperwallEvent = .reset
var customParameters: [String: Any] = [:]
func getSuperwallParameters() async -> [String: Any] { [:] }
}

struct AppClose: TrackableSuperwallEvent {
let superwallEvent: SuperwallEvent = .appClose
var customParameters: [String: Any] = [:]
Expand Down Expand Up @@ -258,6 +264,7 @@ enum InternalSuperwallEvent {

struct TriggerFire: TrackableSuperwallEvent {
let triggerResult: InternalTriggerResult
let sessionId: String
var superwallEvent: SuperwallEvent {
return .triggerFire(
eventName: triggerName,
Expand All @@ -266,16 +273,13 @@ enum InternalSuperwallEvent {
}
let triggerName: String
var customParameters: [String: Any] = [:]
unowned let sessionEventsManager: SessionEventsManager

func getSuperwallParameters() async -> [String: Any] {
var params: [String: Any] = [
"trigger_name": triggerName
]

if let triggerSession = await sessionEventsManager.triggerSession.activeTriggerSession {
params["trigger_session_id"] = triggerSession.id
}
params["trigger_session_id"] = sessionId

switch triggerResult {
case .noRuleMatch(let unmatchedRules):
Expand Down
18 changes: 16 additions & 2 deletions Sources/SuperwallKit/Analytics/Internal Tracking/Tracking.swift
Expand Up @@ -40,12 +40,26 @@ extension Superwall {
)
}

let eventData = EventData(
let eventData = EventData(
name: event.rawName,
parameters: JSON(parameters.eventParams),
createdAt: eventCreatedAt
)
await dependencyContainer.queue.enqueue(event: eventData.jsonData)

// If config doesn't exist yet we rely on previous saved feature flag
// to determine whether to disable verbose events.
let existingDisableVerboseEvents = dependencyContainer.configManager.config?.featureFlags.disableVerboseEvents
let previousDisableVerboseEvents = dependencyContainer.storage.get(DisableVerboseEvents.self)

let verboseEvents = existingDisableVerboseEvents ?? previousDisableVerboseEvents

if TrackingLogic.isNotDisabledVerboseEvent(
event,
disableVerboseEvents: verboseEvents,
isSandbox: dependencyContainer.makeIsSandbox()
) {
await dependencyContainer.queue.enqueue(event: eventData.jsonData)
}
dependencyContainer.storage.coreDataManager.saveEventData(eventData)

if event.canImplicitlyTriggerPaywall {
Expand Down
Expand Up @@ -83,6 +83,52 @@ enum TrackingLogic {
)
}

static func isNotDisabledVerboseEvent(
_ event: Trackable,
disableVerboseEvents: Bool?,
isSandbox: Bool
) -> Bool {
guard let disableVerboseEvents = disableVerboseEvents else {
return true
}
if isSandbox {
return true
}

if event is InternalSuperwallEvent.PresentationRequest {
return !disableVerboseEvents
}

if let event = event as? InternalSuperwallEvent.PaywallLoad {
switch event.state {
case .start, .complete:
return !disableVerboseEvents
default:
return true
}
}

if let event = event as? InternalSuperwallEvent.PaywallProductsLoad {
switch event.state {
case .start, .complete:
return !disableVerboseEvents
default:
return true
}
}

if let event = event as? InternalSuperwallEvent.PaywallWebviewLoad {
switch event.state {
case .start, .complete:
return !disableVerboseEvents
default:
return true
}
}

return true
}

/// Makes optional variables non-optional. Removes `nil`, `NSArray`, `NSDictionary`, and anything that can't be `JSON`, `Date` or `URL`.
private static func clean(input: Any?) -> Any? {
guard let input = input else {
Expand Down
Expand Up @@ -149,6 +149,9 @@ public enum SuperwallEvent {
/// When the user chose the close button on a survey instead of responding.
case surveyClose

/// When ``Superwall/reset()`` is called.
case reset

var canImplicitlyTriggerPaywall: Bool {
switch self {
case .appInstall,
Expand Down Expand Up @@ -265,6 +268,8 @@ extension SuperwallEvent {
return .init(objcEvent: .touchesBegan)
case .surveyClose:
return .init(objcEvent: .surveyClose)
case .reset:
return .init(objcEvent: .reset)
}
}
}
Expand Down
Expand Up @@ -136,6 +136,9 @@ public enum SuperwallEventObjc: Int, CaseIterable {
/// When the user taps the close button to skip the survey without recording a response.
case surveyClose

/// When ``Superwall/reset()`` is called.
case reset

public init(event: SuperwallEvent) {
self = event.backingData.objcEvent
}
Expand Down Expand Up @@ -218,6 +221,8 @@ public enum SuperwallEventObjc: Int, CaseIterable {
return "touches_began"
case .surveyClose:
return "survey_close"
case .reset:
return "reset"
}
}
}
Expand Up @@ -91,7 +91,7 @@ extension TriggerSession.Transaction {
type: introductoryPrice.type
)

self.introductoryRedeemable = await Superwall.shared.dependencyContainer.storeKitManager.isFreeTrialAvailable(for: product)
self.introductoryRedeemable = await Superwall.shared.dependencyContainer.receiptManager.isFreeTrialAvailable(for: product)
self.hasIntroductoryOffer = true
} else {
self.hasIntroductoryOffer = false
Expand Down
Expand Up @@ -175,8 +175,8 @@ actor TriggerSessionManager {
if let triggerResult = triggerResult {
let trackedEvent = InternalSuperwallEvent.TriggerFire(
triggerResult: triggerResult,
triggerName: eventName,
sessionEventsManager: sessionEventsManager
sessionId: session.id,
triggerName: eventName
)
_ = await trackEvent(trackedEvent)
}
Expand Down
18 changes: 12 additions & 6 deletions Sources/SuperwallKit/Config/ConfigManager.swift
Expand Up @@ -46,15 +46,15 @@ class ConfigManager {
/// A task that is non-`nil` when preloading all paywalls.
private var currentPreloadingTask: Task<Void, Never>?

private let factory: RequestFactory & RuleAttributesFactory
private let factory: RequestFactory & RuleAttributesFactory & ReceiptFactory

init(
options: SuperwallOptions?,
storeKitManager: StoreKitManager,
storage: Storage,
network: Network,
paywallManager: PaywallManager,
factory: RequestFactory & RuleAttributesFactory
factory: RequestFactory & RuleAttributesFactory & ReceiptFactory
) {
if let options = options {
self.options = options
Expand All @@ -68,17 +68,16 @@ class ConfigManager {

func fetchConfiguration() async {
do {
await storeKitManager.loadPurchasedProducts()
_ = await factory.loadPurchasedProducts()

let config = try await network.getConfig { [weak self] in
self?.configState.send(.retrying)
}

Task { await sendProductsBack(from: config) }

triggersByEventName = ConfigLogic.getTriggersByEventName(from: config.triggers)
choosePaywallVariants(from: config.triggers)
await checkForTouchesBeganTrigger(in: config.triggers)
await processConfig(config)

configState.send(.retrieved(config))

Task { await preloadPaywalls() }
Expand All @@ -94,6 +93,13 @@ class ConfigManager {
}
}

private func processConfig(_ config: Config) async {
storage.save(config.featureFlags.disableVerboseEvents, forType: DisableVerboseEvents.self)
triggersByEventName = ConfigLogic.getTriggersByEventName(from: config.triggers)
choosePaywallVariants(from: config.triggers)
await checkForTouchesBeganTrigger(in: config.triggers)
}

/// Reassigns variants and preloads paywalls again.
func reset() {
guard let config = configState.value.getConfig() else {
Expand Down
9 changes: 7 additions & 2 deletions Sources/SuperwallKit/Config/Models/FeatureFlags.swift
Expand Up @@ -17,6 +17,7 @@ struct FeatureFlags: Decodable {
var enablePostback: Bool
var enableExpressionParameters: Bool
var enableUserIdSeed: Bool
var disableVerboseEvents: Bool

enum CodingKeys: String, CodingKey {
case toggles
Expand All @@ -30,18 +31,21 @@ struct FeatureFlags: Decodable {
enableExpressionParameters = rawFeatureFlags.value(forKey: "enable_expression_params", default: false)
enablePostback = rawFeatureFlags.value(forKey: "enable_postback", default: false)
enableUserIdSeed = rawFeatureFlags.value(forKey: "enable_userid_seed", default: false)
disableVerboseEvents = rawFeatureFlags.value(forKey: "disable_verbose_events", default: false)
}

init(
enableSessionEvents: Bool,
enablePostback: Bool,
enableExpressionParameters: Bool,
enableUserIdSeed: Bool
enableUserIdSeed: Bool,
disableVerboseEvents: Bool
) {
self.enableSessionEvents = enableSessionEvents
self.enablePostback = enablePostback
self.enableExpressionParameters = enableExpressionParameters
self.enableUserIdSeed = enableUserIdSeed
self.disableVerboseEvents = disableVerboseEvents
}
}

Expand All @@ -63,7 +67,8 @@ extension FeatureFlags: Stubbable {
enableSessionEvents: true,
enablePostback: true,
enableExpressionParameters: true,
enableUserIdSeed: true
enableUserIdSeed: true,
disableVerboseEvents: true
)
}
}
23 changes: 0 additions & 23 deletions Sources/SuperwallKit/Debug/SWBounceButton.swift
Expand Up @@ -23,9 +23,7 @@ final class SWBounceButton: UIButton {
var toggleKey = "key"
var isOn = false
var canToggle = false

var oldTitle: String = ""

var showLoading = false {
didSet {
if showLoading {
Expand Down Expand Up @@ -53,15 +51,6 @@ final class SWBounceButton: UIButton {
return view
}()

var customTint: UIColor? {
didSet {
if let customTint = customTint {
backgroundColor = customTint.withAlphaComponent(0.15)
setTitleColor(customTint, for: .normal)
}
}
}

var onBackgroundColor: UIColor = primaryButtonBackgroundColor
var offBackgroundColor: UIColor = secondaryButtonBackgroundColor

Expand Down Expand Up @@ -94,14 +83,6 @@ final class SWBounceButton: UIButton {
}
}

private var _borderColor: UIColor?
var borderColor: UIColor? {
didSet {
_borderColor = borderColor
self.layer.borderColor = (borderColor ?? UIColor.clear).cgColor
}
}

// MARK: - Initializers
convenience init() {
self.init(frame: CGRect())
Expand Down Expand Up @@ -201,10 +182,6 @@ final class SWBounceButton: UIButton {
}
}

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
self.borderColor = _borderColor
}

override func didMoveToSuperview() {
super.didMoveToSuperview()
if canToggle {
Expand Down

0 comments on commit f1f2b0b

Please sign in to comment.