#技術書典8 で出版予定であった「クラウドネイティブファーストストーリー」売出します!

こんにちは。horsewin です。

概要

本記事の要点を先に書いておきます。

  • 技術書典8 なくなっちゃって寂しいですね
  • せっかく書いたので、「クラウドネイティブファーストストーリー」の書籍、PDFともに販売します
  • 紙書籍はBOOTH、個人へのDM、とらのあななど様々な経路で対応します

2/29と3/1の技術書典8は開催中止

非常に残念ですが、昨今のコロナ事情により2/29, 3/1のイベントが中止になっています。

blog.techbookfest.org

今回執筆した本、「クラウドネイティブファーストストーリー」について

会社のめちゃくちゃできるエンジニアと共に執筆しました。 こんな本です。

f:id:horsewin:20200301160928p:plain

どんな本?

クラウドネイティブを支える技術である「コンテナ」と「CI/CD(継続的インテグレーション/継続的デリバリー)」を中心トピックにご紹介します。 本書を通して、自分達が過去に悩んだ点、躓いた点、気をつけなければならない点などをシェアすることで、クラウドネイティブなアプリケーションの開発を考えている方々に最初の一歩をお手伝いします!

本書は、AWSのECS/Fargate/Codeシリーズなどの各種サービスを組み合わせていくことで、コンテナやCI/CDのベース環境の構築を行うハンズオン形式で構成しています。アプリケーション観点というよりは、インフラストラクチャーや運用観点にトピックの主軸を置いています。 中級者にも満足してもらうために、ハンズオン内には随所に構築に役立つTipsや補足情報なども記載していますので、是非、Tipsを探して読んでみてください。

対象の読者層は?

  • AWSでコンテナ・CI/CDを使ったことがなくチャレンジしてみたい方
  • AWSでコンテナ・CI/CDの構築に苦戦している方
  • コンテナ・CI/CDに関して、初心者から中級者にステップアップしたい方

イベントがなくちゃったけど買えるの?

印刷するかどうかめっちゃ悩みましたが、紙書籍が好きなのでなんとか届けたいと思い、 PDF、紙書籍ともに様々な購入経路を用意しました!

PDF版、紙版、その他セット売り予定のBOOTH

2020/03/01現在では、PDF版のみ売り出しています。 日光企画様の方に印刷をお願いしており、入荷され次第、物理本+PDF版を売り出す予定です。 書籍版を買うと、電子版もBOOTHで無料ダウンロードしてお読みいただけます。

  • 電子版の価格は1,500円です。
  • 物理+PDF版は1,500円+送料370円=1,870円の予定です。現在、入庫が完了しておらず事前受付状態となっており、入庫完了まで送料が高くなってしまっています!!ご注意ください。

umarai-books.booth.pm

また、今回一緒に技術書典8へ出品予定だったサークルメンバーの本をセット売り(電子のみ)予定です!

techbookfest.org

セット売り版(電子のみ)は3月中旬ごろ公開予定ですので、まとめて買いたいという方は今しばらくお待ち下さい!|

(2020/04/27更新) おかげさまでBOOTHの物理本は完売いたしました!! 電子版は引き続き、1,500円にて販売いただけますので、ぜひ!

現物を手にとってみたいなら、とらのあな

20冊委託予定です。販売価格は1,500円+税です。 こちらの店舗では現物もおいていますので、手にとってご覧になることも可能です! とらのあなの店舗、またはとらのあなの通販にてお求めください。

(2020/03/01更新) 作品ページもオープンになりました!

ec.toranoana.shop

(2020/03/06更新) 物理本、店舗で販売しておりました!

個人から購入

個人用に30冊、次回イベント用に100冊確保しています! 手渡し可能や、ネコポスなどで個人から購入したいという方がいれば、個人のTwitterFacebook宛に連絡いただければ誠心誠意を持って対応いたします!!

(2020/03/03更新) 物理本、納品されました!!手渡しできる方など是非ご購入ください。

f:id:horsewin:20200303235944j:plain

(2020/03/03更新)メルカリで購入

より物理を届けたいと思ったのでメルカリチャネルを開拓しました。取り急ぎ、3冊出品しています。 ゆうゆうメルカリ便、らくらくメルカリ便を利用した匿名配送となっております。 価格は1,500円+送料200円=1,700円としました。

(2020.03.23追記) メルカリも完売いたしました!追加で出品希望の方はメッセージ等いただけるとベストエフォートで対応します!!

(2020/04/27更新) - 1冊、追加しています! https://www.mercari.com/jp/items/m20674005792/

(2020/04/28更新) こちらも完売いたしました!

(2020/03/06更新)技術書典 応援祭に参加します!

応援祭にも参加します!!はじめ物理本は参加するかどうかなやんでましたが、祭りをもりあげたいと思い物理+電子両方の参戦を決めました! 15冊、販売予定です。

techbookfest.org

  • 電子版の価格は1,500円です。
  • 物理+PDF版は1,500円+送料400円=1,900円の予定です。

(2020.03.23追記) 物理本は完売いたしました!引き続きBOOTH、とらのあなは絶賛発売中です!

(2020.09.09追記) BOOTHは完売いたしました!物理本は引き続きとらのあなで絶賛発売中です!

最後に

今回技術書典に初出店の予定でしたので悲しかったですが、中止になったのは致し方ないと思っております。 ただし、様々な出版チャネル、購入チャネルが普及していて、人々に届けるために数々の手段があることもわかりました。

暗くなってばかりいられないので、前向きになって、みなさまにできる限り多くの書籍が届けることができれば幸いです!

最後に本の目次を記載いたしまーす。 f:id:horsewin:20200301161013p:plainf:id:horsewin:20200301161027p:plainf:id:horsewin:20200301161031p:plainf:id:horsewin:20200301161038p:plainf:id:horsewin:20200301161043p:plain

それでは、お買い求めとレビューいただけると嬉しいです!でわでわ。

umarai-books.booth.pm ec.toranoana.shop

react-native のMetro bundlerでNodeエラーが出るときの対処

概要

React Native開発をしているとMetro Bundlerが上がってきます。 このときに自動で立ち上がってくるTerminal上のMetroでエラーが出た時の対処方法のメモとなります。

対象読者

  • React Native v0.59.x >= 利用者

事象

React Native開発をしていると(古いバージョンでは)必ずMetro Bundlerのお世話になります。Metro Bundlerは react-native-clirun-iosコマンドを叩くなどすると上がってきます。

その際、新規PCで何気なく実行すると下記のエラーが出ました。 Screenshot 2020-02-04 13.05.58.png

あれ?nodeがない?となりましたが、普段使いしているterminalで確認したところ下記の通り、nodeは入っていました。

$ node -v
v10.17.0

原因

NVMなどを使っていると、参照しているnodeはホームディレクトリ配下のことが多いです。 しかし、react-native run-iosで起動するターミナルが参照するNodeのPATHは/usr/local/bin/nodeのようです。

よって、自身が利用しているnodeのパスを確認して、/usr/local/bin/nodeへリンクを通してあげると解決します。

# nodeが存在することを確認できます
$ which node
/home/USERNAME/.nvm/versions/node/v10.17.0/bin/node

# 上記パスに対して、シンボリックリンクをはります
# $()とすることで()内コマンドの結果を利用できます
$ ln -s $(which node) /usr/local/bin/node

参考リンク

React NativeのSVGを使うライブラリをAndroidで動かすときにエラー

はじめに

最近、React Nativeの開発を積極的にしています。 その折り、ちょっとしたグラフを書きたくなったのでreact-native-chart-kitというライブラリを使っていました。

www.npmjs.com

iOSでは問題なく動いていたのに、いざAndroidで動かそうとすると動かなかった(しかも実機のみ!)ので、 備忘録として対処を残しておきます。

利用準備

READMEに記載の通り、npmかyarnでライブラリをインストールすることで使うことができます。 なお、react-native-svgが入っていないと動かないので、こちらのライブラリも必要でした。

$ yarn add react-native-svg // 必要であれば
$ yarn add react-native-chart-kit

あとはExampleに記載の通り実装することでバーチャートやパイチャートなどを描画できます。

f:id:horsewin:20190724111701p:plain
こういうやつ

発生した事象

iOS

こちらではシミュレータ、実機いずれも問題なく動きます。

Android

こちらで死にました。。。React Nativeではどちらもテストが必要なのが辛いですね。。。 また、Androidでも下記の通り、挙動が変わります。

動作状況 結果
Android Emulator OK
USBからAPKを転送 OK
APKをインストール NG

単純に実機だとうごかないのではなく、USBデバッグの段階では動くというのが今回いやらしかったです;; NGというのは「[アプリ名]が停止しました」というアラートが出てアプリが落ちた状態を指しています。

原因

adb logcatをしてログを確認すると下記の通り、Exceptionが吐かれていました。 ライブラリ内のNoSuchFieldExceptionとか知らんよーーってなりましたw

07-23 23:00:50.149 10915 10915 E AndroidRuntime: FATAL EXCEPTION: main
07-23 23:00:50.149 10915 10915 E AndroidRuntime: Process: xxxx.xxxx.xxxx, PID: xxxxxx
07-23 23:00:50.149 10915 10915 E AndroidRuntime: java.lang.IllegalStateException: java.lang.NoSuchFieldException: fill
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.v.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.c()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.X.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.v.b()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.c()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.v.b()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.c()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.v.b()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.c()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.j.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.v.b()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.C.a()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.C.j()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.horcrux.svg.C.onDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:17122)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16104)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:17125)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16104)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:17125)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16104)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16099)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:17125)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16104)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16099)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16099)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16099)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.draw(View.java:16888)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at com.facebook.react.views.view.h.dispatchDraw()
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16099)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.149 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.View.updateDisplayListIfDirty(View.java:16067)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1250)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6311)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.Choreographer.doCallbacks(Choreographer.java:683)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.Choreographer.doFrame(Choreographer.java:619)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.os.Handler.handleCallback(Handler.java:751)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:95)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:241)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6217)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
07-23 23:00:50.150 10915 10915 E AndroidRuntime: Caused by: java.lang.NoSuchFieldException: fill
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        at java.lang.Class.getField(Class.java:1549)
07-23 23:00:50.150 10915 10915 E AndroidRuntime:        ... 101 more
07-23 23:00:50.166   756   850 E JavaDumper:FW:  utils.c(248): mkdir (/data/crashdata) failed. File exists

修正内容

困ったときはコミュニティやGoogle様に聞くことが肝心で同じように困った人がやはりいました。下記によるとProguardファイル(proguard.pro)に下記を書くとよいようです。ようするにExceptionの原因となっている、「com.horcrux.svg」パッケージへのリフレクション時の参照時にNo such Fieldといわれているので、参照名と参照プログラムを残すような処理になります。

-keep public class com.horcrux.svg.** {*;} 

github.com

まとめ

相変わらず、React Nativeを書くときはネイティブを触るときのデバッグや各ネイティブ向けの設定が必要だなと痛感しました。

React NativeでPolyfillする必要があるライブラリを使うときにハマった

概要

React Nativeの開発でOSSライブラリを使うことは多々あります。 具体的には下記のライブラリを使うときにハマりました。 その際、iOSでは動作するがAndroidだと動作せず色々はまったので備忘録として残します。

github.com

開発環境

  • React Native Environment Info:
    • System: OS: macOS 10.14.5
    • Binaries:
      • Node: 8.9.4
      • Yarn: 1.12.3
      • npm: 6.9.0
    • SDKs:
      • iOS SDK:
        • Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      • Android SDK:
        • API Levels: 23, 25, 27, 28
        • Build Tools: 23.0.1, 26.0.3, 27.0.3, 28.0.3
    • IDEs:
    • npmPackages:
      • react: ^16.5.0 => 16.8.1
      • react-native: 0.57.8 => 0.57.8
    • npmGlobalPackages:
      • react-native-cli: 2.0.1

エラー内容

いつもどおり、npmインストールをしてexample通りに実装し、iOSデバッグと調整をして問題なく表示されたあとに、Androidで動作確認をしようとしました。 すると、赤い画面でエラーが発生して、「あれ?」ってなりました。

TypeError: TypeError: TypeError: undefined is not a function (evaluating 'data.entries()[typeof Symbol === "function" ? Symbol.iterator : "@@iterator"]()')

どっかで参照するときにエラーでてるのか。。。けどiOSのときは何もならなかったのに・・・ と不安になるが、とりあえずDebugger起動して確認するか、ということでCmd+m→デバッガ立ち上げをします。 するとChrome Debuggerが立ち上がり再ロードが走るわけですが、、、ウゴイタ。。。 あ、これ前に見たやつ!、、、つらい。となりました。 原因としては下記の通り、デバッガを使わないときや実機ではiOSAndroid上のJavascriptCoreScript(JSC)を使ってレンダリングが実行されるが、デバッガを使うとV8というエンジンを用いてレンダリングされるため挙動が異なるという事象です。

facebook.github.io

対策1(Core-js)を使う

ここからはググり力が必要です。まずエラー内容を素直に調べるとGitHubにIssueがありました。

github.com

エラーが出ているpath-jsにentriesをPolyfillしよう、とのこと。 よって、core-jsをnpmインストールし、エントリポイントであるindex.jsにimportします。

$ npm i core-js
import "core-js"
import { AppRegistry } from 'react-native';
import App from './App';

AppRegistry.registerComponent('hogehoge', () => App);

すると次なるエラーが発生しました。

f:id:horsewin:20190716095715p:plain
core-jsをimportしたあとのエラー

対策2

同じようにググります。するとライブラリは違えどGithub Issueがありました。

また、core-js@3.x.xだとうまくいかず、core-js@2.6.5ならうまくいくという報告があったのでそれをつかってみます

(1)インストール済みライブラリを消して、新しいライブラリを入れる

$ yarn remove core-js && yarn add --dev core-js@2.6.5

(2)polyfill.jsを作成(エントリーポイントであるindex.jsと同じディレクトリ階層に作成)

global.Symbol = require('core-js/es6/symbol');
require('core-js/fn/symbol/iterator');
require('core-js/fn/object/entries');
require('core-js/fn/map');
require('core-js/fn/set');
require('core-js/fn/array/find');

(3)index.jsの最初の行にpolyfills.jsをインポート

import "./polyfills.js";
import { AppRegistry } from 'react-native';
import App from './App';

AppRegistry.registerComponent('hogehoge', () => App);

上記設定完了後、react-native run-android をしても問題なく動作させることができました。

まとめ

  • React NativeではJavascriptCoreScript(JSC)を使ってレンダリングされるためサポートされていないjavascript functionが存在する
  • 存在しないfunctionを利用しているライブラリについてはpolyfillsする
  • core-jsでpolyfillsするときはライブラリのダウングレードなども試してみる

Amazon S3 + LINE Messaging APIで画像テキストを出すときにはまったこと

概要

  • LINE Messaging APIで画像を送った時のセキュリティの話
  • そのときにはまったことのメモ

Messaging API

LINEのMessaging APIとはLINE Botを作るときなどに利用するサービスである。本サービスを利用して対象のLINEユーザのIDに対してメッセージを送ることができる。 メッセージにはプレインテキスト以外に画像や音声なども送ることができる。

Messaging APIリファレンス

  • 前提事項
    • LINE Messaging APIでユーザに送信する画像はHTTPSのURLを形式である必要がある。
    • ユーザのLINEが動いている端末から取得しに来るためIP制限等でセキュリティ担保は難しい

Messaging APIのはまりどころ

アクセストークンが切れたときのレスポンストラップ

アクセストークンが切れた=認可切れなのでHTTP403がかえってきてほしいがHTTP400がかえってくるためエラー切り分けに少し手間取った。 個人的にこれ、結構なトラップ。。。

HTTP400トラップ

URL誤りであろうがテキスト誤りであろうが大体のエラーがHTTP400でかえってくるためエラーレスポンスだけからではエラー箇所特定が難しい。

S3から画像取得

S3から画像を取得するためにS3のバケットポリシーをある程度公開することもできる。しかし、S3のバケットをパブリック公開にするのは避けたい。 そこで思いつくのが署名付きURLです。署名付きURLを使うことによって、時間制限をつけてアクセス可能とするURLを発行できます(時間制限付きのIAM Roleがつく)。

S3に格納した画像をLINE Messaging APIで取得する際、この方法を考えましたが今回ここでハマりました。

ハマりどころ

  1. S3の署名付きURLを発行すると約1000文字ちょいのURLが返却される。
  2. LINE Messaging APIの画像格納先URLの最大文字が1000文字。。。
  3. f:id:horsewin:20190519161353p:plain
  4. bitlyなどで短縮URLを発行してアクセスさせることを考える
  5. LINE Messaging APIの画像格納先URLがHTTPSである必要があるため無理。。。

解決策

単純にS3だけではどうしようもなかったです。解決のために取れる手段(パブリック公開を除く)は2つです。

  1. CloudFrontを用いてアクセスさせた際にリダイレクトで返す。
  2. DynamoDBに署名付きURLのクエリパラメータを確保させておき、CloudFrontを用いて短いURLでアクセスさせる。この際、Lambda@Edgeでリクエストをインタセプトし、DynamoDBに保管したクエリパラメータをひっつけて返す。

所感

最大文字数が1100文字とかならこんな苦労なかったのに。。。となりました。

XcodeでPods-frameworks.sh: No such file or directory となる

実施環境

  • MacOS Sierra ver 10.12.5
  • MacBookAir 11inch
  • Xcode8.3.3
  • Swift3
  • CocoaPods ver 1.2.1

そもそも今回やりたかったこと

単純にプロジェクトファイル名がいけてなかったのでそれのRenameをしたかったという要件。 Xcodeではプロジェクトファイル名を変えるのも一苦労であり、Xcodeでプロジェクト名を変更する方法 (Xcode8.0)を参照させていただきました。ありがとうございます。

その中で上記サイトになく、今回ぶちあたった問題はタイトルの通り。

前提条件

  1. もともとpod installで作ったプロジェクトで開発
  2. 何かしらの理由でプロジェクト名を変更したい
  3. 作り直し後も引き続きCocoaPodsは利用する

解決方法

Xcodeでプロジェクト名を変更する方法 (Xcode8.0)の通り、Renameをかけていきますが、最後に下記のようなエラーがでました。

/Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-XXXX/Build/Intermediates/XXXX.build/Debug-iphonesimulator/XXXX.build/Script-XXXX.sh: line 2: /Users/XXXX/workspace/XXXX/XXXX/Pods/Target Support Files/Pods-XXXX/Pods-XXXX-frameworks.sh: 
No such file or directory

Pods-XXX-Frameworkを取り込んでいるあたりがダメっぽいです。 [TARGETS]->[XXX]->[Build Phases]->[Copy Pods Resources]に下記の表記があり、旧名のプロジェクトの名前を持ったシェルをコピーしようとしています。

pod.png

上記のEmbed Pods FrameworksとCopy Pods Resourcesに入っているパスで旧プロジェクト名となっている箇所を新プロジェクト名に変更して再ビルドするとビルド成功します。

プロジェクト名変えるのめんどくさいですね。。。他の人々にも参考になれば。

git on Windowsで aggregateexceptionが発生する

概要

  • WindowsからGit Bashをつかってgitコマンドをたたいていた環境で発生した問題の共有
  • 英語の記事は多かったのですが日本語の記事がピンポイントで見つからなかったので備忘録
  • 結論から言うとGit Bashを最新版にしたら直る問題

環境

事象

下記のエラーメッセージが発生し、ユーザIDとPWを毎回入力しなければgitが使えない(fetch, pull, pushなどなど)。

fatal: AggregateException encountered. 
One or more errors occurred. 

gitのプロキシ設定や、credential-helperをつかっていても同事象が発生していた。原因を調べたところ、この英語の記事を発見。

GithubでTLS1.0が無効化されたことが原因だよ。バージョン2.16.2以降では解決しているよ。

よって、ダウンロードサイトから最新版の2.17.0をインストールすることで無事、毎回ユーザIDとPWをきいてくるプロンプトが出なくなった。