考えすぎてしまう人のブログ

世の中の色んなことをいつも考えすぎてしまう僕の脳内を垂れ流します

【2017】結局RailsユーザーがiPhone&Androidアプリを作る一番良い方法はなんなのか?→「Xamarin ハイブリッド」がいいと思います

※記事の内容があまりにも雑だったので大幅加筆修正しました。つっこみ下さった方ありがとうございますm( )m

どうもせせりです:)

この記事は「Railsしかやったことないけど、Android&iPhoneアプリでサイトの専用アプリをサクッと作りたい、push通知したい」という贅沢な人向けの記事です

※この記事で説明するのは「Xamarin.forms」です

前提

f:id:sesere:20171031153248p:plain

KotlinやSwiftで作るのが一番、と言うのは間違いないかと思います

でも、Webに慣れきった我々としては使い慣れたHTMLやCSSで解決したいしそんなネイティブガリガリに作り込みたいわけではなく、Webにpush通知を添えた程度のものをサクッと作れればそれでいいのです

ページ数だって20枚もない、そのくらいのアプリで良いのです

業務で作っている方からすれば「そんなしょぼいアプリ作る必要あるの?」と思うかもしれませんがpush通知したいんです

PWAがiOSでも標準搭載されて全デバイス対応したらそっちにすぐ移動すると思いますが残念ながら今はまだ未対応なので泣く泣くアプリを作ることになります

……と、この程度のめちゃくちゃ低いモチベーションでアプリ開発をはじめるのでそもそもあんまり手間暇コストをかけたくないのですがここらへんの情報がまとまっていないのでそこらへんをまとめて共有します

※アプリをクロスプラットフォームで作る方法として「ハイブリッドアプリ(Cordova)」と「Xamarin」が今は一番有名なのでその2点について解説します

1. Cordova(Monaca)でハイブリッドアプリ

f:id:sesere:20171203193122p:plain

許されるならこれが一番早いです

CordovaはHTMLとJSとCSSでアプリが作れる優秀なやつです

ただしネイティブアプリのような遷移をするために「OnsenUI」などの特別な書き方を覚える必要があります&仮想ページなのでSPAと同じように変数などがリセットされないため普通のRailsと同じイメージで作ると失敗します

多少覚えることは多いけどHTMLで書けるならいいのでは?→ そう思っていました

Cordovaはアップデートペースがとても早くバージョン同士の組み合わせでPluginが動かない事がしょっちゅう起こり本当にもうそれはそれはすごく消耗します

Monacaのサンプルとして提供されているものすら(nifty push 通知)動かなかったりするので本当に泥沼です。さらにたちの悪いことに

「プラグインを入れてみる」→「エラーが出たからプラグインを削除する」→「削除してもエラーが発生してそれ以降一生コンパイルは通らない」

こういう罠があります。試しにプラグインを入れてみるなんて事をやっただけでそのプロジェクトは壊れるので新しいプロジェクトを作って0からファイルを設置しなおさないといけません

なんでかというと……MonacaでやるにしろVisualStudioでやるにしろ、表に見えているファイルだけでなく裏に隠れている設定ファイル類が沢山有ります

例えば上に書いたniftyのプラグインを一度入れてしまうとmonaca上やvisual studio上からはいじれない裏の設定ファイルにその情報が書き込まれ、pluginを削除しようとこの書き込まれた内容が消えることはないのでそれ以降一生エラーを吐き続けコンパイルできない壊れたプロジェクトへと変貌を遂げます

もちろんVisualStudioでやるなら後ろの方にある設定ファイルを探しに行って手動で修正も出来るのですが自動で変更されるファイル数が多すぎてcordova自体の学習コストがとてもかかります

他にも色々イマイチな点はあるのですがとりあえずまとめると 辛い 本質的じゃない所でつまりまくるので本当に辛い

知り合いにCordovaマスターが居るなら良いですがそうでないなら辞めておいたほうが良いと思います。ハゲるレベルで辛いです

※さらにさらに悲しいことにpush通知系のplugin(Cordova Firebaseプラグインがエラーで動かない)もエラーを吐くので一番使いたいpush通知が現在できません.AzureとかSESとか使うといけるかも

2.Xamarin(C#)でネイティブアプリ

f:id:sesere:20171203193551p:plain

最近Twitterで教えてもらってはじめてみました

複雑な事をしなければワンソースで両対応出来るのですが……ネイティブ辛い

プログラムの部分はまだ良いんですよ、基本コピペと組み合わせでどうにかできるので……問題はデザインの方

例えば水平線を引きたいと思ったら?

HTMLなら<hr>で終わりですが(区切り線だろ!というツッコミは置いといて)、ネイティブには水平線なんて便利なものはありません

じゃあどうするの?と言うと「Rect(四角形)の高さを1pxにして、横幅を100%にしたらそれは水平線だよね!HAHAHA!」って感じです

何年目だ!!!!アプリ開発の歴史はもう10年たってるのに線を引くことすらノウハウがいるのか!!!!

と突っ込むことになります

参考 Xamarinでラインを配置する方法 | Xamarin.Forms - ITブログ時々なんでもブログ

Xamarinでは「テキストに下線をつける」ことすら提供されていないので自分で書く必要があります

テキストに下線をつけるために3つもファイルを作って100行くらい書く必要があります

参考 Xamarin.FormsでLabelに下線を引きたい - かずきのBlog@hatena

何年目だ!!!!アプリ開発の歴史はもう10年たってるのに下線を引くことすらファイル作る必要があるのか!!!!

と再度突っ込むことになります

あとデザインについても「OSごとのデザインを使います!」というものなので、すぐに作るのには向いていてもそのアプリ独自のおしゃれなものは作れません

イメージとして勝手にTwitter BootStrap風のデザインが適用されると思ってください……え?変更したい?その道は泥沼ですよ

ネイティブアプリは独自デザインじゃなくてOSのデザインを遵守すべき

というツッコミもわかりますが、現実問題それ守ってるアプリがあるの?と言うと大手のアプリで守っているところなんて殆ど無いと思います

こんな感じで終始 デザインのめんどくささ に悩まされます。HTML入れてください、CSSで装飾させてください、辛いです

これに関してはJavaやSwiftで直接作っても悩まされるというか「よく世の中のアプリ開発者は暴動を起こさないな……」と思うレベルでwebに比べると非常に辛いです

※JavaやSwiftならビジュアルベースでデザイン組めたりするかもしれません。あまり詳しくないのでここへのツッコミお待ちしてます

3.Xamarinでオレオレハイブリッド

f:id:sesere:20171031125720p:plain

結果的にこうなりました

最初はデザイン要素が必要な部分だけWebViewで組んで、ボタンなどはネイティブで組んでいたのですが途中からもうこれ全部WebViewでよくない?となりました

だってネイティブではボタンのデザインすらまともに変更できないんですよ???ちょっとおしゃれに変更しようと思ったら100行(Android分、iOS分)必要です。頭がおかしくなります

例えばテキストリンクを作りたいとかでLabelにタップイベントを追加するとするじゃないですか?(ちなみにLabelにTapイベントはデフォルトでついていないのでまた200文字くらい書かないといけません)

このリンクをタップします、はい!動きません!

いや正確には動くのですがこのタップイベントというもの(体感)300ms以上押してしまうと遷移しないんですよ、タップじゃなくてドロップかなんかになってしまって

だから押しても中々動かない、すっごいストレス、一瞬でパッとやらないといけない……Webみたいにそこらへん吸収してくれないんです

.

え?「jQueryで mousedown と mouseup を追加するみたいな感じでtap と long tap 両方追加すればいいじゃん?」って?Xamarinにはタップイベントはあるけどそれ以外のイベント使いたかったら自分で書かないと追加できません(勘違いだったら申し訳ないのですが)もうちょっとこう……ね……辛い

ということで、オレオレハイブリッドをやるのが一番おすすめ!となりましたが……例えばInstagramのアプリで言うなら

f:id:sesere:20171203200439p:plain

こんな感じで

  • ヘッダーweb view
  • メインweb view
  • フッター wev view

の3つをXamarinFormのGridで積みます

下のweb viewのメニューがクリックされたらC#側をコールしてメインのweb viewを書き換えます(そう、まるでページ遷移するかのように!)

WebViewからC#をコールする方法については

web viewのnavigation event(ページ遷移)にhookして、遷移先のURLをチェックすることでC#側で何かしらの対応が出来るようにするのがとりあえずiOS & Android共通で動く方法っぽいです(いくつか方法があるので今試してます)

これのメリットはいくつかあるのですが

  • 使い慣れたHTML&CSSでデザイン出来る
  • C#(ネイティブ)の機能を簡単に呼べる
  • HTMLでデザインを組むからiOSでもAndroidでもデザインが変わらない
  • Cordovaと違いネイティブプラグインをそのまま使えるから更新放置されたプラグイン(last updated 2 years ago)を使わずに済みます
  • 全てWebViewで完結するCordovaと違ってweb viewのページ遷移=リセット&ネイテイブベースに見せ方をHTMLでやるのでSPAの知識がなくてもJSとかで詰まらない
  • 前に戻るボタン付きのポップアップページなんかも特に難しい事を考えずにさっと作れる&管理しなくて良い
  • ベースページがあるのでアプリの遷移が非常にシンプルになる
  • JSの資産を使える
  • ネイテイブと、HTMLの良い所を本当の意味でイイトコドリ出来る
  • Xamarinを使うことでロジック部分をAndroid&iOSで共通化できる
  • Visual Studioという鬼サジェストマン(個人の感想です)が使える(だたし重いです)
  • 環境構築が簡単(Visual Studioをインストールするだけ!※16GBあります)

具体的な設計とかページ構築とかは各自で決めちゃっていいので、とりあえず「Viewは全てHTML(WebView)でやる」「ActionはWebViewからURLという形で投げて、それをC#で受け取ってネイテイブでやる」という点だけ共通化してやれば後は特につまるところはないかと思います

WebとのJson周りの通信とか、CookieとかそういうのもjQueryでやってもいいしC#でやってもいいしとかなりゆるい感じです

そうだこれを Xamarin ハイブリッド と名付けよう!

つっこみお待ちしてます

ということでRailsユーザーが辛さを感じずにiPhoneアプリ&Androidアプリをサクサク作る方法でした

最初にも書きましたがそれにさけるお金と時間があるならkotlinやswiftを学ぶのが結果的には一番良いので自分の中でのアプリの立ち位置などを考えて検討してみてください

備忘録というか色々試したその勢いで書いてるのでここらへん詳しい人からのつっこみお待ちしていますm( )m