Xamarin逆引きTips
Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)
Web APIにおけるデータフォーマットの定番になっているJSONを、Xamarin.iOS/Androidで扱うには? 「Json.NET」というライブラリを使う方法を説明する。
モバイルアプリ開発では、ほとんどの場合、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.NETはCに該当するので、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]ボタンを押す。
追加後、ソリューションツリーの[参照]-[From Packages](=パッケージからのアセンブリ参照)を展開すると、図2のように「Newtonsoft.Json」アセンブリへの参照が追加されたのが確認できる。
※なお、[パッケージ]フォルダーを開くと、その中にはNuGetの「Newtonsoft.Json」パッケージが追加されている。
これで導入は完了だ。もし、Json.NETの新しいバージョンが登録されたら、メニューバーの[プロジェクト]-[Update Packages](図3)でプロジェクト内のライブラリを更新できる。
4CalcSample.CoreでJson.NETを使用する
JSONは主に、プログラム中のデータクラスを表すのに使用される。まずはサンプルのデータクラスとして、CalcSample.CoreプロジェクトにPerson
クラスを以下のコードのように実装する。これは、名前と年齢をプロパティに持つだけのクラスだ。
public class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
|
次に、PersonクラスのオブジェクトとJSONデータを相互に変換するためのクラスPersonSerializer
を、以下のコードのように実装する。
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
}
}
}
|
なお、上記の処理では、エラー処理は一切考慮していないことに注意されたい(※実際の開発では、エラー処理が必要になる)。
1が、Person
オブジェクトをJSON文字列に変換する処理で(シリアライズ:Serialize)、
2が、JSON文字列をPerson
オブジェクトに変換する処理だ(デシリアライズ、または逆シリアライズ:Deserialize)。
iOS/Androidプロジェクトからは、このPerson
クラスとPersonSerializer
クラスを使用して実装を行う。
5CalcSample.iOSからPerson&PersonSerializerクラスを使う
4で作成したPerson
クラスとPersonSerializer
クラスを使って、CalcSample.iOSプロジェクトで機能を実装する。
まずは、画面を作成する。MainStoryboard.storyboard
ファイルを開き、前回までのレイアウトを全て削除した上で、図4のようにレイアウトする。
※「<コントロール名>:<Identity名>」の形で記述している。
2つのボタンのTitleプロパティは、左側が[Serialize]、右側が[Deserialize]としている。
TextView:editJson
は、既定では背景色(Background)が透過なので、薄い灰色など適当な色を設定しておくとよいだろう。
次に、CalcSample.iOSViewController.cs
ファイルを開き、以下のように修正する。
……省略……
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();
};
}
……省略……
}
}
|
1で、PersonSerializer
オブジェクトを用意し、シリアライズボタンが押されたときは、2で入力値からPerson
オブジェクトを生成して、3でシリアライズを行い、結果のJSON文字列をeditJson
テキストビューに表示する。
デシリアライズボタンが押されたときは、4でJSON文字列からデシリアライズを行い、5で結果のPerson
オブジェクトの各プロパティを画面に表示している。
ここまでのプログラムを実行すると、図5のようになる。
6CalcSample.AndroidからPerson&PersonSerializerクラスを使う
Android側も手順は同じだ。まずは、画面を作成する。CalcSample.Androidプロジェクト内のMain.axml
ファイルを開き、前回までのレイアウトを全て削除した上で、レイアウトを以下のように記述する。
<?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>
|
これをUIエディターで見ると図6のようになる。
こちらもEditText:editJson
は、既定では背景色が透過なので、薄い灰色など適当な色を設定しておくとよいだろう(※上記のコードでは設定済み)。
次に、MainActivity.cs
ファイルを開き、以下のように修正する。
……省略……
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();
};
}
}
}
|
シリアライズボタンやデシリアライズボタンを押したときの処理は、iOS版とほとんど同じなので、説明の必要はないだろう。
ここまでのプログラムを実行すると、図7のようになる。
まとめ
Xamarin.iOS/Androidでの、Json.NETによるJSONの使用方法を解説した。また、パッケージマネージャーであるNuGetについても軽く触れた。どちらもよく使う機能なので、ぜひ覚えておいてほしい。
Json.NETは最も基本的な機能しか使用しなかったが、
などには、さまざまな機能が紹介されている。利用者の多いライブラリなので、日本語の情報も多いだろう。各自検索してみてほしい。
※以下では、本稿の前後を合わせて5回分(第26回~第30回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
26. Xamarin.iOS/Androidでソースコードを共有するには?(リンクファイル編)
Xamarin.iOS/Android間でソースコードを共有する方法の1つとして、Xamarin Studioのプロジェクト内でソースファイルへのリンクを追加する方法を説明する。
27. Xamarin.iOS/Androidでソースコードを共有するには(ポータブルクラスライブラリ編)
Xamarin.iOS/Android間でソースコードを共有する方法の1つとして、複数のプロジェクトから共通のポータブルクラスライブラリ(PCL)を参照する方法を説明する。
28. 【現在、表示中】≫ Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)
Web APIにおけるデータフォーマットの定番になっているJSONを、Xamarin.iOS/Androidで扱うには? 「Json.NET」というライブラリを使う方法を説明する。
29. Xamarin.iOS/Androidでアプリのデータディレクトリを取得するには?
アプリ固有のデータ領域のディレクトリパスを取得するため方法のうち、iOS/Androidで共通のコードの書き方を説明する。
30. Xamarin.iOS/Androidでアプリの設定情報を保存するには?
iOSのNSUserDefaultsやAndroidのSharedPreferenceではなく.NETのIsolatedStorageを使って、Xamarin.iOS/Androidでアプリの軽量データを保存する方法を解説する。