React NativeでAndroidアプリのビルド失敗対処法まとめ

React Nativeとはいえ、モジュールを使うとネイティブのコードが沢山追加されます。
だから何もしなくても勝手にクロスプラットフォーム対応!とは世の中そう上手くいきません。世知辛ぇよ。
だから先にiOSアプリをひと通り実装してから、いざAndroidアプリをビルドしてみると・・出るわ出るわエラーが笑

筆者がまさにそういうやり方でアプリ作っているので、Androidビルドで生まれた魑魅魍魎たちの退治記録を以下にまとめました。ご参照下さい。

続きを読む React NativeでAndroidアプリのビルド失敗対処法まとめ

AppleのHot Code Pushリジェクト問題、React Nativeへの影響は?

Rollout.io導入アプリがリジェクトされた話題は、3月7日にHackerNewsで盛大に盛り上がりました。
Hot Code Pushというのは、App Storeのレビューを通さずにアプリの挙動を変更できる仕組みのこと。
Rollout.ioはこの仕組みを利用してバグ修正が迅速に行えるサービスを提供していました。

上記Hacker Newsのコメ欄にRolloutのCEOのErezが出てきたりして、顔面蒼白ぶりがひしひしと感じられますねぇ。
これだからプラットフォーム依存は怖い!

ネイティブの動きを変えられるようにするのはダメ

何がダメかっていうと、以下のAPIを使って動的に挙動を変えられるようにすることです:

dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations()

いくら安全にこれを取り扱ったとしても、ハイジャックされてMITMアタックとかが起こりえるからダメというのがAppleの判断。
これ別に昔っからあるライセンス条項だったと思うんですけど、どうやら最近になって急に厳しく取り締まり始めたのが騒動の発端らしい。

続きを読む AppleのHot Code Pushリジェクト問題、React Nativeへの影響は?

Herokuで自動更新アリでLet’s encryptを導入する方法

追記 (2017/03/24)

Herokuがついに公式でLet’s Encryptに対応したようです。

こちらの手順に則ったほうがいいでしょう。

さよならStartSSL

ある日StartSSLのダッシュボードにログインした私。
なんか不穏な空気を醸すメッセージが赤々と表示されている事に気づく。

  1. Mozilla and Google decided to distrust all StartCom root certificates as of 21st of October, this situation will have an impact in the upcoming release of Firefox and Chrome in January. Apple’s decision announced on Nov 30th of distrusting all StartCom root certificates as of 1st of December will have an impact in their upcoming security update.
  2. Any subscribers that paid the validation fee after Oct. 21st can get full refund by request.
  3. StartCom will provide an interim solution soon and will replace all the issued certificates with issuance date on or after Oct 21st in case of requested. Meanwhile StartCom is updating all systems and will generate new root CAs as requested by Mozilla to regain the trust in these browsers.

あっるぇ〜?
花粉が目に入ってよく読めないよ〜?
一体何が起こったって言うんだよ。

続きを読む Herokuで自動更新アリでLet’s encryptを導入する方法

React Nativeでリリースビルドが起動しない問題の解決法

React Nativeを使ってiOSアプリを開発していて、TestFlightで配信しようとした時に問題にぶち当たった。

起動直後に落ちる

配信されたアプリを起動するとすぐにクラッシュしてしまう。
クラッシュレポートも上がってこないから、何が起こったのか分からない。
まるでProvisioning Profileの有効期限が切れた時のような挙動。
しかし、Code SigningやProvisioning Profileの設定は正しい。
そもそも間違っていればTestFlightで配信できないから。

原因1: ダイナミックなクラス名参照を実装している

続きを読む React Nativeでリリースビルドが起動しない問題の解決法

zshからfishに乗り換えた

なんか自分のzshが重い。
ターミナル立ち上げてコマンドが打てるようになるまで1秒ぐらいかかる。
おおかたoh-my-zshあたりが余計なことをしているんだろう。
これは設定を見直す必要がある。
ところで、fish shellというやつが前から気になっていた。
せっかくだし、これに乗り換えてみることにした。
fishの良さは検索すれば山ほど出てくるので割愛する。

自分の環境は以下の通り:

  • OS: macOS Sierra
  • ターミナルエミュレータ: iTerm2
  • 配色: Solarlized Dark

個人的な作業記録なので「ふーん」ぐらいの感じで読んで欲しい。

続きを読む zshからfishに乗り換えた

ES6でクラス名を動的に変更する方法

ES7のdecoratorsでクラスを生成するとクラス名がそのデコレータのものになってしまいます。
例えば:

import React from 'react'

function addAwesomeProperty (Spec, Component = Spec) {
  class AwesomeClass extends React.Component {
    render () {
      return React.createElement(
        Component,
        Object.assign({ awesome: 'yes!' }, this.props)
      )
    }
  }
  return AwesomeClass
}

@addAwesomeProperty
class OriginalClass extends React.Component {
  ...
}

こうすると生成後のクラスの名前は AwesomeClass になってしまいます。これは不便。
だからといってクラス名を以下のように変えようとしても出来ません:

AwesomeClass.name = 'OriginalClass'

なぜなら name プロパティは writable ではないからです:

Object.getOwnPropertyDescriptor(AwesomeClass, 'name')
    { value: 'func',
      writable: false,
      enumerable: false,
      configurable: true }

しかしES6の仕様によると以下の方法で変更できるとの記述を見つけました:

> Object.defineProperty(func, 'name', {value: 'foo', configurable: true});
> func.name
  'foo'

という事は、前述の例を以下のように修正すればクラス名に影響を与えずに済みます:

import React from 'react'

function addAwesomeProperty (Spec, Component = Spec) {
  class AwesomeClass extends React.Component {
    render () {
      return React.createElement(
        Component,
        Object.assign({ awesome: 'yes!' }, this.props)
      )
    }
  }
  // 追加
  Object.defineProperty(AwesomeClass, 'name', { value: Component.name, configurable: true })

  return AwesomeClass
}

まぁ、これが設計として正しいのかは謎です。

蛇足

動的なクラス名を定義する方法として、

const classes = { [ dynamicClassName ]: class { ... } }
classes[dynamicClassName].name  // => dynamicClassName

みたいな方法もあるみたいだけど、自分の環境では常に _class となって上手く行かなかった。
自分のbabelの設定が悪いのかもしれないけど。

Dockerで子プロセスからのstdoutをsupervisordにリダイレクトする方法

Dockerではsupervisordを使ってプロセス管理をする事が多いですね。
そのようなコンテナでは、以下のコマンドでsupervisordが吐いたログを確認できます:

docker logs -f <container_id>

さらに、子プロセスが吐いたstdout/stderrを同様に確認したくなることがあります。
例えばmysqlapache2のログなどです。
いちいちコンテナにログインしてtail -fなんてやってられませんよね。
supervisord.confを以下のように設定すれば、これら子プロセスのログをsupervisordに転送できます:

続きを読む Dockerで子プロセスからのstdoutをsupervisordにリダイレクトする方法