雑にReactNative触ってみた感想
Native開発しかしたことがない人がReactNativeに触ってみた感想です。
話すこと
AndroidとiOSといったNative開発しかしていない人が、ReactNativeを触ってみた感想、いわゆる First Impression をAndroid, iOSそれぞれと比較しながら雑に話します。
しっかりしたものが読みたい方は、きりみんさんの記事を参考にしてください。
ちなみに作ったものはGithubに上げているので、見ていただけるとありがたいです。
Screen
Deck Swipe | Chat |
---|---|
良いと思った点
画面とその他のViewとの違いがなく楽
AndroidだとActivity
, Fragment
、iOSだとUIViewController
といった様な、画面全体とその他のViewが区切られておらず、
画面全体もその他のViewもComponent
という単位で考えるため学ぶことが少なくて楽。
とりあえず、render()
にレイアウトをぶち込めば描画してくれる。
ListViewをReact Nativeで作ってみるとView関連は以下の様になる。
簡単。onCreateViewHolder()
でViewをinflateしたりだとか、func tableView(_: ,cellForRowAt:)
とかでtableView.dequeue()
とかしなくて良い。
XMLに似たレイアウトを記述したものをreturnするだけ。
また、view.setOnClickListener
とかaddTarget(), addGestureRecognizer()
とかしないで良い。
クリックイベントを発生させたいものを<TouchableOpacity></>
で囲んで関数を渡すだけ。
学習コストが低い、簡単に作れる
上で述べたものとかぶるが、学習コストがかなり低い。
公式のチュートリアルを進めていくだけで、なんとなく実装できる。
今回作ったものは、ライブラリのExampleをコピペしたものを組み合わせただけで大した事はしていないが、それでも1日とそこらでこれくらいのものを作れるのはすごいと思った。
JavaScript未経験、React Native未経験でReact Nativeのタスクを振られたときは厳しいと思ったが、
割とすぐに画面ができて楽しかった。
ビルドが早い
Web系の特徴でもあるが、ビルドがとにかく早い。
Android, iOSだとビルド時間が1分以上かかることがざらにあるが、React Nativeだと10秒待つ方が少ないくらい。
ノンストレスで開発ができるのはとても良いことだと思う。
良くないなと思った点
UIパーツの実装方法が多すぎる
Viewのライブラリが豊富で嬉しいと思う反面、ListView使いたいんだけど...と調べると結構な種類が出てくる。
「どれが今使うのに適しているか」と考えて様々なライブラリを巡って、実装の仕方を調べるのは少し億劫になる。
遷移がやや面倒
遷移について考えると、
AndroidだとIntent
を使う。iOSだとNavigationController
のpush
やpresent
を使う。
となるが、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を実際に試してつまづいた点について話します。
先駆者がいらっしゃるので、そちらの記事もぜひ参考にしてください。
ざっくりした手順
- carthage update --platform ios --no-use-binaries
- ld.pyを設置
carthage-build-static.sh
を作成- chmod +x ~
- 静的フレームワークの作成
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)を使っている方は必要ありません
下記から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に書いてあったものを参考にさせていただきました。
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
エラーなどが出た際は、それが発生しているライブラリを動的なものに戻しましょう。
静的フレームワークが作成されない場合
この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
Get started React-Native with WebStorm
インターン先でReactNativeを触る機会があったので、ReactNativeのセットアップについて書いていきます。
今回はIDEにWebStorm
を使います。
話すこと
- プロジェクトの作成方法と実行方法
話さないこと
- WebStormの便利機能
- ReactNativeの実装方法
プロジェクト作成方法の種類
主に2つに分けられると思います。
react-native init
で作成する。create-react-native-app
で作成する。(expoを使う。)
この2つのプロジェクト作成の仕方について書いていきます。
メリット・デメリット
react-native init
標準で用意しているProjectの作成方法です。android, ios それぞれのファイルが用意されるので、
react-native run-ios (run-android)
とコマンドを打てば実行することができます。
ちなみにWebStormでReactNativeのプロジェクト作成を行うと、この方法で作成されます。
メリット
- WebStormの
Run
で実行できる。
デメリット
create-react-native-app
FacebookとExpoのReactにおけるcreate-react-app
のReactNative版。
Expoを使っているので、Xcode / AndroidStudioを使う必要がない。
メリット
詳しくは下記の記事を読んでみてください。
デメリット
プロジェクト作成の仕方
それぞれのプロジェクト作成の仕方と実行方法について書いていきます。
共通
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
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
それぞれのデバイスで実行する。
終わり。
参考
node.jsのversionを管理するためにnodebrewを利用する
終わりに
今回、どうしてもRun
ボタンを使って実行したくて色々調べたのですが、Expo
で実行した方がはるかにメリットがあると調べていて気づきました。
プロジェクトの作成の仕方によって実行の仕方も変わるということに気付かず、結構な時間を使ってしまいました。
Run
ボタンは飾りやったんやな....
はじめて勉強会で登壇した話 - Shibuya.apk
先日、念願だった勉強会での初登壇を果たしてきたので、その目的と感想を書いていきます。
LTやろうと思っているけど出来ずに居るという方の後押しに成れれば幸いです。
WHY
- "知識を貰う側"から"知識を共有する側"になりたかった
- InputしたことをOutputする経験を得たかった
- アウトプット駆動学習の一環として
- つながりを広げたい!
HOW
Shibuya.apkの「LT発表 5分枠(登壇初めての方優先)」で初めて登壇しました!
初めてLTした感想
応募前
「一ヶ月先だし、登壇初めての方優先枠あるから勢いで申し込んだろ!」
という凄い軽い感じで申し込みました。
結局、やらない後悔よりやる後悔が良いし、失敗したとしても、それはそれで良い経験になると思い参加させていただきました。
資料づくり
「Shibuya.apkに来る方々は凄い方ばかりだし、自分の発表することなんて知っているだろう...」というネガティヴ思考に陥っていましたが、
自分は小者なのだから偉大な方々の胸を借りるつもりで行こう!
と切り替えて資料づくりに取り組みました。
テーマは正式リリース直後だった『Material Componentsについて』にしました。
作った資料をSpeakerDeckに上げましたので、よろしければご覧ください!
発表直前
自分の順番は一番最後から二番目だったのですが、その間ずっと緊張していました。
友人とその場で知り合った方3人で話していたのですが、全く内容を覚えていないくらいでした。
またReyurnibleさんとネタのオチが被っていたことに絶望していました...
発表後
自分の出番は乾杯後の発表だったので、みなさんカジュアルに聞くという感じでとても発表しやすかったです。
発表中は自分が用意したネタに反応して貰い、それまであった緊張が一気にほぐれました。
とても暖かい環境で初めての発表をさせていただきました!
その後色んな人から声をかけていただき、とても嬉しかったです!
結果
当初の目的であった、
- "知識を貰う側"から"知識を共有する側"になりたかった
- InputしたことをOutputする経験を得たかった
- アウトプット駆動学習の一環として
- つながりを広げたい!
は全て達成することだ出来ました!
終わってみればあっという間でしたが、苦労した分だけ成果が返ってきてとても有意義な経験でした。
今度は是非、15分枠での登壇をしたいと思います!
反省点
十分な準備が出来ていなかった
登壇から十分な時間があったにも関わらず、後回しに後回しにと資料づくりを避けていた結果、
登壇当日に資料づくりを終わらせることになり、話す内容を考えずに当日ぶっつけ本番という方になってしまいました。
乾杯のあとでゆるい環境だったからよかったものの、話がたどたどしく、とても良い発表とは言えませんでした。
今後は、期日を決めて資料を作り、最低でも5回はリハーサルしてから臨みたいと思います。
とても良い記事なので是非一読してください!
終わりに...
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
Migrate to AndroidXしようと思ったけどRefresh java project dataが終わらない……進んでんのかこれ……?
— ませぎ (@boc_sho) 2018年9月17日
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にコードを公開しているので、よろしければ参照してください!
WHY
HOW
今回は上のデザインを使って、実際にStoryboardを使わないでどう開発していくかを紹介します。
Storyboardを使わないプロダクトを立ち上げる際の手順については詳しい記事があるので、それを参考にしてください。
StoryBoardを使わないでプロジェクト作成(Xcode8,Swift3)
ViewController
Initialize
上記のように、Storyboardからの呼び出しではfatalError()
を発生させ、自前で用意するinitializerでは、
super.init(nibName: nil,bundle: nil)
を呼ぶようにします。
nibName, bundleは、nibファイルを探すために使われる引数です。
Layout
ここでは簡単な右のスプラッシュ画面を作ってみます。要素はUILabel一つにUIActivityIndicatorView一つです。
Layoutを組む際にSnapKitを用いているのでご了承下さい。
- 画面構成に必要なViewの評価式を書いていく
- それぞれのViewを
addSubview
していく - それぞれのViewごとConstraintを作っていく
完成!
遷移の方法
とても簡単です。UINavigationControllerの関数を使います。
Push
Present
TableView
TableView
先ほどと同じように、tableViewの評価式を書いていきます。
ここでは、UITableView#registerを拡張しています。
詳細を知りたい方は、以下の記事を参考にしてください。
TableViewCell
Initialize
ViewControllerのときと同様に、init?(coder:)
ではfatalError()
を返すようにします。
init(style:, reuseIdentifier:)
をOverrideして、Layoutを行うようにsetupSubviews()
を呼び出します。
Layout
ViewControllerとほどんど同じなので省略していきます。
完成!
終わりに
Storyboardを使わない開発は、初めのうちは慣れずに時間がかかってしまうこともありますが、
慣れてしまえば、Storyboardを使うより断然楽に開発を行えます。
アニメーションを入れる際も、『どの位置からどの位置まで』という情報がわかりやすいので、とても便利だと思います。
既存のプロダクトへの導入も、画面単位、View単位で行えるので難しくありません。
この機会にぜひ使ってみてはいかかでしょうか?
Welcome pull request, issue and review!!!
シンプルなUITableViewのregister, dequeue
UITableViewのregister
、dequeue
をシンプルにします。
既出で色々な記事がありますが、今回は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をシンプルにする