Files
purchases-ios/Sources/Purchasing/TransactionsFactory.swift
T
NachoSoto 29c034dfc8 Converted CustomerInfo and related types to use Codable (#1496)
### Depends on:
- #1537
- #1540
- #1541
- #1543
- #1546
- #1547
- #1550
- #1551,
- #1565

### Changes

- Removed all custom deserialization code thanks to #1537, #1541, and #1543.
- The format of the customer info response is now very concise and only in one place (`CustomerInfoResponse`) instead of being passed through dictionaries and magic strings everywhere.
- `CustomerInfo` was combining the dictionaries inside of `"subscriptions"` and `"non_subscriptions"`, despite them having different formats. This is now made explicit through type conversions between the two, (see `CustomerInfoResponse.allTransactionsByProductId`).
- Removed all custom `CustomerInfo` errors since deserialization is automatic, and the underlying `Error` information will be provided thanks to `ErrorUtils.logDecodingError`.
- `CustomerInfo` deserialization always wraps errors into `ErrorCode.customerInfoError`, which is now also covered in a new test.
- Added a new snapshot test that covers `CustomerInfo` serialization by storing the result in a JSON file.

### Other changes:
- `CustomerInfo` equality is now automatic through the `CustomerInfoResponse` `Equatable` conformance.
- Simplified `schemaVersion` handling
- All tests still use `CustomerInfo(data: [String: Any])`, but that method is only visible for tests now, and it uses the underlying `Decodable` implementation (see `CustomerInfo+TestExtensions.swift`).
- Added extra tests for `CustomerInfoResponse` that use a fixture `CustomerInfo.json`, which is easier to maintain than having JSON in code.
- `RawDataContainer` implementation is changed in #1565.

### TODO:
- [x] Fix all tests
- [x] Update `RawValueContainer`
- [x] Consider recovering `CustomerInfoError`
- [x] Look at all previously logged errors
- [x] Finish `CustomerInfoResponseTests`
- [x] Handle all TODOs
- [x] Make `RawDataContainer` actually store all the original data: #1565
2022-05-24 14:22:11 -07:00

58 lines
1.8 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
//
// TransactionsFactory.swift
//
// Created by RevenueCat.
//
import Foundation
enum TransactionsFactory {
static func nonSubscriptionTransactions(
withSubscriptionsData subscriptionsData: [String: [CustomerInfoResponse.Transaction]]
) -> [StoreTransaction] {
subscriptionsData
.flatMap { (productID, transactions) -> [StoreTransaction] in
transactions
.lazy
.compactMap { BackendParsedTransaction(with: $0, productID: productID) }
.map { StoreTransaction($0) }
}
.sorted { $0.purchaseDate < $1.purchaseDate }
}
}
/// `StoreTransactionType` backed by data parsed from the server
private struct BackendParsedTransaction: StoreTransactionType {
let productIdentifier: String
let purchaseDate: Date
let transactionIdentifier: String
let quantity: Int
init?(with transaction: CustomerInfoResponse.Transaction, productID: String) {
guard let transactionIdentifier = transaction.transactionIdentifier,
let purchaseDate = transaction.purchaseDate else {
Logger.error("Couldn't initialize Transaction. " +
"Reason: missing data: \(transaction).")
return nil
}
self.transactionIdentifier = transactionIdentifier
self.purchaseDate = purchaseDate
self.productIdentifier = productID
// Defaulting to `1` since multi-quantity purchases aren't currently supported.
self.quantity = 1
}
}