I have followed the StoreKit test setup guide and it is worked in integrated test.
After that, I want to create unit test about SKPaymentTransactionObserver.
I have write the unit test code like below.
import XCTest
import StoreKitTest
@available(iOS 14.0, *)
final class SimpleSKProductTransactionObserverTest: XCTestCase {
var sut: MockSKProductTransactionObserver!
var session: SKTestSession!
override func setUpWithError() throws {
session = try SKTestSession(configurationFileNamed: "ShopStoreKitConfig")
session.resetToDefaultState()
session.disableDialogs = true
session.clearTransactions()
sut = .init()
SKPaymentQueue.default().add(sut)
}
override func tearDownWithError() throws {
SKPaymentQueue.default().remove(sut)
sut = nil
session = nil
}
func testPaymentQueue() throws {
let productId = "prod_sale1_battery_1_day"
try session.buyProduct(productIdentifier: productId)
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
}
}
However, it is failed the assert codes.
/Users/jooyoulkim/git/rp_ios/PickaTests/SimpleSKProductTransactionObserverTest.swift:39 testPaymentQueue(): XCTAssertTrue failed
/Users/jooyoulkim/git/rp_ios/PickaTests/SimpleSKProductTransactionObserverTest.swift:40 testPaymentQueue(): XCTAssertEqual failed: ("nil") is not equal to ("Optional("prod_sale1_battery_1_day")")
The other side, I can see that SKPaymentTransactionObserver added in AppDelegate is worked normally.
So, the question is why observer is not added. Please tell me if have any idea about it. Thanks.
Post
Replies
Boosts
Views
Activity
Hello.
I has a plan to release the app with pre-order. And I want to give the user who has preorder to some reward. So I have research about preorder.
Related Doc:
Offering Your Apps for Pre-Order
The preorder_date receipt field helps you identify customers who pre-ordered your app. You can use this information to unlock rewards — such as additional coins in a game — for pre-order customers or display in-app messaging to thank them for their purchase.
responseBody.Receipt
preorder_date
The time the user ordered the app available for pre-order, in a date-time format similar to ISO 8601.
Validating Receipts with the App Store
Fetch the Receipt Data
To retrieve the receipt data from the app on the device, use the appStoreReceiptURL method of NSBundle to locate the app’s receipt, and encode the data in Base64. Send this Base64-encoded data to your server.
I have read these doc and tested verifyReceipt API. Now I know how to verify receipt and how to check if whether preorder date is presented.
However, I cannot know the user has always receipt data.
I have tested fetching the receipt data in Xcode and TestFlight when user is just installed first time. Result is fail and throw error like below:
appStoreReceiptUrlNotFound(url: "/private/var/mobile/Containers/Data/Application/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX/StoreKit/sandboxReceipt")
Unfortunately, I have not found yet how to test for fetching receipt data in preorder status.
Now I have question about preorder.
If app is free and user has purchase nothing, can I fetch receipt data in production app?
If the data cannot be fetched, should I wait the user purchasing something for checking preorder?
Or if someone know how to test this in preorder status, please let me know it.
Thanks for reading.