From 10a028dcf39c0cbce2f8bca5f93102b487be7562 Mon Sep 17 00:00:00 2001 From: Andrea Bizzotto Date: Wed, 11 Oct 2017 21:13:47 +0200 Subject: [PATCH 1/2] Update ReceiptValidator and FetchReceiptResult to use receipt as Data rather than String. Validators can then convert with receiptData.base64EncodedString(options: []) --- README.md | 3 ++- SwiftyStoreKit/AppleReceiptValidator.swift | 5 +++-- SwiftyStoreKit/InAppReceiptVerificator.swift | 18 ++++++------------ SwiftyStoreKit/SwiftyStoreKit+Types.swift | 4 ++-- .../InAppReceiptVerificatorTests.swift | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 9af75dbd..29aae273 100644 --- a/README.md +++ b/README.md @@ -289,7 +289,8 @@ Use this method to get the updated receipt: ```swift SwiftyStoreKit.fetchReceipt(forceRefresh: true) { result in switch result { - case .success(let encryptedReceipt): + case .success(let receiptData): + let encryptedReceipt = receiptData.base64EncodedString(options: []) print("Fetch receipt success:\n\(encryptedReceipt)") case .error(let error): print("Fetch receipt failed: \(error)") diff --git a/SwiftyStoreKit/AppleReceiptValidator.swift b/SwiftyStoreKit/AppleReceiptValidator.swift index 1f961ac1..9b27a10d 100644 --- a/SwiftyStoreKit/AppleReceiptValidator.swift +++ b/SwiftyStoreKit/AppleReceiptValidator.swift @@ -47,12 +47,13 @@ public struct AppleReceiptValidator: ReceiptValidator { self.sharedSecret = sharedSecret } - public func validate(receipt: String, completion: @escaping (VerifyReceiptResult) -> Void) { + public func validate(receiptData: Data, completion: @escaping (VerifyReceiptResult) -> Void) { let storeURL = URL(string: service.rawValue)! // safe (until no more) let storeRequest = NSMutableURLRequest(url: storeURL) storeRequest.httpMethod = "POST" + let receipt = receiptData.base64EncodedString(options: []) let requestContents: NSMutableDictionary = [ "receipt-data": receipt ] // password if defined if let password = sharedSecret { @@ -106,7 +107,7 @@ public struct AppleReceiptValidator: ReceiptValidator { let receiptStatus = ReceiptStatus(rawValue: status) ?? ReceiptStatus.unknown if case .testReceipt = receiptStatus { let sandboxValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: self.sharedSecret) - sandboxValidator.validate(receipt: receipt, completion: completion) + sandboxValidator.validate(receiptData: receiptData, completion: completion) } else { if receiptStatus.isValid { completion(.success(receipt: receiptInfo)) diff --git a/SwiftyStoreKit/InAppReceiptVerificator.swift b/SwiftyStoreKit/InAppReceiptVerificator.swift index 0ad95acf..d49ba5dd 100644 --- a/SwiftyStoreKit/InAppReceiptVerificator.swift +++ b/SwiftyStoreKit/InAppReceiptVerificator.swift @@ -56,8 +56,8 @@ class InAppReceiptVerificator: NSObject { fetchReceipt(forceRefresh: forceRefresh, refresh: refresh) { result in switch result { - case .success(let encryptedReceipt): - self.verify(receipt: encryptedReceipt, using: validator, completion: completion) + case .success(let receiptData): + self.verify(receiptData: receiptData, using: validator, completion: completion) case .error(let error): completion(.error(error: error)) } @@ -77,7 +77,7 @@ class InAppReceiptVerificator: NSObject { completion: @escaping (FetchReceiptResult) -> Void) { if let receiptData = appStoreReceiptData, forceRefresh == false { - fetchReceiptSuccessHandler(receiptData: receiptData, completion: completion) + completion(.success(receiptData: receiptData)) } else { receiptRefreshRequest = refresh(nil) { result in @@ -87,7 +87,7 @@ class InAppReceiptVerificator: NSObject { switch result { case .success: if let receiptData = self.appStoreReceiptData { - self.fetchReceiptSuccessHandler(receiptData: receiptData, completion: completion) + completion(.success(receiptData: receiptData)) } else { completion(.error(error: .noReceiptData)) } @@ -97,21 +97,15 @@ class InAppReceiptVerificator: NSObject { } } } - - private func fetchReceiptSuccessHandler(receiptData: Data, completion: (FetchReceiptResult) -> Void) { - - let base64EncodedString = receiptData.base64EncodedString(options: []) - completion(.success(encryptedReceipt: base64EncodedString)) - } /** * - Parameter receiptData: encrypted receipt data * - Parameter validator: Validator to check the encrypted receipt and return the receipt in readable format * - Parameter completion: handler for result */ - private func verify(receipt: String, using validator: ReceiptValidator, completion: @escaping (VerifyReceiptResult) -> Void) { + private func verify(receiptData: Data, using validator: ReceiptValidator, completion: @escaping (VerifyReceiptResult) -> Void) { - validator.validate(receipt: receipt) { result in + validator.validate(receiptData: receiptData) { result in DispatchQueue.main.async { completion(result) diff --git a/SwiftyStoreKit/SwiftyStoreKit+Types.swift b/SwiftyStoreKit/SwiftyStoreKit+Types.swift index 1967a71a..fff8cc9b 100644 --- a/SwiftyStoreKit/SwiftyStoreKit+Types.swift +++ b/SwiftyStoreKit/SwiftyStoreKit+Types.swift @@ -45,7 +45,7 @@ public struct PurchaseDetails { //Conform to this protocol to provide custom receipt validator public protocol ReceiptValidator { - func validate(receipt: String, completion: @escaping (VerifyReceiptResult) -> Void) + func validate(receiptData: Data, completion: @escaping (VerifyReceiptResult) -> Void) } // Payment transaction @@ -91,7 +91,7 @@ public enum RefreshReceiptResult { // Fetch receipt result public enum FetchReceiptResult { - case success(encryptedReceipt: String) + case success(receiptData: Data) case error(error: ReceiptError) } diff --git a/SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift b/SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift index 7c81908a..967fd5ed 100644 --- a/SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift +++ b/SwiftyStoreKitTests/InAppReceiptVerificatorTests.swift @@ -28,7 +28,7 @@ import XCTest class TestReceiptValidator: ReceiptValidator { var validateCalled = false - func validate(receipt: String, completion: @escaping (VerifyReceiptResult) -> Void) { + func validate(receiptData: Data, completion: @escaping (VerifyReceiptResult) -> Void) { validateCalled = true completion(.success(receipt: [:])) } From 78b52c670a5c7e3f0386916dd785c48acb2091f7 Mon Sep 17 00:00:00 2001 From: Andrea Bizzotto Date: Wed, 11 Oct 2017 21:17:33 +0200 Subject: [PATCH 2/2] Remove unused RefreshReceiptResult --- SwiftyStoreKit/SwiftyStoreKit+Types.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/SwiftyStoreKit/SwiftyStoreKit+Types.swift b/SwiftyStoreKit/SwiftyStoreKit+Types.swift index fff8cc9b..f4c3a526 100644 --- a/SwiftyStoreKit/SwiftyStoreKit+Types.swift +++ b/SwiftyStoreKit/SwiftyStoreKit+Types.swift @@ -83,12 +83,6 @@ public typealias ShouldAddStorePaymentHandler = (_ payment: SKPayment, _ product // Info for receipt returned by server public typealias ReceiptInfo = [String: AnyObject] -// Refresh receipt result -public enum RefreshReceiptResult { - case success(receiptData: Data) - case error(error: Error) -} - // Fetch receipt result public enum FetchReceiptResult { case success(receiptData: Data)