雑にReactNative触ってみた感想

Native開発しかしたことがない人がReactNativeに触ってみた感想です。

話すこと

AndroidiOSといったNative開発しかしていない人が、ReactNativeを触ってみた感想、いわゆる First Impression をAndroid, iOSそれぞれと比較しながら雑に話します。

しっかりしたものが読みたい方は、きりみんさんの記事を参考にしてください。

medium.com

ちなみに作ったものはGithubに上げているので、見ていただけるとありがたいです。

github.com

Screen

Deck Swipe Chat

良いと思った点

画面とその他のViewとの違いがなく楽

AndroidだとActivity, FragmentiOSだとUIViewControllerといった様な、画面全体とその他のViewが区切られておらず、

画面全体もその他のViewもComponentという単位で考えるため学ぶことが少なくて楽。

とりあえず、render()にレイアウトをぶち込めば描画してくれる。

ListViewをReact Nativeで作ってみるとView関連は以下の様になる。

簡単。onCreateViewHolder()でViewをinflateしたりだとか、func tableView(_: ,cellForRowAt:)とかでtableView.dequeue()とかしなくて良い。

XMLに似たレイアウトを記述したものをreturnするだけ。

また、view.setOnClickListenerとかaddTarget(), addGestureRecognizer()とかしないで良い。

クリックイベントを発生させたいものを<TouchableOpacity></>で囲んで関数を渡すだけ。

学習コストが低い、簡単に作れる

上で述べたものとかぶるが、学習コストがかなり低い。

公式のチュートリアルを進めていくだけで、なんとなく実装できる。

facebook.github.io

今回作ったものは、ライブラリのExampleをコピペしたものを組み合わせただけで大した事はしていないが、それでも1日とそこらでこれくらいのものを作れるのはすごいと思った。

JavaScript未経験、React Native未経験でReact Nativeのタスクを振られたときは厳しいと思ったが、

割とすぐに画面ができて楽しかった。

ビルドが早い

Web系の特徴でもあるが、ビルドがとにかく早い。

Android, iOSだとビルド時間が1分以上かかることがざらにあるが、React Nativeだと10秒待つ方が少ないくらい。

ノンストレスで開発ができるのはとても良いことだと思う。

良くないなと思った点

UIパーツの実装方法が多すぎる

Viewのライブラリが豊富で嬉しいと思う反面、ListView使いたいんだけど...と調べると結構な種類が出てくる。

「どれが今使うのに適しているか」と考えて様々なライブラリを巡って、実装の仕方を調べるのは少し億劫になる。

遷移がやや面倒

遷移について考えると、

AndroidだとIntentを使う。iOSだとNavigationControllerpushpresentを使う。

となるが、React Nativeだとそうはいかない。

遷移にも様々なライブラリがあり、実装の仕方も人によりけりな所がある。

今回はList画面からChat画面に遷移するときに、Tabを無くしたかったのだが、その遷移を実装するのに手間取った。

結果、新しい画面を生やす(iOSでいうpresent)のではなく、スタックした画面を作って(iOSでいうpush)、遷移の際にTabを非表示とする形になった。

それぞれのOSでの表示崩れ

UIのライブラリを使ったときに、『iOSでは上手く表示されているのにAndroidでは上手く表示されない』ということがあった。

また、Android Oreoでは表示崩れを起こしているのに、Android Pieでは綺麗に表示されたりもした。

これはクロスプラットフォームで開発する際には必ず起こる問題だと思う。

綺麗に映すにはNativeでの開発が結局良いと思われる。

終わりに

軽いものや、今後長く使わない、アプリが大きくなる予定がないものであれば、React Nativeはとても良い選択だと思う。

しかし、デザインがしっかりと決まっていてAndroid, iOSそれぞれちゃんと描画しないといけないとなると、まだまだ厳しいと思われる。

やはり、用途に合わせてNative, React Nativeと切り替えていくのが良いと感じた。

Build static frameworks to speed up app’s launch times

iOSのライブラリ管理ツールCarthageの動的フレームワークを静的フレームワークにしてアプリ起動時間を短くした話

話すこと

本記事は、下記のCarthageのDocumentsにある Build static frameworks to speed up app’s launch timesを実際に試してつまづいた点について話します。

github.com

先駆者がいらっしゃるので、そちらの記事もぜひ参考にしてください。

medium.com

ざっくりした手順

  1. carthage update --platform ios --no-use-binaries
  2. ld.pyを設置
  3. carthage-build-static.shを作成
  4. chmod +x ~
  5. 静的フレームワークの作成

1. carthage update --platform ios --no-use-binaries

Documentsにも書いてある通り、--no-use-binariesオプションを付けてcarthage updateする。 もともとあるバイナリデータを用いていると、依存?があったりして上手く静的フレームワークを作成できないらしい。

carthage update --platform ios --no-use-binaries

2. ld.pyを設置

Xcode 9以降(New Build System)を使っている方は必要ありません

github.com

下記からld.pyをDownloadし、Project内の好きな場所に置きます。

swift-staticlibs/ld.py at master · keith/swift-staticlibs · GitHub

3. carthage-build-static.shを作成

Xcode 9のNew Build Systemを使っているかで違います

New Build Systemを使っている方

#!/bin/sh -e

xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT

echo "MACH_O_TYPE = staticlib" >> $xcconfig
echo "DEBUG_INFORMATION_FORMAT = dwarf" >> $xcconfig

export XCODE_XCCONFIG_FILE="$xcconfig"

carthage build "$@"

上記をcarthage-build-static.shとして保存します。

issueに書いてあったものを参考にさせていただきました。

github.com

New Build Systemを使っていない方

#!/bin/sh -e

xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT

echo "LD = $PWD/the/path/to/ld.py" >> $xcconfig
echo "DEBUG_INFORMATION_FORMAT = dwarf" >> $xcconfig

export XCODE_XCCONFIG_FILE="$xcconfig"

carthage build "$@"

上記をcarthage-build-static.shとして保存します。

echo "LD = $PWD/the/path/to/ld.py" >> $xcconfig

その時に、PATHをld.pyを置いた場所に変更してください。 直下に置いた際は、$PWD/ld.pyになります。

4. chmod +x ~

実行権限を与えるため、コマンドを実行します。

chmod +x carthage-build-static.sh
# ↓Xcode 8以前を使っている方は不要
chmod +x ld.py

5. 静的フレームワークの作成

まず、正しく静的フレームワークが作成できているか、1つのライブラリで確認します。

自分の場合はSnapKitで試しました。

./carhage-build-static <Library名> --platform ios

実行後、Carthage/Build/iOS/Static/~にFrameworkが生成されていれば成功です。(CarthageのDocumentにはStaticディレクトリ下に生成されると書いてありませんでした...)

静的なものかどうかは、

file Carthage/Build/iOS/Static/<Library名>.framework/<Library名>

このコマンドを打って下の様にcurrent ar archiveかどうかで確認できます。

確認できたら、CarthageでCarthage/Build/iOS/Static/~にあるライブラリを追加しましょう。

carthage copy-frameworksにあるInput Filesに動的フレームワークのPATHを登録している場合は、消しましょう。

更に、もともと作成していたCarthage/Build/iOS/~にある動的フレームワークは削除しましょう。

削除しないと、動的のものを参照してしまいimage not foundのエラーが出てしまう可能性があります。

エラーが出ずに実行できたら、全てのライブラリに適用しましょう。

./carhage-build-static --platform ios

これを実行すれば、Carthageに登録しているライブラリ全ての静的フレームワークが作成されます。

あとは同様にアプリに登録するだけです。

注意する点

イメージリソースを使用しているライブラリは、静的フレームワークを使用できません。

具体的にはSVProgressHUDがそうでした。作成は成功するのですが、Build時にエラーが出ます。

linkerエラーなどが出た際は、それが発生しているライブラリを動的なものに戻しましょう。

静的フレームワークが作成されない場合

github.com

このissueを参考にしてみてください。それでも作成できない場合はあきらめましょう...

結果

環境

Xcode - Version 10.0

Simulator - iPhoneXs MAX iOS 12.0

Time

Before(Dynamic) After(Static)
total pre-main time 882.84 milliseconds (100.0%) 794.82 milliseconds (100.0%)
dylib loading time 270.73 milliseconds (30.6%) 233.54 milliseconds (29.3%)
ebase/binding time 248.72 milliseconds (28.1%) 225.53 milliseconds (28.3%)
objC setup time 82.90 milliseconds (9.3%) 77.49 milliseconds (9.7%)
initializer time 280.31 milliseconds (31.7%) 258.05 milliseconds (32.4%)

動的フレームワークを静的にしたので、表のdylib loading timeが大幅に減少するはずなのですが、

270msec -> 233msecとあまり大きな結果は得られませんでした。

大きめのアプリでもやってみましたが、参考の記事よりも大幅に減少する結果にはなりませんでした。

全てのライブラリを静的にできてないからでしょうか、それともNew Build Systemが上手くやっているおかげなのでしょうか...

Before After
total pre-main time 2.7 seconds (100.0%) 2.3 seconds (100.0%)
dylib loading time 706.75 milliseconds (25.6%) 492.44 milliseconds (20.6%)
ebase/binding time 1.2 seconds (44.2%) 1.1 seconds (46.4%)
objC setup time 164.16 milliseconds (5.9%) 218.17 milliseconds (9.1%)
initializer time 666.76 milliseconds (24.1%) 565.18 milliseconds (23.7%)

終わりに

期待していたよりあまり効果がでず、うーん..という感じです。

CIなどを行なっている場合は、変更する努力に見合う成果が得られるか検討する必要がありそうですね。

参考

CarthageでStatic FrameworkとしてビルドしてiOSアプリの起動時間を短縮する – Ryoichi Izumita – Medium

Static frameworks - Task failed with exit code 65 · Issue #2425 · Carthage/Carthage · GitHub

Automatically change dynamic frameworks to static? · Issue #2575 · Carthage/Carthage · GitHub

iOSアプリ起動時のダイナミックリンクライブラリの読み込み時間を調べる

Get started React-Native with WebStorm

インターン先でReactNativeを触る機会があったので、ReactNativeのセットアップについて書いていきます。

今回はIDEWebStormを使います。

話すこと

  • プロジェクトの作成方法と実行方法

話さないこと

  • WebStormの便利機能
  • ReactNativeの実装方法

プロジェクト作成方法の種類

主に2つに分けられると思います。

  1. react-native initで作成する。
  2. create-react-native-appで作成する。(expoを使う。)

この2つのプロジェクト作成の仕方について書いていきます。

メリット・デメリット

react-native init

標準で用意しているProjectの作成方法です。android, ios それぞれのファイルが用意されるので、 react-native run-ios (run-android) とコマンドを打てば実行することができます。

ちなみにWebStormでReactNativeのプロジェクト作成を行うと、この方法で作成されます。

メリット

  • WebStormRunで実行できる。

デメリット

  • コード変更ごとにRunしなければいけない。
  • iOS実行(リリース)のためにはMacOSでなければいけない
  • ビルドがやや遅い

create-react-native-app

FacebookとExpoのReactにおけるcreate-react-appのReactNative版。 Expoを使っているので、Xcode / AndroidStudioを使う必要がない。

メリット

  • 変更がリアルタイムで反映される
  • MacOSでなくてもiOSでの実行(リリース)ができる
  • Expo SDKが様々な機能を提供してくれている。

詳しくは下記の記事を読んでみてください。

ducklings.hateblo.jp

デメリット

  • WebStormRunで実行できない
  • 実行に少し手間がかかる
  • iOS / Androidのコードが一切かけない。 Bridgeできない。

プロジェクト作成の仕方

それぞれのプロジェクト作成の仕方と実行方法について書いていきます。

共通

nodebrew

nodeのバージョン管理ができるtoolです。nodeをすでにインストールしている場合は飛ばして構わないです。

brew install nodebrew
echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.bash_profile
source ~/.bash_profile
nodebrew setup
brew uninstall node
nodebrew install-binary stable (or latest)
nodebrew use stable (or latest)

watchman

ReactNativeのアプリをビルドするのに使います。

brew install watchman

react-native-cli

react-native ~というコマンドを使うためのものです。

npm install -g react-native-cli

react-native init

Android Studio env

Androidで実行するためにPATHを通す必要があります。

export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$ANDROID_HOME/platform-tools:$PATH
export PATH=$ANDROID_HOME/tools:$PATH

作成 & 実行

Terminalで実行する際は、react-native start, react-native run-ios/androidをする必要があります。

WebStormで実行する際は公式のヘルプを参考にしてください。

react-native init <Project_name>
cd <Project_name>
npm install
react-native start --reset-cache &
react-native run-ios

pleiades.io

create with create-react-native-app

作成 & 実行

npm install -g create-react-native-app
create-react-native-app <Project_name>
cd <Project_name>
npm install
npm start

それぞれのデバイスで実行する。

終わり。

参考

React NativeでiOSアプリをリリースビルドする

Expo ではじめる ReactNative 開発環境

node.jsのversionを管理するためにnodebrewを利用する

終わりに

今回、どうしてもRunボタンを使って実行したくて色々調べたのですが、Expoで実行した方がはるかにメリットがあると調べていて気づきました。

プロジェクトの作成の仕方によって実行の仕方も変わるということに気付かず、結構な時間を使ってしまいました。

Runボタンは飾りやったんやな....

はじめて勉強会で登壇した話 - Shibuya.apk

先日、念願だった勉強会での初登壇を果たしてきたので、その目的と感想を書いていきます。

LTやろうと思っているけど出来ずに居るという方の後押しに成れれば幸いです。

WHY

  • "知識を貰う側"から"知識を共有する側"になりたかった
  • InputしたことをOutputする経験を得たかった
  • アウトプット駆動学習の一環として
  • つながりを広げたい!

HOW

Shibuya.apkの「LT発表 5分枠(登壇初めての方優先)」で初めて登壇しました!

shibuya-apk.connpass.com

初めてLTした感想

応募前

「一ヶ月先だし、登壇初めての方優先枠あるから勢いで申し込んだろ!」

という凄い軽い感じで申し込みました。

結局、やらない後悔よりやる後悔が良いし、失敗したとしても、それはそれで良い経験になると思い参加させていただきました。

資料づくり

「Shibuya.apkに来る方々は凄い方ばかりだし、自分の発表することなんて知っているだろう...」というネガティヴ思考に陥っていましたが、

自分は小者なのだから偉大な方々の胸を借りるつもりで行こう!

と切り替えて資料づくりに取り組みました。

テーマは正式リリース直後だった『Material Componentsについて』にしました。

作った資料をSpeakerDeckに上げましたので、よろしければご覧ください!

発表直前

自分の順番は一番最後から二番目だったのですが、その間ずっと緊張していました。

友人とその場で知り合った方3人で話していたのですが、全く内容を覚えていないくらいでした。

またReyurnibleさんとネタのオチが被っていたことに絶望していました...

発表後

自分の出番は乾杯後の発表だったので、みなさんカジュアルに聞くという感じでとても発表しやすかったです。

発表中は自分が用意したネタに反応して貰い、それまであった緊張が一気にほぐれました。

とても暖かい環境で初めての発表をさせていただきました!

その後色んな人から声をかけていただき、とても嬉しかったです!

結果

当初の目的であった、

  • "知識を貰う側"から"知識を共有する側"になりたかった
  • InputしたことをOutputする経験を得たかった
  • アウトプット駆動学習の一環として
  • つながりを広げたい!

は全て達成することだ出来ました!

終わってみればあっという間でしたが、苦労した分だけ成果が返ってきてとても有意義な経験でした。

今度は是非、15分枠での登壇をしたいと思います!

反省点

十分な準備が出来ていなかった

登壇から十分な時間があったにも関わらず、後回しに後回しにと資料づくりを避けていた結果、

登壇当日に資料づくりを終わらせることになり、話す内容を考えずに当日ぶっつけ本番という方になってしまいました。

乾杯のあとでゆるい環境だったからよかったものの、話がたどたどしく、とても良い発表とは言えませんでした。

今後は、期日を決めて資料を作り、最低でも5回はリハーサルしてから臨みたいと思います。

とても良い記事なので是非一読してください!

kakakakakku.hatenablog.com

終わりに...

Shibuya.apkでは、

  • 登壇始めての方優先枠がある
  • 5分と少し短いが初めてには丁度良い時間
  • 乾杯後なので場がすでにあったまっている
  • 参加されている方みんな優しい

というLT初めての人にとって挑戦するにはとても良い環境が揃っています。

「LTしてみたいが自分には荷が重い...」と考えている方は是非Shibuya.apkに応募してみてください!

また、Shibuya.apkの運営の方々、このような機会を作っていただきありがとうございました!

"AndroidX" 移行の際につまずいた点

AndroidX移行を行なった際につまずいた点を残しておきます。

AndroidXとは直接関係ないところでつまずいているのですが、流れで自分と同じ問題にぶつかった人の助けになればと思います。

環境

- 移行前 移行後
Android Studio version 3.0 3.3 Canary 10
Gradle version 4.1 4.10
Plugin version 3.0.1 3.3.0-alphp10
Kotlin version 1.2.30 1.2.70

Android Studio 3.0 -> 3.1

Android Studio 3.0 -> 3.1のマイグレーションの際は、こちらの記事を参考にさせていただきました。

この記事では載せられていなかったのですが、3.1 Canary 8から、

kapt "com.android.databinding:compiler:$version"

を書かなくてもよくなりました。

Databindingのkaptの有無 ( + annotationProccessorにするかどうか)によって、エラーが発生するということはありませんでした。

kapt -> annotationProccessorにしようとした

※AndroidX移行とは無関係

gradle fileのimplementationやらannotationProccessorやら、kapの違いがイマイチよく分かっていなかったため、compile -> implementationにする際に、kapt->annotationProccessorとしてしまいました。

結果、DaggerでよくあるDaggerAppComponentが生成されず頭を抱えることになりました。

Kotlin使ってるならkaptでしょ...

どうして生成されないかは、JavaとKotlinのコンパイルの順番に関係しているようで、それは以下の記事を読むとよくわかります。

終わらないMigrate to AndroidX

Android Studio 3.3 Canary 10 特有のバグかわかりませんが、Migrate to AndroidXを行なったらUpdate indecies - Refresh java project dataと出て、そこから進まないっといったことが起きました。(Android Studio 3.2では起きませんでした。)

File -> Invalidate Caches /Restart...

を行なってから、またMigrate to AndroidXを行うと完了できます。

Dagger versionを上げることによってのエラー

Gradle Plugin versionを上げた際に、「Daggerも同じくversionを上げてください。」という警告が出たので、2.11 -> 2.17に上げてしまいました。(2.15で十分だったが、この際に最新にあげようと思って)

その後ビルドできたので、いざMigrate to AndroidX...したら、

Cannot find symbol databindingComponent
e: [kapt] An exception occurred: java.util.NoSuchElementExceptione: [kapt] An exception occurred: java.util.NoSuchElementException

2種類のエラーが発生しました。

初めはDatabinding周りのエラーだと思っていましたが、後者が原因だったようです。

二つ目のエラーはDagger 2.17に起こるバグのようで、issueが立っていました。

Daggerのversionを2.16にすることによって、両方のエラーが解決できました。

最後に

AndroidX移行はそこそこ最近のことで、それぞれの環境に依存するということもあり、情報があまりありません。

もし自分の記事によって、エラーが解決出来たなら幸いです。

Good-bye Storyboard

iOSのチーム開発を妨げるものとして、GitHub管理がし辛いという理由でStoryboard(xib)ファイルが挙げられます。

その打開策ということで、実際の開発現場ではStoryboardを使わない開発が多く見受けられます。

この記事では、実際にどうやってStoryboardを使わずに開発していくかを紹介していきます。

Githubにコードを公開しているので、よろしければ参照してください!

github.com

WHY

  • Storyboardのコンフリクトを解決するのが面倒なので無くしたい
  • ViewControllerの生成が面倒、Segueとか使いたくない
  • GUIでいじるより、CUIで全部行いたい

HOW

今回は上のデザインを使って、実際にStoryboardを使わないでどう開発していくかを紹介します。

Storyboardを使わないプロダクトを立ち上げる際の手順については詳しい記事があるので、それを参考にしてください。

StoryBoardを使わないでプロジェクト作成(Xcode8,Swift3)

https://qiita.com/rika-tawashi/items/d975c2d9f85e8bb4aef5

ViewController

Initialize

上記のように、Storyboardからの呼び出しではfatalError()を発生させ、自前で用意するinitializerでは、

super.init(nibName: nil,bundle: nil)を呼ぶようにします。

nibName, bundleは、nibファイルを探すために使われる引数です。

Layout

ここでは簡単な右のスプラッシュ画面を作ってみます。要素はUILabel一つにUIActivityIndicatorView一つです。

Layoutを組む際にSnapKitを用いているのでご了承下さい。

  1. 画面構成に必要なViewの評価式を書いていく
  2. それぞれのViewをaddSubviewしていく
  3. それぞれのViewごとConstraintを作っていく

完成!

遷移の方法

とても簡単です。UINavigationControllerの関数を使います。

Push

Present

TableView

TableView

先ほどと同じように、tableViewの評価式を書いていきます。

ここでは、UITableView#registerを拡張しています。

詳細を知りたい方は、以下の記事を参考にしてください。

masegi.hatenablog.com

TableViewCell

Initialize

ViewControllerのときと同様に、init?(coder:)ではfatalError()を返すようにします。

init(style:, reuseIdentifier:)をOverrideして、Layoutを行うようにsetupSubviews()を呼び出します。

Layout

ViewControllerとほどんど同じなので省略していきます。

完成!

終わりに

Storyboardを使わない開発は、初めのうちは慣れずに時間がかかってしまうこともありますが、

慣れてしまえば、Storyboardを使うより断然楽に開発を行えます。

アニメーションを入れる際も、『どの位置からどの位置まで』という情報がわかりやすいので、とても便利だと思います。

既存のプロダクトへの導入も、画面単位、View単位で行えるので難しくありません。

この機会にぜひ使ってみてはいかかでしょうか?

Welcome pull request, issue and review!!!

github.com

シンプルなUITableViewのregister, dequeue

UITableViewのregisterdequeueをシンプルにします。

既出で色々な記事がありますが、今回はStoryboardをつか言わない人用の簡略化されたものを紹介します。

使い方

新しく作るTableViewCellにReusableを追加で継承させる。

class ReadMeTableViewCell: UITableViewCell, Reusable {...}

tableViewにregisterする

tableView.register(TableViewCell.self)

dataSourceでdequeueする

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: TableViewCell = tableView.dequeueReusableCell(for: indexPath)
    return cell
}

作り方

UITableView+Extension

Reusable

終わり

参考

Swiftでセルのregisterとdequeueをシンプルにする

https://qiita.com/gonsee/items/9ab89581996ad950b436