絶品ゆどうふのタレ

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

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

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-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-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-6 ドッグフーディングしやすい環境を整える

ドッグフーディング

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

きっかけ

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

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

改善ポイントを探す

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

アプリ利用依頼

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

アプリDL

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

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

フィードバック作成

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

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

プライバシー配慮

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

改善後

  • 10件 -> 1600件!!

その後の変化

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

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

おまけ

まとめ

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

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-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 参加メモ: B-9 Swiftのこれまでの動向のまとめと今後のさらなる発展の期待

  • @_mono 小野 将之さん Join.us の中の人

Swiftの変遷

これまでをおさらい

  • 2014/06公開

    • WWDCでSwiftを公開
    • 良かった点
      • ダンな言語仕様
      • リファレンスの出来も良かった
      • Xcode 6ですぐ使えた
      • 既存との混在もできた
    • 悪かった点
      • 頻繁にXcode / コンパイラのクラッシュ
      • ビルドが遅い
        • ちょっとした変更でも全体ビルド
    • 当時はまだ色々言語仕様がなかったがまぁOKな範囲
  • 2015/09

    • Swift 2
    • 主な不満点が解消
      • クラッシュ頻度低下
      • 差分ビルド対応
      • 言語仕様が十分揃ってきた
  • 2015/12/03

これからの話

  • Swift 3.0

  • Swift 2.2

    • 3.0のプレリリース的扱い

Swift 3のアップデート内容

  • 最後の大きな破壊的変更

    • 微妙な言語仕様を全面見直し
  • あらゆるものをSwiftyに

互換性問題

  • 後方互換性の保証では、ない
    • バージョンアップのたびの破壊的な変更はなくなりそう
  • ABIの安定化は4.0に持ち越し
    • 古いSwiftでビルドしたライブラリとリンク可能になる

Swiftyにしていく

最後に

  • 連載もよろしくね!

QA

  • Swift 3を使いはじめるのはいつ頃をめどに考えればいい?

    • 仕様変更は、そろそろなくなると思う
    • 使い始めはエンジニアがどれくらい熟知しているか、かも
    • 自動コンバートツールもついてくる
  • 逆に3で不満な変更点は?

    • 個人としてそんなに反対な変更はない
  • 一番素晴らしい変更は?

    • 無駄な部分をそぎ落としていこうという姿勢がいいと思う
  • Swift3の正しい書き方とか、ガイドになるようないいものありますか?

iOSDC Japan 2016 参加メモ: A-10 SwiftでJavaScript始めませんか?

SwiftでJavaScript

JavaScriptCoreとは

  • JSのランタイム実行環境
  • Swiftとの相互運用が可能

  • 使用例

    • 再ビルドをせずに実装を差し替える
    • カスタムスクリプト環境を提供
    • JSを使ってネイティブアプリを制御できる
    • Web経由でソースコードをダウンロード、など

ちょっとまった

  • 強力すぎないか?
  • 審査通る?

    • 考えてなかった!
  • 環境

基本的な使い方

  • JavaScriptCoreをimport
  • JSContext生成
  • JSコード実行
    • evalの結果はcontextに溜まっていく
  • 実行結果をSwiftで受け取る
    • 返り値をSwiftで受け取れる

変数の扱い

  • JSValueで表現

    • toTypenameメソッドでSwiftの型にできる
    • isTypenameプロパティで判定してから取り出せる
  • オブジェクトもJSValueで

    • swift側からforPropertyなどで取り出したりできる

JavaScript API

  • JSの基本的な組み込み機能だけが備わっている
  • DOMなどの高度なものはない

  • 自分の手でAPIを構築していく

    • やり方は色々
      • JSからでもSwiftからでも
  • 変数/関数/オブジェクトをJSで定義する

    • 普通にeval
  • Swiftで定義する

    • setObjectすることで、JS上で参照できるようになる
    • 参照型だと共有しちゃう
  • 関数をSwiftから取り込む

    • クロージャをコンテキストに設定する
    • AnyObjectにキャストしてsetObjecすると、JS上から呼び出せる
  • Swiftの型をJSで使う

    • @objcをつけてNSObjct継承してやれば、渡せる
    • インスタンスを渡す事もできる
    • meta typeを渡すこともできるので、JSの中でインスタンス化することも可能
  • Swiftの機能をそのままJS上で使える!

コードを書きやすくする方法

  • 普通に書いてると読みづらい
  • プロジェクトにJSファイルを組み込んで、Bundleから読み込んでStringにしてevalに流してあげれば楽にできる

まとめ

  • JSをSwiftから簡単・自在に扱える
  • 審査通るかは、後日!

QA

  • ECMAScript 2016は対応してる?

    • 行けそう
  • JS側でSwiftのオブジェクトを参照した場合、開放されたオブジェクトの扱いはどうなる?

    • JS Managed Valueあたりを見るとわかるかも
  • React Nativeは使ってたはずなので、審査は通りそう

iOSDC Japan 2016 参加メモ: A-11 Xcodeで快適なデバッグライフを追い求める

Xcode

  • XcodeなくしてiOSの開発はありえない
    • 原因にいかに早くたどり着くか

クラッシュしたらAppDelegateだった問題

Exception Breakpointを追加

  • Breakpoint追加時に Exception Breakpoint を選んで追加

    • ただし、Exception前提で書かれていると意図と違うタイミングでbreakしてしまう
      • storyboardがなければフォールバックする、とか
  • Diagonosticsを設定

    • 不正なメモリ操作を検知
    • dynamic library
    • Edit Schemaから設定できる
      • Enable Zombi Object
      • Enable Address Sanitizor -> パフォーマンスは下がる
    • アセンブラレベルまでクラッシュした場合、これがあれば追える

どのViewControllerかわからない問題

  • 新しいプロジェクトに入ると。。。

  • Symblic Breakpointを追加

    • SymbolにviewWillAppear / viewDidLoadなどを追加
      • commandで bt 0するとでる
    • viewControllerで設定しておかないと、Symbolic Breakpointが効かない
  • Share Breakpointすると、チーム間で共有できる

起動時に特定のViewControllerにしたい問題

  • デバッグ時に深いページ開くの辛い。。。
  • Environment Variables
    • Edit Schemaから設定できる
      • この環境変数を参照して挙動を変える処理をAppDelegateに書いておく
    • メリット
      • Xcode から起動した時のみ有効になる!
      • 一時的な挙動の切替に便利

端末のログやファイルを取得したい問題

  • 実機のログやRealmをみたい

    • できるけどめんどくさい
  • LLDBを使って該当ファイルをSlackに送信

    • breakpointでbreakしてコマンドを打つ
    • gistに公開しました
      • ./llidbinit の中に呼び出しを入れておく

まとめ

  • 快適になると良いね!

QA

  • Closureの中でオブジェクトを参照する方法とかありますか?

    • lldbが巧くフレームを取れてないのが悪そう
    • 2連発で取ると巧く行くことはある。。。けど基本諦めてる
  • Breakpointとlogが多すぎてわからなくなるのはどうしてますか?

    • Loglevelを切り替えられるようにしたりして、フィルタしてる

iOSDC Japan 2016 に参加してきた

https://iosdc.jp/2016/

iOSDC Japana 2016、まるっと一日参加してきました。 すごくたくさんの人と熱気で、トークも面白いものがぎっしり詰まっていてとても充実したイベントでした。

スタッフならびにスピーカーの皆様、素敵なイベントをありがとうございますっ!\\\٩( 'ω' )و ///

LTはペースに追いつけずにまとめられなかったんですが、今日聞いてきたトークはそれぞれログを取りました。 (資料が貼ってないものは、見つけ次第足します)

色々新しい情報とか参考になる話を聞けたので、明日は気になるところを少し深掘りとかしてみようかなー。