ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Visual Studio 2019 for MAC を試してみた

先日 GA したばかりの Visual Studio 2019 for MAC を試してみました。
初めて MAC 向けの Visual Studio(Preview)が発表された際と同様に、ASP.NET Core で作った Web API を Xamarin Forms のアプリから呼び出してみます。

gooner.hateblo.jp

インストール

Visual Studio 2019 for MAC は、Community Edition であれば、こちらから無料でダウンロードすることができます。

visualstudio.microsoft.com

Xcode が必須なので最初にインストールしましたが、それ以外はウィザード通りに進めれば、問題なくインストールできました。

f:id:TonyTonyKun:20190411004439p:plain

ASP.NET Core で Web API を作る

Visual Studio を起動して、新しいプロジェクトを作成します。テンプレートは、ASP.NET Core MVC のアプリケーションを選択します。

f:id:TonyTonyKun:20190411004524p:plain

まず、モデルとして、Person クラスを追加します。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

API コントローラーとして、PersonController クラスを追加します。サンプルデータは前回と同じにしました。「君の名は。」が流行っていた頃だったようです。

[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var result = new List<Person> {
            new Person{ Id = 1, Name = "立花 瀧"},
            new Person{ Id = 2, Name = "宮水 三葉"},
        };
        return Ok(result);
    }
}

iOS と Android のエミュレータからは、localhost に HTTPS で接続できないので、Azure Web Apps にデプロイしておきます。Windows 版と同様に、Visual Studio からダイレクトに Azure Web Apps へアプリケーションを発行できるようになりました。

f:id:TonyTonyKun:20190411011405p:plain

Xamarin Forms から Web API を呼び出す

前回はターミナルからコマンドで起動する必要がありましたが、Dock から複数の Visual Studio を起動できるようになりました。

f:id:TonyTonyKun:20190411011851p:plain

Xamarin Forms 用にもう1つの Visual Studio が起動したら、新しいプロジェクトを作成します。テンプレートは、Xamarin.Forms の空白フォームのアプリを選択します。

f:id:TonyTonyKun:20190411005226p:plain

Web API から返された JSON をデシリアライズするための JSON.NET の NuGet ライブラリをインストールします。

f:id:TonyTonyKun:20190411005502p:plain

Xamarin Forms プロジェクトにボタンとリストビューを追加して、コードビハインドから Web API を呼び出すコードを追加します。

<?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:xamarinapp2" x:Class="xamarinapp2.MainPage">
    <StackLayout>
        <ListView x:Name="personList" >
          <ListView.ItemTemplate>
            <DataTemplate>
              <TextCell Text="{Binding Name}" />
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
        <Button Text="your name" Clicked="getPerson" />
    </StackLayout>
</ContentPage>
[DesignTimeVisible(true)]
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    public async void getPerson(object sender, System.EventArgs e)
    {
        using (var client = new HttpClient())
        {
            var response = await client.GetAsync("https://xxx.azurewebsites.net/api/person");
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                this.personList.ItemsSource = JsonConvert.DeserializeObject<List<Person>>(json);
            }
        }
    }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

結果確認(iOS)

Xamarin Forms プロジェクトで iOS のプロジェクトをスタートアップに設定してデバッグ実行すると、エミュレータが起動して Web API を呼び出して結果を表示することができます。

f:id:TonyTonyKun:20190411010008p:plain

結果確認(Android)

同様に Android のプロジェクトをスタートアップに設定してデバッグ実行すると、エミュレータが起動して Web API を呼び出して結果を表示することができます。

f:id:TonyTonyKun:20190411010052p:plain

まとめ

Visual Studio for MAC が最初にリリースされてから2年半が経ち、実用に耐え得るようになってきたかなという印象です。
Visual Studio Code もありますし、開発者が好きなデバイスでモバイルやクラウドのアプリケーションを作れるのはいいことだと思います。

Azure DevOps を使って Azure Functions v2 の CI/CD パイプラインを構築する

昨年の9月に Azure Functions v2 が GA しましたので、これから .NET で Azure Functions を構築するなら、.NET Core 2.1 ベースの v2 を選択することになります。
今回は、Azure DevOps を使って Azure Functions v2 の CI/CD パイプラインを構築する手順をまとめておきます。

ローカル開発環境

Azure Functions v2 は、Azure にデプロイせずとも、ローカル開発環境で Visual Studio を使って開発とデバッグができます。基本的には、下記の2つのツールがインストールされていれば大丈夫です。

  • Visual Studio の拡張機能「Azure Functions と Web ジョブ ツール」
  • Azure Storage Emulator

Visual Studio のプロジェクトテンプレートを選択すれば、すぐにローカル開発環境で Azure Functions を実行できますし、Visual Studio の発行機能を使えば、Azure Functions にデプロイすることもできます。
詳細な手順は、公式ドキュメントが分かりやすいです。先日 GA したばかりの Visual Studio 2019 でも、同様の手順で実行できます。
docs.microsoft.com

サンドボックスな Azure 環境であればこの方法でもいいですが、自動でビルドやデプロイを行いたい場合は、Azure DevOps で CI/CD パイプラインを構築するのがお勧めです。

ソースコードのリポジトリ

Azure DevOps のリポジトリを使ってもよかったのですが、今回は GitHub のリポジトリを使いました。上記の手順でプロジェクトを作成し、そのままプッシュしたシンプルなリポジトリです。
Azure DevOps と GitHub の関連付けは、Pipelines メニューから行います。

f:id:TonyTonyKun:20190404182141p:plain

Build パイプライン

Azure DevOps の Pipelines - Builds メニューより、「ASP.NET Core」のテンプレートを選択します。

f:id:TonyTonyKun:20190404182220p:plain

Azure Functions v2 向けに、デフォルトの設定から1つだけ変更する必要があります。通常の Web アプリケーションではないので、「Publish Web Projects」のチェックをオフにします。

f:id:TonyTonyKun:20190404182232p:plain

Save & Queue ボタンを押し、ビルドを実行して結果を確認します。

Releases パイプライン

事前に、Azure Portal から Azure Functions を作成しておきます。今回は、Consumption で .NET 向けの Azure Functions を作成しました。
Azure DevOps の Pipelines - Releases メニューより、「Azure App Service deployment」のテンプレートを選択します。

f:id:TonyTonyKun:20190404182246p:plain

Azure Functions v2 向けに、デフォルトの設定から2つだけ変更する必要があります。

  • App Service type は「Function App on Windows」を選択する
  • Additional Deployment Options で「Select deployment method」のチェックをオンにし、「Run From Package」を選択する

f:id:TonyTonyKun:20190404182302p:plain

Build と Releases パイプラインの関連付け

まず、Releases パイプラインにおいて、Build パイプラインで生成した Artifact を関連付けます。

f:id:TonyTonyKun:20190404182318p:plain

次に、Build パイプラインの Continuous deployment trigger を有効にします。

f:id:TonyTonyKun:20190404182331p:plain

最後に、Releases パイプラインにおいて、新しいリリースを作成します。

f:id:TonyTonyKun:20190404182344p:plain

以上で、Azure Functions v2 向けの CI/CD パイプラインが完成しました。

CI/CD パイプラインの実行

GitHub のリポジトリに変更をプッシュし、CI/CD パイプラインを実行します。トリガーが発火すると、Build パイプラインの Artifact を使って、Azure Functions にデプロイが実行されます。

f:id:TonyTonyKun:20190404182415p:plain

Azure Portal を開くと、Azure Functions にデプロイされていることが確認できます。

f:id:TonyTonyKun:20190404182427p:plain

Kudu で「data/SitePackages」ディレクトリを確認すると、Run From Package の zip ファイルが配置されていることが分かります。

f:id:TonyTonyKun:20190404182441p:plain

まとめ

サーバーレスの Azure Functions ですが、v2 になってローカル開発から CI/CD パイプラインの構築まで、通常の Web アプリケーションと同じように開発できるようになりました。
コールドスタートやVNET統合などに対応した Premium Plan(Public Preview)も登場してきましたし、Durable Functions もあるので、サーバーレスを適用できるシナリオは増えてくると思います。

MVP Global Summit 2019 に参加してきました

昨年に続き、MVP Global Summit(グロサミ)に参加してきました。グロサミは、ワシントン州レドモンドのマイクロソフト本社で開催される MVP 向けのイベントです。セッション内容はすべて NDA のため、シアトルのダウンタウンを中心とした観光の情報のみとなります。

フライト

3/17(日)夕方の ANA の直行便で、成田空港からシアトル・タコマ国際空港へ向かいました。所要時間は9時間~10時間、日本の方が16時間進んでいます。
長時間フライトはあまり得意ではないので、今年は対策を練りました。

  • 座席は通路側(自分の好きなタイミングでトイレに行ける!)
  • ペットボトルの水を持ち込む(機内は乾燥するので、すぐに水分補給できる!)
  • ネックピローを購入(寝ているときに首が痛くならない!)
  • Amazonプライムビデオからスマホにアニメをダウンロード(退屈しない!)

あとは、ボヘミアン・ラプソディを観て過ごしたりしていたら、昨年よりは短く感じた気がします。シアトル・タコマ国際空港へ到着したのは、3/17(日)昼の10時過ぎでした。

シアトル(その1)

シアトル・タコマ国際空港から、グロサミのレジストを行うホテルの Hyatt Regency Bellevue まで向かいます。昨年は空港から Uber を使って向かったのですが、今年はシアトルの街並みを眺めながら公共交通機関を使って行くことにしました。
まずは、シアトルの電車「Link Light Rail」を使って、シアトルのダウンタウンに向かいました。Uber だと 40 ドル弱ですが、Link Light Rail だと 3.5 ドルなので、かなりお得です。所要時間は、International district / chinatown という駅まで 30 分ぐらいだったと思います。(意外とスピード出してた)

f:id:TonyTonyKun:20190327203109j:plain

今回はバスにも乗る予定だったので、交通ICカード「Orca Card」を購入しました。小銭を用意するが面倒だし、バスはお釣りがでないので便利です。自動販売機でクレジットカードを使って購入できます。ひとまず 20 ドルをチャージしました。駅には改札口らしきものがないので、ホーム階段下にある機械でピッとします。

f:id:TonyTonyKun:20190327210006j:plain

シアトルのダウンタウンを少し散策した後、ランチに Ivar's のクラムチャウダーを食べました。

f:id:TonyTonyKun:20190327203447j:plain

f:id:TonyTonyKun:20190327203524j:plain

ランチの後、International district / chinatown の駅まで戻り、ベルビュー行きの550番のバスに乗って、Hyatt Regency Bellevue に向かいました。バスは、乗口にある機械でピッとします。乗るバスの方向を間違えるハプニングなんかもありましたが、無事にレジストを完了しました。

f:id:TonyTonyKun:20190327203600j:plain

ベルビュー(その1)

グロサミのレジストとかパーティーを考えるとハイアットに泊まるのが便利なのですが、今年は Courtyard by Marriott Seattle Bellevue/Downtown に泊まりました。

f:id:TonyTonyKun:20190327203633j:plain

f:id:TonyTonyKun:20190327203732j:plain

f:id:TonyTonyKun:20190327203801j:plain

コートヤードは規模が小さいのでホテル内の移動が楽だし、2ドルのコインランドリーがあったのが便利でした。ハイアットから徒歩で10分弱でしたが、やっぱり移動なんかは面倒だったので、次回はハイアットがいいかなあと思ったり。

レドモンド

5日間のセッションは、レドモンドにあるマイクロソフト本社キャンパスで開催されます。ベルビューのホテルからシャトルバスが出ていて、所要時間は20分ほどです。キャンパスには、100を超える Building があって、Building の間にはレストランやカフェがあり、緑も豊かな広い敷地です。(敷地内に高速道路が通っている!)

f:id:TonyTonyKun:20190327203843j:plain

f:id:TonyTonyKun:20190327210430j:plain

f:id:TonyTonyKun:20190327204009j:plain

セッション期間中、コーヒーとかドリンク類は飲み放題です。おやつには、すごく甘いカップケーキやピザが出たりします。

f:id:TonyTonyKun:20190328005830j:plain

こんなラテアートもありました。

f:id:TonyTonyKun:20190328005947j:plain

セッションの合間に、Azure Functions チームのメンバーとのミーティングに参加させてもらいました。オフィス内は、いろいろとお洒落な感じで、ミーティングスペースや仕事場のほかに休憩スペースなんかもあり、仕事しやすそうな環境で羨ましかったです。

f:id:TonyTonyKun:20190327210331j:plain

f:id:TonyTonyKun:20190327210356j:plain

去年は行きそびれたツリーハウスにも行ってきました。ここでは WiFi が完備されていて、ミーティングとか雑談をする場所らしいです。

f:id:TonyTonyKun:20190327204132j:plain

f:id:TonyTonyKun:20190327204217j:plain

f:id:TonyTonyKun:20190327204244j:plain

シアトルは例年曇りや小雨の日が多いですが、今回は最終日に少し雨が降ったぐらいで、ずっと快晴で暑いぐらいでした。(27度を超えた日もあった!)ちなみに、キャンパス内は緑が豊かなので杉の木も多く、花粉症はけっこう辛かった・・・

ベルビュー(その2)

ホテルやセッション会場の食事は、だいたいこんな感じです。

f:id:TonyTonyKun:20190328004739j:plain

数日もすると飽きてくるので、今年もショッピングモールの「BELLEVUE SQUARE」とスーパーの「QFC」にはお世話になりました。

f:id:TonyTonyKun:20190328005000j:plain

BELLEVUE SQUARE にあるラーメン屋「輝月」は、日本よりも少し割高ですが、けっこう美味しかったです。ほかにも、マイクロソフトストアやアマゾンの実店舗書店があります。QFC では、部屋飲み用のビールや水なんかを買ったりしました。

シアトル(その2)

最終日は、シアトルのダウンタウンに観光に行きました。マイクロソフト本社キャンパスから 450 番のバスに乗って、Westlake Center という駅まで 20 分ぐらいでした。
まずは、シアトル水族館。シアトル近郊の海の生き物たち(サーモンとかラッコとか)がいて、コンパクトな感じでわりと良かったと思います。

f:id:TonyTonyKun:20190327204429j:plain

f:id:TonyTonyKun:20190327204529j:plain

f:id:TonyTonyKun:20190327212554j:plain

シアトル水族館から歩いてすぐの PIKE PLACE MARKET を散策しながら、スペースニードルに向かいました。市場の中を通ったり、スタバ1号店を横目に見たりしながら進みました。有名な魚を投げるシーンには、なかなか出会えないなあ。

f:id:TonyTonyKun:20190327204646j:plain

スペースニードルまでは結構距離があるので、モノレールを使いました。(去年は歩いた!)所要時間は 2 分ほどで 2.5 ドル、残念ながら Orca Card は使えませんでした。

f:id:TonyTonyKun:20190327204748j:plain

去年は近くまで行っただけだったので、今年は登ることにしました。ガラス張りの展望台は高いところが苦手な自分にはアレでしたが、眺めもいいので1度は登ってみることをお勧めします。

f:id:TonyTonyKun:20190327204816j:plain

f:id:TonyTonyKun:20190327204918j:plain

f:id:TonyTonyKun:20190327204948j:plain

お土産

マイクロソフト本社キャンパス内にあるカンパニーストアで購入した Surface Go。開発機にはできないけど、ちょっとした外出や仕事の打ち合わせでは活躍できそう。

f:id:TonyTonyKun:20190327205019j:plain

ホテルの近くの本屋で購入した英語版のワンピース1巻。「海賊王に、おれはなる」の有名なセリフは、「I'M GOING TO BECOME、THE KING OF PIRATES」でした。

f:id:TonyTonyKun:20190327205059j:plain

まとめ

今年もたくさんの刺激を受けることができたし、いろいろな方々と仲良くなれたし、いろいろと観光もできたし、非常に楽しめた1週間でした。時差ボケのためか、夜はあまり寝られず昼のセッションは睡魔との格闘でした。前日入りすれば、もう少し楽になるのかも。そんなことを考えながら、日本への帰路についたのでした。

f:id:TonyTonyKun:20190327202959j:plain