絶品ゆどうふのタレ

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

iOSDC Japan 2016 参加メモ: A-8 デザイナーにStoryboardをお任せする技術

背景

  • はてなのデザイナーはWebアプリだとHTML / CSSのコーディングをして、git管理してる
  • でも、モバイルアプリはAdobe CCまで

  • 最近変わってきた

    • デザイナさんがAutoLayoutの書き換えまでやるようになってきている

今回のゴール

  • デザイナーがStoryboardを編集するワークフローの獲得
  • チームの生産性向上

導入

  • チームや個人のモチベーション重視
    • やる気がなさそうならさっさと諦める
  • 開発環境をセットアップ
  • 手取り足取り教える
  • 実際に触れてもらう

Interface Builder

  • 意外といろいろ新しい要素がある
  • デザイナ的には案外わかりやすい

  • 登場する要素について

    • View
      • ここはわかりやすい
    • ViewController
      • 黄色いアイコンのやつがViewControllerだよ!
      • Viewとペアになってるよ
    • AutoLayout
      • これが。。。。
  • UIKit User Interface Catalog

    • これを教えてあげるのが良い
  • ViewController Catalog for iOS
    • ちょっと古い

AutoLayout

  • 教えるべきことがたくさんある

    • Layout Constraint
    • Intrisic Content Size
    • Priority
    • Error / Warning
  • NSLayoutConstraint

    • 制約の式の中に対象のattributeなどを設定すると考える、というのを教えてあげる
    • 揃える、という意識とConstraintは対応してるので意外と行ける
  • Intrinsic Size

    • 固有のサイズって話でわかる
  • Priority

    • 伸びにくさ、ちぢみにくさのPriorityのことを徐々に教えてあげる必要がある
    • 絵で説明する
  • AutoLayoutのエラー

    • エラーがあると怒られる
    • どういう時に怒られるか知っておいてもらう
  • Adaptivity

    • Dynamic Text
    • Size Class
    • Trait Collection

ここまで学ぶのにどこまで大変か?

  • 3日かかった
    • 多分速い方
  • iOSAndroidのLayoutを理解してもらうのにかかった時間

ワークフロー

  • アプリの機能が企画される
  • デザイナーがレイアウトを決める
  • エンジニアが実装
  • デザイナが細部を調整
  • コードレビュー

Make App Designable

  • IBDesignable
    • Storyboardで見れる
  • IBInspectable
    • Storyboardから値を設定できる

ヒント

  • 前提を共有する
  • 同じドメイン知識を共有する

  • 用語をきっちり揃える

  • 独自のViewをたくさん作る

    • 再利用性のあるコンポーネント
    • パラメータを @IBInspectable
    • 最初から作り込み過ぎない
  • よく作る例

    • Border
      • 線の幅を指定できたり
      • 物理pixcelにしたい場合、とか
    • AttributedTLabel
    • BorderedButton

エンジニアにとって大事なこと

  • UIKitについて学ぶ
    • 知らないことは意外と多い
  • Storyboardを巧く管理する
    • 分割は必須
    • コンフリクトは最大の敵
    • 同じ所を同時に触らない
      • デザイン調整は後で、ぐらいでも良い
  • デザイナーを手助けする
    • 忙しい
    • 丁寧なサポートを心がける
    • レビューがあると安心感が出る

まとめ

  • 開発チームが協力することで実現
  • 難易度は高め
  • 大きなメリット

QA

  • Storyboardのレビューはどうしてる?

    • 複雑な場合はcheckoutしてアウトラインで見てみたり
  • ContainerViewを多用したい場合はどうしている?

    • エンジニア側でContainerを作ってStoryboardを分割してしまう
    • 中身だけお願いします、みたいな

iOSDC Japan 2016 参加メモ: A-7 メモリー管理の嬉しいバイキング料理

  • Ray Fix さん
    • めっちゃ日本語うまい

モリー管理

  • ほぼ自動的にメモリ管理をしてくれる
  • 仕組みがわかれば、バグの少ないアプリがかける

スタックとヒープ領域

スタック

  • スタックはとにかく速い
  • ロックする必要は全く無い
  • スタックから出るときには必ず開放が必要になる

  • もっと広く使いたい場合はヒープを使う

ヒープ領域

  • 共通メモリ

    • ヒープ領域に情報を確保し、スタックの領域の参照とカウントを持つ
  • 参照型を使うときには、定数型をつかうと上書きのデメリットが消せる

  • 循環参照問題

    • 複数のクラス間でそれぞれが持ち合うと、参照のサイクルが出来上がってしまう
    • Xcode 8で参照がグラフィカルに見える
    • 解決するには
      • weak型の参照を使う
      • 弱い参照が勝手にnilになる

Swiftの弱い参照

  • Objective-Cの時は強い参照が0になると開放されていたが、Swiftではそうではない。

  • 強い参照がなくなるとdeinitalizeが走って、weak countが0でない場合はゾンビができる

  • weak countが0になった時に、初めてメモリから開放される

    • つまりweak 用のカウントは別にある
  • weak

    • 参照先がゾンビの場合はnilを返すようになる
  • unowned

    • 参照先がゾンビの場合はエラーになる
  • 呼び出す場合の例

    • Closureのなかで値を使う場合、selfをつけろと言われる
    • 循環参照しているかもしれない!というヒントをXcodeがくれる
    • キャプチャーリスト [unowned self] みたいにする
  • 非同期の問題

    • 非同期の場合、[unowned self] してしまうと、selfが消えてしまうことがある
    • なので、書かないのが正解になる
  • また、そのような状況で循環参照を防ぐには[weak self] を使えばよい

  • weak selfの場合、selfがOptionalになるので、実行されないところが出てくる

  • それを防ぎたいなら storngSelfに代入するような strong weak danceのパターンでguardする

まとめ

しっかりメモリを理解してバグを少なく!

QAより

  • Apple的には、あんまりキャプチャするのは良いと思ってない様子
  • back tick selfを使ってる人もいるが、MLでバグだ、っていう話になってたので、strong weak selfの方がいいはず

iOSDC Japan 2016 参加メモ: A-6 ドッグフーディングしやすい環境を整える

ドッグフーディング

  • 自分で使い倒す
  • 継続するのは色々大変

きっかけ

  • 数千人の全社員に配布してフィードバックをもらおう!

    • 結果はアンケートフォームに!
    • 結果が10件...
  • きっとやり方が悪い

改善ポイントを探す

  • アプリ利用依頼
  • DL
  • フィードバック作成
  • プライバシー

アプリ利用依頼

  • 新機能つけました、やってみてください -> ダメ
    • メリットがわからない
  • テストアプリのメリットを分かる形で伝えるようにする

アプリDL

  • Apple Developer Enterprise Programに参加して配布
  • AppStoreから入れたアプリを消したくはない

    • bundle Identiierを変更すれば削除せずに済む
  • 普段使いの環境を壊さない

フィードバック作成

  • 鬼門
  • 悪いところを見つけても、文章もキャプチャも色々面倒
  • フィードバックを楽にする仕組みをできるだけ楽に
  • テスト配布版にだけ現れるレポート用画面を用意

  • 運用でカバーせず、社員も一般ユーザーとみなしてあげる

プライバシー配慮

  • そのままスクショを送るとIDばれちゃう!
    • フィードバックの手が止まる
  • キャプチャ時にその辺をマスクするような処理

改善後

  • 10件 -> 1600件!!

その後の変化

  • チームのモチベーション向上

    • 人に見られると議論が活発になる
  • 良くないものを良くないと言いやすくなった

おまけ

まとめ

  • ドッグフーディングを継続していきましょう

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は、同じサイズになるのでは。。。