絶品ゆどうふのタレ

ふと気づいたことを綴るだけのメモ

iOSDC Japan 2016 参加メモ: A-5 Reactive State Machine

  • @inamiy さん LINE

リアクティブプログラミング

  • 時間経過に伴うイベントストリーム

  • FRP 関数型リアクティブプログラミング

    • データフローを構築する
  • データフロー = 川の流れ

    • 流れてくる状態の管理
  • Data Binding

    • 定期的にデータを流して、データを常に変更できる状態に
  • Data Observing

    • KVO出ないかぎり、永続監視はできない
    • 継続的なデータフローとして永続化したい
  • Observable / Signal = EventEmitter

  • Variable / Mutable Property = EventEmitterの現在の値

  • FRP + MVVM で簡単になる

    • 本当に?

ポケモンに例えてみるw

  • ViewModelがどんどんできてくる

    • Viewの数だけViewModelが出来上がってしまう
  • これらが相互に連携して・・・複雑なデータフローを形成していってしまう

    • つらい
  • FRP + MVVM

    • フロー構築は楽になる
    • 状態管理が楽になるわけではない

FRP + MVVMの問題点

  • let Variableとvar rawValueと変わらない
  • データフローそのものが状態になってしまう

  • 状態操作は楽になった

  • が、状態の数は増えてしまった

どうすればいいのか

  • 発送の転換

    • データフローの固定化
    • 状態の数を最小化
  • React.js

React.jsとは

  • Viewをステートレスに扱うフレームワーク

    • 狭義の意味でのリアクティブプログラミングってわけじゃないよ
  • 親の一つだけがstateful

  • 子が全てstateless

  • しかし、データフロー構築は面倒

    • 子から親へのデータフローが辛い

Redux

  • 状態を一つのコンテナで管理
  • 状態の管理がシングルトンにまとまる

問題点もある

  • Middlewareの位置づけ

    • 役割が明確に位置づけられているが、分割しすぎていて面倒になる
    • Reducerと密結合な方が楽なこともある
  • 非同期処理が難しい

    • 同期処理を前提に設計されているので、非同期に連鎖反応した時にフローが予測しにくい
    • 非同期処理はFRPに任せてしまったほうがシンプル

Reduxの型を眺める

  • よく見ると、State Machineのことを言っている
    • ミーリ・マシンと同じ

Redux + FRP

ReactiveAutomatonまとめ

*小さな状態管理から大きなシングルトンまで幅広く対応可能 * Elmの基本設計に近い

Model View ViewModel -> Model View Automatonへ

まとめ

  • データフローという名の状態
  • 状態管理の問題
  • Redux + FRP = Reactive State Machine
  • Elmは要チェック (A Farewell to FRP)

iOSDC Japan 2016 参加メモ: A-3 iOS 10時代の新しいCollectionView使いこなし術

New Lifecycle of Cell

  • iOS 10からcellのライフライクルが変わる

現在のライフライクルの復讐

  • cellForItemAtIndexPath によって画面内の分生成され、それが画面外に出ると次のcellに使いまわされる
    • 1画面分のcellが作られていた
  • 元々、このスタイルはTableViewで考えられたスタイルだが、CollectionViewでは一気に複数使いまわされることもあった

iOS 10から

  • 画面外に用意されるcellの数がぐっと多くなった
    • 1.5画面分用意されるようになった
  • willDisplayCellとcellForItemAtIndexPathの時間差が大きくなった

prefetch API

  • ライフサイクルで増えた分より、更に奥のセルに対してprefetchすることができるようになった
  • prefetchのキャンセルも出る
  • かなり事前に作れるので、ユーザー体験が上がる

iOS9以前では、どうすると軽くできる?

  • 基本だが

    • CollectionViewよりTableView
  • 重い処理はcellForItemAtIndexPathでやろう

  • willDisplayCell / didEndDisplayCell は軽めに

  • 描画処理の高速化

    • Blend-Layer処理をなるべく使わない
      • シミュレータの Color Blend Layerをチェック入れるとわかる
      • 赤がBlend 緑がBlendじゃない
      • 緑を増やそう
    • 透過pngやclearColor背景を使わない
      • 画像に背景色を含めてしまったりするといい
      • 角丸やシャドウを画像に含めてもらうほうが高速

QA

  • prefetchはデリゲート?iOS9の時に書いてあっても大丈夫?

    • iOS9だと呼ばれないだけだから大丈夫!
  • prefetchはどういう処理に向いてる?

    • 画像の先読みや、計算が必要な処理にいいかも
    • cell自体はまだ存在しない段階

iOSDC Japan 2016 参加メモ: A-2 RxSwiftは開発をどう変えたか

  • ishkawaさん

RxSwift

  • イベントストリームを抽象化

    • UIの変化やアクションなど
  • Observable

    • イベントストリームを表す型
  • subscribe(_:)

    • イベントごとにクロージャを実行
    • イベントを受け取って実行できる
  • bindTo(_:)

    • Observerに自動反映する
    • イベントストリームに接続できる
  • Observable と Observerは対になる概念

    • 入出力の関係
  • Operator

    • 実際の開発では、streamの間にOperatorを挟んで色々変換をしてデータを加工したりしていく
    • map, filterなど

もう少しアプリらしい例

  • 苗字と名前を入れてsubmitすると、くっついたフルネームがUILabelに反映される
  • combineLatestとsample
    • 複数のobservableを組み合わせ、sampleでタイミングを調整

Rx vs 従来のイメージ

  • Rx

    • 水道のイメージ
      • 蛇口と、それをバルブなどで調整してる
  • 従来

    • バケツのイメージ
      • バケツにデータを貯めといて、それを取りに行く

Rxの概念とは

  • 全てのイベントストリームの表現手段が同じ
  • ためておいて後で取りに行く、という動作がない
    • イベントストリームの依存関係がoperatorで表される

現在地の天気アプリの例

  • 位置情報を許可すると、天気が出る
  • 位置情報を拒否すると、NGと出る

  • コード紹介

    • 従来のスタイルでデリゲートスタイルで書くと、パッと全体のフローを把握するのが難しい
    • Rxのコードだと、処理の流れに沿ってコードが追える
      • ここで何が起きてるのか、というのがそこを見ればわかる
  • 複雑な制御がイベントストリームだけでかける

  • 処理の依存関係が見えるようになった

まとめ

  • イベントストリームを宣言的に扱えるようになった
  • 複雑なイベントストリームでも全体を把握しやすい
  • データを貯めなくて良くなり、ストアドプロパティを減らせる

iOSDC Japan 2016 参加メモ: A-1 - Handling rich text in Swift

  • Realm 岸川さん

何も考えずにiOSのテキストを作ると、色々ずれてたり、切れてたりしてしまう。

デザイナさんはここを直してほしい、というけどiOSのラベルでは難しい、とか、そういう状況をなくしていくためにTextを理解しよう。

アジェンダ

TextKit

  • iOS7から導入
    • CoreTextをベースに作られている
    • UIKItとの統合
    • UILabel / UITextView などのベース

UILabel

  • ヒラギノとシステムフォント
  • system font

    • 英字はsanfrancisco
    • 日本語はヒラギノにフォールバック
  • 明示的にヒラギノを指定したりすると、英字もヒラギノになり、ベースラインより下にはみ出るものが切れてしまったりする

    • 日本語ははみ出る文字がないので無事だが。。。
  • 中身のテキストによって切れてしまう。

なぜこんなことが起こるのか?

  • 行の高さを知る

    • アルファベットのFontのお話
    • BaselineやCap height、Ascent、Descent、x-heightなど
    • これらのFont metricsによって高さが決まる
  • systemfontは、これらが全体にだいたい収まるようになっている

  • ヒラギノは特殊なメトリクスを持つ

    • Ascent Descentが狭い(半分ずつ)
    • Noto Sans CJK なんかだと大丈夫だたりする
  • バッドノウハウ

    • 上下にDescentを補う
      • Descentを倍にする

いったんまとめ

  • ヒラギノのメトリクスに注意

    • 明示的にヒラギノを指定しない
    • システムフォントを使う
      • ヒラギノ指定のデザインは、システムフォントを意図しているはず
      • 中国語フォントにフォールバックさせたくない、とか。
    • ヒラギノを指定する場合にはアルファベットに注意
  • Tips 日本語フォントにフォールバックを指定することはできる

  • Tips

    • 描画サイズを得る
    • iOS7からならできる

UITextView

  • 普通につかう

    • ヒラギノを指定すると、だいぶ大きくなったりする
  • TextViewにはデフォルトのマージンがある

    • textContainerInset
    • lineFragmentPadding
    • ヒラギノの場合は font.leadingという値のぶん高さがついてくる

デフォルトのスタイルをリセットする

textView.textContainerInset = UIEdgeInsetsZero
textView.textContainer.lineFragmentPadding = 0
textView.layoutManager.usesFontLeading = false // leadingを取り除く
  • ドキュメントには、UIに使うときはleadingはoffにすると良いよって書いてある
  • leadingを含めた描画サイズをオプションを指定することで取ることもできる

これを元に様々なスタイルに対応する

  • 行間の変更

    • NSAttributedString
    • NSParagraphStyle
      • minimumLineHeight
      • maximumLineHeight
        • これを同一にすると行の高さが一致する
        • これらは、複数のフォントサイズが混在する文章のためにある
      • lineSpacing = 8
  • NSAttributedStringを活用する

まとめ

  • iOS7 以降はいかに綺麗なNSAttributedStringを作るか
  • タイポグラフィの基礎を知ろう
  • フォントにヒラギノを指定するときは注意
  • できればシステムフォントに

QA

  • システムフォントは、日本語のヒラギノフォントよりも小さい。これをデザイナに指摘される場合どうするか
    • デザイナの人と共有・コンセンサスを取るのがいいのでは
    • たぶん、MacヒラギノとSanfranciscoは、同じサイズになるのでは。。。

Vagrantで `unknown filesystem type 'vboxsf'` のエラーが出た場合

Vagrantでエラーに当たってちょっと調べ物したので記録しとく。

起きたこと

久しぶりに、Vagrantを使って Ubuntu 15の環境を作ろうとしたところ、 chef_zero provisionerで以下の様なエラーが出た

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u ubuntu`,gid=`getent group ubuntu | cut -d: -f3` v-csn-cf1999bf2 /tmp/vagrant-chef/890ab396746b083fc8c6a52ec67db241/nodes
mount -t vboxsf -o uid=`id -u ubuntu`,gid=`id -g ubuntu` v-csn-cf1999bf2 /tmp/vagrant-chef/890ab396746b083fc8c6a52ec67db241/nodes

The error output from the last command was:

sudo: unable to resolve host ubuntu-xenial
mesg: ttyname failed: Inappropriate ioctl for device
mount: unknown filesystem type 'vboxsf'

どうやら、 vboxsfがうまく扱えていなくて、chefが使うnodesなどのディレクトリをGuest側でmountできない。

原因と対策

詳しく調べなかったが、使っていたイメージの Virtualbox GuestAdditions がないか、バージョンが古くてうまく動かない、という状態のようだった。

この問題が発生した場合は最新GuestAdditionsを入れてやればよいが、普通にVirtualBoxの手順でいろいろやろうとすると面倒。

なので vagrnt-vbguest pluginをinstallしておくと、imageの起動時にGuestAdditionをチェックして最新版をインストールしてくれる。

vagrant plugin install vagrant-vbguest`

今回はvagrant chef_zeroでエラーが出てたけど、vagrantで作ったimage全般でできる対策だとは思う。

CarthageでGithubのAPI rate limitに対処する

Carthageって結構ごりごりGithubからcheckoutしてくるので、大勢でやってると

"API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)"

みたいなことを言われてしまう時があります。

対処法としては Homebrewなどと同様に Github APIAccess Tokenを使う事になるんですが、Carthageではこのtokenを GITHUB_ACCESS_TOKEN という環境変数に指定することで利用できます。

export GITHUB_ACCESS_TOKEN=xxxxxxxxxxxx
carthage checkout

なお、Githubのtokenは生成時に1度だけしか表示されないので、 .*rcとかの中のコミットしないどこかにこっそり書いておくと良いと思います。

この辺で実装されたようで、利用できるのはcarthage 0.8以上っぽいです。

そんな小ネタ。

iOSシミュレータでの通信状態のテストにNetwork Link Conditionerが便利だった

や、僕が知らなかっただけで世の中では常識の可能性もありますが。めっちゃ便利だった。

ネットワーク悪環境の場合のテスト。。。

iOSのネットワーク環境が悪い場合のテストって前から悩ましいと思ってて、MacWifiをOffにするとか開発中のアプリを実機に入れて建物の隅っこに行くとか涙ぐましい感じでやってたんですけど。

ちゃんとネットワーク状態を調整してくれるツールあった。

Network Link Conditioner

Apple Developer Center から Hardware IO Tools っていうユーティリティ群をダウンロードすると、その中に入ってる。 他に同梱されてるアプリも便利そうな名前が色々。。。

f:id:Yudoufu:20160528120815p:plain

起動すると、再現したいネットワーク状況が色々選べて、スイッチをONにするとMac上の通信が制限される。

f:id:Yudoufu:20160528120835p:plain

他にも、自分で通信状態を細かく指定したカスタム環境も作成できる。 up/downそれぞれのLoss率と速度などなど。

f:id:Yudoufu:20160528120850p:plain

なお、操作できるのはパケットロスの度合いと通信速度までで、ネットワークON/OFFののテストしたいときは直接MacwifiをON/OFFしてやることになりそう。

100% Lossとか使うとTimeoutのテストが手軽にできる。 めっちゃ良くて捗りそう。今まで知らなかったのは悔やまれる。