tag:crieit.net,2005:https://crieit.net/tags/ionic/feed 「ionic」の記事 - Crieit Crieitでタグ「ionic」に投稿された最近の記事 2021-04-13T16:45:08+09:00 https://crieit.net/tags/ionic/feed tag:crieit.net,2005:PublicArticle/16841 2021-04-13T16:45:08+09:00 2021-04-13T16:45:08+09:00 https://crieit.net/posts/38e8f748a2d53951f9604bea786870bf モバイルアプリ開発フレームワーク <p>現在、40億人を超えるモバイルユーザーがいるため、モバイルでオーディエンスとつながることができなければ、あなたは存在しません。人々はスマートフォンの使用をとても楽しんでいるので、技術のない日を過ごすために自分自身に挑戦する必要があります。スマートフォンは、電話、テキストメッセージ、メールのチェック、さらには娯楽まで、必要なものをすべて提供できます。そのため、モバイルアプリフレームワークが実現します。<br /> このような陰謀的なアプリケーションの舞台裏には、何千ものモバイルアプリ開発フレームワークがあります。ただし、モバイルアプリをうまく作るには、適切なモバイルアプリ開発フレームワーク、関連技術、プラットフォーム、データベースが不可欠です。とはいうものの、あまりにも多くの選択肢があり、どれかひとつに絞るのはこれまで以上に難しい状況です。そこでこの記事では、iOSとAndroid両方のプラットフォームで最も人気の高いモバイルアプリ開発フレームワークについて説明します。その前に、効率的な モバイルアプリ開発フレームワーク とはどのようなものかを簡単に見ていきましょう。</p> <p><strong>1. React Native</strong><br /> React Nativeは、AndroidアプリとiOSアプリの両方向けに構築された非常に人気のあるフレームワークです。特に、モバイルアプリの開発者は、より短いビルドサイクルでより高速なデプロイ時間で高性能アプリをビルドでき、予算にやさしいオプションです。さらに、React Nativeは、ビュー、テキスト、画像など、プラットフォームに依存しないネイティブコンポーネントのコアセットを提供し、すべてプラットフォームのネイティブUIビルディングブロックにマップされます。また、フルスタックに必須のJavaScriptもサポートしています。</p> <p><strong>2. Flutter</strong><br /> FlutterはGoogle が作ったオープンソースの<a target="_blank" rel="nofollow noopener" href="https://kaopiz.com/ja-news-cross-platform-framework-flutter-vs-react-native/">ネイティブアプリケーション開発フレームワーク</a>です。Dart という共通言語で開発を行います。詳しいデバッグができるので React Native で感じる「隔靴掻痒」感は少ないです。<br /> Flutterを使うことで同一のコードベースからAndroidやiOSアプリを構築でき、その見た目もネイティブアプリです。FlutterはGoogleによる導入が2015年でしたが、2018年12月の公式リリースまではベータ段階にとどまっていました。<br /> Flutterのユーザーは、携帯電話、テレビ、タブレット、ウェアラブルデバイス、スマートディスプレイ用のアプリを作成できます。<br /> ちなみに Flutter Studio は Flutter の UI 作成のために使えるサイトです。ビルドのためのものではありません。Flutter を採用するなら使うことになるのではないかと思われます。Flutter ではそれぞれの Native パートをプロジェクト含めることができる。</p> <p><strong>3. Ionic</strong><br /> Ionicは、クロスプラットフォームアプリケーションとともにインタラクティブハイブリッドおよびPWAを構築するのに役立ちます。このオープンソースフレームワークは、アプリケーションを作成するためのプレミアムサービスを提供します。さらに、Ionicは、Web、Android、およびiOS用のアプリケーションの構築をカバーしています。さらに、Ionicで作業している間は、常にアプリケーションを作成して、展開可能な場所に出荷できます。すぐに使用できる機能を備えているため、アプリケーション開発に最適です。</p> <p><strong>まとめ</strong><br /> 以上挙げた3つのフレームワーク以外、他にも<a target="_blank" rel="nofollow noopener" href="https://kaopiz.com/ja-news-mobile-application-development-frameworks-20202021/">モバイルアプリ開発フレームワーク</a>があります。どのフレームワークを選択するかは、要件、予算、技術的要件、そして短期的または長期的な成功の可能性に応じて、最も適したものを選ぶと良いでしょう。</p> hanhnh tag:crieit.net,2005:PublicArticle/15633 2019-12-22T23:20:13+09:00 2019-12-23T03:48:26+09:00 https://crieit.net/posts/ionic-angular-WebComponents @ionic/angularがWebComponentsでテンプレートチェックを効かせるためにやっていることを調べる <h1 id="AngularでWebComponetsライブラリを使う時の基本"><a href="#Angular%E3%81%A7WebComponets%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E4%BD%BF%E3%81%86%E6%99%82%E3%81%AE%E5%9F%BA%E6%9C%AC">AngularでWebComponetsライブラリを使う時の基本</a></h1> <p>CustomElementsは基本的にはHTMLElementです(正確にはHTMLElementを継承して作ったもの)。<code>customElements.define()</code>することでグローバルに存在するようになるので、なんらかの方法でライブラリをインクルードすれば、あとはtemplateに書いておけば動きます。Angularから見れば、<code>input</code>タグでも<code>custom-input</code>タグでも同じ話なわけです。</p> <pre><code class="html"><input type="text"/> <custom-input type="text"></custom-input> </code></pre> <p>ただし、Angularのテンプレートチェックに<code><input></code>はわかるけど<code><custom-input></code>は知らないやつだなあと怒られるので対策が必要です。</p> <pre><code class="ts">@NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA], ←templateチェックを無効にする }) export class SomeModule {} </code></pre> <p>これで自由にHTML要素を書いてもよくなりますが、テンプレートの事前チェックが無効化されて実行時の存在判定に後送りされるため、他のタイポなども道連れで検出できなくなります。</p> <pre><code class="html"><typo-input type="text"></typo-input> ←どこにも定義されてないがビルド時にエラーにならない </code></pre> <p>このようにAngularでWebComponetsを使うには<strong>誓約と制約</strong>があります。</p> <h1 id="@ionic/angularがやっていること"><a href="#%40ionic%2Fangular%E3%81%8C%E3%82%84%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8">@ionic/angularがやっていること</a></h1> <p>さて、ionicのv4はWebComponentsベースで書き直され、Angularだけでなくreactやvueでもできるようになりましたが、Angularは引き続きテンプレートチェックがビシッと効いています。</p> <p>不思議なので中身を調べてみましょう。</p> <p>なんと、同じ名称のAngularComponentが定義されていました❗️</p> <p>ソースを読むとプロキシという扱いのようなので、これをプロキシコンポーネントと呼びます。<br /> どうやらこいつがビルド時にAngularに差し出されているから、テンプレートの型チェックが効いてるようです。</p> <p><code><ion-input></code>を例に引っ張ってきました。現バージョンだと<code>@ProxyCmp</code>という新デコレータが作られていて、<code>proxyMethods</code>や<code>proxyInputs</code>の記述は省力化されていますが、構造がわかりやすいので旧スタイルで掲載しています。</p> <pre><code class="ts">export declare interface IonInput extends StencilComponents<'IonInput'> {} @Component({ selector: 'ion-input', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: [ 'accept', 'autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'debounce', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'spellcheck', 'step', 'type', 'value', ], }) export class IonInput { ionInput!: EventEmitter<CustomEvent>; ionChange!: EventEmitter<CustomEvent>; ionBlur!: EventEmitter<CustomEvent>; ionFocus!: EventEmitter<CustomEvent>; protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; proxyOutputs(this, this.el, ['ionInput', 'ionChange', 'ionBlur', 'ionFocus']); } } proxyMethods(IonInput, ['setFocus', 'getInputElement']); proxyInputs(IonInput, [ 'color', 'mode', 'accept', 'autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'debounce', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'spellcheck', 'step', 'size', 'type', 'value', ]); </code></pre> <h2 id="全体構造"><a href="#%E5%85%A8%E4%BD%93%E6%A7%8B%E9%80%A0">全体構造</a></h2> <p>通常のAngularComponentに則ったデコレータとclassです。<code>proxyOutputs</code>、<code>proxyMethods</code>、<code>proxyInputs</code>はionicが用意しているユーティリティ関数です。</p> <h2 id="生のWebComponentsに対してバインドする方法"><a href="#%E7%94%9F%E3%81%AEWebComponents%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E3%83%90%E3%82%A4%E3%83%B3%E3%83%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95">生のWebComponentsに対してバインドする方法</a></h2> <h3 id="接続"><a href="#%E6%8E%A5%E7%B6%9A">接続</a></h3> <p>コンポーネントデコレータのselectorをcustomElementと同じ名称にしています。相当ハックだと思ったのですが、Angularのコンポーネントはカスタム要素としてHTMLにそのまま出力するので、selectorをHTMLに存在している要素名にするとHTMLではHTMLに存在している要素として解釈するわけなんですよね。もちろん<code>_nghost-wke-c2</code>のような属性は付きます。良い子は真似するな案件ですが、customElementに限らず標準HTML要素の<code>input</code>とか<code>span</code>とかでも同じことできます。</p> <h3 id="プロキシ"><a href="#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7">プロキシ</a></h3> <p>コンポーネントでは、elementRefから引っ張ったnativeElementの生DOM参照をクラスプロパティに保持しています。<br /> proxyInputsとproxyMethodsは、そのクラスプロパティに保持したnativeElementを通して生の<code>ionic-input</code>に対して、HTML属性のget/setやionic内部に用意されているメソッドを生やしています。</p> <pre><code class="ts">export const proxyInputs = (Cmp: any, inputs: string[]) => { const Prototype = Cmp.prototype; inputs.forEach(item => { Object.defineProperty(Prototype, item, { get() { return this.el[item]; }, set(val: any) { this.z.runOutsideAngular(() => (this.el[item] = val)); } }); }); }; export const proxyMethods = (Cmp: any, methods: string[]) => { const Prototype = Cmp.prototype; methods.forEach(methodName => { Prototype[methodName] = function () { const args = arguments; return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args) ); }; }); }; </code></pre> <p>proxyOutputsは、rxjsの<code>fromEvent</code>(中でaddEventListenerやremoveEventListenerしながらObservable化するやつ)を、コンポーネントの各EventEmitter型のプロパティにセットしているものです。コンポーネントclassに同名のクラスプロパティが用意されています。</p> <pre><code class="ts">export const proxyOutputs = (instance: any, el: any, events: string[]) => { events.forEach(eventName => instance[eventName] = fromEvent(el, eventName)); } </code></pre> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>プロキシするコンポーネントを用意することで、グローバルに存在しているWebComponentsライブラリでも、Angularのテンプレートの中でまるでAngularComponentかのように扱えるようになり、テンプレートの型チェックが効くようになっています。</p> studioTeaTwo tag:crieit.net,2005:PublicArticle/15079 2019-06-09T23:29:17+09:00 2019-06-10T04:54:16+09:00 https://crieit.net/posts/ionic-AngulaCLI ionicをAngulaCLIで使う <p>ionicは長らくAngularとcordovaを用いたUIフレームワークでしたが、最新バージョンではwebComponentsベースになり、reactでもvueでも生jsでもなんでもいけるようになりました。</p> <p>素晴らしいんですが、逆に構成パターンがめっちゃ増えて迷うというところもあります。<br /> Angularをベースにする上でもパッと3パターンがありえます。</p> <ol> <li>ionic CLIを用いる(従来通り)</li> <li>scriptタグで@ionic/coreをインクルードしてピュアWebComponentとして利用する</li> <li>angularCLIプロジェクトに@ionic/angularをインストールして利用する</li> </ol> <p>本記事では3番を取り上げます。普通にnpmPackageとして組み込むだけで、組み込んだ後はいつものngコマンドで開発します。</p> <hr /> <h1 id="インストール"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">インストール</a></h1> <p>最初にインストールします。angularCLIで作成したプロジェクトの前提です。</p> <pre><code>$ npm install @ionic/angular </code></pre> <p><code>ng add @ionic/angular</code>ができそうな記述も見られますが、Anuglar v8ではダメです。さっとコードを見た限りだとangular.jsonのスキーマ変更をキャッチアップすればいけそうな感もありましたが、ionic v4はもはや別ライブラリでは?というくらい内部的には激しい刷新が行われているので焦らず待ちましょうという判断しました。</p> <p>ionicCLIでは<code>*.page.ts</code>とかの独自レイヤーがあるようですが、このやり方ではそういうのは考えない感じです。</p> <p>他にも<code>@ionic/angular-toolkit</code>というcordvaやschematicsのプラグインを提供しているパッケージがありますが、現時点では要らなそうです。cordvaはただのwebアプリなら要らないですし、schematicsは上述のようにもう少し待ちましょう判断です。もしかしたらng addだけでなく<code>*.page.ts</code>とかをng generateできるようになるのかな。</p> <h1 id="コンフィグレーション"><a href="#%E3%82%B3%E3%83%B3%E3%83%95%E3%82%A3%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3">コンフィグレーション</a></h1> <p>普通にNgModuleをimportすればOKです。WebComponentなので、Angularのtemplateコンパイラチェックを外すために<code>CUSTOM_ELEMENTS_SCHEMA</code>を加えます。</p> <p>app.module.ts</p> <pre><code class="typescript">import { BrowserModule } from '@angular/platform-browser'; import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { IonicModule } from '@ionic/angular'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, IonicModule.forRoot(), ], providers: [], bootstrap: [AppComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) export class AppModule {} </code></pre> <p>ルートのcssファイルにスタイルをインポートします。著者はscssでAngularCLIを起こしていますが、それぞれ置き換えてください。</p> <pre><code class="scss">/* Core CSS required for Ionic components to work properly */ @import "~@ionic/angular/css/core.css"; /* Basic CSS for apps built with Ionic */ @import "~@ionic/angular/css/normalize.css"; @import "~@ionic/angular/css/structure.css"; @import "~@ionic/angular/css/typography.css"; /* Optional CSS utils that can be commented out */ @import "~@ionic/angular/css/padding.css"; @import "~@ionic/angular/css/float-elements.css"; @import "~@ionic/angular/css/text-alignment.css"; @import "~@ionic/angular/css/text-transformation.css"; @import "~@ionic/angular/css/flex-utils.css"; @import "~@ionic/angular/css/display.css"; </code></pre> <p>アイコンは若干トリックが要りました。参照解決してくれなかったのでassetsにコピーして利用しています。<br /> この辺りは、<code>ng add @ionic/angular</code>を実装している<a target="_blank" rel="nofollow noopener" href="https://github.com/ionic-team/ionic/blob/master/angular/src/schematics/add/index.ts">schematicsのコード</a>が大変参考になります。というか、ピックアップして手動でコピペします。</p> <p>angular.json</p> <pre><code class="json">{ "projects": { "architect": { "build": { "options": { "assets": [ "src/favicon.ico", "src/assets", { "glob": "**/*.svg", "input": "node_modules/ionicons/dist/ionicons/svg", "output": "./svg" } ], } } } } } </code></pre> <p>アイコンタグでは相対URLを記述します。</p> <pre><code class="html"><ion-item button routerLink="/home"> <ion-icon slot="start" src="/assets/svg/md-home.svg"></ion-icon> <ion-label> Home </ion-label> </ion-item> </code></pre> <p>以上となりますが、基本的にはschematicsの<a target="_blank" rel="nofollow noopener" href="https://github.com/ionic-team/ionic/blob/master/angular/src/schematics/add/index.ts"><code>ng add</code>のコード</a>を教科書にして構成するとよいです。<code>ng add @ionic/angular</code>コマンドそのものは動きませんが、リファレンスには最適です。</p> studioTeaTwo