Search Unity

[Solved] Android IAP : switch target store at runtime vs. buildtime ?

Discussion in 'Unity IAP' started by elenzil, Sep 28, 2017.

Thread Status:
Not open for further replies.
  1. elenzil

    elenzil

    Joined:
    Jan 23, 2014
    Posts:
    73
    howdy.

    it looks like changing the target android store (eg between Google Play and Kindle)
    results in a change to the "androidStore" field in the file "UnityPurchasing/Resources/BillingMode.json" .

    is it possible to make this switch at runtime rather than at buildtime ?

    because we're publishing to both Google and Kindle that means we'll need to maintain two separate builds,
    which complicates the build pipeline, the app-submission process, and QA. ie instead of a single APK there will now be two.

    I see this in the release notes for UnityIAP Version 1.9.1, 2016-11-17 :
    ,

    so it looks like this is indeed a buildtime setting.
    i guess i'd be happy to pay 196kb in the APK in exchange for having one APK instead of N.

    alternatively, it would be great if the radio-button to choose exactly one of the android stores were replaced with a list of toggle-buttons which determine what app-stores should be supported by the build.
     
  2. elenzil

    elenzil

    Joined:
    Jan 23, 2014
    Posts:
    73
    can we do this in BillingMode.json ?

    Code (csharp):
    1. {"androidStore":["AmazonAppStore","GooglePlay"]}
    doing so removes all checkmarks in the IDE menu for this setting.
    altho no errors in the console.
     
  3. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I discussed this with the IAP team, and this process has not been tested, and would not be supported. For this reason I would hesitate to offer the steps that might work. Would you be OK with attempting a non-supported build process?
     
  4. elenzil

    elenzil

    Joined:
    Jan 23, 2014
    Posts:
    73
    Hi Jeff -

    Many thanks for following up on this.

    If the non-standard build process works w/ a gradle build and results in a single APK instead of two, i'm happy to try it out!
     
  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Here are the instructions. Please keep in mind that these are untested and unsupported:

    The issues are:

    1) Unity IAP disables all but the Targeted Android Store’s AAR file from inclusion in the build.
    2) Unity IAP by default relies on the contents of the BillingMode.json file when instantiating an App Store implementation.

    Solutions:
    1) It’s possible to post-process the scene, before the build, after the Unity disabling code has ran, but re-enabling the disabled AAR files in the project. Use the PluginImporter.GetAtPath( path-to-AAR-file ) method to get a handle to the AAR in the project. Then call importer.SetCompatibleWithPlatform(BuildTarget.Android, true). Repeat this for all AAR files. Use the annotation `[PostProcessSceneAttribute(1)]` with a greater-than-zero value on your method which enables platform compatibility on the AARs to ensure the AARs are enabled as the last step before the build commences. Here is a C# Dictionary of the AAR files to be enabled:

    Code (CSharp):
    1. private static Dictionary<string, AppStore> StoreSpecificFiles = new Dictionary<string, AppStore>() {
    2.     { "GooglePlay.aar", AppStore.GooglePlay },
    3.     { "GoogleAIDL.aar", AppStore.GooglePlay },
    4.     { "AmazonAppStore.aar", AppStore.AmazonAppStore },
    5.     { "CloudMoolah.aar", AppStore.CloudMoolah },
    6.     { "SamsungApps.aar", AppStore.SamsungApps },
    7.     { "UnityChannel.aar", AppStore.XiaomiMiPay }
    8. };
    9.  
    They are located in the `Assets/Plugins/UnityPurchasing/Bin` folder.

    2) Instead of performing the default configuration steps to initialize Unity IAP, replace one step with a manual specification of the desired Android app store.

    Code (CSharp):
    1. storeModule = StandardPurchasingModule.Instance(AndroidStore.GooglePlay);
    2. ConfigurationBuilder builder = ConfigurationBuilder.Instance(storeModule);
    The current AppStore enum, for reference:

    Code (CSharp):
    1. public enum AppStore
    2. {
    3.     NotSpecified,
    4.     GooglePlay,
    5.     AmazonAppStore,
    6.     CloudMoolah,
    7.     SamsungApps,
    8.     XiaomiMiPay,
    9.     MacAppStore,
    10.     AppleAppStore,
    11.     WinRT,
    12.     TizenStore,
    13.     FacebookStore,
    14.     fake
    15. }
     
    Last edited by a moderator: Nov 7, 2017
    DarekRusin likes this.
  6. DarekRusin

    DarekRusin

    Joined:
    Nov 15, 2013
    Posts:
    47
    @JeffDUnity3D I've also discovered this issue and would love to see the option to be able to target both Google Play and Amazon in a single apk and select proper store at runtime. Are there any plans to make it officially supported? I understand that it used to be possible, but then this option has been taken away?

    Also, building two different apks is a tolerable alternative, but currently it requires me to baby sit the process and click through the menu options to change the target store between builds. Is there any reliable way to automate and batch build two apk for two stores?

    I keep seeing references to UnityPurchasingEditor but the example from:
    https://support.unity3d.com/hc/en-us/articles/213564363-How-do-I-build-for-different-Android-stores-
    won't compile on my side, complaining that "The name `UnityPurchasingEditor' does not exist in the current context". Googling around I see I'm not the only one with that problem.

    Has UnityPurchasingEditor been removed recently as well? I didn't find anything about this in the changelog...

    What's the proper way to batch build two apks for two stores?

    Thanks so much!
     
    lifeisfunxyz likes this.
  7. elenzil

    elenzil

    Joined:
    Jan 23, 2014
    Posts:
    73
    yes.
    assuming you have a batch build of some sort, you can change the contents of BillingMode.json to match what you want. the approach i took to this was to make two copies of BIllingMode.json off somewhere, and copy the one i want into place for each build.

    also fwiw, i haven't had the nerve to try the multi-store-build approach outlined by JeffDUnity3D above. sorry, JeffD!
     
    DarekRusin likes this.
  8. DarekRusin

    DarekRusin

    Joined:
    Nov 15, 2013
    Posts:
    47
    @elenzil thanks so much! That's the kind of last hope solution I was planning to fallback into, so it's good to know that it's working for you. I'll probably do this as well.

    And yet, I was hoping that there'd be a proper way to do this... It's very sad that in the past there was a "Select store at runtime" option (which would be perfect for a single apk appload) but then it was removed, and even the support for building multiple apk (switching store from a build script) seems to be removed now and we have to resort to manually changing JSON files...
     
  9. elenzil

    elenzil

    Joined:
    Jan 23, 2014
    Posts:
    73
    I understand the motivation for making this a build-time setting: it does save space in the final .APK, which is especially important for the google play store and it's ridiculous 100MB limit, but i agree it would be nice to have the option to do it at runtime. you did see that unity posted an experimental, unsupported approach to achieving a single APK ?
     
  10. DarekRusin

    DarekRusin

    Joined:
    Nov 15, 2013
    Posts:
    47
    Yes, but it really does scream experimental ;) I'm not really confident using that in production, especially since it came with "untested and unsupported" labels.

    And I do understand about saving space, etc, but I'd prefer to have an option to make that choice. For some people that extra few hundreds KB might be critical, but for me it would be a tradeoff I'd be happy to make. But it's seems to have been already decided on my behalf ;)
     
    lifeisfunxyz likes this.
  11. csumsky3

    csumsky3

    Joined:
    Jan 29, 2014
    Posts:
    13
    Hey guys! Happened upon this thread and wanted to share the solution we implemented for this. In the editor, we leave the IAP Android Target pointed to Google Play. Then we wrote a simple pre-build script:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine.Purchasing;
    3. using System.IO;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6. using UnityEditor;
    7.  
    8. public static class PrebuildScript
    9. {
    10.     const string pathToBillingJSON = @"path/from/project/root/Assets/Plugins/UnityPurchasing/Resources/BillingMode.json";
    11.     #if UNITY_EDITOR
    12.     [MenuItem ("Window/ChangeType")]
    13.     #endif
    14.     public static void ChangeToAmazon()
    15.     {
    16.         var currentPath = Directory.GetCurrentDirectory();
    17.         var splitChars = new []{'\\', '/'};
    18.         var pathArray = currentPath.Split(splitChars, 100);
    19.         var billingArray = pathToBillingJSON.Split(splitChars, 100);
    20.         var combined = new List<string>(pathArray);
    21.         for (int i = 0; i < billingArray.Length; ++i) {
    22.             if (!combined.Contains(billingArray[i])) {
    23.                 combined.Add(billingArray[i]);
    24.             }
    25.         }
    26.         var path = string.Join(Path.DirectorySeparatorChar.ToString(), combined.ToArray());
    27.         doProcessing(path);
    28.     }
    29.     static void doProcessing(string _filePath)
    30.     {
    31.         var text = File.ReadAllText(_filePath);
    32.         text = text.Replace("GooglePlay", "AmazonAppStore");
    33.         File.WriteAllText(_filePath, text);
    34.     }
    35. }
    And then we set up 2 separate targets in Unity Cloud Build, one for Google Play and one for Amazon, and for the Amazon one call that pre-build function `ChangeToAmazon` as a pre-build function (see the advanced settings on the target). And then UCB spits out both Google Play and Amazon builds that work with their respective stores!

    Hope that helps! I know I kinda rushed over the UCB part, sort of assuming most people are familiar with UCB targets, but can provide more details or point to refs if needed.

    Chris
     
    DarekRusin and ap-unity like this.
  12. DarekRusin

    DarekRusin

    Joined:
    Nov 15, 2013
    Posts:
    47
    @csumsky3 Thank you so much! You saved me a lot of time writing and debugging the code, especially that it looks like you have the UCB integration done and battle tested. Much appreciated :)
     
Thread Status:
Not open for further replies.