hiragram no blog

iOSとか

iOSDC2017参加した

トークの内容などは他の方がたくさん書いてるのでそういうのは割愛して感想だけ。

前回のiOSDCに参加したときはただトークを聞いてふんふんして終わったから帰るか〜という感じで当時はそれで満足していたけど、今年はTwitterで繋がってた人と初めて挨拶できたり僕が以前別の場所でした発表を聞いて覚えててくれた人に声かけられたり@tarunon@omochimetaruにくっついてたらすごい人を連れてきて議論してるのを聞けたり今までつながってなかった人と新しくつながれたり当日適当にメンバーを集めて終了後に焼肉に行くというコミュニティの一員感のあるムーブが出来たりしてよかった。

こういうカンファレンスの一番価値ある部分は上にあげたような対面コミュニケーションだなと感じた。トーク内容はスライドが公開されたり誰かがブログにまとめてたりあとで録画が公開されたりする(ありがたい。2017年最高)ので当日は無理して全部聞こうとするより空き時間にスピーカー捕まえて話聞いてみたり知人とこのコードどう思うみたいな議論をしまくるほうがチケット代と消費した時間がより有益に感じられると思った。

身近(と僕が一方的に思っている)な人はすごい人ばっかだし刺激をもらった。

あと、TwitterのアイコンとIDが明記された名札、あれが最高だった。

Pairsのクラッシュバグをみつけたお


pairs-2017-09-16

項目 情報
アプリバージョン 5.26.0
iOSバージョン 10.3.2
端末 iPhone 6s

操作

  • ユーザー詳細画面で、上方向に素早くスワイプしたあと、写真の上に表示されている右方向のインジケータをタップする
  • 次のユーザーに切り替わるが、スクロール位置的に本来隠れているべきと思われるNavigationBarもどきのViewが見えている
  • 同様の操作を数回(3回の場合が多い)繰り返すと数秒アプリが固まったのちクラッシュする

原因を想像する

わからん

iOSアプリのバックエンドにFirebase使ってみた感想

習作としてレシピのマスターデータがあってそれを作ったよというレポートをアプリから投稿できるようなやつを作ってみて感じたこと。

とりあえず動かすのが超簡単

コンソールからプロジェクトつくってキー発行してSDK入れて初期化すればDBにアクセスできて簡単だった。

考えなしに使うと多分いろいろ破綻する

  • DBがスキーマレスなのでなんでもぽいぽいpostできちゃう
    • DB操作する所は1箇所にまとめて抽象化しないと欠けたオブジェクトがDBに乗っちゃったりして詰みそう。そこはSwiftのカチッとした型と柔らかいスキーマレスDBとの境界で大変というかんじ。考えなしに進めてオブジェクトのプロパティがどんどんOptionalになっていくのは見ていられないので抽象化がんばりましょう
    • 既にデータが刺さってるモデルにプロパティ追加したりしても古いデータは当然マイグレートされないので古いデータが落ちてきてパースに失敗するみたいなこともよく起きそう。
  • DBへの書き込みはアプリ内で直接やらないほうがいいかもしれない
    • アプリのアップデートで書き込みの操作が変わっても古いアプリでDBいじられて壊れるみたいなことが将来ありそう。
    • 使ってないけどFirebase Functions経由でしかwrite操作できないようにすればいいのかしら。そうするとオフラインでも使えますみたいな旨味が無くなっちゃうけど。

オフラインDB、開発中は便利かもしれないけど本番運用で役に立つイメージあんまない

オフラインでデータの読み書きができたところで、画像などは結局ダウンロードできないので「オフラインでもアプリが完全に動作する」を実現するのはそんなに簡単じゃなさそうだなーという印象。 僕は通勤の電車のなかでコード書くのでその時はオフラインDBすごく助かった。

RxSwiftとの相性はいい感じに見えた

DB抽象層としてRxSwiftのObservableをふんだんにつかったRepository層みたいなのを作ったけどデータ更新されたら都度ストリームにながすみたいなことができてリアクティブプログラミングとの相性は良さそうな感じだった。

[2017/09/08追記] ユーザー管理が超楽

iOSアプリのバックエンドにFirebase使ってみた感想 - hiragram no blog

Firebase使ってみた× Firebase Realtime Database使ってみた◯

2017/09/08 09:54
b.hatena.ne.jp

仰る通りなので追記してみます

ユーザー管理、メールアドレスとパスワードとか、Twitter/facebook連携とか、そういうの全部面倒見てくれるのは体験としてすごく良かった。習作アプリは特にSNS連携とかいらなかったので、匿名ログインみたいなやつを使った。ユーザーから情報を得ることなく、端末を識別してくれるので「自分の投稿」をIDで抽出することができたし、トークンの更新みたいなことも全部SDKに丸投げでよかったのでよかった。

総評

お手軽に使えるが、お手軽に使いすぎると容易に死ぬことがわかったので長く保守する大きなアプリをFirebaseだけでやっていくのはなかなか難しいんじゃないかという感じがした。将来Firebaseを剥がすってなったときに死なないようなアプリ側/サービスの設計が必要で、それをちゃんとやろうとするとFirebaseのお手軽さみたいな所をどんどん鈍らせていく感じがしてものを作るというのは難しいなあと思いました。

行動指針

SwiftでiOSアプリを作るにあたっての自分の行動指針をまとめて公開してみた。

というのも、最近転職したり個人でアプリ作ったり友人とのプロジェクトが動き出しそうになったりしており、複数のコーディング規約にまたがってコードを書くことになりそうで(仕事-個人間では既に起きてる)、頭のスイッチコストやそもそもどういうルールだっけみたいなのが問題になりそうなので個人側の規約みたいなものもテキスト化してついでに公開しようと思った次第。

個人プロジェクトは僕一人でやってるのでチームで円滑にやるためのルールみたいなのは考えてないし、そもそも細かい具体的なコーディング規約はないので、迷ったときにはこう判断するのだというのを示す意味で行動指針としてみた。

以下のリポジトリにおいた。

hiragram/my-guidelines

一応思いついただけ普段書いてるコードの規約みたいなのを書き出してみたが言いたいことは冒頭のBasis of thoughtsの部分なのでそこだけ和訳しておいておく。

Humans must not do anything which a compiler can do. A compiler is far more reliable than humans are.

コンパイラができることを人間はやらない。コンパイラは人間よりはるかにずっと信頼できる。

型推論が効くところは型を書かない、省略記法が使える所は省略記法を使う

Do not make extra efforts for tiny readability. The most important thing is that each parson has same understanding, not same appearance of code.

小さな可読性のために余計な手間をかけない。重要なのは誰が読んでも同じ理解をできることで、コードの見た目が同じであることではない。

改行のあるなし、ブレースのあるなし、など。 ifの括弧かかないとかブラケット前後のスペースとかはまあ常識的に。

Take advantage of IDE(Xcode) strongly.

IDE(Xcode)をめちゃ活用する

定義へのジャンプ、型の表示、MARK、など

Do not choose a way that can crash apps on the runtime if there are another options that can prevent crash or detect errors on compilation time.

実行時にクラッシュしうるやり方より、クラッシュしなかったりコンパイル時にエラーチェックできる選択肢があるならそっちを使う。

User Defined Runtime Attributes, Implicitly Unwrapped Optional, Any, など

退職します!

3年2ヶ月在籍したSpeeeを退職します。今日が最終日です。

なにしてたの?

元々サーバーサイドのエンジニアとして新卒入社してPHPやっていて、自社サービスのiOSアプリ用のAPIを作ってました。そのうちアプリ側のちょっとしたデバッグとか修正をXcodeでやるようになり、アプリおもしれーなとなってきたタイミングで社内公用語がPHPからRubyになるとのことで、どうせ未経験から勉強するならRubyよりアプリやりたいなとなり転向させてもらいました。そこからはそのプロジェクトでObjective-Cを書いたり幾つかのプロジェクトでSwiftを書いたりしました。

取り組んだこととしては、

  • Swift1.xから2.0への移行
  • RxSwiftの導入
  • API抽象レイヤーの型々しい設計
  • TravisCI上でCarthageの依存フレームワークをキャッシュしたりCartfile.resolvedの差分をみて更新分だけ再ビルドしたりする仕組みを作って導入
  • typo警察

なんで辞めるの?

アプリチームは半分くらい(以上かな?)が業務委託メンバーで入れ替わりもそこそこあってさみしいなーみたいなことと、Ruby勢のわいわいやっていくぞという雰囲気を羨ましく思っていたことがちょっとモニョっていました。 あと、去年の夏秋くらいにプロジェクトにモニョモニョ〜という感じの状態があったことをきっかけに、漠然とあと1年くらいかな〜くらいな気持ちが湧きました。

あとは直接的な理由があるわけじゃなくて、名前を知ってる会社からオファーを貰って、経営層から現場のエンジニアまで話を聞かせてもらい、いろいろ比較するとこっちのほうがいい!となって辞めることにしたという感じです。9時半に出社しなくていいのと台風の時は自宅作業ができるのすごいという感じ。

次どうするの?

7月から五反田でiOSアプリエンジニアとして働きます。希望すればiOS以外のポジションも挑戦させてもらえそうなので、落ち着いたらKotlinでAndroidをやってみたいと思っています。六本木よりもランチが安いとのことで嬉しいです。かれーの店うどんという気になりすぎる店があるので楽しみです。ホームページがパンクで良かったです。

ほしいものリスト

http://amzn.asia/1otnYYA

AutoLayoutのエラーを紐解くときにやっていること

以前ふとこんなツイートをしたところ意外とLikeされた。

AutoLayoutの制約に矛盾があるときにコンソールにでるメッセージ

f:id:hiragram:20170611004037p:plain

これをみて直さないといけないときに自分がやっていることをまとめておく。

ビューのaccessibilityIdentifierを設定する

コードからならhogeView.accessibilityIdentifier

xib/storyboardならここ。

f:id:hiragram:20170611004958p:plain

すると

f:id:hiragram:20170611005235p:plain

UIView:0xXXXXXXXXXXXXと出てたところがaccessibilityIdentifierに置き換わる。

制約のidentifierを設定する

コードからならconstraint.identifier

xib/storyboardなら制約を選択してここ。

f:id:hiragram:20170611005813p:plain

すると

f:id:hiragram:20170611005858p:plain

アドレスを指定してビューに背景色をつけたりする

コンフリした制約が多すぎてidentifierつけるのがだるいときとかはlldb上でアドレスを指定してUIViewのインスタンスをとってきてbackgroundColorで色を変える。 エラーでる画面のviewDidAppearとかでブレークして、

(lldb) e let $v = unsafeBitCast(0x7fc85dd0a0f0, to: UIView.self)
(lldb) e $v.backgroundColor = UIColor.yellow

でブレークを解除して動かすとアプリ上で色が変わる。隠れてたら階層見るアレで見て。

NSLayoutConstraintのアドレスを渡すと対象のビューに枠線をつけるlldbプラグインを作った

Python初めて書いたので許して

#!/usr/bin/python

import lldb

def process(debugger, command, result, internal_dict):
    lldb.debugger.HandleCommand("""
    expr -l swift --
    func $process(_ address: Int) {
        let constraint = unsafeBitCast(address, to: NSLayoutConstraint.self)
        guard let view1 = constraint.firstItem as? UIView else {
            return
        }
        view1.layer.borderColor = UIColor.red.cgColor
        view1.layer.borderWidth = 2

        guard let view2 = constraint.secondItem as? UIView else {
            return
        }
        view2.layer.borderColor = UIColor.blue.cgColor
        view2.layer.borderWidth = 2
    }
    """.strip())
    lldb.debugger.HandleCommand('expr -l swift -- $process('+command+')')

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand("command script add -f visualizeAutoLayoutTargets.process visualizeAutoLayoutTargets")
    print "enabled visualizeAutoLayoutTargets command."

導入とか使い方はこの辺を参考にしたのでそっちを見てください

iOSエンジニアのための LLDB Plugin 入門

使った感じはこんな感じ

これは記事頭のツイートがちょっと盛り上がってからふーんと思って作ったものなので実務から生まれたものではないです。使いづらいとか知らない。

おわり

Mastodon用のiOSクライアントアプリを作っている

Mastodon、どうせ1ヶ月で飽きるっしょという思いがあったのでユーザーとしては全然使っていなかったが、流行りモノのサービスでアプリ開発競争みたいになってるのには参加してみたいという思いがあったので作っている。

f:id:hiragram:20170508044227g:plain

開発に使っているアカウントはPawooにあり、一旦はPawoo用クライアントという位置づけで出すつもり。

半年先には誰もMastodonの話してないでしょという思いは相変わらず持っているので、一旦リリースして飽きたらTwitterクライアントに転生させると思う。