Skip to content

Commit 2894d3a

Browse files
authored
Release 3.0.1 (#62)
Release `3.0.1`
2 parents 8ac4f11 + f09c737 commit 2894d3a

File tree

14 files changed

+257
-46
lines changed

14 files changed

+257
-46
lines changed

.github/actions/upload_test_coverage_report/action.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,14 @@ runs:
1515
using: "composite"
1616

1717
steps:
18-
- name: Dir
19-
shell: bash
20-
run: pwd && ls -al
2118
- name: Upload coverage reports to Codecov
22-
uses: codecov/codecov-action@v3.1.0
19+
uses: codecov/codecov-action@v4.5.0
2320
with:
2421
token: ${{ inputs.token }}
2522
xcode: true
2623
flags: ${{ inputs.scheme_name }}
2724
xcode_archive_path: test_output/${{ inputs.filename }}.xcresult
28-
- name: Dir
29-
shell: bash
30-
run: pwd && ls -al
3125
- uses: actions/upload-artifact@v4
3226
with:
3327
name: ${{ inputs.filename }}
34-
path: test_output
28+
path: test_output

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
All notable changes to this project will be documented in this file.
33

44
#### 3.x Releases
5-
- `3.0.x` Releases - [`3.0.0`](#300)
5+
- `3.0.x` Releases - [`3.0.0`](#300) | [`3.0.1`](#301)
66
- `3.0.0` Release Candidates - [`3.0.0-rc.1`](#300-rc1) | [`3.0.0-rc.2`](#300-rc2)
77

88
#### 2.x Releases
@@ -11,6 +11,19 @@ All notable changes to this project will be documented in this file.
1111
#### 1.x Releases
1212
- `1.0.x` Releases - [1.0.0](#100)
1313

14+
## [3.0.1](https://github.com/space-code/flare/releases/tag/3.0.1)
15+
Released on 2024-08-09.
16+
17+
## Added
18+
- Implement restoring transactions for StoreKit 1
19+
- Added in Pull Request [#57](https://github.com/space-code/flare/pull/57).
20+
21+
## Updated
22+
- Update `codecov` version
23+
- Updated in Pull Request [#59](https://github.com/space-code/flare/pull/59)
24+
- Update mocks
25+
- Updated in Pull Request [#60](https://github.com/space-code/flare/pull/60)
26+
1427
## [3.0.0](https://github.com/space-code/flare/releases/tag/3.0.0)
1528
Released on 2024-06-15.
1629

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ GEM
4747
open4 (1.3.4)
4848
public_suffix (5.0.3)
4949
rchardet (1.8.0)
50-
rexml (3.2.8)
51-
strscan (>= 3.0.9)
50+
rexml (3.3.3)
51+
strscan
5252
ruby2_keywords (0.0.5)
5353
sawyer (0.9.2)
5454
addressable (>= 2.3.5)

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/Flare/Classes/Flare.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Flare
3-
// Copyright © 2024 Space Code. All rights reserved.
3+
// Copyright © 2023 Space Code. All rights reserved.
44
//
55

66
import struct Log.LogLevel
@@ -153,11 +153,22 @@ extension Flare: IFlare {
153153
try await iapProvider.checkEligibility(productIDs: productIDs)
154154
}
155155

156-
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
157156
public func restore() async throws {
158157
try await iapProvider.restore()
159158
}
160159

160+
public func restore(_ completion: @escaping (Result<Void, any Error>) -> Void) {
161+
iapProvider.restore(completion)
162+
}
163+
164+
public func receipt(updateTransactions: Bool) async throws -> String {
165+
try await iapProvider.refreshReceipt(updateTransactions: updateTransactions)
166+
}
167+
168+
public func receipt(updateTransactions: Bool, completion: @escaping (Result<String, IAPError>) -> Void) {
169+
iapProvider.refreshReceipt(updateTransactions: updateTransactions, completion: completion)
170+
}
171+
161172
#if os(iOS) || VISION_OS
162173
@available(iOS 15.0, *)
163174
@available(macOS, unavailable)

Sources/Flare/Classes/IFlare.swift

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Flare
3-
// Copyright © 2024 Space Code. All rights reserved.
3+
// Copyright © 2023 Space Code. All rights reserved.
44
//
55

66
import Foundation
@@ -105,17 +105,31 @@ public protocol IFlare {
105105
promotionalOffer: PromotionalOffer?
106106
) async throws -> StoreTransaction
107107

108-
/// Refreshes the receipt, representing the user's transactions with your app.
108+
/// Refreshes the receipt and optionally updates transactions.
109109
///
110-
/// - Parameter completion: The closure to be executed when the refresh operation ends.
111-
func receipt(completion: @escaping Closure<Result<String, IAPError>>)
110+
/// - Parameters:
111+
/// - updateTransactions: A boolean indicating whether to update transactions.
112+
/// - If `true`, the method will refresh completed transactions.
113+
/// - If `false`, only the receipt will be refreshed.
114+
/// - completion: A closure that gets called with the result of the refresh operation.
115+
/// - On success, it returns a `Result<String, IAPError>` containing the updated receipt information as a `String`.
116+
/// - On failure, it returns a `Result<String, IAPError>` with an `IAPError` describing the issue.
117+
///
118+
/// - Note: Use this method to handle asynchronous receipt refreshing and transaction updates with completion handler feedback.
119+
func receipt(updateTransactions: Bool, completion: @escaping (Result<String, IAPError>) -> Void)
112120

113-
/// Refreshes the receipt, representing the user's transactions with your app.
121+
/// Refreshes the receipt and optionally updates transactions.
114122
///
115-
/// `IAPError(error:)` if the request did fail with error.
123+
/// - Parameter updateTransactions: A boolean indicating whether to update transactions.
124+
/// - If `true`, the method will refresh completed transactions.
125+
/// - If `false`, only the receipt will be refreshed.
116126
///
117-
/// - Returns: A receipt.
118-
func receipt() async throws -> String
127+
/// - Returns: A `String` containing the updated receipt information.
128+
///
129+
/// - Throws: An `IAPError` if the refresh process encounters an issue.
130+
///
131+
/// - Note: Use this method for an asynchronous refresh operation with error handling and receipt data retrieval.
132+
func receipt(updateTransactions: Bool) async throws -> String
119133

120134
/// Removes a finished (i.e. failed or completed) transaction from the queue.
121135
/// Attempting to finish a purchasing transaction will throw an exception.
@@ -151,9 +165,30 @@ public protocol IFlare {
151165
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
152166
func checkEligibility(productIDs: Set<String>) async throws -> [String: SubscriptionEligibility]
153167

154-
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
168+
/// Restores completed transactions.
169+
///
170+
/// This method initiates the process of restoring any previously completed transactions.
171+
/// It is an asynchronous function that might throw an error if the restoration fails.
172+
///
173+
/// - Throws: An error if the restoration process encounters an issue.
174+
///
175+
/// - Note: This method should be called when you need to restore purchases made by the user on a different device or after
176+
/// reinstallation.
155177
func restore() async throws
156178

179+
/// Restores completed transactions.
180+
///
181+
/// This method initiates the process of restoring any previously completed transactions.
182+
/// It uses a completion handler to provide the result of the restoration process.
183+
///
184+
/// - Parameter completion: A closure that gets called with a `Result` indicating success or failure of the restoration.
185+
/// - On success, it returns `Result<Void, Error>.success(())`.
186+
/// - On failure, it returns `Result<Void, Error>.failure(Error)` with an error describing the issue.
187+
///
188+
/// - Note: Use this method when you need to handle the restoration process asynchronously and provide feedback through the completion
189+
/// handler.
190+
func restore(_ completion: @escaping (Result<Void, Error>) -> Void)
191+
157192
#if os(iOS) || VISION_OS
158193
/// Present the refund request sheet for the specified transaction in a window scene.
159194
///
@@ -259,4 +294,20 @@ public extension IFlare {
259294
) async throws -> StoreTransaction {
260295
try await purchase(product: product, options: options, promotionalOffer: nil)
261296
}
297+
298+
/// Refreshes the receipt, representing the user's transactions with your app.
299+
///
300+
/// - Parameter completion: The closure to be executed when the refresh operation ends.
301+
func receipt(completion: @escaping Closure<Result<String, IAPError>>) {
302+
receipt(updateTransactions: false, completion: completion)
303+
}
304+
305+
/// Refreshes the receipt, representing the user's transactions with your app.
306+
///
307+
/// `IAPError(error:)` if the request did fail with error.
308+
///
309+
/// - Returns: A receipt.
310+
func receipt() async throws -> String {
311+
try await receipt(updateTransactions: false)
312+
}
262313
}

Sources/Flare/Classes/Providers/IAPProvider/IAPProvider.swift

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Flare
3-
// Copyright © 2024 Space Code. All rights reserved.
3+
// Copyright © 2023 Space Code. All rights reserved.
44
//
55

66
import StoreKit
@@ -143,19 +143,46 @@ final class IAPProvider: IIAPProvider {
143143
}
144144
}
145145

146-
func refreshReceipt(completion: @escaping Closure<Result<String, IAPError>>) {
147-
receiptRefreshProvider.refresh(requestID: UUID().uuidString) { [weak self] result in
148-
switch result {
149-
case .success:
150-
if let receipt = self?.receiptRefreshProvider.receipt {
151-
completion(.success(receipt))
152-
} else {
153-
completion(.failure(.receiptNotFound))
146+
func refreshReceipt(updateTransactions: Bool) async throws -> String {
147+
try await withCheckedThrowingContinuation { continuation in
148+
refreshReceipt(updateTransactions: updateTransactions) { result in
149+
continuation.resume(with: result)
150+
}
151+
}
152+
}
153+
154+
func refreshReceipt(updateTransactions: Bool, completion: @escaping (Result<String, IAPError>) -> Void) {
155+
let refresh = { [weak self] in
156+
self?.receiptRefreshProvider.refresh(requestID: UUID().uuidString) { [weak self] result in
157+
switch result {
158+
case .success:
159+
if let receipt = self?.receiptRefreshProvider.receipt {
160+
completion(.success(receipt))
161+
} else {
162+
completion(.failure(.receiptNotFound))
163+
}
164+
case let .failure(error):
165+
completion(.failure(error))
154166
}
155-
case let .failure(error):
156-
completion(.failure(error))
157167
}
158168
}
169+
170+
if updateTransactions {
171+
restore { result in
172+
switch result {
173+
case .success:
174+
refresh()
175+
case let .failure(error):
176+
completion(.failure(IAPError.with(error: error)))
177+
}
178+
}
179+
} else {
180+
refresh()
181+
}
182+
}
183+
184+
func refreshReceipt(completion: @escaping Closure<Result<String, IAPError>>) {
185+
refreshReceipt(updateTransactions: false, completion: completion)
159186
}
160187

161188
func refreshReceipt() async throws -> String {
@@ -192,11 +219,14 @@ final class IAPProvider: IIAPProvider {
192219
return try await eligibilityProvider.checkEligibility(products: products)
193220
}
194221

195-
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
196222
func restore() async throws {
197223
try await purchaseProvider.restore()
198224
}
199225

226+
func restore(_ completion: @escaping (Result<Void, any Error>) -> Void) {
227+
purchaseProvider.restore(completion)
228+
}
229+
200230
#if os(iOS) || VISION_OS
201231
@available(iOS 15.0, *)
202232
@available(macOS, unavailable)

Sources/Flare/Classes/Providers/IAPProvider/IIAPProvider.swift

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Flare
3-
// Copyright © 2024 Space Code. All rights reserved.
3+
// Copyright © 2023 Space Code. All rights reserved.
44
//
55

66
import StoreKit
@@ -103,6 +103,32 @@ public protocol IIAPProvider {
103103
promotionalOffer: PromotionalOffer?
104104
) async throws -> StoreTransaction
105105

106+
/// Refreshes the receipt and optionally updates transactions.
107+
///
108+
/// - Parameters:
109+
/// - updateTransactions: A boolean indicating whether to update transactions.
110+
/// - If `true`, the method will refresh completed transactions.
111+
/// - If `false`, only the receipt will be refreshed.
112+
/// - completion: A closure that gets called with the result of the refresh operation.
113+
/// - On success, it returns a `Result<String, IAPError>` containing the updated receipt information as a `String`.
114+
/// - On failure, it returns a `Result<String, IAPError>` with an `IAPError` describing the issue.
115+
///
116+
/// - Note: Use this method to handle asynchronous receipt refreshing and transaction updates with completion handler feedback.
117+
func refreshReceipt(updateTransactions: Bool, completion: @escaping (Result<String, IAPError>) -> Void)
118+
119+
/// Refreshes the receipt and optionally updates transactions.
120+
///
121+
/// - Parameter updateTransactions: A boolean indicating whether to update transactions.
122+
/// - If `true`, the method will refresh completed transactions.
123+
/// - If `false`, only the receipt will be refreshed.
124+
///
125+
/// - Returns: A `String` containing the updated receipt information.
126+
///
127+
/// - Throws: An `IAPError` if the refresh process encounters an issue.
128+
///
129+
/// - Note: Use this method for an asynchronous refresh operation with error handling and receipt data retrieval.
130+
func refreshReceipt(updateTransactions: Bool) async throws -> String
131+
106132
/// Refreshes the receipt, representing the user's transactions with your app.
107133
///
108134
/// - Parameter completion: The closure to be executed when the refresh operation ends.
@@ -150,9 +176,30 @@ public protocol IIAPProvider {
150176
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
151177
func checkEligibility(productIDs: Set<String>) async throws -> [String: SubscriptionEligibility]
152178

153-
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
179+
/// Restores completed transactions.
180+
///
181+
/// This method initiates the process of restoring any previously completed transactions.
182+
/// It is an asynchronous function that might throw an error if the restoration fails.
183+
///
184+
/// - Throws: An error if the restoration process encounters an issue.
185+
///
186+
/// - Note: This method should be called when you need to restore purchases made by the user on a different device or after
187+
/// reinstallation.
154188
func restore() async throws
155189

190+
/// Restores completed transactions.
191+
///
192+
/// This method initiates the process of restoring any previously completed transactions.
193+
/// It uses a completion handler to provide the result of the restoration process.
194+
///
195+
/// - Parameter completion: A closure that gets called with a `Result` indicating success or failure of the restoration.
196+
/// - On success, it returns `Result<Void, Error>.success(())`.
197+
/// - On failure, it returns `Result<Void, Error>.failure(Error)` with an error describing the issue.
198+
///
199+
/// - Note: Use this method when you need to handle the restoration process asynchronously and provide feedback through the completion
200+
/// handler.
201+
func restore(_ completion: @escaping (Result<Void, Error>) -> Void)
202+
156203
#if os(iOS) || VISION_OS
157204
/// Present the refund request sheet for the specified transaction in a window scene.
158205
///

Sources/Flare/Classes/Providers/PurchaseProvider/IPurchaseProvider.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,29 @@ protocol IPurchaseProvider {
5858
completion: @escaping PurchaseCompletionHandler
5959
)
6060

61-
@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
61+
/// Restores completed transactions.
62+
///
63+
/// This method initiates the process of restoring any previously completed transactions.
64+
/// It is an asynchronous function that might throw an error if the restoration fails.
65+
///
66+
/// - Throws: An error if the restoration process encounters an issue.
67+
///
68+
/// - Note: This method should be called when you need to restore purchases made by the user on a different device or after
69+
/// reinstallation.
6270
func restore() async throws
71+
72+
/// Restores completed transactions.
73+
///
74+
/// This method initiates the process of restoring any previously completed transactions.
75+
/// It uses a completion handler to provide the result of the restoration process.
76+
///
77+
/// - Parameter completion: A closure that gets called with a `Result` indicating success or failure of the restoration.
78+
/// - On success, it returns `Result<Void, Error>.success(())`.
79+
/// - On failure, it returns `Result<Void, Error>.failure(Error)` with an error describing the issue.
80+
///
81+
/// - Note: Use this method when you need to handle the restoration process asynchronously and provide feedback through the completion
82+
/// handler.
83+
func restore(_ completion: @escaping (Result<Void, Error>) -> Void)
6384
}
6485

6586
extension IPurchaseProvider {

0 commit comments

Comments
 (0)