C#
Xamarin
チュートリアル
Xamarin.Forms

Xamarin.FormsでQiitaのAPIを叩いて表示する

概要

Xamarinに入門するにあたって、QiitaのAPIを叩いて表示するアプリを作ってみました。

APIを叩くのはアプリ開発の基本ですが、入門者や初級者にとっては最初の壁と言うか、一個の学習の基準になると思います。
今回はQiitaのAPIを叩き、最新記事一覧を取得・表示することを通して、Xamarinを紹介していきますので参考にしてもらえたら嬉しいです。

今回はXamarin.Formsを使用します。

以下は完成イメージです。

20180521_225208.GIF

全体のコードはGithubにあげてあります。
https://github.com/r-kaga/Xamarin-QiitaClientApp

Xamarinとは

・.NETの技術でAndroidやiOSアプリが開発できるSDKや統合開発環境などを加えたクロスプラットフォームアプリ開発環境
・AndroidとiOS、MacOSアプリもC#で開発可能
・ビジネスロジック部分のコードを共通化するだけでなく、Xamarin.FormsによりUIも共通化可能
・Nintendo Switch OnlineアプリもXamarin.Formsで作られている。
https://qiita.com/amay077/items/53fc0d6d0cd46f1885bd

ダウンロード

ダウンロードがまだの方は以下のURLからダウンロードしてください。
https://www.xlsoft.com/jp/products/xamarin/index.html

プロジェクト作成

まずはプロジェクトの作成行います。
Visual Studioを立ち上げて、マルチプラットフォーム->アプリ->空白フォームのアプリ
を選択します。

スクリーンショット 2018-05-20 20.48.52.png

次に以下の内容でプロジェクトを作成していきます。

スクリーンショット 2018-05-21 23.32.15.png

スクリーンショット 2018-05-21 23.33.41.png

これでプロジェクトの作成が終了しました。
この段階でiOS、Andorid両方にビルドすることが可能です。

シュミレーターが選択されてるのを確認した上で、左上の再生ボタンをクリックすれば以下のようなシュミレーターが立ち上がるかと思います。

スクリーンショット 2018-05-20 20.52.57.png

ここではAndroidのシュミレーターを立ち上げていますが、これからはiOSで動作確認を行っていきます。

記事一覧の表示

次にListの表示をします。
iOSで言うUITableViewです。

それではMainPage.xaml.csを以下のように編集していきます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace QiitaClient
{
    public partial class MainPage : ContentPage
    {

        public ListView listView;

        public MainPage()
        {
            InitializeComponent();

            listView = new ListView
            {
                RowHeight = 60 //Cellの高さを設定
            };

            // ListViewに表示するデータを設定
            listView.ItemsSource = new String[] {
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
            };

            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                Children = { listView }
            };

        }
    }
}

ここで一旦ビルドして確認してみましょう。
以下の通りになれば成功です。

IMG_0075.PNG

今の所では単に予め設定した内容を表示しているだけなので、これからAPIを叩いてそのデータを用いてListを表示してみたいと思います。

まず最初にQiitaAPIという名前でファイルを作成します。
メニューバーからファイル->新しいファイルを選択すると以下のようなファイル新規作成のプロンプトが表示されます。

ここでは画像の通り空のクラスを作成します。
ファイルを作成したら以下のように変更して下さい。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;


namespace QiitaClient
{
    public class QiitaAPI
    {
        public List<QiitaArticleEntity> articleList;

        // QiitaAPIのURl
        public string API_URL = "https://qiita.com//api/v2/items";

        // データを取得するメソッド
        public async Task<List<QiitaArticleEntity>> AsyncGetWebAPIData()
        {
            // Listの作成
            articleList = new List<QiitaArticleEntity>();
            // HttpClientの作成 
            HttpClient httpClient = new HttpClient();
            // 非同期でAPIからデータを取得
            Task<string> stringAsync = httpClient.GetStringAsync(API_URL);
            string result = await stringAsync;
            // JSON形式のデータをデシリアライズ
            articleList = JsonConvert.DeserializeObject<List<QiitaArticleEntity>>(result);

            // List でデータを返す
            return articleList;
        }
    }

    // QiitaApiから取得するデータのEntity
    public class QiitaArticleEntity
    {
        public string title { get; set; }         
        public string url { get; set; }       
    }
}

これでQiitaAPIから記事の一覧を取得することが出来るようになりました。
ここで取得した内容を先ほどのListViewに反映していきます。

MainPage.xaml.csに戻り、以下の内容に書き換えていきます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using System.Threading.Tasks;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.IO;
using Newtonsoft.Json;

namespace QiitaClient
{
    public partial class MainPage : ContentPage
    {

        public ListView listView;
        public List<QiitaArticleEntity> articleList;

        public MainPage()
        {
            InitializeComponent();

            listView = new ListView
            {
                RowHeight = 60
            };

            listView.ItemsSource = new String[] {
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
                "ダミーテキスト",
            };

            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                Children = { listView }
            };

            fetchArticles(new QiitaAPI());
        }

        // 非同期でデータ取得のメソッドを実行するメソッド
        async void fetchArticles(QiitaAPI api)
        {

            try
            {
                // 取得したデータをListに設定
                articleList = await api.AsyncGetWebAPIData();

                var items = new List<String>();
                foreach (QiitaArticleEntity value in articleList)
                {
                    items.Add(value.title);
                }
                listView.ItemsSource = items;
            }
            // エラー表示処理
            catch (System.Exception ex)
            {
                await DisplayAlert("Error", ex.Message.ToString(), "OK");
            }

        }

    }


}

このままだとNewtonsoft.JSonの部分がエラーになると思います。
このライブラリを使用するためには、NuGetでライブラリを入手する必要があります。

まずNuGetパッケージの追加を選択し、

スクリーンショット 2018-05-21 23.54.09.png

右上の検索バーからjsonと検索し、ここでは2番めに出てきているNewtonsoft.JSon選択し、パッケージを追加するを選択してください。

スクリーンショット 2018-05-21 23.54.58.png

これでビルドをすることができるようになりました。
ここまで作成したらビルドして確認してみましょう。

以下のようにQiitaの最新記事が表示させることが出来ました。

IMG_0076.PNG

記事をWebViewで表示

新着記事の表示は出来たので、次に選択した記事をWebViewで表示できるようにしていきます。
まずはCellを選択した際のアクションを設定します。
MainPage()の中に以下のようなコードを追加してください。

listView.ItemSelected += async (sender, e) => {
    await DisplayAlert("Tapped!", e.SelectedItem + " was tapped.", "OK");
};

これによりListViewのCellをタッチした場合に、ItemSelectedイベントを実装して、以下のように簡単なアラートを表示することが出来ます。
ItemSelected イベントは、e.SelectedItemでタップしたCellに関連したデータを取得することが出来ます。

ここの中でWebViewを表示する処理を行いたいと思います。
ItemSelectedイベントを以下のように書き換えてください。

listView.ItemSelected += async (sender, e) => {
  var index = (listView.ItemsSource as List<String>).IndexOf(e.SelectedItem as String);
  var articleUrl = articleList[index].url;
  await Navigation.PushModalAsync(new ArticlePage(url: articleUrl));
};

ここでは選択されたセルのインデックスを取得し、対象の記事のUrlを引数として次の画面に渡しています。

次にWebviewを表示するViewを作成します。

ファイル名をArticlePageとして、新たなファイルを作成し、

スクリーンショット 2018-05-22 0.07.49.png

以下のようなコードを記述します。

using System;
using Xamarin.Forms;

namespace QiitaClient
{
    public partial class ArticlePage : ContentPage
    {
        public ArticlePage(String url)
        {
            var webView = new WebView
            {
                Source = url
            };
            Content = webView;

        }
    }
}

これで選択した記事をWebviewで表示することが出来ました。

ナビゲーションバーの実装

ただこれだけだと記事一覧に戻ることが出来ません。
記事閲覧画面から一覧画面に戻るためにアプリ上部にナビゲーションバーを付けていきたいと思います。

まずMainPage.xaml.csを修正します。
MainPage()の中に以下の記述を追加します。

public MainPage()
{
    InitializeComponent();
    Title = "新着記事";

    ToolbarItems.Add(new ToolbarItem
    {
        Text = "更新",
        Command = new Command(() => fetchArticles(new QiitaAPI()))
    });

    ...省略

またlistView.ItemSelected内の

await Navigation.PushModalAsync(new ArticlePage(url: articleUrl));

となっている部分を

await Navigation.PushAsync(new ArticlePage(url: articleUrl));

このように変更して下さい

次にApp.xaml.csを開き、以下のように修正します。

public App()
{
    InitializeComponent();
    MainPage = new NavigationPage(new MainPage());
}

ここまで来たらビルドして確認してみましょう。
これでQiitaAPIで新着記事を取得し、その記事を閲覧できるアプリの完成です。

20180521_225208.GIF

まとめ

記事ではiOSでビルドしていましたが、Xamarin.Formsを使用してるので、Androidでも動くことが確認出来ると思います。
これだけでiOS、Andoridの両方で動くアプリを開発することが出来ました。

またXamarin.iOSやXamarin.Androidを使えばUIはそれぞれで構築しながら、ビジネスロジックを共通化することが出来ます。
このようにXamarinを使用すれば、クロスプラットフォームで動くアプリを開発することが可能です。

ぜひXamarinでアプリ開発をしてみてください。

P.S

何か間違い等あったら、ご指摘頂けるとありがたいです。