Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)

2014年11月26日

Web APIにおけるデータフォーマットの定番になっているJSONを、Xamarin.iOS/Androidで扱うには? 「Json.NET」というライブラリを使う方法を説明する。

奥山 裕紳(@amay077
  • このエントリーをはてなブックマークに追加

 モバイルアプリ開発では、ほとんどの場合、Web APIを用いたデータのやりとりが必要になる。そのデータフォーマットとして定番になっているのがJSON(JavaScript Object Notation)だ。今回は、Xamarin.iOS/AndroidでJSONを扱う方法を解説する。

 なお、前回作成したソリューション「CalcSample」を使用するので、準備できていない人は前回のTipsを参照してほしい。

1Json.NETについて

 JSONを扱うライブラリは各言語でさまざまなものが存在するが、.NET開発では、Json.NETが主流だ。Xamarin.iOS/Androidからも、このライブラリが使用可能であり、さらにPCL(ポータブル・クラス・ライブラリ)にも対応しているので、iOSとAndroidでJSONに関わる処理を共通化できる。

 今回は、このJson.NETを使って、Xamarin.iOS/AndroidアプリからJSONデータを入出力する共通処理を実装する。

2パッケージマネージャー「NuGet」について

 Json.NETは公式サイトなどからバイナリ(.dllファイル)を直接入手することもできるが、NuGetからも入手可能だ。

 NuGetとは、.NET開発で使われるライブラリの管理ツール+リポジトリで、ネイティブのiOS開発におけるCocoaPods、Android(+Android Studio)開発におけるmavenに相当するものだ。

 NuGetにはさまざまなプラットフォーム用のライブラリが登録されているが、下記に挙げるものはXamarinで使用可能だ。

  • AXamarin.Android用のライブラリ
  • BXamarin.iOS用のライブラリ
  • CPCLで、かつXamarin.iOS、Xamarin.Androidが対応するProfileでビルドされているもの

 Json.NETCに該当するので、Xamarin.iOS/Androidで利用可能だ。

 NuGetを利用するには、パッケージマネージャー(Package Manager)と呼ばれる、専用のツールが必要で、WindowsではVisual Studioやコマンドライン用のツールが存在する。Macでは、Xamarin Studioがパッケージマネージャーとして利用できる。

 今回は、Xamarin Studioの機能を使ってNuGetのJson.NETライブラリを使用する。

3Json.NETを導入する

 実際に、Json.NETを自分のプロジェクトに導入する方法を解説する。今回はiOSとAndroidアプリの共通処理としたいので、共通なライブラリである「CalcSample.Core」にJson.NETを追加する。

 まず、ソリューションツリーの[CalcSample.Core]プロジェクト項目をマウスで右クリックして[追加]-[Add Packages]を選択し、表示されるダイアログボックス(図1)の検索ボックスに「json」と入力し、見つかったライブラリの中から「Json.NET」にチェックを入れて[Add Package]ボタンを押す。

図1 NuGetのダイアログボックスを使った(Json.NETの)「Newtonsoft.Json」パッケージの導入

 追加後、ソリューションツリーの[参照]-[From Packages](=パッケージからのアセンブリ参照)を展開すると、図2のように「Newtonsoft.Json」アセンブリへの参照が追加されたのが確認できる。

図2 Json.NET追加後のソリューションツリー
図2 Json.NET追加後のソリューションツリー

なお、[パッケージ]フォルダーを開くと、その中にはNuGetの「Newtonsoft.Json」パッケージが追加されている。

 これで導入は完了だ。もし、Json.NETの新しいバージョンが登録されたら、メニューバーの[プロジェクト]-[Update Packages](図3)でプロジェクト内のライブラリを更新できる。

図3 パッケージを更新するメニュー

4CalcSample.CoreでJson.NETを使用する

 JSONは主に、プログラム中のデータクラスを表すのに使用される。まずはサンプルのデータクラスとして、CalcSample.CoreプロジェクトにPersonクラスを以下のコードのように実装する。これは、名前と年齢をプロパティに持つだけのクラスだ。

C#
public class Person
{
  public string Name
  {
    get;
    set;
  }

  public int Age
  {
    get;
    set;
  }
}
サンプルのデータクラス(Person.cs)

 次に、PersonクラスのオブジェクトJSONデータを相互に変換するためのクラスPersonSerializerを、以下のコードのように実装する。

C#
using System;
using Newtonsoft.Json;

namespace CalcSample.Core
{
  public class PersonSerializer
  {
    public string Serialize(Person person)
    {
      return JsonConvert.SerializeObject(person); //<--1
    }

    public Person Deserialize(String text)
    {
      return JsonConvert.DeserializeObject<Person>(text); //<--2
    }
  }
}
PersonオブジェクトとJSON文字列を相互に変換するためのクラス(PersonSerializer.cs)

なお、上記の処理では、エラー処理は一切考慮していないことに注意されたい(実際の開発では、エラー処理が必要になる)。

 1が、PersonオブジェクトをJSON文字列に変換する処理で(シリアライズ:Serialize)、
 2が、JSON文字列をPersonオブジェクトに変換する処理だ(デシリアライズ、または逆シリアライズ:Deserialize)。

 iOS/Androidプロジェクトからは、このPersonクラスとPersonSerializerクラスを使用して実装を行う。

5CalcSample.iOSからPerson&PersonSerializerクラスを使う

 4で作成したPersonクラスとPersonSerializerクラスを使って、CalcSample.iOSプロジェクトで機能を実装する。

 まずは、画面を作成する。MainStoryboard.storyboardファイルを開き、前回までのレイアウトを全て削除した上で、図4のようにレイアウトする。

図4 CalcSample.iOSの画面レイアウト

「<コントロール名>:<Identity名>」の形で記述している。
2つのボタンのTitleプロパティは、左側が[Serialize]、右側が[Deserialize]としている。

 TextView:editJsonは、既定では背景色(Background)が透過なので、薄い灰色など適当な色を設定しておくとよいだろう。

 次に、CalcSample.iOSViewController.csファイルを開き、以下のように修正する。

C#
……省略……
using CalcSample.Core;

namespace CalcSample.iOS
{
  public partial class CalcSample_iOSViewController : UIViewController
  {
    ……省略……

    public override void ViewDidLoad()
    {
      base.ViewDidLoad();

      var serializer = new PersonSerializer(); //<--1

      // シリアライズボタンが押された時
      buttonSerialize.TouchUpInside += (sender, e) =>
      {
        var person = new Person() //<--2
        {
          Name = editName.Text,
          Age = Convert.ToInt32(editAge.Text)
        };

        editJson.Text = serializer.Serialize(person); //<--3
      };

      // デシリアライズボタンが押された時
      buttonDeserialize.TouchUpInside += (sender, e) =>
      {
        var person = serializer.Deserialize(editJson.Text); //<--4

        editName.Text = person.Name; //<--5
        editAge.Text = person.Age.ToString();
      };
    }

    ……省略……
  }
}
iOSアプリの[Serialize]/[Deserialize]ボタンが押されたときの変換処理(CalcSample.iOSViewController.cs)

 1で、PersonSerializerオブジェクトを用意し、シリアライズボタンが押されたときは、2で入力値からPersonオブジェクトを生成して、3でシリアライズを行い、結果のJSON文字列をeditJsonテキストビューに表示する。

 デシリアライズボタンが押されたときは、4でJSON文字列からデシリアライズを行い、5で結果のPersonオブジェクトの各プロパティを画面に表示している。

 ここまでのプログラムを実行すると、図5のようになる。

図5 CalcSample.iOSの実行画面

6CalcSample.AndroidからPerson&PersonSerializerクラスを使う

 Android側も手順は同じだ。まずは、画面を作成する。CalcSample.Androidプロジェクト内のMain.axmlファイルを開き、前回までのレイアウトを全て削除した上で、レイアウトを以下のように記述する。

C#
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:padding="20dp">
  <EditText
    android:id="@+id/editName"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name" />
  <EditText
    android:id="@+id/editAge"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20dp"
    android:hint="Age" />
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_marginBottom="20dp">
    <Button
      android:id="@+id/buttonSerialize"
      android:layout_weight="1"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:text="Serialize" />
    <Button
      android:id="@+id/buttonDeserialize"
      android:layout_weight="1"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:text="Deserialize" />
  </LinearLayout>
  <EditText
    android:id="@+id/editJson"
    android:hint="json"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="top"
    android:background="#555555" />
</LinearLayout>
CalcSample.Androidの画面レイアウト用のコード(Main.axml)

 これをUIエディターで見ると図6のようになる。

図6 CalcSample.Androidの画面レイアウト

 こちらもEditText:editJsonは、既定では背景色が透過なので、薄い灰色など適当な色を設定しておくとよいだろう(上記のコードでは設定済み)。

 次に、MainActivity.csファイルを開き、以下のように修正する。

C#
……省略……
using CalcSample.Core;

namespace CalcSample.Android
{
  [Activity(Label = "CalcSample.Android", MainLauncher = true, Icon = "@drawable/icon")]
  public class MainActivity : Activity
  {
    protected override void OnCreate(Bundle bundle)
    {
      base.OnCreate(bundle);

      SetContentView(Resource.Layout.Main);

      var editName = FindViewById<EditText>(Resource.Id.editName);
      var editAge = FindViewById<EditText>(Resource.Id.editAge);
      var editJson = FindViewById<TextView>(Resource.Id.editJson);

      var serializer = new PersonSerializer();

      // シリアライズボタンが押された時
      FindViewById<Button>(Resource.Id.buttonSerialize).Click += (sender, e) =>
      {
        var person = new Person()
        {
          Name = editName.Text,
          Age = Convert.ToInt32(editAge.Text)
        };

        editJson.Text = serializer.Serialize(person);
      };

      // デシリアライズボタンが押された時
      FindViewById<Button>(Resource.Id.buttonDeserialize).Click += (sender, e) =>
      {
        var person = serializer.Deserialize(editJson.Text);

        editName.Text = person.Name;
        editAge.Text = person.Age.ToString();
      };
    }
  }
}
Androidアプリの[Serialize]/[Deserialize]ボタンが押されたときの変換処理(MainActivity.cs)

 シリアライズボタンやデシリアライズボタンを押したときの処理は、iOS版とほとんど同じなので、説明の必要はないだろう。

 ここまでのプログラムを実行すると、図7のようになる。

図7 CalcSample.Androidの実行画面

まとめ

 Xamarin.iOS/Androidでの、Json.NETによるJSONの使用方法を解説した。また、パッケージマネージャーであるNuGetについても軽く触れた。どちらもよく使う機能なので、ぜひ覚えておいてほしい。

 Json.NETは最も基本的な機能しか使用しなかったが、

などには、さまざまな機能が紹介されている。利用者の多いライブラリなので、日本語の情報も多いだろう。各自検索してみてほしい。

※以下では、本稿の前後を合わせて5回分(第26回~第30回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Xamarin逆引きTips
26. Xamarin.iOS/Androidでソースコードを共有するには?(リンクファイル編)

Xamarin.iOS/Android間でソースコードを共有する方法の1つとして、Xamarin Studioのプロジェクト内でソースファイルへのリンクを追加する方法を説明する。

Xamarin逆引きTips
27. Xamarin.iOS/Androidでソースコードを共有するには(ポータブルクラスライブラリ編)

Xamarin.iOS/Android間でソースコードを共有する方法の1つとして、複数のプロジェクトから共通のポータブルクラスライブラリ(PCL)を参照する方法を説明する。

Xamarin逆引きTips
28. 【現在、表示中】≫ Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)

Web APIにおけるデータフォーマットの定番になっているJSONを、Xamarin.iOS/Androidで扱うには? 「Json.NET」というライブラリを使う方法を説明する。

Xamarin逆引きTips
29. Xamarin.iOS/Androidでアプリのデータディレクトリを取得するには?

アプリ固有のデータ領域のディレクトリパスを取得するため方法のうち、iOS/Androidで共通のコードの書き方を説明する。

Xamarin逆引きTips
30. Xamarin.iOS/Androidでアプリの設定情報を保存するには?

iOSのNSUserDefaultsやAndroidのSharedPreferenceではなく.NETのIsolatedStorageを使って、Xamarin.iOS/Androidでアプリの軽量データを保存する方法を解説する。

サイトからのお知らせ

Twitterでつぶやこう!