Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add forceRefresh option to verifyReceipt method #224

Merged
merged 1 commit into from
Jun 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ let receiptString = receiptData.base64EncodedString(options: [])

```swift
let appleValidator = AppleReceiptValidator(service: .production)
SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secret") { result in
SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secret", forceRefresh: false) { result in
switch result {
case .success(let receipt):
print("Verify receipt Success: \(receipt)")
Expand All @@ -272,6 +272,8 @@ SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secre
}
```

Note: you can specify `forceRefresh: true` to force SwiftyStoreKit to refresh the receipt with Apple, even if a local receipt is already stored.

## Verifying purchases and subscriptions

Once you have retrieved the receipt using the `verifyReceipt` method, you can verify your purchases and subscriptions by product identifier.
Expand Down
4 changes: 3 additions & 1 deletion SwiftyStoreKit/InAppReceiptVerificator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ class InAppReceiptVerificator: NSObject {
* * If the receipt is available or is refreshed, validate it
* - Parameter validator: Validator to check the encrypted receipt and return the receipt in readable format
* - Parameter password: Your app’s shared secret (a hexadecimal string). Only used for receipts that contain auto-renewable subscriptions.
* - Parameter forceRefresh: If true, refreshes the receipt even if one already exists.
* - Parameter refresh: closure to perform receipt refresh (this is made explicit for testability)
* - Parameter completion: handler for result
*/
public func verifyReceipt(using validator: ReceiptValidator,
password: String? = nil,
forceRefresh: Bool,
refresh: InAppReceiptRefreshRequest.ReceiptRefresh = InAppReceiptRefreshRequest.refresh,
completion: @escaping (VerifyReceiptResult) -> Void) {

if let receiptData = appStoreReceiptData {
if let receiptData = appStoreReceiptData, forceRefresh == false {

verify(receiptData: receiptData, using: validator, password: password, completion: completion)
} else {
Expand Down
5 changes: 3 additions & 2 deletions SwiftyStoreKit/SwiftyStoreKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,12 @@ extension SwiftyStoreKit {
* Verify application receipt
* - Parameter validator: receipt validator to use
* - Parameter password: Only used for receipts that contain auto-renewable subscriptions. Your app’s shared secret (a hexadecimal string).
* - Parameter forceRefresh: If true, refreshes the receipt even if one already exists.
* - Parameter completion: handler for result
*/
public class func verifyReceipt(using validator: ReceiptValidator, password: String? = nil, completion: @escaping (VerifyReceiptResult) -> Void) {
public class func verifyReceipt(using validator: ReceiptValidator, password: String? = nil, forceRefresh: Bool = false, completion: @escaping (VerifyReceiptResult) -> Void) {

sharedInstance.receiptVerificator.verifyReceipt(using: validator, password: password, completion: completion)
sharedInstance.receiptVerificator.verifyReceipt(using: validator, password: password, forceRefresh: forceRefresh, completion: completion)
}

/**
Expand Down
36 changes: 28 additions & 8 deletions SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class InAppReceiptVerificatorTests: XCTestCase {
let verificator = InAppReceiptVerificator(appStoreReceiptURL: nil)

var refreshCalled = false
verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

refreshCalled = true
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)
Expand All @@ -95,7 +95,27 @@ class InAppReceiptVerificatorTests: XCTestCase {
let verificator = InAppReceiptVerificator(appStoreReceiptURL: testReceiptURL)

var refreshCalled = false
verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

refreshCalled = true
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)

}) { _ in

}
XCTAssertTrue(refreshCalled)
}

func testVerifyReceipt_when_appStoreReceiptURLIsNotNil_hasReceiptData_forceRefreshIsTrue_then_callsRefresh() {

let testReceiptURL = makeReceiptURL()
writeReceiptData(to: testReceiptURL)

let validator = TestReceiptValidator()
let verificator = InAppReceiptVerificator(appStoreReceiptURL: testReceiptURL)

var refreshCalled = false
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: true, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

refreshCalled = true
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)
Expand All @@ -112,7 +132,7 @@ class InAppReceiptVerificatorTests: XCTestCase {
let verificator = InAppReceiptVerificator(appStoreReceiptURL: nil)
let refreshError = NSError(domain: "", code: 0, userInfo: nil)

verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

callback(.error(e: refreshError))
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)
Expand All @@ -128,7 +148,7 @@ class InAppReceiptVerificatorTests: XCTestCase {
let validator = TestReceiptValidator()
let verificator = InAppReceiptVerificator(appStoreReceiptURL: nil)

verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

callback(.success)
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)
Expand All @@ -147,7 +167,7 @@ class InAppReceiptVerificatorTests: XCTestCase {
let validator = TestReceiptValidator()
let verificator = InAppReceiptVerificator(appStoreReceiptURL: nil)

verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

writeReceiptData(to: testReceiptURL)
callback(.success)
Expand All @@ -168,7 +188,7 @@ class InAppReceiptVerificatorTests: XCTestCase {
let validator = TestReceiptValidator()
let verificator = InAppReceiptVerificator(appStoreReceiptURL: testReceiptURL)

verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

writeReceiptData(to: testReceiptURL)
callback(.success)
Expand All @@ -182,15 +202,15 @@ class InAppReceiptVerificatorTests: XCTestCase {
}

// MARK: non-refresh tests (receipt url and data are set)
func testVerifyReceipt_when_appStoreReceiptURLIsNotNil_hasReceiptData_then_refreshNotCalled_validateIsCalled() {
func testVerifyReceipt_when_appStoreReceiptURLIsNotNil_hasReceiptData_forceRefreshIsFalse_then_refreshNotCalled_validateIsCalled() {

let testReceiptURL = makeReceiptURL()
writeReceiptData(to: testReceiptURL)

let validator = TestReceiptValidator()
let verificator = InAppReceiptVerificator(appStoreReceiptURL: testReceiptURL)

verificator.verifyReceipt(using: validator, password: nil, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in
verificator.verifyReceipt(using: validator, password: nil, forceRefresh: false, refresh: { (properties, callback) -> InAppReceiptRefreshRequest in

XCTFail("refresh should not be called if we already have a receipt")
return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)
Expand Down