From 8513ad86f34b51e09bf1448d0d949c789a60af1a Mon Sep 17 00:00:00 2001 From: Pavel Tikhonenko Date: Sun, 10 Oct 2021 09:51:36 +0300 Subject: [PATCH] Update README, add purchase restoring functionality --- README.md | 40 ++++++++++++++++++++++++- Sources/Mercato/Mercato+StoreKit.swift | 30 +++++++++++++++++++ Sources/Mercato/Mercato.swift | 5 ++++ Sources/Mercato/ProductService.swift | 10 ++----- www/logo-social.png | Bin 0 -> 27529 bytes 5 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 Sources/Mercato/Mercato+StoreKit.swift create mode 100644 www/logo-social.png diff --git a/README.md b/README.md index 0dbc100..b087230 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,48 @@ [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://mit-license.org) [![Platform](http://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS-lightgrey.svg?style=flat)](https://developer.apple.com/resources/) -[![Language](https://img.shields.io/badge/swift-5.0-orange.svg)](https://developer.apple.com/swift) +[![Language](https://img.shields.io/badge/swift-5.5-orange.svg)](https://developer.apple.com/swift) Mercato is a lightweight In-App Purchases (StoreKit 2) library for iOS, tvOS, watchOS, macOS, and Mac Catalyst. +Installation +------------ + +### Swift Package Manager + +To integrate using Apple's Swift package manager, add the following as a dependency to your `Package.swift`: + +```swift +.package(url: "https://github.com/tikhop/Mercato.git", .upToNextMajor(from: "0.0.1")) +``` + +Then, specify `"Mercato"` as a dependency of the Target in which you wish to use Mercato. + +Lastly, run the following command: +```swift +swift package update +``` + +### CocoaPods + +In progress... + +Then, run the following command: + +```bash +$ pod install +``` + +In any swift file you'd like to use Mercato, import the framework with `import Mercato`. + +### Requirements + +- iOS 15.0 / OSX 12.0 / watchOS 8.0 +- Swift 5.5 + +Usage +------------- + ## Essential Reading * [Apple - Meet StoreKit 2](https://developer.apple.com/videos/play/wwdc2021/10114/) * [Apple - In-App Purchase](https://developer.apple.com/documentation/storekit/in-app_purchase) diff --git a/Sources/Mercato/Mercato+StoreKit.swift b/Sources/Mercato/Mercato+StoreKit.swift new file mode 100644 index 0000000..26650a2 --- /dev/null +++ b/Sources/Mercato/Mercato+StoreKit.swift @@ -0,0 +1,30 @@ +// +// File.swift +// +// +// Created by Pavel Tikhonenko on 10.10.2021. +// + +import Foundation +import StoreKit + +typealias RenewalState = Product.SubscriptionInfo.RenewalState + +public extension Product +{ + var isEligibleForIntroOffer: Bool + { + get async + { + await subscription?.isEligibleForIntroOffer ?? false + } + } + + var hasActiveSubscription: Bool + { + get async + { + await (try? subscription?.status.first?.state == RenewalState.subscribed) ?? false + } + } +} diff --git a/Sources/Mercato/Mercato.swift b/Sources/Mercato/Mercato.swift index 10f247e..08227eb 100644 --- a/Sources/Mercato/Mercato.swift +++ b/Sources/Mercato/Mercato.swift @@ -118,6 +118,11 @@ extension Mercato { await shared.beginRefundProcess(for: productID, in: scene) } + + public static func restorePurchases() async throws + { + try await AppStore.sync() + } } func checkVerified(_ result: VerificationResult) throws -> T diff --git a/Sources/Mercato/ProductService.swift b/Sources/Mercato/ProductService.swift index ebea908..d271633 100644 --- a/Sources/Mercato/ProductService.swift +++ b/Sources/Mercato/ProductService.swift @@ -17,7 +17,9 @@ class ProductService { do { - return try await Product.products(for: productIds) + let products = try await Product.products(for: productIds) + cachedProducts = products + return products }catch{ throw MercatoError.storeKit(error: error as! StoreKitError) } @@ -36,12 +38,6 @@ class ProductService } let transaction = try checkVerified(result) - - //Ignore revoked transactions, they're no longer purchased. - - //For subscriptions, a user can upgrade in the middle of their subscription period. The lower service - //tier will then have the `isUpgraded` flag set and there will be a new transaction for the higher service - //tier. Ignore the lower service tier transactions which have been upgraded. return transaction.revocationDate == nil && !transaction.isUpgraded } } diff --git a/www/logo-social.png b/www/logo-social.png new file mode 100644 index 0000000000000000000000000000000000000000..544df454513dfd7eac520231cfd61522a168642c GIT binary patch literal 27529 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ⅈ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 literal 0 HcmV?d00001