JXUG主催　初心者向けXamarinハンズオン備忘録

この記事は11/17(土)に実施された初心者向けXamarinハンズオンの中で時間が余ったので行った宿題部分の備忘録的な記事です。
問題があったら消すかもしれないです…
あとQiita初投稿なので指摘の点とかあればコメントでバシバシお願いします！


### 目次
1. [イベントについて](#01)
2. [宿題部分備忘録](#02)
3. [ちょっとだけ遊んでみた](#03)
4. [感想とか](#04)





<a id="01"></a>

### 1. イベントについて

今回参加させて頂いたイベントは「Xamarin.Forms」を使って、スマートフォン向けのアプリケーションを作ってみようというハンズオン形式のイベントでした！

自分はC#、モバイル開発未経験でしたが、自分でコードを書くことはほとんどしなかったのでとても敷居が低くてこれからモバイル開発やってみようかなとかXamarinって聞いたことあるけど一人だとなぁ…って思ってる人にはめちゃくちゃオススメのイベントでした。

主催の田淵さんや講師の方々曰く、「初めてビルドするのが一番難しくてそれができちゃえば勝ち！」とのことだったので、このイベントに参加して勝ち方を知って開発ガリガリやってくのがおすすめです！

JXUGのページは[こちら！](https://jxug.connpass.com/)

<a id="02"></a>

### 2. 宿題部分備忘録
さて、ここからが本題です。今回は参加人数が少なかったこともあり、想定よりも早くイベントが進みました。
そこで、本来なら宿題となっている部分をみんなでやってみようという話になりました。ただし、この部分テキストが無いので復習しようと思ってもテキストが無いのでここで少し書き残して備忘録としようって感じです。

- 目的：ハンズオンで作ったアプリをもとに、FaceAPIを使って人の年齢・性別・笑顔を数値化する

**※以下の説明はハンズオンが一通り終わった前提&Azureのアカウントある前提です。**
Azureアカウントない人でも
　[https://azure.microsoft.com/ja-jp/services/cognitive-services/face/](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/)
ここにアクセスしてFaceを試す　> ゲスト　を選べば7日間使うことができます。

1.NuGetパッケージを追加
DevDaysSpeakers.Droidを右クリック > 追加　> NuGetパッケージの追加
ここで出てきた画面で左下のプレリリースパッケージを表示するにチェックを入れた状態で「face」と検索
そうすると上から5,6番目くらいに下のやつが出てくるのでこいつを追加してあげてください。
iOSの方も同様のことをやるのを忘れずに！

<img width="848" alt="スクリーンショット 2018-11-18 18.13.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/302561/5a363645-7924-e885-70c4-b243fafd20ca.png">


2. 画面にボタンを作りたいので以下の記述をDevDaysSpeakers > View > DetailsPage.xamlに追記します。

```xml
<Button Text="表情" x:Name="ButtonFace"/>
```

Text="hoge"でhogeがボタン内のテキストとして表示されるので適宜変更OK

3.次に以下の記述をDevDaysSpeakers > View > DetailsPage.xaml > DetailsPage.xaml.csに追記します。

```csharp
//上のコード省略
public DetailsPage(Speaker speaker)
{

//省略
ButtonFace.Clicked += ButtonFaceClicked;
}
//省略
async void ButtonFaceClicked(object sender, EventArgs e)
{
var subscriptionKey = "<自分のkey>";
//以下URLは自分のリージョンにあったやつを記載
var faceEndpoint="https://westcentralus.api.cognitive.microsoft.com";

FaceClient faceClient = new FaceClient(            
    new ApiKeyServiceClientCredentials(subscriptionKey),
             new System.Net.Http.DelegatingHandler[] { });
            faceClient.Endpoint = faceEndpoint;
            IList<DetectedFace> faceList =
                    await faceClient.Face.DetectWithUrlAsync(
                    speaker.Avatar, true, false, faceAttributes);
           var age = faceList[0].FaceAttributes.Age;
           var gender = faceList[0].FaceAttributes.Gender;
           var happiness = faceList[0].FaceAttributes.Emotion.Happiness * 100;
           await DisplayAlert("faceAPI", $"Age: {age}\n Gender: {gender}\n Happiness: {happiness}%", "OK");
}
```

4.デバッグしてみる
<img width="320" alt="スクリーンショット 2018-11-18 16.53.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/302561/59321a7d-4f90-ac7b-6e0d-d77e4a8a5cf9.png">

出た！

ちなみに処理の流れとしては、対象の顔写真のURLをFaceAPIにソースとして投げる→FaceAPIが認識する→結果を返却→加工って感じのはず…

顔写真URLが短縮URLだったりすると失敗します。

<a id="03"></a>

### 3. さらにちょっとだけ遊んでみる

会場で遠くの紳士たちが「女性に年齢を聞くとうんたらかんたら」って言っているのが聞こえた（多分女性を選んだらたまたま短縮URLだったのかエラーで落ちた）のでちょっと改造してみました。(時間そんなになかったので、ちょっとだけ）

主な改造点としては2つ

- 女性だった場合は年齢をsecretにする。(17歳〇〇〇ヶ月表記とちょっと迷った)
- 短縮URLのときはエラーアラートを出す。

先程の

```csharp
var age = faceList[0].FaceAttributes.Age;
           var gender = faceList[0].FaceAttributes.Gender;
           var happiness = faceList[0].FaceAttributes.Emotion.Happiness * 100;
           await DisplayAlert("faceAPI", $"Age: {age}\n Gender: {gender}\n Happiness: {happiness}%", "OK");
}

```
このあたりを下のように書き換えます。

```csharp
try
{
            var age = "";
            var gender = faceList[0].FaceAttributes.Gender;
                  if(gender==0){
                       age = faceList[0].FaceAttributes.Age.ToString();
                    }else{
                        age = "secret";
                    }
                    var happiness = faceList[0].FaceAttributes.Emotion.Happiness * 100;
                    await DisplayAlert("faceAPI", $"Age: {age}\n Gender: {gender}\n Happiness: {happiness}%", "OK");
                }
                catch(Exception){
                    await DisplayAlert("Error", "エラーが発生しました", "OK");
                }
               
            }

```

genderは画面表記だと勝手に文字にしてくれるみたいなんですが、値としては0,1で持っているようで0が男性だったので0の場合は年齢を代入して、それ以外はsecretと文字列を代入しました。

あとは、短縮URLのときは配列の中身がないのに取り出そうとして例外発生という形になっていたのでtry-catchしてアラートを出すって感じにしてます！

<a id="04"></a>

### 4. 感想とか

Xamarinどころかモバイル系すらも初めてでしたが、共通コードを書き換えるだけでAndroidもiOSもそれぞれ反映してくれているのはすごい楽だなぁと個人的には感じました。
あと、{}の位置に違和感をずっと覚えっぱなしでした笑(Xamarin関係ない…)

個人的な開発案件とかで使えるなら使ってみたいなぁとも思っています。
ハンズオンの方はずっとゆったりした感じですし、困ったときは講師の方たちが察してやってきてくれていたので、コミュ障にも優しい？仕様になっていました。

はじめの一歩が一番重いので、踏み出してしまえば結構楽だと思います。
今後も予定と興味が合うときには積極的に参加していきます！