(Visual Studio for Mac)Xamarin.FormsでHelloWorldしてみる


#環境
macOS High Sierra
Visual Studio for Mac 7.3.3

(Visual Studio for Macと書いているので当たり前かもしれませんが)Macですることを前提に書きます

#内容
とりあえず、XamarinでAndroidとiOSのマルチプラットフォーム開発を試してみたい人向けに
iOSとAndroidの両方に対応した共通コードの作成手順を書いてみようと思います

自分自身始めたばかりなので詳しくありませんが、AndroidとiOSへのビルドまではできたので、纏めてみました。

既に2016/11/24の時点でマイクロソフトのテクニカルエバンジェリストの千代田まどかさんが手順を書かれてるブログがあるのですが、
少し変更がある部分と補足を付け足したものを書こうと思います
[【無料】Mac用のIDE “Visual Studio for Mac” で iOS/Android アプリを作ってみた [Xamarin][新規作成から実行まで]](https://blogs.msdn.microsoft.com/chomado/xamarin/tried-creating-an-app-using-visual-studio-for-mac/)


ビルドするためのXcode等は既にインストールしてあることを前提にしたいと思います
理由として、私自身それらはだいぶ前にインストールしているので、インストール手順が曖昧だからです
ですので申し訳ないですが、環境の準備は別途検索して頂けたらと思います

#Xamarin.Formsについて

>
Xamarin.FormsはUIを作る機能であり、
プラットフォームに依存しないコードで画面を作成することができます。
1つのXamarin.Formsの画面コードでAndroidとiOSの両方の画面が作れます。

[Xamarin.Formsで画面を作成](https://qiita.com/ta-yamaoka/items/196d998333c7bbc557fb#xamarinforms%E3%81%A7%E7%94%BB%E9%9D%A2%E3%82%92%E4%BD%9C%E6%88%90)

上記の記事に`Shared Projects`と`PCL`に関しても分かりやすく纏められていて参考になりました

Xamarinの公式ガイドは以下になります
[https://developer.xamarin.com/guides/xamarin-forms/](https://developer.xamarin.com/guides/xamarin-forms/)


#XAMLとXMAL.CS(C#)について
手順の中に、初めてXamarinを触る人なら見慣れないXMALというファイルが目につくと思います、
そしてXMALファイルに紐づけられてXMAL.CS(C#)ファイルがあるようです

まだ私自身よく分かってないのですが、`.xmalは画面構成`、`.xmal.csは処理`という感じなようです
ただ、XAMLを使わず、C#のみで書くこともできるそうです

参考URL:
[画面作成はXAMLとC#コードをどのように使い分けるか](https://qiita.com/ta-yamaoka/items/196d998333c7bbc557fb#%E7%94%BB%E9%9D%A2%E4%BD%9C%E6%88%90%E3%81%AFxaml%E3%81%A8c%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%82%8B%E3%81%8B)

因みに読み方は`ザムル`で`eXtensible Application Markup Language`の略だそうです

#各インストール
参考になりそうな記事のURLだけ貼らせて頂こうと思います
[Xamarin やりたい人向け Visual Studio 2017 インストール手引書](http://ytabuchi.hatenablog.com/entry/visualstudio2017)
[【Visual Studio for Mac】C#を使ってMac上で動くアプリをつくる。【環境構築／開発】](http://www.milkmemo.com/entry/visual_studio_for_mac)

#HelloWorld
##プロジェクトの作成
[New Project...]をクリックします
![スクリーンショット 2018-01-15 18.20.15.png](https://qiita-image-store.s3.amazonaws.com/0/72559/4606141c-ce32-96dc-c340-5b361a3cdd80.png "スクリーンショット 2018-01-15 18.20.15.png")

サイドメニューの`Mulutiplatform`から`App`->`Blank Forms App`を選択肢`Next`をクリック
![スクリーンショット 2018-01-15 18.21.48.png](https://qiita-image-store.s3.amazonaws.com/0/72559/bc19eda0-778c-a6a1-128e-1c1b5eeed15e.png "スクリーンショット 2018-01-15 18.21.48.png")


`App Name`に[HelloWorld]と入力します(アプリ名になります)
今回、他の項目はデフォルトのまま`Next`をクリックします
![スクリーンショット 2018-01-15 18.24.54.png](https://qiita-image-store.s3.amazonaws.com/0/72559/79e8a959-3b11-8ee0-be2e-f56d702e5028.png "スクリーンショット 2018-01-15 18.24.54.png")

今回この画面ではプロジェクトの保存場所だけ設定し、あとはデフォルトのままでいきます
`Location`が保存場所になるのですが、デフォルトは確か`/Users/[ユーザ名]/Project`になってると思います
そのままか、`Browse..`から任意の場所を選択し、`Create`をクリックでプロジェクトの作成を完了させます(少し時間がかかる)
![スクリーンショット 2018-01-15 18.30.47.png](https://qiita-image-store.s3.amazonaws.com/0/72559/7e27767f-27b2-e595-60b3-40545ac1d678.png "スクリーンショット 2018-01-15 18.30.47.png")

とりあえずこんな画面になります
![スクリーンショット 2018-01-15 18.37.14.png](https://qiita-image-store.s3.amazonaws.com/0/72559/2d2a0968-dbc7-03e9-17a1-7487256e8f93.png "スクリーンショット 2018-01-15 18.37.14.png")

左側の`HelloWorld(Master)`配下の`HelloWorld`プロジェクトが`iOSとAndroid共通プロジェクト`となり
`HelloWorld.Droid`が`Androidプロジェクト`、`HelloWorld.iOS`が`iOSプロジェクト`となります。

基本的に`HelloWorldプロジェクト`を触ることになりますが、 iOS、Android各固有の部分は各プロジェクトで行う感じです(多分。始めたばかりなのでまだ色々と分かってない)

##ビルド
早速ビルドをしてみます
iOSとAndroidを一緒にビルドをすることはできないので、片方ずつビルドします
`iOS`をビルドしたい場合は`HelloWorld.iOS`を右クリックし、 `Set AS StartUp Project`をクリック
![スクリーンショット 2018-01-15 18.54.41.png](https://qiita-image-store.s3.amazonaws.com/0/72559/ae89817d-b6f5-0c24-a9b6-f184d209a532.png "スクリーンショット 2018-01-15 18.54.41.png")

すると、左上の`▶︎マーク`の横の欄が`HelloWorld.iOS`に切り替わるので、確認できたら`▶︎マーク(実行ボタン)`をクリックでシミュレータが起動します
![スクリーンショット 2018-01-15 18.54.46.png](https://qiita-image-store.s3.amazonaws.com/0/72559/895f2e39-eef3-0558-00d3-a830c4928735.png "スクリーンショット 2018-01-15 18.54.46.png")

![スクリーンショット 2018-01-15 18.57.37.png](https://qiita-image-store.s3.amazonaws.com/0/72559/98769545-0bf1-aa3f-b8f3-9bdc6d5cae15.png "スクリーンショット 2018-01-15 18.57.37.png")

うまくアプリが実行されたら、一度、実行を停止し、もう片方も同じような手順で起動して下さい(Androidは時間がかかります)
停止するには`■マーク`をクリックします(元々▶︎マークだった場所)
![スクリーンショット 2018-01-15 19.00.12.png](https://qiita-image-store.s3.amazonaws.com/0/72559/b752811f-5e77-1fff-9ae3-38b155b35e5d.png "スクリーンショット 2018-01-15 19.00.12.png")
また、`Set AS StartUp Project`からではなく、左上の`▶︎マーク`の横の欄の部分をクリックでも、ビルドターゲットは変更できます
![スクリーンショット 2018-01-15 19.03.01.png](https://qiita-image-store.s3.amazonaws.com/0/72559/5e7a1f14-a3bc-bf31-4e75-4733828f59b6.png "スクリーンショット 2018-01-15 19.03.01.png")

起動できたら、同じような画面のアプリになってることが確認できます
![スクリーンショット 2018-01-15 19.06.47.png](https://qiita-image-store.s3.amazonaws.com/0/72559/1994675d-8839-79bf-09da-52b25d002230.png "スクリーンショット 2018-01-15 19.06.47.png")

最初に起動したほうはホーム画面に戻ってると思うので、アプリをクリックして確かめることができます


#表示している文字を変えてみる
デフォルトのままだと画面に`Welcom to Xamarin Forms!`と書かれている部分を別の文字に置き換えつつ、どの部分でコードが書かれているかを確認します

##初期化処理
その前にiOS、Androidの初期化処理が書かれている部分を確認します
初期化のように共通化できないものは各プロジェクト内で行うことになります

###Androidの初期化
左のメニューの`HelloWorld.Droid`->`MainActivity.cs`

``` MainActivity.cs
sing System;

using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace HelloWorld.Droid
{
    [Activity(Label = "HelloWorld.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            LoadApplication(new App());
        }
    }
}
```

`global::Xamarin.Forms.Forms.Init(this, bundle);`の部分と
`LoadApplication(new App());`の部分が`初期化処理`になっているようです
![スクリーンショット 2018-01-15 19.22.51.png](https://qiita-image-store.s3.amazonaws.com/0/72559/a4f2ad93-ff86-0eaf-fe48-f5cf78cbbfe1.png "スクリーンショット 2018-01-15 19.22.51.png")


###iOSの初期化
左のメニューの`HelloWorld.iOS`->`AppDelegate.cs`

``` AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using UIKit;

namespace HelloWorld.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }
    }
}
```

iOSも、
`global::Xamarin.Forms.Forms.Init();`と
`LoadApplication(new App());`の部分が`初期化処理`になっているようです
![スクリーンショット 2018-01-15 19.23.03.png](https://qiita-image-store.s3.amazonaws.com/0/72559/6cdcc68d-d590-b465-7703-1cc51d703161.png "スクリーンショット 2018-01-15 19.23.03.png")

##文字を変更する
固有の部分を確認できたところで共通の部分を確認し、変更してみたいと思います

まず、先程の各コードをもう一度見て頂けると、どちらも
`LoadApplication(new App());`とかかれており、`Appクラスが呼ばれている`ことが分かると思います。

このAppクラスの場所は`HelloWorld`プロジェクトの`App.xmal`と、`App.xmal`の左側にある`▶︎マーク`をクリックすると展開されるのですが、展開すると出てくる`App.xmal.cs`の２つのファイルになります。

![スクリーンショット 2018-01-15 19.37.08.png](https://qiita-image-store.s3.amazonaws.com/0/72559/ce2f19ef-731d-d79b-59c3-b3eda31208d1.png "スクリーンショット 2018-01-15 19.37.08.png")


`App.xmal.cs`の中身をみてみると

``` App.xmal.cs
using Xamarin.Forms;

namespace HelloWorld
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new HelloWorldPage();
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}
```

`App()`の中で、イニシャライズ的なことがやってそうな後に`MainPage`プロパティとして`HelloWorldPageクラス`が呼ばれていることが確認できます

次に`HelloWorldPage`を確認します。
HelloWorldPageも`HelloWorldPage.xmal`と`HelloWorldPage.xmal.cs`で構成されています
![スクリーンショット 2018-01-15 19.44.46.png](https://qiita-image-store.s3.amazonaws.com/0/72559/cf39c9a3-e2ec-195f-dca9-99f54dd43057.png "スクリーンショット 2018-01-15 19.44.46.png")


今度は`HelloWorldPage.xmal`の方を確認してみます

``` HelloWorldPage.xmal
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:HelloWorld" 
    x:Class="HelloWorld.HelloWorldPage"
    >
    
	<Label Text="Welcome to Xamarin Forms!" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" />
    
</ContentPage>
```

実際のコードは横長だったのですが、見辛かったので改行しました

上のコードを見て頂けると、各エミュレータで表示されてた部分と思われる
`Text="Welcome to Xamarin Forms!"`
という箇所が見つかると思います。

試しにこの部分を`Text="Hello WORLD!"`と修正し、`command + s`で保存、ビルドしてみましょう
![スクリーンショット 2018-01-15 19.54.57.png](https://qiita-image-store.s3.amazonaws.com/0/72559/60590335-87b4-61cf-a5b7-0aef07f3a583.png "スクリーンショット 2018-01-15 19.54.57.png")
一つのファイルの修正でAndroid、iOSのアプリが修正できたことが確認できたと思います！

XAMLに関して以下の記事がとても参考になりました
[XAMLをコードで表現する](https://qiita.com/toshi0607/items/241a7161491092d2a3e0#xaml%E3%82%92%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E8%A1%A8%E7%8F%BE%E3%81%99%E3%82%8B)


#実機にインストール
(自分の環境では)iPhoneは簡単にインストールできたのですが、Androidの方は(最近買い換えた)こともあって少し手間取ったので
Androidの方を少し詳しく書こうと思います

##iPhone
USBで接続し、実行するだけで特に問題なくインストール完了
![スクリーンショット 2018-01-16 12.03.57.png](https://qiita-image-store.s3.amazonaws.com/0/72559/b2a97e3b-1400-9895-f7b0-bc1eebe88946.png "スクリーンショット 2018-01-16 12.03.57.png")

##Android
Android側は端末側で少しだけ設定が必要です(最近端末を変えたので忘れてた)

Andridの場合端末側でUSBデバッグモードをONにしてあげる必要があり、そのモードを切り替えるために`開発者オプション`項目を表示させる必要があります。


`開発者オプション`項目は`設定`画面にあるのですが、デフォルトでは表示されていないので、表示させる必要があります。

###開発者オプション項目を表示
端末によって場所が違うかもしれませんが
 `設定`->`端末情報`->`ソフトウェア情報`(または　`設定`->`端末情報`)にある`ビルド番号`項目を`連続タップ`すると`これでデベロッパーになりました!`と表示され、
 `設定`画面に`開発者向けオプション`が表示されます
 
###開発者オプションとUSBデバッグモードをON
`開発者向けオプション`が表示されたら、タップし、項目を表示させます
開発者オプションはデフォルトでONになっているかもしれませんが、`USBデバッグモード`はOFFになってるかもしれないのでONにします

これらは実機テストをしない際はOFFにしておいた方がいいかもしれません

###端末データへのアクセス許可
接続した際に`端末データへのアクセス許可`や`USBデバッグの許可`が聞かれた場合OKして下さい

###インストール
![スクリーンショット 2018-01-16 12.36.09.png](https://qiita-image-store.s3.amazonaws.com/0/72559/e8194d0e-495f-cb9f-2a26-f6f27a324827.png "スクリーンショット 2018-01-16 12.36.09.png")

参考URL:
[Xamarin.FormsでAndroidの実機デバッグする方法](http://oxamarin.com/android-actual-debug/)
[Visual Studio for Mac で作成した Xamarin.Forms アプリを実機（iOS/Android）にインストールする](https://qiita.com/oda-i3/items/16604faebf7133c53b07)

###インストール時のエラー
```
The emulator exited unexpectedly.Please check the emulator settings.
```

```
Running an x86 based Android Virtual Device (AVD) is 10x faster. We strongly recommend creating a new AVD. 
```

これらのエラーが出た際は、必要なパッケージが足りてないかもしれません。

`Tools`->`Android`->`SDK Manager`から
![スクリーンショット 2018-01-16 10.31.05.png](https://qiita-image-store.s3.amazonaws.com/0/72559/4fc85abd-95ab-48a6-2254-57533e69d2bd.png "スクリーンショット 2018-01-16 10.31.05.png")

`Google APIs xxxxxxxx System Image` を確認し、インストールしてみて下さい
![スクリーンショット 2018-01-16 14.46.12.png](https://qiita-image-store.s3.amazonaws.com/0/72559/a1b03620-e0bc-d6ee-c4f5-e76ce81f0d9f.png "スクリーンショット 2018-01-16 14.46.12.png")

他のエラーとして
`performing clean boot : Snapshot doesn't exist`というダイアログが出てたのですが、パッケージを入れた後にVisual Studioを再起動すると消えてました

##インストールしたアプリの画面
iPhone画面
![xamarin_ios.png](https://qiita-image-store.s3.amazonaws.com/0/72559/c361f3fe-e6e9-d0e4-27ff-b271824a6540.png "xamarin_ios.png")


Android画面
![xamarin_android.jpg](https://qiita-image-store.s3.amazonaws.com/0/72559/29e93866-08dc-87d5-2bb4-a610212d864e.jpeg "xamarin_android.jpg")

#オススメサンプルデータ
[Simple List App](https://github.com/chomado/SimpleList)
→URLからJSONデータを引っ張ってきてリストビューに表示させるアプリ

以上