chirag04 / react-native-in-app-utils

A react-native wrapper for handling in-app payments
MIT License
890 stars 185 forks source link

Error when canceling purchase #89

Open zubru opened 7 years ago

zubru commented 7 years ago

I have upgraded my app from react-native 0.34.1 to 0.44 and in-app utils from 2.3.0 to 5.2.3. Eralier everything was working, now I have problem when click on 'Cancel' during purchase, for example when asking for password. It crashes app with error:

JSON value '{ code = ESKERRORDOMAIN2; domain = SKErrorDomain; message = "Nie mo\U017cna po\U0142\U0105czy\U0107 si\U0119 z iTunes Store"; nativeStackIOS = ( "0 APPName 0x00163ba5 RCTJSErrorFromCodeMessageAndNSError + 104", "1 APPName 0x00163b11 RCTJSErrorFromNSError + 218", "2 APPName 0x0020c62f -[InAppUtils paymentQueue:updatedTransactions:] + 518", "3 StoreKit 0x267b36bf + 90", "4 CoreFoundation 0x1aebcbd5 CFArrayApplyFunction + 36", "5 StoreKit 0x267b3657 + 128", "6 StoreKit 0x267b3f2d + 1028", "7 StoreKit 0x267b48b1 + 120", "8 StoreKit 0x267b3575 + 132", "9 libdispatch.dylib 0x003d4467 _dispatch_call_block_and_release + 10", "10 libdispatch.dylib 0x003d4453 _dispatch_client_callout + 22", "11 libdispatch.dylib 0x003d8d47 _dispatch_main_queue_callback_4CF + 1042", "12 CoreFoundation 0x1af6bd69 + 8", "13 CoreFoundation 0x1af69e19 + 848", "14 CoreFoundation 0x1aebd1af CFRunLoopRunSpecific + 470", "15 CoreFoundation 0x1aebcfd1 CFRunLoopRunInMode + 104", "16 GraphicsServices 0x1c667b41 GSEventRunModal + 80", "17 UIKit 0x2023ee13 UIApplicationMain + 150", "18 APPName 0x000ca44f main + 106", "19 libdyld.dylib 0x1a6aa4eb + 2" ); userInfo = { NSLocalizedDescription = "Nie mo\U017cna po\U0142\U0105czy\U0107 si\U0119 z iTunes Store"; }; }' of type NSMutableDictionary cannot be converted to NSString

Purchasing works fine. Tested only on sandbox. Is it some problem with in-app-utils or I did something wrong?

brianomchugh commented 7 years ago

I am getting a similar error:

ExceptionsManager.js:71 JSON value '{
    code = ESKERRORDOMAIN0;
    domain = SKErrorDomain;
    message = "Cannot connect to iTunes Store";
    nativeStackIOS =     (
        "0   AppName                             0x0000000107ac3826 RCTJSErrorFromCodeMessageAndNSError + 134",
        "1   AppName                             0x0000000107ac3753 RCTJSErrorFromNSError + 275",
        "2   AppName                             0x0000000107b9ba68 -[InAppUtils paymentQueue:updatedTransactions:] + 728",
        "3   StoreKit                            0x00000001080ad475 __NotifyObserverAboutChanges + 90",
        "4   CoreFoundation                      0x0000000109a60014 CFArrayApplyFunction + 68",
        "5   StoreKit                            0x00000001080ad406 -[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 143",
        "6   StoreKit                            0x00000001080ae05c -[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1620",
        "7   StoreKit                            0x00000001080aebd3 -[SKPaymentQueue _updatePaymentsForMessage:] + 131",
        "8   StoreKit                            0x00000001080ad2bf __44-[SKPaymentQueue _handleMessage:connection:]_block_invoke + 140",
        "9   libdispatch.dylib                   0x000000010dc51810 _dispatch_call_block_and_release + 12",
        "10  libdispatch.dylib                   0x000000010dc7312e _dispatch_client_callout + 8",
        "11  libdispatch.dylib                   0x000000010dc5a52d _dispatch_main_queue_callback_4CF + 1054",
        "12  CoreFoundation                      0x0000000109ad34f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9",
        "13  CoreFoundation                      0x0000000109a98f8d __CFRunLoopRun + 2205",
        "14  CoreFoundation                      0x0000000109a98494 CFRunLoopRunSpecific + 420",
        "15  GraphicsServices                    0x000000010fcf7a6f GSEventRunModal + 161",
        "16  UIKit                               0x000000010c2f1f34 UIApplicationMain + 159",
        "17  AppName                             0x00000001079835ff main + 111",
        "18  libdyld.dylib                       0x000000010dcbc68d start + 1",
        "19  ???                                 0x0000000000000001 0x0 + 1"
    );
    userInfo =     {
        NSLocalizedDescription = "Cannot connect to iTunes Store";
    };
}' of type NSDictionary cannot be converted to NSString
chirag04 commented 7 years ago

There are some breaking change so going 2.5 to 5.x is not going to be non breaking. I suggest checks the docs again. I am on my phone so can't really tell what's going on here

brianomchugh commented 7 years ago

So react-native is expecting a string, but instead gets the JSON value I posted. Not sure how to fix this, but a dirty workaround is to change line 38 in InAppUtils.m from: callback(@[RCTJSErrorFromNSError(transaction.error)]); to callback(@[RCTErrorUnspecified]);

I can't see what error occurred, but at least I get the callback now... I will try to figure out how to fix it for real.

ryancoughlin commented 7 years ago

Same issue here, not sure what else is happening.

Will try that temp fix in the meantime.

ryancoughlin commented 7 years ago

Shouldn't it just escape the whole workflow? We shouldn't trigger an error when they cancel. Perhaps that fix is ok?

@chirag04 Were you able to take a look at all?

ryancoughlin commented 7 years ago

Playing with this now, will open a PR if I get anywhere for some feedback.

kenandalda commented 7 years ago

Same issue. However, I fixed it by modify the JS code in the purchaseProduct callback.

onPurchaseBtnPress_(product) {
  InAppUtils.purchaseProduct(product.identifier, (error, response) => {
      if (response && response.productIdentifier) {
        AlertIOS.alert('Purchase Successful', 'Your Transaction ID is ' 
          + response.transactionIdentifier);
        //unlock store here.
        this.props.setIAPPurchased(true);
      }
      else if (error) {
        /* error occurs here  */
        //AlertIOS.alert('Purchase Failed', error);
        /* this would fix */
        AlertIOS.alert('Purchase Failed', 'Could not connect to itunes store.');
      }
  });
}

I guess the error occurs in the AlertIOS.alert method because the second argument must be string.

ryancoughlin commented 7 years ago

@kenandalda Great, thanks. I can give this a shot.

As an aside, do you mind sending me a gist of how you're implementing your purchase action and how you toggle that on the component to show the new purchase. I am running into some weird delays after a purchase is made. I have an action that sets purchased to true and I have a conditional based on that prop to render purchased content. Interested in seeing another implementation to compare.

ryancoughlin commented 7 years ago

@kenandalda I have a file that handles the logic for purchasing, etc. here https://github.com/ryancoughlin/Salty/blob/master/app/lib/in-app-purchase.js

And the implementation is: https://github.com/ryancoughlin/Salty/blob/master/app/components/upsell.js

My action for marking a product purchased is a simple boolean that I check in my app.js

brianomchugh commented 7 years ago

On a related note, any idea why the error code I get when cancelling is ESKERRORDOMAIN0, when it should be ESKERRORDOMAIN2?