LoginSignup
8
5

More than 3 years have passed since last update.

NativeScript-VueとAWS Amplifyで爆速でアプリを実装する

Last updated at Posted at 2020-05-05

はじめに

NativeScript-Vueを用いてアプリ開発をしています。
その中で、AWS Amplifyと連携する機会があったので紹介していきたいと思います。

アプリの完成イメージ

下部の入力エリアで入力した内容が追加ボタンで追加されます。
タスクのトグルボタンを押下することでタスクに取り消し線と文字が薄くなります。

image.png

今回使用する技術を軽く説明

NativeScript-Vue


NativeScript-Vueは、モバイルアプリをJavaScriptで開発するためのOSSです。
モバイルアプリを構築するフレームワークだと、ReactNativeやionicなどReactやAngularを用いることが多いですが、Vue.jsで書けるのがNativeScript-Vueの大きな特徴です。(NativeScriptはAngular)

AWS Amplify


AWS Amplifyは、モバイルアプリやWebアプリの作成、実装、設定を容易にしてくれるライブラリです。
認証機能やデータの連携を簡単に構築することができます。

環境

動作が確認できた環境です。
また、AWS Amplifyを使用する関係でAWSのアカウントが必要となります。
※amplify mockを使用するため、料金はかかりません。

MacOS Mojave: 10.14.6
Node.js: 12.13.1
Python: 3.6.8

Java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment Corretto-8.232.09.2 (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM Corretto-8.232.09.2 (build 25.232-b09, mixed mode)

※Python3系は、NativeScript-Vueを実行するために必要です。

アプリの構築

NativeScript-Vueのセットアップ

vue-cliを利用して、NativeScript-Vueのアプリを構築します。

npm install -g @vue/cli @vue/cli-init

vue init nativescript-vue/vue-cli-template <app-name>
# ? Select a preset (more coming soon) (Use arrow keys)
# ❯ Simple

cd <app-name>
npm install

NativeScriptでは、tnsというコマンドを使用します。
下記のコマンドで、iPhone 11 Proのシミュレータが起動します。
もちろん、tns run androidと実行するとAndroidを起動することが可能です。

tns run ios --debug --device 'iPhone 11 Pro'

AWS Amplifyのセットアップ

npm install @aws-amplify/cli
npm i @aws-amplify/api aws-amplify

amplify --version
# 4.18.1

AWS Amplifyを使う準備

webpackの設定を変更する

ここが今回のポイントです。
AWS amplifyをWebのフレームワークで使用した場合には発生しないのですが、Nativescriptで実装した場合、mjsファイルを明示的に読み込めるようにしてあげる必要があります。

webpack.config.js
(省略)

+aliasFields: ["browser"],
+extensions: [".mjs", ".vue", ".ts", ".js", ".scss", ".css"],
-extensions: [".vue", ".ts", ".js", ".scss", ".css"],

(省略)

main.jsにAmplifyのモジュールを使う設定

下記を追加する。

main.js
import Amplify, * as AmplifyModules from 'aws-amplify'
import awsmobild from './aws-exports'

Amplify.configure(awsmobild)
Vue.use(AmplifyModules)

APIを作成する

# IAMの作成をしていない方は、aws configureを実行する必要があります。
amplify configure

amplify init

amplify add api
amplify/backend/api/schema.graphql
type Message @model {
  id: ID!
  username: String!
  content: String!
}

APIのモックサーバ起動

今回は、amplify mockを利用します。
amplify mockは、作成したAPIをローカル環境で確認することができます。

amplify mock api

# amplify pushをすれば、AppSyncを構築し、DynamoDBにテーブルが作成まで行われます。今回は、mockに留めます。

todoアプリのUIを作成する

ビュー部分

todosという配列をfor文で回して表示しています。
todosが空の時は、メッセージを表示しています。

/app/components/App.vue
<template>
  <Page>
    <ActionBar title="Todo" />
    <GridLayout columns="*" rows="*, auto">
      <ScrollView class="todo-area" row="0">
        <StackLayout v-if="todos.length > 0" class="todos">
          <StackLayout v-for="(todo, i) in todos" :key="i" orientation="horizontal" class="todo">
            <Label class="content" :class="{ done: todo.isDone }" :text="todo.title" />
            <Switch class="check" v-model="todo.isDone" @checkedChange="doneTodo(todo)" />
          </StackLayout>
        </StackLayout>
        <StackLayout v-else id="empty-msg">
          <Label text="タスクがありません" />
        </StackLayout>
      </ScrollView>
      <GridLayout columns="*, auto" row="1">
        <TextField id="comment-input" col="0" v-model="content" hint="タスクを入力" />
        <Button id="submit" col="1" text="追加" @tap="add()" />
      </GridLayout>
    </GridLayout>
  </Page>
</template>

ロジック部分

addでタスクの登録処理、doneTodoでタスクの更新処理、fetchTodosでタスクの一覧を取得しています。
amplifyのmutationsが登録、更新処理。queriesが取得処理です。

/app/components/App.vue
<script>
import API, { graphqlOperation } from '@aws-amplify/api';
import { createTodo, updateTodo } from '@/graphql/mutations';
import { listTodos } from '@/graphql/queries';

export default {
  data() {
    return {
      todos: [],
      content: ''
    }
  },
  created() {
    this.fetchTodos()
  },
  methods: {
    generateId () {
      return this.todos.length
    },
    async add () {
      let todo = {
        id: this.generateId(),
        title: this.content,
        isDone: false
      }
      try {
        await API.graphql(graphqlOperation(createTodo, { input: todo }))
      } catch (error) {
        console.error(error)
      } finally {
        this.resetInput()
        this.fetchTodos()
      }
    },
    async fetchTodos () {
      try {
        const res = await API.graphql(graphqlOperation(listTodos, { limit: 100 }))
        this.todos.push(...res.data.listTodos.items)
      } catch (error) {
        console.error(error)
      }
    },
    async doneTodo (todo) {
      try {
        const res = await API.graphql(graphqlOperation(updateTodo, {
          input: todo
        }))
      } catch (error) {
        console.error(error)
      }
    },
    resetInput () {
      this.content = ''
    }
  }
}
</script>

ソースコード全体像
/app/components/App.vue
<template>
  <Page>
    <ActionBar title="Todo" />
    <GridLayout columns="*" rows="*, auto">
      <ScrollView class="todo-area" row="0">
        <StackLayout v-if="todos.length > 0" class="todos">
          <StackLayout v-for="(todo, i) in todos" :key="i" orientation="horizontal" class="todo">
            <Label class="content" :class="{ done: todo.isDone }" :text="todo.title" />
            <Switch class="check" v-model="todo.isDone" @checkedChange="doneTodo(todo)" />
          </StackLayout>
        </StackLayout>
        <StackLayout v-else id="empty-msg">
          <Label text="タスクがありません" />
        </StackLayout>
      </ScrollView>
      <GridLayout columns="*, auto" row="1">
        <TextField id="comment-input" col="0" v-model="content" hint="タスクを入力" />
        <Button id="submit" col="1" text="追加" @tap="add()" />
      </GridLayout>
    </GridLayout>
  </Page>
</template>

<script>
import API, { graphqlOperation } from '@aws-amplify/api';
import { createTodo, updateTodo } from '@/graphql/mutations';
import { listTodos } from '@/graphql/queries';

export default {
  data() {
    return {
      todos: [],
      content: ''
    }
  },
  created() {
    this.fetchTodos()
  },
  methods: {
    generateId () {
      return this.todos.length
    },
    async add () {
      let todo = {
        id: this.generateId(),
        title: this.content,
        isDone: false
      }
      try {
        await API.graphql(graphqlOperation(createTodo, { input: todo }))
      } catch (error) {
        console.error(error)
      } finally {
        this.resetInput()
        this.fetchTodos()
      }
    },
    async fetchTodos () {
      try {
        const res = await API.graphql(graphqlOperation(listTodos, { limit: 100 }))
        this.todos.push(...res.data.listTodos.items)
      } catch (error) {
        console.error(error)
      }
    },
    async doneTodo (todo) {
      try {
        const res = await API.graphql(graphqlOperation(updateTodo, {
          input: todo
        }))
      } catch (error) {
        console.error(error)
      }
    },
    resetInput () {
      this.content = ''
    }
  }
}
</script>

<style scoped>
ActionBar {
  color: white;
}

.todo-area {
  background: #E5E5E5;
  width: 100%;
  height: 100%;
}

.todos {
  height: 100%;
  margin: 8px;
  border-right: 1 solid #ddd;
  border-left: 1 solid #ddd;
  background-color: #E5E5E5;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2) inset;
}

.todo {
  padding: 4px;
}

.content {
  font-size: 20px;
  width: 80%;
}

.done {
  color: gray;
  text-decoration: line-through;
}

.check {
  width: 20%;
}

#empty-msg {
  text-align: center;
  font-size: 16px;
  margin-top: 40px;
}


#submit {
  margin: 0 auto;
}

#comment-input {
  border-width: 1;
  border-color: #2E2E2E;
  border-radius: 8px;
  height: 100px;
}
</style>


アプリの起動(シミュレータ)

tns run ios --debug --device 'iPhone 11 Pro'

おわりに

本来であれば、バックエンドのAPIを構築してデータベースと連携してと実装が、大変なイメージですがAWS Amplifyを使うと簡単にバックエンドが実装できます。

また、アプリもNativeScript-Vueを使えばVue.jsの知識で作れてしまいます。

Vue.jsでアプリ作りたい方、AWS Amplify試してみたい方、NativeScript-Vue + AWS Amplify、是非試してみてください!

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5