Просмотр исходного кода

Add forceRefresh option to verifyReceipt method

Andrea Bizzotto 8 лет назад
Родитель
Сommit
2ed13981ac

+ 3 - 1
README.md

@@ -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)")
@@ -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.

+ 3 - 1
SwiftyStoreKit/InAppReceiptVerificator.swift

@@ -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 {

+ 3 - 2
SwiftyStoreKit/SwiftyStoreKit.swift

@@ -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)
     }
     
     /**

+ 28 - 8
SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift

@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -182,7 +202,7 @@ 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)
@@ -190,7 +210,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
             
             XCTFail("refresh should not be called if we already have a receipt")
             return TestInAppReceiptRefreshRequest(receiptProperties: properties, callback: callback)