読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Azure Mobile AppsでUWPを作ってみよう

Azure UWP

食わず嫌いしてるMobile Appsですがここらへんで触ってみようと思います。バックエンドが簡単に作れるならそれにこしたことはないよね。ということで行ってみよう。

Mobile Apps Quickstartの作成

まず手始めにとっかかりをつかむには、Mobile Apps Quickstartというのを作るといいです。こいつはTodoアプリの完成形が出来上がってます。

f:id:okazuki:20160907194448p:plain

下のような感じで適当に作ります。

f:id:okazuki:20160907194822p:plain

そうすると、以下のセットが出来上がります。

f:id:okazuki:20160907202118p:plain

プロジェクトのダウンロードと実行

AppServiceを選んで、Quickstartを選ぶと、様々なプラットフォームのプロジェクトのひな型がDLできるようになっています。今回はUWPでいきたいのでWindows(C#)を選びます。

f:id:okazuki:20160907202449p:plain

Quickstartは、SQLiteを使ってるみたいですね。後で、SQL Databaseに変えてね的なメッセージが出てます。しばらく待つと、大体緑になりますので、Downloadボタンを押します。ダウンロードしたらプロパティからブロックを解除して展開します。

x86をターゲットに変えて何も考えずに実行してみましょう。 以下のように、TODOアプリが立ち上がります。動きますね。

f:id:okazuki:20160907202919p:plain

データの確認

Azureのポータルで、ドキュメントでは簡単テーブルと残念翻訳されてるEasy Tableを選びます。するとテーブルの中身を見ることが出来ます。先ほど実行したデータが入ってることが確認できます。

f:id:okazuki:20160907203151p:plain

認証をつけてみよう

Twitterで認証かけてみましょう。Twitterの開発者ポータルに行ってアプリを登録します。

Twitter Developers

ここの下のほうにManage Your Appsがあるので、そこからアプリを登録します。登録時に入力するコールバックとウェブサイトですが、以下のドキュメントにあるようにhttps://アプリ名.azurewebsites.net/.auth/login/twitter/callbackを指定します。今回は、okazukitodoという名前で私は作ったのでhttps://okazukitodo.azurewebsites.net/.auth/login/twitter/callbackになります。

azure.microsoft.com

DetailsタブとKeys And Access Tokensタブに必要な情報があるので、閉じずにキープしておきます。

Easy Tabletodoitemテーブルを選んで上のほうにあるChange permissionsを選択します。Insert, Update, Delete, Read, Undeleteのpermissionが全部匿名ユーザーに対して許すようになってるので、これをAuthenticated access onlyに変更して認証が必要なようにします。Saveを押すのを忘れずに。

f:id:okazuki:20160907204608p:plain

次にアプリ全体に認証をかけます。App Serviceを選んでAuthentication / Authroizationを選択します。App Service AuthenticationOffになってるのでOnに変更します。 そして、Twitterを選択します。先ほどのTwitterのページから取得できるAPI Key(Cosumer Keyともいう)とAPI Secret(Cosumer Secretともいう)をコピペします。

f:id:okazuki:20160907204952p:plain

入力したらSaveを忘れずにやっておきます。

この時点でアプリを実行すると認証エラーが起きるようになります。

f:id:okazuki:20160907205152p:plain

そして、テーブル自体にも認証が必要なようにします。Easy Tabletodoitemを選択して、Edit scriptを選択します。ブラウザでスクリプトが編集できるので、以下の1行を13行目あたりに追加しておきます。

table.access = 'authenticated';

認証処理を追加しましょう。MainPage.xamlにアプリバーを追加して、そこにログインボタンを置くようにししてみましょう。

<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton Label="SignIn"
                      Icon="Contact" 
                      Click="SignInButton_Click"/>
    </CommandBar>
</Page.BottomAppBar>

そして、コードビハインドで以下のようなコードを書きます。

private MobileServiceUser User { get; set; }

private async void SignInButton_Click(object sender, RoutedEventArgs e)
{
    try
    {
        this.User = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);
        await new MessageDialog($"サインインに成功しました: {this.User.UserId}").ShowAsync();
    }
    catch(InvalidOperationException)
    {
        await new MessageDialog("サインインに失敗しました").ShowAsync();
    }
}

実行してアプリバーのボタンを押すと以下のような画面が出てきます。

f:id:okazuki:20160907210404p:plain

サインインに成功すると、ちょっと残念なユーザー名が表示されます。

f:id:okazuki:20160907210502p:plain

そうすると、アプリが使えるようになります。

f:id:okazuki:20160907210604p:plain

毎回サインインするのは怠いので、認証トークンを保存しておくようにしましょう。サインインのボタンのクリック処理を以下のようにします。

private async void SignInButton_Click(object sender, RoutedEventArgs e)
{
    try
    {
        this.User = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Twitter);

        // これを追加
        var vault = new PasswordVault();
        vault.Add(new PasswordCredential("Twitter", this.User.UserId, this.User.MobileServiceAuthenticationToken)); 

        await new MessageDialog($"サインインに成功しました: {this.User.UserId}").ShowAsync();
    }
    catch(InvalidOperationException)
    {
        await new MessageDialog("サインインに失敗しました").ShowAsync();
    }
}

そして、MainPageOnNavigatedToあたりで復元処理を追加します。Userを作ってCurrentUserにセットする感じです。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var vault = new PasswordVault();
    try
    {
        var c = vault.FindAllByResource("Twitter").FirstOrDefault();
        if (c != null)
        {
            this.User = new MobileServiceUser(c.UserName);
            c.RetrievePassword();
            this.User.MobileServiceAuthenticationToken = c.Password;
            App.MobileService.CurrentUser = this.User;
        }
    }
    catch
    {
    }

    //await InitLocalStoreAsync(); // offline sync
    ButtonRefresh_Click(this, null);
}

これで、二度目の実行からは無事ログインしなくてもデータが読み込まれます。

次はサーバーサイドの処理を色々見ていけたらなと思います。JavaScript嫌いだけど…。