Post

Replies

Boosts

Views

Activity

Reply to Cannot add SKPaymentTransactionObserver in Unit Test
This is the example of storekit file. You can save it as file named ShopStoreKitConfig.storekit in your project. {  "identifier" : "BB337E99",  "nonRenewingSubscriptions" : [  ],  "products" : [   {    "displayPrice" : "4.99",    "familyShareable" : false,    "internalID" : "60FA6345",    "localizations" : [     {      "description" : "Unlimited battery for 1 day",      "displayName" : "Unlimited battery for 1 day",      "locale" : "en_US"     }    ],    "productID" : "prod_sale1_battery_1_day",    "referenceName" : “Unlimited battery for 1 day”,    "type" : "Consumable"   },  ],  "settings" : {  },  "subscriptionGroups" : [  ],  "version" : {   "major" : 1,   "minor" : 1  } }
Mar ’23
Reply to Cannot add SKPaymentTransactionObserver in Unit Test
The problem is not that an observer cannot be added but an observer is worked async. So, it should be written by using expectation. For using expectation's fulfill, it need to callback after observer is updated or removed transaction. class ProxySKProductTransactionObserver: NSObject, SKPaymentTransactionObserver {   var origin: SKPaymentTransactionObserver   var updatedTransactionsPostCallback: ((SKPaymentQueue, [SKPaymentTransaction]) -> Void)?   var removedTransactionsPostCallback: ((SKPaymentQueue, [SKPaymentTransaction]) -> Void)?       init(_ origin: SKPaymentTransactionObserver) {     self.origin = origin   }       func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {     origin.paymentQueue(queue, updatedTransactions: transactions)     updatedTransactionsPostCallback?(queue, transactions)   }       func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {     origin.paymentQueue?(queue, removedTransactions: transactions)     removedTransactionsPostCallback?(queue, transactions)   } } After using expectation, test is passed import XCTest import StoreKitTest @available(iOS 14.0, *) final class SimpleSKProductTransactionObserverTest: XCTestCase {   var sut: MockSKProductTransactionObserver!   var proxy: ProxySKProductTransactionObserver!   var session: SKTestSession!       override func setUpWithError() throws {     session = try SKTestSession(configurationFileNamed: "ShopStoreKitConfig")     session.resetToDefaultState()     session.disableDialogs = true     session.clearTransactions()           sut = .init()     proxy = .init(sut)           SKPaymentQueue.default().add(proxy)   }       override func tearDownWithError() throws {     SKPaymentQueue.default().remove(proxy)     proxy = nil     sut = nil     session = nil   }       func testPaymentQueue() throws {     let productId = "prod_sale1_battery_1_day"     let expectation = self.expectation(description: "updatedTransaction is called")           proxy.updatedTransactionsPostCallback = { _, _ in       expectation.fulfill()     }           try session.buyProduct(productIdentifier: productId)           waitForExpectations(timeout: 5)           XCTAssertTrue(sut.isPaymentQueueCalled)     XCTAssertEqual(sut.previousTransactions.first?.payment.productIdentifier, productId)   } } class MockSKProductTransactionObserver: NSObject, SKPaymentTransactionObserver {   var previousTransactions = [SKPaymentTransaction]()   var isPaymentQueueCalled = false       func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {     isPaymentQueueCalled = true     previousTransactions = transactions   } }
Jan ’23