読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Windows Runtime の IMap<K, V> インターフェイスを実装したオブジェクトを JS で使用する (ワークアラウンド)

Windows Runtime Windows ストアアプリ C# JavaScript Windows

Windows Runtime の API を JS から使用する際に問題となることの一つとして、JS ではインターフェイスを扱うことができない、というものがあります。 Windows Runtime の API には、引数として IIterable<IKeyValuePair<string, string>> オブジェクトや IMap<string, string> オブジェクトを取るものがありますが、そういったインターフェイスを実装するオブジェクトを JS から作成するのは Windows Runtime API を使うだけでは難しそうでした。 *1

しょうがないので、ワークアラウンドとして C# などで独自の Windows Runtime コンポーネントを生成するという方法を採ります。

具体的な問題の例

例えば、Windows.Web.Http.HttpFormUrlEncodedContent クラスインスタンスを生成したいとします。 HttpFormUrlEncodedContent のコンストラクタは、Windows.Foundation.Collections.IIterable<IKeyValuePair<string, string>> オブジェクトを引数に取ります。

なので、JS で IIterable<IKeyValuePair<string, string>> オブジェクトを生成できれば良いのですが、その方法が見つかりませんでした。 下記フォーラムで質問を見つけましたが、ちゃんとした解決には至っていませんでした。

ちなみに

ちなみに IIterable<IKeyValuePair<string, Object>> というインターフェイスIMap<string, Object> というインターフェイスを実装したオブジェクトが欲しい場合は PropertySet クラスを使うと良いです。

ワークアラウンド : 独自の Windows Runtime コンポーネントを生成して JS から使用する

Windows.Foundation.Collections.IMap<K, V> インターフェイスIIterable<IKeyValuePair<K, V>> インターフェイスを継承しているので、ここでは IMap<K, V> オブジェクトを返すことを考えてみます。 言語は C# を使います。 (C++VB でも可能なはずです。)

まずはカスタムコンポーネント用のプロジェクトを作成します。 次のエントリが参考になります。

プロジェクトができたら、C# でクラスを作成します。 次のような感じです。 下の例は IMap<string, string> オブジェクトを返すメソッドの例です。 (IMap<K, V> インターフェイスC# では System.Collections.Generic.IDictionary<K, V らしい。)

<feff>using System;
using System.Collections.Generic;

namespace YourNameSpace
{
    public sealed class CollectionsUtil
    {
        /// <summary>
        /// <code>Windows.Foundation.Collections.IMap&lt;string, string></code> オブジェクトを返す。
        /// JS でこのインターフェイスを実装したオブジェクトを生成する方法がわからないので苦肉の策。
        /// </summary>
        public static IDictionary<string, string> CreateStringMap()
        {
            return new Dictionary<string, string>();
        }
    }
}

System.Type を使って JS 側から文字列で型を指定してオブジェクトを生成させるとかもできそうだけど今のところ必要ないのでそこまではやってません。

どう考えてもおかしい

こんなことしないといけないのはどう考えてもおかしいのでもっといい方法があるはず……!!

*1:もしかしたら方法があるのかもしれませんが、見つけられませんでした。