mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-09 22:35:56 +05:45
* fix(paywalls): preserve workflow context in custom impressions * refactor: simplify offering context copies --------- Co-authored-by: Álvaro Marco <alvaro.marco@revenuecat.com>
66 lines
2.4 KiB
Swift
66 lines
2.4 KiB
Swift
//
|
|
// Copyright RevenueCat Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the MIT License (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://opensource.org/licenses/MIT
|
|
//
|
|
// DefaultCheckpointWorkflowResolver+Offering.swift
|
|
//
|
|
// Created by Rosie Watson on 10/30/26.
|
|
|
|
import Foundation
|
|
|
|
extension DefaultCheckpointWorkflowResolver {
|
|
|
|
func resolveOfferingStep(
|
|
_ rule: CheckpointRule,
|
|
step: WorkflowStep,
|
|
in workflowData: WorkflowDataResult,
|
|
checkpointIdentifier: String,
|
|
traceID: String
|
|
) async -> (resolution: CheckpointResolution, stepEvents: [WorkflowEvent]) {
|
|
guard workflowData.workflow.steps.count == 1 else {
|
|
return (Self.unservable(rule, reason: "an offering step cannot be mixed with other steps"), [])
|
|
}
|
|
// Validated before the step starts, so a step that was never servable emits nothing.
|
|
guard let offeringID = step.offeringIdentifier else {
|
|
return (Self.unservable(rule, reason: "the offering step has no valid offering identifier"), [])
|
|
}
|
|
|
|
return await Self.trackingStepEvents(for: step, in: workflowData, traceID: traceID) {
|
|
guard let offering = await self.offering(identifier: offeringID, for: rule) else {
|
|
return .noAction(.configurationUnavailable)
|
|
}
|
|
|
|
return .matchedOffering(
|
|
offering.withPresentedCheckpointIdentifier(checkpointIdentifier, traceID: traceID)
|
|
.withPresentedWorkflowContext(
|
|
workflowId: workflowData.workflow.id,
|
|
stepId: step.id,
|
|
blobRef: workflowData.workflowBlobRef
|
|
),
|
|
traceID: traceID
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Loads the offerings and picks `identifier` out of them, logging why the rule can't be served when it
|
|
/// isn't there.
|
|
private func offering(
|
|
identifier: String,
|
|
for rule: CheckpointRule
|
|
) async -> Offering? {
|
|
guard let offerings = await self.loadOfferings() else { return nil }
|
|
guard let offering = offerings.offering(identifier: identifier) else {
|
|
Self.unservable(rule, reason: "offering '\(identifier)' is unavailable")
|
|
return nil
|
|
}
|
|
|
|
return offering
|
|
}
|
|
|
|
}
|