iOSDC Japan 2017に行ってきました

子どもができてからというもの、なかなか勉強会やイベントに参加できなくなっていましたが、久々に参加してきました。

iosdc.jp

かなり悩みつつセッションの選択をしたなかで、特に印象に残ったものをあげます。

両OSやるマンという選択

speakerdeck.com

実際に1人でiOS/Android対応されている方の発表。

意外とAndroidも開発してるよって人が多かったのが印象的でした。

違いを意識してプロダクトに落とし込むことが一番重要っていう部分は同意しかなくて、ディレクターさんやデザイナーさんにこそ共有したいなーと思いました。

Android開発もやってみよっかなーという気分になりました。

アプリエンジニアはどのように事業に貢献すべきか

speakerdeck.com

近々、初めてBtoCのサービス開発に関わる予定なのですが、同じようなことに悩むんだろうかと思いつつ聞いていました。

気になったキーワード

  • アプリを使うことがユーザーにとってやりたいことではない
  • ユーザーが喜ぶ体験を理解して、アプリ上で実現する
  • アプリ以外も含めてサービスでありユーザー体験である

何度か読んで、自分なりの考えをまとめてみるつもり。

結婚式を支えた技術 Firebaseを活用したサーバレスiOSアプリケーション開発

speakerdeck.com

結婚式の写真を共有してもらうために1ヶ月でアプリを作ってしまうという素敵なお話。

身近なところにある問題を解決するのは、ユーザーも近くてフィードバックもらいやすいし、なにより解決すれば喜んでもらえるし、いいことずくめですね。

我が家でも、妻からこんなアプリできないの?みたいなことをたまに言われるのですが、子どもと遊ぶのを言い訳にしてしまっていて反省。

とりあえずFirebase触ってみようと思いました。

全体通しての感想

めちゃめちゃ楽しかったです。

以下、楽しかったことを雑にまとめます。

  • オープニングから力の入ったムービーでテンションあがる
  • セッションはどれも面白く、同じ枠で聞きたいものがかぶりまくって泣く泣く選択するという贅沢な状況
  • 懇親会でもないのにビールが配られて、飲みながら聞くLT最高
  • 運営の方々が、ほんとによく動いていて、とにかくスムーズな運営が印象的

ただ、2日目の途中で体調を崩してしまい、途中で帰らざるを得なくなってしまったのが心残りです。

来年も開催されたら、最後まで参加するぞ。懇親会も参加できたらいいな。

Swiftはプロパティもオーバーライドできる

バージョン

  • Swift 3.0.2
  • Xcode 8.2.1

クラスのプロパティ

知らなかっただけなのですが、Swiftはプロパティもオーバーライドできます。

使い方次第で便利に使えそう。

サンプルコード

プロパティのオーバーライドとプロパティ監視を組み合わせて、ボタンが無効化されたらアルファ値を変えるコードです。

import UIKit

class CustomButton: UIButton {
    override var isEnabled: Bool {
        didSet {
            super.isEnabled = isEnabled
            self.alpha = isEnabled ? 1.0 : 0.4
        }
    }
}

let customButton: CustomButton = CustomButton()

print(customButton.isEnabled) // true
print(customButton.alpha) // 1.0
customButton.isEnabled = !customButton.isEnabled

print(customButton.isEnabled) // false
print(customButton.alpha) // 0.4

UIViewからUITableViewのカスタムセルを作るとボタンタップイベントが取れない

現象

UITableVIewのカスタムセルにボタンを置いて、タップ用の処理を書いたがタップイベントを検知できない。

原因

ボタンの上のレイヤーに、UITableViewCellContentView というビューが描画されており、このビューに邪魔されてタップイベントが検知できていなかったため。

f:id:y_sumida:20170301094905p:plain

根本原因

カスタムセルのxibファイルを、UITableViewCell ではなく、 UIView を使って作成していたため。

UITableViewCell で作ったxibは、UITableViewCellContentView の上に自分の配置したパーツが描画されています。

f:id:y_sumida:20170301094946p:plain

ちなみに、xibファイルの新規作成すると、デフォルトで UIView が置いてあるというXCodeのおせっかい機能のがほんとの原因かもしれません。

f:id:y_sumida:20170301095134p:plain

対策

カスタムセルを作る際には、xibファイルのデフォルトで置いてある UIView を消して、UITableViewCell を置くと良いです。

f:id:y_sumida:20170301095039p:plain

または、新規ファイルを作成する際に、クラスファイルから作成して、 Cocoa Touch Class を選択して、次の画面で Also create XIB file にチェックを入れると、勝手に UITableViewCell を配置したxibファイルを生成してくれます。

f:id:y_sumida:20170301095245p:plain

f:id:y_sumida:20170301095341p:plain

AutoLayoutに慣れてる人には当たり前なのかもしれないですが、ちょっとわかりにくいなーと思いました。

2016年の振り返り

今年もあんまりブログ書けなかったけど、振り返りはしておく。

お仕事全般

こまごまPHPもやったけど、ほぼSwiftでiOSアプリ開発ばっかりだった。

チームでのアプリ開発を経験できたり、RxSwift触ってみたり楽しかった。

プチSCMBCとかを開催して、ちょっとずつプルリクエスト方式での開発ができるようになってきた。

Qiita:Team

去年に引き続き、積極的に投稿するようにしていた。

だんだん書いてくれる人が増えてきて嬉しい。

少しは役に立っているのかも。

社内勉強会

Bitbucketを使うことが増えてきたので、プチSCMBCみたいなことをした。 コンフリクト祭りが楽しかった。

全職種向けにバージョン管理についての勉強会を開催して日付zipがなぜダメなのかを伝えた。

社外勉強会など

ほぼ参加できなかったけど、まあ、これは仕方ない。

プライベート

第二子である次男が生まれて家の中がさらに賑やかになった。

長男が保育園に通うようになって、より時間を効率的に使う必要が出てきた。

早めに出社して勉強してたのが、子どもを寝かしつけてからの時間に変わった。

たまに一緒に寝落ちしちゃうのどうにかしたい。

来年の目標

  • Qiita:Teamをディレクターさん、デザイナーさんも使うようになってきたのでそっち向けの記事も書く
  • Swift環境での自動テストを導入する
  • iOSアプリ開発に偏った1年だったので、Web開発もうちょっとがんばる
  • 何かしらアウトプットする

配列の要素をオプショナルバインディング

はじめに

コードレビューで、ちょっと不思議なコードがあったのでメモ。

結論

配列の添字アクセスをオプショナルバインディングしてもビルドエラーにならないけど、わかりにくいのでやめたほうがいい。

コード

var hoge:[Int] = []

// hogeを更新する処理など

if let n: Int = hoge[0] { //ランタイムエラー
    print(n)
}
else {
    print("nothing")
}

一見すると良さそうですが、配列が空っぽなのでコメントした行で fatal error: Index out of range になります。

当たり前といえば当たり前ですね。

改善案

配列でこういった判定を行うなら、空配列の判定したほうがわかりやすい気がします。

if hoge.isEmpty {
    print("nothing")
}
else {
    print(hoge[0])
}

そもそも、配列アクセスでnilが返る可能性を想定したコードになっていますが、hogeInt型の配列であって、Optional<Int>型の配列ではないので、オプショナルバインディングは適切ではないです。

なんでビルドエラーにならないのかは謎です。

どうしてもオプショナルバインディングしたい場合

if let n: Int = hoge.first {
    print(n)
}
else {
    print("nothing")
}

今回の場合は、配列の最初の要素にアクセスしたいので、Array クラスの first プロパティでOK。

first はオプショナル型なので問題なし。

似たようなプロパティとして最後の要素を参照する last もあります。

どちらも正確には Array クラスに適用している CollectionType プロトコルの特徴ですが。

PHPで画像やcssの404エラーでセッション切れになる現象

はじめに

FuelPHPを使っていて、セッションが切れることがあり調査していました。

ググるとドキュメントルートにファビコンが存在していないと発生するなどの記事がヒットするのですが、ファビコンだけでなく読み込んでいる画像やcssがなくても同じ事象が発生することがわかったのでまとめておきます。

結局FuelPHPだけの話ではなかったです。

原因

FuelPHPに限らず、PHPのWebアプリケーションフレームワークだと、たいてい.htaccessにこんな感じの設定があります。

リクエストされたパスがファイルやディレクトリじゃなかったら、フロントコントローラーであるindex.phpに処理を投げるというものです。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php$1 [L]

通常、画像やcssは最初の条件に該当するのでindex.phpで処理しないのですが、ファイルが存在しない場合、どちらの条件にも該当せずindex.phpで処理することになります。

コントローラーには画像やcssファイル名のアクションはないので、最終的に404に流れます。

index.php内(というか、その先のコントローラーなど)で、FuelPHPで言うフラッシュセッションのような次のリクエスト時に消えるセッションを使用していると、404リクエストで消えてしまうためセッション切れが発生します。

生存期間の長い通常のセッション使っても解決するのですが、フォームデータの削除し忘れとか嫌ですし。

対策

コントローラのアクション以外をindex.phpで処理しなければいいので、.htaccessの設定をこんな感じにすれば良いです。

特定の拡張子(この例ではcss/jpeg/png)の場合、index.phpで処理しないようにしています。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^.*\.(css|jp?g|png)$
RewriteRule ^(.*)$ /index.php$1 [L]

Sketchで透過オブジェクトを含むグループごとスライスする

はじめに

最近、PhotoShopの代わりにSketchを使うことも増えてきました。

SketchはMake Exportableで@2xや@3xもまとめて簡単に切り出せていいなーとか思ってたら、よくあるアイコンの下に固定サイズの透過オブジェクトがあるパターンで、グループごと切り出しても透過オブジェクトのサイズに切り出せずアイコン自体のサイズになってしまって困りました。

プラグインとかいれないで解決できたのでメモ。

確認バージョン

Version 3.6.1 (26313)

解決策

グループ化する

ヘルプアイコンと24x24の矩形をグループ化。 f:id:y_sumida:20160615155147p:plain

アイコンと透過レイヤーを選択

f:id:y_sumida:20160615155146p:plain

スライスツールを使ってオブジェクトを選択

スライスツールはここ。

f:id:y_sumida:20160615152532p:plain

外側を選ばないと、アイコンだけ切り出すことになるので注意。

f:id:y_sumida:20160615155145p:plain

アイコンだけ選んだ場合

f:id:y_sumida:20160615155144p:plain

選択すると切り出した結果が右側に表示されるが、背景も含んでしまっている。

f:id:y_sumida:20160615155143p:plain

Export Group Contents Onlyにチェック

グループ以外のオブジェクトが除外されるので透過になる。

f:id:y_sumida:20160615155142p:plain

あとは必要に応じて@2や@3を追加してExportShapeでOK。