Files
purchases-ios/Sources/Purchasing/ProductRequestData+Initialization.swift
T
Antonio Pallares 0c3467ae78 Improve accuracy of transactions origin Part 1: refactor to allow caching transaction metadata (#5940)
* Small cleanup

* add `LocalTransactionDetailsStorage`

* Add models for local transaction metadata caching. Reset PurchasesOrchestrator

* Complete `Codable`, lossless implementation of `LocalTransactionMetadata`

* Rename `LocalTransactionMetadataCache` to `LocalTransactionMetadataStore`

* Comment

* lint

* Remove unnecessary import

* Remove unused method

* Replace `Storefront` with `storeCountry` in both `ProductRequestData` and `PurchasedTransactionData`

This removes the need of a `StorefrontEncodedWrapper` object

* Disambiguate `asDictionary()` method

Now that `SubscriberAttribute` is `Codable`, `Encodable`'s `asDictionary()` and `SubscriberAttribute`'s `asDictionary()` were clashing

* Undo `Codable` conformance of `PresentedOfferingContext` and `TargetingContext`

* lint

* `LocalTransactionMetadata` now refers to a single transaction. `LocalTransactionMetadataStore` now stores one file per transaction and does not use an in-memory cache

* Temporarily remove `LocalTransactionMetadata` and `LocalTransactionMetadataStore` for easier PR review

* Undo `Codable` conformance of `EncodedAppleReceipt`

Not needed for now
2026-01-23 08:29:08 +01:00

91 lines
3.0 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
//
// ProductRequestData+Initialization.swift
//
// Created by Juanpe Catalán on 8/7/21.
//
import Foundation
import StoreKit
extension ProductRequestData {
/// Initializes a `ProductRequestData` from a `StoreProduct`
init(with product: StoreProduct, storeCountry: String?) {
let paymentMode = Self.extractPaymentMode(for: product)
let introPrice = Self.extractIntroPrice(for: product)
let normalDuration = Self.extractNormalDuration(for: product)
let introDuration = Self.extractIntroDuration(for: product)
let introDurationType = Self.extractIntroDurationType(for: product)
let subscriptionGroup = Self.extractSubscriptionGroup(for: product)
let discounts = Self.extractDiscounts(for: product)
self.init(
productIdentifier: product.productIdentifier,
paymentMode: paymentMode,
currencyCode: product.priceFormatter?.currencyCode,
storeCountry: storeCountry,
price: product.price as Decimal,
normalDuration: normalDuration,
introDuration: introDuration,
introDurationType: introDurationType,
introPrice: introPrice as Decimal?,
subscriptionGroup: subscriptionGroup,
discounts: discounts
)
}
}
// MARK: - private methods
private extension ProductRequestData {
static func extractIntroDurationType(for product: StoreProduct) -> StoreProductDiscount.PaymentMode? {
return product.introductoryDiscount?.paymentMode
}
static func extractSubscriptionGroup(for product: StoreProduct) -> String? {
return product.subscriptionGroupIdentifier
}
static func extractDiscounts(for product: StoreProduct) -> [StoreProductDiscount]? {
return product.discounts
}
static func extractPaymentMode(for product: StoreProduct) -> StoreProductDiscount.PaymentMode? {
return product.introductoryDiscount?.paymentMode
}
static func extractIntroPrice(for product: StoreProduct) -> NSDecimalNumber? {
return product.introductoryDiscount?.price as NSDecimalNumber?
}
static func extractNormalDuration(for product: StoreProduct) -> String? {
if let subscriptionPeriod = product.subscriptionPeriod,
subscriptionPeriod.value != 0 {
return ISOPeriodFormatter.string(fromProductSubscriptionPeriod: subscriptionPeriod)
} else {
return nil
}
}
static func extractIntroDuration(for product: StoreProduct) -> String? {
if let subscriptionPeriod = product.introductoryDiscount?.subscriptionPeriod {
return ISOPeriodFormatter.string(fromProductSubscriptionPeriod: subscriptionPeriod)
} else {
return nil
}
}
}