• Categories
  • Recent
  • Tags
  • Popular
  • Solved
  • Unsolved
  • Users
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Darkly)
  • No Skin
Collapse
brainCloud Forums
Michael CostaM

Michael Costa

@Michael Costa
About
Posts
7
Topics
0
Groups
2
Followers
0
Following
0

Posts

Recent Best Controversial

    Newtonsoft.Json fails to deserialize integer fields after BrainCloud SDK upgrade 5.9.3
  • Michael CostaM Michael Costa

    @LEE-JONG-GUN,

    Hmm, unfortunately I don't believe you can set JsonReader to be able to use a converter. In this case you might want to continue using JsonConvert then.

    The first solution I shared where you deserialize & serialize the response to strip out the trailing .0 might be your option here. Additionally, you can also modify your local copy of BrainCloudComms.cs to do this for all responses in-case this situation pops up elsewhere. This will essentially replicate the same behaviour in BC 5.9.2 and older.

    If that's the route you take you can modify BrainCloudComms.cs in the HandleResponseBundle function on line 972 like so:

    private void HandleResponseBundle(string jsonData)
    {
        jsonData = jsonData.Trim();
        if ((jsonData.StartsWith("{") && jsonData.EndsWith("}")) ||
            (jsonData.StartsWith("[") && jsonData.EndsWith("]")))
        {
            jsonData = JsonWriter.Serialize(JsonReader.Deserialize(jsonData)); // This will strip any leading .0 for int values, replicating the behaviour from 5.9.2
        }
    

    We will have to look into if we should have this be an optional flag that can be enabled for compatibility... Do note though that this will mean that a lot of the memory and performance gains from 5.9.3 will be lost.

    There is another option though and that's to leverage JsonConverter 😃

    Here's a script that should take floats/doubles during deserialization and convert them to an int. I modified it and tested it, I think it should work for this situation:

    using System;
    using Newtonsoft.Json;
    
    /// <summary>
    /// Converts JSON floating-point numbers (float/double) to int during deserialization.
    /// </summary>
    public class FloatToIntJsonConverter : JsonConverter<int>
    {
        public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            switch (reader.TokenType)
            {
                case JsonToken.Float:
                    return Convert.ToInt32(Math.Round(Convert.ToDouble(reader.Value), MidpointRounding.AwayFromZero));
    
                case JsonToken.Integer:
                    return Convert.ToInt32(reader.Value);
    
                case JsonToken.String:
                    string sVal = reader.Value?.ToString() ?? "0";
                    if (double.TryParse(sVal, out double parsed))
                    {
                        return Convert.ToInt32(Math.Round(parsed, MidpointRounding.AwayFromZero));
                    }
    
                    throw new JsonSerializationException($"Cannot deserialize string to int: {sVal}");
    
                case JsonToken.Null:
                    return 0;
    
                default:
                    throw new JsonSerializationException($"Unexpected token when tryign to deserialize as int: {reader.TokenType}");
            }
        }
    
        public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
        {
            writer.WriteValue(value);
        }
    }
    

    You can apply this to any specific problematic int like so:

    public class ScoreData
    {
        [JsonConverter(typeof(FloatToIntJsonConverter))]
        public int tier;
    }
    

    Of course you can also apply it globally, but that might be a bit riskier to do 😅 Also note that this script will round floats/doubles to the nearest whole number so if you end up using it make sure to keep that in-mind (or feel free to modify it to suit your needs).

    Let us know if either of these work out for you!


  • Newtonsoft.Json fails to deserialize integer fields after BrainCloud SDK upgrade 5.9.3
  • Michael CostaM Michael Costa

    Hello @LEE-JONG-GUN!

    So looking into JsonConvert it looks like it actually uses LitJson underneath the hood 🤔

    So one option to replicate the old functionality is to use BrainCloud.JsonFx.Json.JsonReader to deserialize into Dictionary<string, object> and then BrainCloud.JsonFx.Json.JsonWriter back into a string before having JObject.Parse() use it. This is basically what the old behaviour was and it would strip out trailing .0 values from JS Numbers.

    SuccessCallback successCallback = (response, cbObject) =>
    {
        response = JsonWriter.Serialize(JsonReader.Deserialize(response)); // Replicate the old BCComms behaviour
    
        DisplayLog(string.Format("Success | {0}", response));
        JObject jsonData = JObject.Parse(response);
    
        if (jsonData["data"]["response"] != null && jsonData["status"].ToString() == "200")
        {
            scoreData = JsonConvert.DeserializeObject<ScoreData>(jsonData["data"]["response"].ToString()); // This should be working now as JsonWriter will strip trailing .0 from doubles
            // ...
        }
        // ...
    }
    

    Although you could also just use JsonReader instead of JsonConvert as this should also strip the trailing .0 so you don't have to waste CPU cycles on the serialization/deserialization:

    scoreData = JsonReader.Deserialize<ScoreData>(jsonData["data"]["response"].ToString());
    

    Alternatively you can also bypass using JObjects and JsonConvert in this situation and make use of our BrainCloud.Common.JsonParser together with JsonReader like so:

    SuccessCallback successCallback = (response, cbObject) =>
    {
        DisplayLog(string.Format("Success | {0}", response));
    
        if (JsonParser.GetString(response, "data", "response") is string responseData &&
            !string.IsNullOrEmpty(responseData) &&
            JsonParser.GetValue<int>(response, "status") == 200) // JsonParser can grab strings directly without having to do object memory allocations
        {
            scoreData = JsonReader.Deserialize<ScoreData>(responseData);
            // ...
        }
        // ...
    }
    

    I think JsonParser can be handy for grabbing strings of json objects, json arrays, and values directly without having to do memory allocations 😃

    Let us know if any of these solutions work for you!


  • Are there plans to support Storekit 2 receipt verification?
  • Michael CostaM Michael Costa

    Hello @peter.

    That's correct, you get the TransactionID from deserializing PendingOrder.Info.Receipt (at least that is the method I'm using 😅). The reason why you want the TransactionID and NOT the OriginalTransactionID is because renewed subscription purchases will have two different values for this.

    Just a couple questions so we have more context:

    1. Do you have the Bundle Id field filled on the Apple Platforms page on brainCloud? This is still a requirement for validating purchases. You'll need to make sure to have one set up for your app on Certificates, Identifiers & Profiles and that it matches the Bundle Identifier in your Unity Player Settings.

    2. Are you running CachePurchasePayloadContext() (docs) before VerifyPurchase()? This is also a requirement for purchases of itunes type.

    Please let me know so we can look deeper into this! Thanks 😄


  • Are there plans to support Storekit 2 receipt verification?
  • Michael CostaM Michael Costa

    Hello @peter. Thank you for letting us know, we are currently looking into it.

    As a work around, if you ENABLE "Use App Store Server API for legacy receipts (optional)", and the other fields are filled, you should be able to save. Afterwards you can DISABLE the optional value and it will still be able to save.


  • Are there plans to support Storekit 2 receipt verification?
  • Michael CostaM Michael Costa

    Hello @LEE-JONG-GUN!

    In order to fill out these values, you will first need to go your app on App Store Connect, then go to App Information. Under General Information you will see the app's Apple ID (this number should also appear in the URL for your app, FYI).

    Next you will need to go to the Users and Access > Integrations > In-App Purchases page in App Store Connect.

    From there you can find the Issuer ID. Next you'll want to click on the + button to Generate In-App Purchase Key. Give it whatever name you think suitable and it should add it to the page. You will then need to download this IAP subscription key; this should reveal the Key ID for that subscription.

    The downloaded IAP subscription key file should be in a .p8 file format. You can open it with a text editor in order to view the Encoded Key. Ctrl + A then Ctrl + C to copy the entire file to the Encoded Key field. Also keep this file somewhere safe, you can only download it once!

    That should be all that's required in order to make use of brainCloud's StoreKit 2 integration 😁 .

    Finally the option for Use App Store Server API for legacy receipts (optional) is there to have apps with older integrations of the brainCloud client to make use of the new implementation with the old StoreKit 1 receipt system.


  • Issue with Auth when running outside of Unity editor
  • Michael CostaM Michael Costa

    Hello @Gavin-Beard!

    We've had trouble reproducing this issue on our end. After some testing with a small app on MacOS and iOS, we have not been able to see the error you are encountering using Unity 2021.3.8.

    If you could, please check out the app here and let us know if this issue is still persisting. It is a barebones authentication app and it should run on multiple devices. The Authentication.cs script has all the gory details. Just open up the Main scene under Assets > App > Misc > Main.unity to get it running. You will also need to add your brainCloud credentials, but you can copy the Authentication example template in brainCloud to test the app.

    Please let us know how this app works on your end and if any issues are encountered! You should be able to click on any error logs in the in-app console to copy the log to your device's clipboard.

    As for your specific issue, my best guess is that perhaps an external library of sorts might not be supported with brainCloud, such as the Newtonsoft Json.NET library. For JSON de/serializing, brainCloud comes with JsonFX. You can also make use of Unity's own JsonUtility for structured JSON de/serialization. Both the app I've shared and the examples on our GitHub make use of JsonFX extensively.

    If you'd like to know more and see how a more robust app can handle brainCloud authentication, as Franco suggested, you should check out our Authentication example on our Unity Examples GitHub.

    Hope this helps! Please let us know if you have further questions or inquiries about this.


  • Difficulty parsing JSON response in Unity
  • Michael CostaM Michael Costa

    Hello! Thanks for your inquiry.

    The format of this response has been used for several years so to change it at this point would cause many errors for our clients. However, in situations like this, we have included the JsonFx library to help deserialize dynamic JSON objects with.

    One way to deserialize the JSON items would be to include a DeserializeItems(string) method in your Data class to be able to store them in an array using JsonFx's JsonReader.Deserialize(string) method:

    public List<Item> Items = new List<object>();
    public void DeserializeItems(string jsonResponse)
    {
        var response = JsonReader.Deserialize<Dictionary<string, object>>(jsonResponse);
        var data = response["data"] as Dictionary<string, object>;
        var items = data["items"] as Dictionary<string, object>;
    
        foreach (Dictionary<string, object> item in items.Values)
        {
            var newItem = new Item();
            newItem.itemId = (string)item["itemId"];
            newItem.defId = (string)item["boost_rapidfire"];
            newItem.quantity = (int)item["quantity"];
            // etc...
            Items.Add(newItem);
        }
    }
    

    Alternatively, you can also use JsonFx's JsonWriter.Serialize(object) method in the foreach loop to then be able to use Unity's JsonUtility to automatically map it as an Item.

    Understandably, both methods have their own pros and cons. However, it should be able to get the job done in this case.

    Hope this helps! Please let us know if you have further questions or inquiries about this.

  • Login

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • Solved
  • Unsolved
  • Users