skip to Main Content

I don’t understand how to log event with array items in parameters.

For example, if I need to log something like EventNamesConstants.Login I can to do

var parameters = new Dictionary<object, object> {
  ParameterNamesConstants.Method, "Google" }
};
Analytics.LogEvent(EventNamesConstants.Login, parameters);

But now I need to log EventNamesConstants.ViewItem
And one of parameters is array of items where item has a name.
When I try to do something like that

var items = new[]{
new Dictionary<object, object> {
ParameterNamesConstants.ItemName, title }
     }
 };
 
 var parameters = new Dictionary<object, object> {
   ParameterNamesConstants.Currency, currencyCode },
   ParameterNamesConstants.Value, value },
   ParameterNamesConstants.Items, items }
 };

I got an error.
I tried to find examples, but they didn’t have an array.
I am so sorry.

An error is:

Do not know how to marshal object of type

 'System.Collections.Generic.Dictionary`2[System.Object,System.Object][]'
 to an NSObject

And func Analytics.LogEvent of Firebase is:

public static void LogEvent (string name, Dictionary<object, object>? parameters) 
{   
 LogEvent (name, (parameters == null) ? null :
 ((parameters!.Keys.Count == 0) ? new NSDictionary<NSString, NSObject>
 () : NSDictionary<NSString, NSObject>.FromObjectsAndKeys
 (parameters!.Values.ToArray (), parameters!.Keys.ToArray (),
 nint.op_Implicit (parameters!.Keys.Count)))); 
}

Help me please.

2

Answers


  1. As a workaround, you could try the following way to create your parameters,

    var keys = new[]
    {
        new NSString("key1"),
        new NSString("key2"),
    };
    
    var objects = new NSObject[]
    { 
        new NSString("object1"),
        new NSString("object1"),
    };
    
    NSDictionary dicionary = new NSDictionary<NSString, NSObject>(keys, objects);
    
    NSArray items =  NSArray.FromNSObjects(dicionary);
    
    var parameters = new Dictionary<object, object>
    {
        { ParameterNamesConstants.Currency, currencyCode },
        { ParameterNamesConstants.Value, value },
        { ParameterNamesConstants.Items, items }
    };
    
    Login or Signup to reply.
  2. I use also Firebase Analytics in my apps.

    Here is a suitable extension method on IDictionary<string, string> that anyone can use to convert easily C# IDictionary to iOS NSDictionary

    /// <summary>
    /// Converts an <see cref="IDictionary{TKey, TValue}"/> of string key-value pairs to an <see cref="NSDictionary"/> of <see cref="NSString"/> keys and <see cref="NSObject"/> values.
    /// </summary>
    /// <param name="dictionary">The dictionary to convert. Cannot be null.</param>
    /// <returns>An <see cref="NSDictionary"/> with <see cref="NSString"/> keys and <see cref="NSObject"/> values corresponding to the entries in the input dictionary.</returns>
    /// <exception cref="ArgumentNullException">Thrown if the input dictionary is null.</exception>
    /// <remarks>
    /// This method iterates over the input dictionary to create a pair of arrays for keys and values, which are then used to construct the NSDictionary.
    /// It's designed to be used as an extension method for any IDictionary&lt;string, string&gt; instance.
    /// Note: Null keys or values in the input dictionary will result in exceptions, as <see cref="NSString"/> cannot be instantiated with a null reference.
    /// </remarks>
    /// <example>
    /// <code>
    /// var myDict = new Dictionary&lt;string, string&gt; { { "key1", "value1" }, { "key2", "value2" } };
    /// var nsDict = myDict.ToNSDictionary();
    /// </code>
    /// </example>
    public static NSDictionary<NSString, NSObject> ToNSDictionary(this IDictionary<string, string> dictionary)
    {
        ArgumentNullException.ThrowIfNull(dictionary);
    
        var keysAndValues = dictionary
            .Select(kv => (Key: new NSString(kv.Key), Value: new NSString(kv.Value)))
            .ToArray();
    
        var keys = keysAndValues
            .Select(kv => kv.Key)
            .ToArray();
    
        var values = keysAndValues
            .Select(kv => kv.Value)
            .ToArray();
    
        return new NSDictionary<NSString, NSObject>(keys, values);
    }
    

    If you need, here is another one on IDictionary<string, object>

    /// <summary>
    /// Converts an <see cref="IDictionary{TKey, TValue}"/> of string key-value pairs to an <see cref="NSDictionary"/> of <see cref="NSString"/> keys and <see cref="NSObject"/> values.
    /// </summary>
    /// <param name="dictionary">The dictionary to convert. Cannot be null.</param>
    /// <returns>An <see cref="NSDictionary"/> with <see cref="NSString"/> keys and <see cref="NSObject"/> values corresponding to the entries in the input dictionary.</returns>
    /// <exception cref="ArgumentNullException">Thrown if the input dictionary is null.</exception>
    /// <remarks>
    /// This method iterates over the input dictionary to create a pair of arrays for keys and values, which are then used to construct the NSDictionary.
    /// It's designed to be used as an extension method for any IDictionary&lt;string, object&gt; instance.
    /// Note: Null keys or values in the input dictionary will result in exceptions, as <see cref="NSString"/> cannot be instantiated with a null reference.
    /// </remarks>
    /// <example>
    /// <code>
    /// var myDict = new Dictionary&lt;string, object&gt; { { "key1", object1 }, { "key2", object2 } };
    /// var nsDict = myDict.ToNSDictionary();
    /// </code>
    /// </example>
    public static NSDictionary<NSString, NSObject> ToNSDictionary(this IDictionary<string, object> dictionary)
    {
        ArgumentNullException.ThrowIfNull(dictionary);
    
        var keys = dictionary.Keys
            .Select(arg => new NSString(arg))
            .ToArray();
    
        var objects = dictionary.Values
            .Select(NSObject.FromObject)
            .ToArray();
    
        return new NSDictionary<NSString, NSObject>(keys, objects);
    }
    

    FYI: I use ArgumentNullException.ThrowIfNull => Only available since C#10, use classic way if you are under C#10.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search