SwiftyStoreKit v0.9.0 Release Notes

  • NOTE This release introduces some API breaking changes (see #202). Change-set:

    #198: Subscription verification unit tests

    🛠 #199 (fixes #192, #190 and #65): Add ReceiptItem to VerifyPurchaseResult, VerifySubscriptionResult

    This change introduces a new strong-typed ReceiptItem struct:

    public struct ReceiptItem {
        // The product identifier of the item that was purchased. This value corresponds to the productIdentifier property of the SKPayment object stored in the transaction’s payment property.
        public let productId: String
        // The number of items purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction’s payment property.
        public let quantity: Int
        // The transaction identifier of the item that was purchased. This value corresponds to the transaction’s transactionIdentifier property.
        public let transactionId: String
        // For a transaction that restores a previous transaction, the transaction identifier of the original transaction. Otherwise, identical to the transaction identifier. This value corresponds to the original transaction’s transactionIdentifier property. All receipts in a chain of renewals for an auto-renewable subscription have the same value for this field.
        public let originalTransactionId: String
        // The date and time that the item was purchased. This value corresponds to the transaction’s transactionDate property.
        public let purchaseDate: Date
        // For a transaction that restores a previous transaction, the date of the original transaction. This value corresponds to the original transaction’s transactionDate property. In an auto-renewable subscription receipt, this indicates the beginning of the subscription period, even if the subscription has been renewed.
        public let originalPurchaseDate: Date
        // The primary key for identifying subscription purchases.
        public let webOrderLineItemId: String
        // The expiration date for the subscription, expressed as the number of milliseconds since January 1, 1970, 00:00:00 GMT. This key is only present for auto-renewable subscription receipts.
        public let subscriptionExpirationDate: Date?
        // For a transaction that was canceled by Apple customer support, the time and date of the cancellation. Treat a canceled receipt the same as if no purchase had ever been made.
        public let cancellationDate: Date?
    
        public let isTrialPeriod: Bool
    }
    

    📜 This is parsed from the receipt and returned as part of the verifySubscription and verifyPurchase methods:

    // Result for Consumable and NonConsumable
    public enum VerifyPurchaseResult {
        case purchased(item: ReceiptItem)
        case notPurchased
    }
    
    // Verify subscription result
    public enum VerifySubscriptionResult {
        case purchased(expiryDate: Date, items: [ReceiptItem])
        case expired(expiryDate: Date, items: [ReceiptItem])
        case notPurchased
    }
    

    Note that when one or more subscriptions are found for a given product id, they are returned as a ReceiptItem array ordered by expiryDate, with the first one being the newest.

    This is useful to get all the valid date ranges for a given subscription.

    #202 (fix for #200): It's now possible to specify the quantity when making a purchase. Quantity is also accessible in the callback.

    This is an API breaking change. Product has been renamed to Purchase:

    public struct Purchase {
        public let productId: String
        public let quantity: Int
        public let transaction: PaymentTransaction
        public let needsFinishTransaction: Bool
    }
    

    PurchaseResult

    public enum PurchaseResult {
        //case success(product: Product) // old
        case success(purchase: Purchase) // new
        case error(error: SKError)
    }
    

    RestoreResults

    public struct RestoreResults {
        //public let restoredProducts: [Product] // old
        //public let restoreFailedProducts: [(SKError, String?)] // old
        public let restoredPurchases: [Purchase] // new
        public let restoreFailedPurchases: [(SKError, String?)] // new
    }
    

    #203 (fix for #193): Add originalTransaction from SKPaymentTransaction.original to Payment type