Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Works in Editor but not in IOS device connected to XCODE

Discussion in 'Unity IAP' started by jsx001, Dec 19, 2019.

  1. jsx001

    jsx001

    Joined:
    Nov 28, 2016
    Posts:
    12
    Hi there,
    I have implemented IAP in our project for a single non-consumable purchase.
    We have followed the instructions and it works perfectly in the editor.
    When we run our app on an iPhone we go through the Sandbox purchase, it recognises we have purchased before and prompts to get it again. Next, we get the 'you're all set' message.
    Clicking ok does not then call any of our IAP functions, specifically our OnPurchaseComplete.

    Unity Version 2019.2.15f1

    These are the logs from XCODE
    2019-12-19 20:25:10.975026+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Created

    2019-12-19 20:25:10.976145+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Registered for lifecycle events

    2019-12-19 20:25:11.271527+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Added to the payment queue

    UnityIAP Version: 1.23.1

    2019-12-19 20:26:54.891979+0000 Swiperly[2020:748483] UnityIAP: Requesting 1 products

    2019-12-19 20:26:54.892781+0000 Swiperly[2020:748483] UnityIAP: Requesting product data...

    2019-12-19 20:26:55.834922+0000 Swiperly[2020:749161] UnityIAP: Received 1 products

    2019-12-19 20:26:56.110041+0000 Swiperly[2020:748483] UnityIAP: Transaction 1000000606943210 not pending, nothing to finish here

    UnityIAP Promo: Clearing promo product metadata

    2019-12-19 20:26:56.110745+0000 Swiperly[2020:748483] UnityIAP: Add transaction observer

    2019-12-19 20:26:56.110819+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

    2019-12-19 20:26:56.112257+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Request to initiate queued payments

    2019-12-19 20:26:56.116600+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607284798

    UnityIAP Promo: Clearing promo product metadata

    2019-12-19 20:27:40.428896+0000 Swiperly[2020:748483] UnityIAP: PurchaseProduct: [correct code is here]

    2019-12-19 20:27:40.433988+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

    2019-12-19 20:28:04.140794+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

    2019-12-19 20:28:09.693418+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607287688

    UnityIAP Promo: Clearing promo product metadata
    We have followed the code, which we can breakpoint in XCode, until it goes into the depth of the Unity interface warp system.

    Also none of the buttons update.

    Finally - pressing the restore button - we get the following logs - but again no callbacks.

    2019-12-19 20:49:16.757951+0000 Swiperly[2020:748483] UnityIAP: Restore transactions

    2019-12-19 20:49:23.128785+0000 Swiperly[2020:748483] UnityIAP: RestorePurchase

    2019-12-19 20:49:24.103200+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

    2019-12-19 20:49:24.104717+0000 Swiperly[2020:748483] UnityIAP: PaymentQueueRestoreCompletedTransactionsFinished

    2019-12-19 20:49:24.112193+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607292620

    UnityIAP Promo: Clearing promo product metadata




    Regards

    jon
     
    Last edited: Dec 19, 2019
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  3. jsx001

    jsx001

    Joined:
    Nov 28, 2016
    Posts:
    12
    Hi there,

    Yes, you are correct, I forgot to mention, we are using codeless. So we have a simple purchase manager script with functions
    OnPurchaseComplete and OnPurchaseFailure

    OnPurchaseComplete gets called when we play the game in the editor (we have lots of debug logs).
    But when in xcode it fails to be called.

    It appears to get as far as paymentQueue in UnityPurchasing.m
    In that function, it gets to the switch statement SKPaymentTransactionStateFailed

    the following code:

    NSString* errorCode = [NSString stringWithFormat:mad:"%ld",(long)transaction.error.code];
    UnityPurchasingLog(@"PurchaseFailed: %@", errorCode);

    where transaction.error.code seems to be 2, upshot being that we end up with the debug output of
    PurchaseFailed: 0

    which then means:
    if (errorCodeString == nil) {
    errorCodeString = @"SKErrorUnknown";
    }
    hence the failed callback in csharp doesn't get called.

    Other points of interest:
    in the Editor, the price panel is always zero, however on the devices it is correct.
    On one of the devices where we made a purchase, a look in the itunes purchase history, shows us 2 purchases, one for £0.99 (as expected) and another for £0.00, not sure why.

    Thanks

    jon
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    The Editor doesn't connect to an actual store. Please show a screenshot of your purchase button Inspector properties. Have you configured your products on iTunes Connect, and properly filled out the Apple Business and Tax info? Are you testing via TestFlight? https://docs.unity3d.com/Manual/UnityIAPAppleConfiguration.html
     
  5. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Also, I might add, if this is eventually for a production game, I might recommend scripted IAP vs Codeless, it's much more flexible. For what you're trying to do, you will likely need a Codeless Listener and will probably need to write some code anyway. The Sample IAP project link previously has two projects, the first is scripted IAP and the second is Codeless IAP. Please check out the first project.
     
  6. jsx001

    jsx001

    Joined:
    Nov 28, 2016
    Posts:
    12
    Hi Jeff,
    Thanks for coming back,
    It really is the most simple set up- a single non-consumable to remove ads and access all levels, so I think it should be ideal for Codeless.

    A couple more notes of interest, when running in Xcode, we see all of the startup function debug logs being called, stating the IAP version etc, so its all running ok.

    The buttons are on a UI panel, which I assume is standard, one point of note, the panel in question is deactivated (SetActive(False)) on startup and enabled when a user clicks the store button - not sure if this may have an impact.

    Finally - last night while trying to figure out the objective-c code, we noticed that in the depths of one of the object was an error code saying "Apple_cannot connect to ITunes" or something like that.

    Attached are screenshots of the purchase button, the restore button and the IAP catalog (I have redacted id's etc, however, they all match up ok).

    Finally - we are developing on the legendary Catalina!

    thanks

    jon
     

    Attached Files:

  7. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  8. jsx001

    jsx001

    Joined:
    Nov 28, 2016
    Posts:
    12
    Hi there,

    here is the code - although it never gets called

    thanks

    jon




    Code (CSharp):
    1. public class PurchaseManager : MonoBehaviour
    2. {
    3.     public GameObject iapButton;
    4.  
    5.     public void Awake()
    6.     {
    7.         iapButton.SetActive(true);
    8.     }
    9.      public void OnPurchaseComplete(Product product) {
    10.             Debug.Log("-- Purchased product: " + product.definition.id + ", " + product.definition.ToString() );
    11.          #if UNITY_EDITOR
    12.             StartCoroutine(DisableIapButton() );
    13.          #else
    14.             iapButton.SetActive(false);
    15.         #endif
    16.        
    17.  
    18.         Debug.Log("Setting Purchase preferences");
    19.         // turn ads off
    20.         GameSettings.MakePurchase();
    21.         GameSettings.SetPurchasedAdsOff();
    22.         GameSettings.SetUnlockAllOn();
    23.  
    24.     }
    25.  
    26.     public void OnPurchaseFailure(Product product, PurchaseFailureReason reason)
    27.     {
    28.         Debug.Log("purchase of product: " + product.definition.id + "failed due to " + reason);
    29.            
    30.     }
    31.  
    32.     private IEnumerator DisableIapButton() {
    33.         yield return new WaitForEndOfFrame();
    34.             iapButton.SetActive(false);
    35.     }
    36.  
     
  9. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446