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

Critical issue when app have multi products. #22

Closed
atjason opened this issue Apr 23, 2016 · 10 comments
Closed

Critical issue when app have multi products. #22

atjason opened this issue Apr 23, 2016 · 10 comments

Comments

@atjason
Copy link
Contributor

atjason commented Apr 23, 2016

First, thanks for your framework.

But, after spend days to finish the IAP with your framework, I find a critical issue which prevent me to release this product. This really make me feel upset, change another framework (or implement using Apple's api), or provide help and wait you until this critical issue is fixed?

Steps to reproduce this issue:

  • The App has 2 products to purchase: Plus and Pro.
  • First purchase Plus and succeed.
  • Start to purchase Pro.
  • The problem is, in func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
    • sometimes it has 3 transactions: 1 for Pro with status of Purchasing. 2 for Plus with status of restored (Note: I didn't purchase Plus at this time, I purchase Pro.)
    • sometimes it has 1 transaction for Plus with status of restored (Note: I didn't purchase Plus at this time, I purchase Pro.) I attached the screen capture for this case.
      purchasefailed
    • sometimes it's correct, with normal status of Purchasing (as I even hasn't input password in App Store's pop up dialog.)
  • If has issue in pre-step, it returns, call the handler with SwiftyStoreKit.InternalErrorCode.RestoredPurchaseWhenPurchasing.
    purchasefailed2

This issue doesn't happen every time, but happen 4 times for the 5 test. I guess it's related with the multi-threads/queue. Similar with issue #3 . As AlexCatch said,

I get this error occasionally. It makes the library unusable in Production.

I would like to provide test account if you need. You can also directly contact me beside Github. Thanks.
Jason

@atjason
Copy link
Contributor Author

atjason commented Apr 23, 2016

BTW, at following patch could help me walk around this issue, even I'm not sure it's safe or correct to do it.

    // MARK: SKPaymentTransactionObserver
    func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {

        var transactionResults: [TransactionResult] = []

        for transaction in transactions {
            // Patch start
            if let productIdentifier = product?.productIdentifier {
                if productIdentifier != transaction.payment.productIdentifier {
                    continue
                }
            }
            // Patch end

@bizz84
Copy link
Owner

bizz84 commented Apr 23, 2016

Thank you for reporting this and for the detail in the explanation. I'll try to look into it soon.
Could you send me a separate email with the test account you're using in your tests and the list of available IAPs?

@atjason
Copy link
Contributor Author

atjason commented Apr 23, 2016

Just send another email to b*[email protected] for test account and IAPs, please let me know if you didn't receive it.

@bizz84
Copy link
Owner

bizz84 commented Apr 23, 2016

I opened a PR for this: #24

Would you be able to test on that branch and let me know if it fixes your problem?

With this change I could start two concurrent purchases and only get one completion for each:
paymentqueue

@atjason
Copy link
Contributor Author

atjason commented Apr 23, 2016

Sure, I will test now and feedback later.

@atjason
Copy link
Contributor Author

atjason commented Apr 23, 2016

I test again and it's fine. Thanks.

To be honest, now I'm not familiar with git pull request, so I manually merge code and test. Here are the steps:

  • Manually merge the code (I'm sure the merge is correct).
  • Create a new test account.
  • Buy first product. Succeed.
  • Buy second product. Succeed.

Another information is, I ever integrate SwiftStoreKit by framework, but now I directly copy folder of "SwiftyStoreKit" with swift files into my project to integrate it. The key reason is it's easily to debug.

BTW, another issue I also walk around is, if I already purchase a product, remove the local information and try to purchase again, it will return SwiftyStoreKit.InternalErrorCode.RestoredPurchaseWhenPurchasing in the handler and will not call again. The way I walk around is detect this error, launch another request of verify. If get the product, just tell user the purchase is succeed. But I don't think this is a good way. The error code should tell me this product is already purchased. How do you think? I'm not sure it's related with this issue or not, or should I report another issue?

  func purchaseProductHandler(result: SwiftyStoreKit.PurchaseResult) {
    // some code    
    switch result {
    case .Error(let purchaseError):
      switch purchaseError {
      case .Failed(let errorType):
        let error = errorType as NSError
        if error.domain == SwiftyStoreKitErrorDomain {
          if error.code == SwiftyStoreKit.InternalErrorCode.RestoredPurchaseWhenPurchasing.rawValue {
            verify()
          }
    // some code

@bizz84
Copy link
Owner

bizz84 commented Apr 23, 2016

I'll look into this today or tomorrow.

@bizz84
Copy link
Owner

bizz84 commented Apr 23, 2016

I made some progress and figured out that since each purchase or restore purchase request registers to the same SKPaymentQueue, it's possible that the callbacks get mixed up when multiple requests are running concurrently.

This pull request should address the problem:
#24

Would you be able to test this in your configuration?
To test the latest code you can pull my branch like so:

git clone -b hotfix/transactionQueue-mismatch-fix https://github.com/bizz84/SwiftyStoreKit

@atjason
Copy link
Contributor Author

atjason commented Apr 23, 2016

Great! Will test and update you.

@atjason
Copy link
Contributor Author

atjason commented Apr 24, 2016

This issue should be fixed with the patched. Thanks.

My code didn't change, just replace the SwiftyStoreKit by git clone -b hotfix/transactionQueue-mismatch-fix https://github.com/bizz84/SwiftyStoreKit. This time when purchase a product which ever being purchased, it doesn't return in case of SwiftyStoreKit.InternalErrorCode.RestoredPurchaseWhenPurchasing , but return the case case .Success(let productId).

bizz84 added a commit that referenced this issue Apr 24, 2016
@atjason atjason closed this as completed Apr 25, 2016
@Vithanco Vithanco mentioned this issue Nov 3, 2018
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants