React Nativeのリリース間隔は月次
2017/1 から。以前は2週間に一度だった。月末に新しいバージョンがリリースされるので、月の初めには新しいバージョンが利用可能になっている。また、リリース時にはすでにFacebookのプロダクションで2週間ほど運用した状態であるだろうとのこと。
Relay: containerのinitialVariablesに値を渡す
追記: 2017/08/31 これはRelay Classicの時に書いたものです。
Introduction
非同期処理で何かごにょごにょした後、Relayにその値を使ってサーバーにリクエストを投げてほしかった。
やり方
Relay.createContainerを関数でラップする
雑な実装例:
componentDidMount() { this._asyncFunc() } async _asyncFunc() { try { let asyncVal = await someAsyncThings() this.setState({asyncVal}) } catch (error) { console.log(error) } } render () { let component = null if (this.state.asyncVal) { component = ( <Relay.RootContainer Component={createRelayComponent(this.state.asyncVal)} route={yourRoute} renderLoading={function() { return <div>Loading...</div>; }} /> ) } else { component = <div>Loading...</div>; } return component } function createRelayComponent(asyncVal) { return ( Relay.createContainer(Component, { initialVariables: { yourVar: asyncVal } fragments: { ... } }) ) }
参考リンク
感想
他のやり方があれば教えほしい
React Nativeの画像キャッシュ
追記 2017-11-27: 結局今はFastImageを使っている。GitHub - DylanVann/react-native-fast-image: 🚩 FastImage, performant React Native image component. 最高。
プロローグ
React Native使ってみた。Image
コンポーネント、毎回ネットワークから取得してるじゃん、これキャッシュしてくれないの?と思った。
調べた
[0.32] Image caching broken · Issue #9581 · facebook/react-native · GitHub
なんか壊れてんヨーという報告を発見。やっぱ壊れてんのかと思いつつ。 でもキャッシュしてもらえる人ともらえない人がいるみたい。日頃のおこない? ちなみに俺はキャッシュしてもらえてない。バージョンは0.38.0で。
なんでやねんと色々思っていると、画像サイズが大きいとダメだというコメントが目に入る。 画像サイズを小さくして試してみる。いけた。600KB -> 178kBぐらいに絞った。
どうやらReact Nativeは画像の取得にiOSに元からあるNSURLRequest
という仕組み使っていて、そのNSURLRequest
はNSURLCache
さらにはNSURLSession
とやらの仕様にしたがってキャッシュを行うらしい。
そしてこのNSURLSession
は指定した上限の、5%までのファイルサイズしかキャッシュしないみたい。
で、React Nativeはどれほど指定しているのかなーと思ったら
_decodedImageCache.totalCostLimit = 5 * 1024 * 1024; // 5MB
なるほど600KBはキャッシュされないですねと。てか上限小さすぎない?そしてそもそも
static const NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 1048576; // 1MB
1MB以上のファイルはRN側でキャッシュしないように指定してるみたい。参照したのはここらへんhttps://github.com/facebook/react-native/blob/v0.38.0/Libraries/Image/RCTImageCache.m#L23
まぁただここらへんの挙動は変数名から推測した程度なので、自信はない。
TL;DR
画像サイズが大きいとダメみたい。250KB以下にした方が良さげ。
Image
コンポーネント、キャッシュしてくれる。シミュレーターでも動作が怪しいかもしれない。実機で動かしたらちゃんとキャッシュしてくれてた。
その他
[追記: 2017/3/30]
書き忘れていたけれど、画像をuriで指定して得るレスポンスのメタデータにcache-contolを含めていないとキャッシュしてくれない。 S3とかに上げるときは設定を確かめるのを忘れずに。
[追記: 2017/4/19]
Facebook内部ではオープンになってるコンポーネントとは別のImage, Cachingモジュールを使ってるみたい。 このIssueが閉じるまでは、Imageコンポーネントのキャッシュは安定しなさそう。自分の場合、3回ぐらいアプリ開くとキャッシュが消されるという挙動をしている。(0.43.3)
https://github.com/facebook/react-native/issues/9581#issuecomment-287834859
参考リンク
[0.32] Image caching broken · Issue #9581 · facebook/react-native · GitHub
https://github.com/facebook/react-native/blob/v0.38.0/Libraries/Image/RCTImageCache.m
ios - How to cache using NSURLSession and NSURLCache. Not working - Stack Overflow
Show an image on launch screen in React Native iOS app
My long attempts to show an image on launch screen (or splash screen) in iOS app with React Native have failed so far and here is a solution I finally found. The key is to make use of LaunchScreen.xib
and not to use bunch of launch screen assets settings. (cf:
xcode - iOS Launch screen in React Native - Stack Overflow )
1. Find LaunchScreen.xib
This blog post well describes how to find and edit LaunchScreen.xib so just watch it :How to Remove the “Powered by React Native” Message in iOS Apps | React Cafe. LaunchScreen.xib
file is located under a file which name is the one you chosen for your app.*1
2. Provide image assets
Let’s provide assets. Find and select a file named Images.xcassets
on XCode and show context menu with ctrl-click
then select “New Image Set” as shown in an image below.
Drag'n'Drop images required in XCode. You may need to provide images which size are 1x, 2x and 3x. I named assets SplashIcon
as shown in the image.
3. Set images in LaunchScreen.xib
This is the last step. Open LaunchScreen.xib then drag drop an Image View
into a View
.
Chose an image which added in the step 2.
Basically that’s all. You should be able to see the image you’ve set on launch screen. Make sure do Reset Content and Settings...
on iOS simulator to reflect those changes if you are on the simulator.
Omake*2
Set constrains on the image in order to show it always in the center of the launch screens. Drag a connection with ctrl-clicking the image to the View
. See this post to check required constrains: How to create ImageView center on storyboard using iOS? - Stack Overflow
*1:If you don’t want to use images (so as your logo) for your launch screen, that’s fine and just edit the screen. Actually Apple says “Don’t include logos or other branding elements unless they’re a static part of your app’s first screen.” and “Design a launch screen that’s nearly identical to the first screen of your app.” in their guide line for launch screen.
As far as I checked, some developers follow the guidelines and others don’t. Facebook, for example, follows the guidelines but Google mostly ignores it. Of course, Apple’s applications follow them. You might find it interesting to check out Apps on your device to see the difference of effects.
React Native で文字を truncate
プロローグ
Railsって色々ヘルパーが用意されていて便利。ActionView::Helpers::TextHelper#truncateもその一つ。これは、文字列を切り詰めて末尾に...
と付けてくれる。そういうヘルパーみたいなのがRNにもあったら便利だな?と思った。そしたら、あった。
numberOfLines と ellipsizeMode
ヘルパーメソッドとかじゃなくて、Text
コンポーネントのprop指定でできる。numberOfLines
で表示する行数を指定する。そして、ellipsizeMode
であの...
やつをどこに用いるかを指定できる。末尾に...
をつけて省略したい場合、
<Text numberOfLines={1} ellipsizeMode={'tail'} > longlongfoobarbazbarfoobarbazbar </Text>
というような具合だ。これで ‘longlongfooba…’ のように表示されるようになる。...
をつける箇所の指定の仕方は、公式ドキュメントに詳しい。ひとつ注意をあげるとすれば、ellipsizeMode
を指定する場合はnumberOfLines
を指定する必要がある。
エピローグ
こうして無事truncate
を自分で実装せずに済んだ。他にもonLayout
などの指定できるprop
がある。これらを適切に使うことで、不要であったり不適切な実装を避けることができる。ReactやReact Native, RelayといったFacebookのOSSに触れていて素晴らしいと思うことの一つは、ドキュメントがきっちりと整備されていることだ。*1
S3のログから日付とアクセス元を漁るコマンドライン
プロローグ
S3のログ、見たいと思ったんだよね。アクセス時間と、アクセス元を。
やったこと
ターミナル開く
aws-cliをいれて設定などする
brew aws-cli
,aws configure
詳しくは: http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html#config-cli- ログを取ってくる
あらかじめ保存先ディレクトリを用意して移動しておいて、
aws s3 cp --region ap-northeast-1 s3://バケット名/ . --recursive
参考: S3 から ファイルをAWSCLIでディレクトリごとダウンロード - Qiita - ファイル結合
find . -type f -exec cat {} + > 保存先のファイルパス
参考: shell - cat files in current folder and all subfolders - Unix & Linux Stack Exchange - 目的の文字列を抽出
cat 保存したログのパス | cut -d ' ' -f 3,9,20 | grep 抽出したいアクセス元の名前 > 保存先のファイルパス
まぁ大方はこんな感じ。cut -d ' ' -f
に指定する数字は必要に応じて調節すると良い。デリミタ(この場合空白 ‘ ')で区切った前から何番目という感じで指定できる。grepで特定のものに絞り込みたくない場合は、pecoに食わせてもいいかもね。
cat 保存したログのパス | cut -d ' ' -f 3,9,20 | peco
エピローグ
昨日は雪が降ってた
Carrierwave TypeError - no implicit conversion of nil into String on multiple upload
Carrierwaveで複数アップロードしようにもどうにもうまくいかない。 調べたあげく普通にIssueにあった。
mount_uploader
じゃなくてmount_uploaders
を使うとのこと。
同じくs
見落としてた…