iPhoneが数秒おきに
クラッシュするんだけど!
iOSDC 2018
株式会社 Zaim watura (西本 航)
2017年12月02日06時24分
iPhoneが数秒おきに
クラッシュしている
という報告が!
アプリが数秒おきに
クラッシュしている

ということ?
🤔
違うらしい
iPhoneが再起動するらしい
このアプリが悪いらしい
国内最大級750万ダウンロード
突破のオンライン家計簿
結論:Zaimは悪くない
積極採用中
Android Security Marketing
「Zaim スタッフの頭の中」始めました
https://blog.zaim.co.jp
結論:Zaimは悪くない
2017年12月2日
06:24 トレンドになっていることに気がつき で共有
2017年12月2日
06:24 トレンドになっていることに気がつき で共有
06:38
Slack チャンネルを作成
関係者がチャンネルに追加される
06:42 Crashlytics をチェックしていた私Slackに登場
@watura (西本航)
•iOS
•インフラ
•セキュリティ
•朝6時から15時まで勤務
•パンを焼いたり
•ジムに行ったり
2017年12月2日
06:24 トレンドになっていることに気がつき で共有
06:38
Slack チャンネルを作成
関係者がチャンネルに追加される
06:42 Crashlytics をチェックしていた私Slackに登場
06:48 原因不明ながら手元で再現
7時頃の時点でわかっていたこと
• 12月2日になったら突然発症
• 一部アプリの通知をオフにすると解消
• 通知を受けない設定だったらクラッシュしない
• Zaimサーバ側にエラーはない
• Xcodeにもエラーは出ない
• Zaim悪者になってる感が感じられる
2017年12月2日
06:24 トレンドになっていることに気がつき Slack で共有
06:38
Slack チャンネルを作成
関係者がチャンネルに追加される
06:42 Crashlytics をチェックしていた私Slackに登場
06:48 原因不明ながら手元で再現
07:40 原因判明
二つのNotification
• Push Notification
• サーバから端末に対して送信
• Local Notification ←こいつが犯人
• 条件を指定してアプリが端末に登録
• どちらを使うにも「通知の許可」が必要
• ユーザ的には違いがない
2017年12月2日
06:24 トレンドになっていることに気がつきSlackで共有
06:38
Slack チャンネルを作成
関係者がチャンネルに追加される
06:42 Crashlytics をチェックしていた私Slackに登場
06:48 原因不明ながら手元で再現
07:40 悪いのはPush通知じゃない
07:51 再現しない版Zaimが手元で作られる
やっていたこと
• 発症したユーザを救う方法の探索
• 削除/通知をオフして欲しくない
• 原因の調査
• Zaim上の設定変更で回避したい
→できる
• Twitterで情報共有/収集
• ユーザへの連絡準備
一度発症すると
影響の大きい方法でしか
解消できない。
2017年12月2日
06:24 トレンドになっていることに気がつきSlackで共有
08:02 アプリのアップデートで解消するのは無理と判明
10:40 対応版アップデートをアップロード&特急申請
10:59
開発者に向けて再現コードの共有
https://github.com/ktakayama/NotificationCrash
フルビルド 10 min
↓
サンプルコード 10 sec
努力の結果今は2分くらい
2017年12月2日
06:24 トレンドになっていることに気がつきSlackで共有
10:40
まだ発動していない人のためのアップデートを

アップロード&特急申請
10:59
開発者に向けて再現コードの共有
https: //github.com/ktakayama/NotificationCrash
11:30 絶対これが原因だろ!というツイートをする人現る
https://twitter.com/miyagawa/status/936785405462003713
https://robservatory.com/month-13-is-out-of-bounds/参考
13月は範囲外!?
まじで。。。
2017年12月2日
06:24 トレンドになっていることに気がつきSlackで共有
10:59
開発者に向けて再現コードの共有
https: //github.com/ktakayama/NotificationCrash
11:30 絶対これが原因だろ!というツイートをする人現る
13:30
すでにできることは全部やった感があったので

一旦調査等終了
17:40
iOS 11.2

公式対応記事リリースされる
以降やったこと
• Blog, Twitter等でお知らせ
• 一般ユーザ向け
• https://zaim.co.jp/news/archives/3333
• 技術者向け
• https://zaim.co.jp/news/archives/3337
• お知らせメールの送信
• 訂正依頼
• Zaimが犯人だ!と言っているようなところ
ちょっとだけ技術な内容
もうあんまり
意味ないんですけどね
対象
iOS 11.0.x
iOS 11.1.x
発見された不具合を起こすコード1
// 2017/12/01のDateComponentsを作る
guard let date = DateComponents(
calendar: Calendar(identifier: .gregorian),
timeZone: TimeZone.autoupdatingCurrent,
year: 2017, month: 12, day: 1).date else { return }
// 毎月1日に実行されるNotificationを作る
let notify = UILocalNotification()
notify.repeatInterval = .month // 毎月繰り返す
notify.fireDate = date // 終了ずみの日付を指定
// Notificationを登録する
UIApplication.shared.scheduleLocalNotification(notify)
// → クラッシュループ
iOS側で実行されるので、iOSがクラッシュする
発見された不具合を起こすコード2
// 日付を指定したDateComponents作成
let dateComponents = DateComponents(day: 1)
// 毎月1日に発動するNotificationのTriggerを作成
let trigger = UNCalendarNotificationTrigger(
dateMatching: dateComponents,
repeats: true)
// 12/01の次にNotificationが発生する日付を計算
print(trigger.nextTriggerDate()) // → メモリを食いつぶす
アプリ側で動いているコードなので
アプリがクラッシュするだけ
なぜクラッシュするのか
(推測)
• Local Notificationを管理しているのは、iOS側
• 一定時間ごとに通知すべき通知がないか確認
• 復帰後数秒間は操作できる理由
• 次の繰り返しを登録
• nextTriggerDate()
2017年13月01日 ・・・ NG
2017年14月01日 ・・・ NG
2017年15月01日 ・・・ NG
︙
2017年2147483647月01日 ・・・NG
︙
(推測)
なぜZaimが一番燃えたか
• 日本がJST
• 多くのユーザが使っている
• 通知を許可したユーザ全員が対象
• Zaim社は朝一から活動している
• Twitterなどで情報共有した
やばい障害が発生した時にやること
1. Blog, Twitter等を調査
2. デモコードを可能な限り作ってテストする
3. 英語で騒ぐ
4. さっさと修正版を申請して、広報する
Zaimは悪くない
悪いのは
iOS 11.0, 11.1 だった
ご静聴ありがとうございました
注意:

クラッシュとか再起動するとか言ってますが、実際にはSrpingboardがクラッシュしてい
たのでiOSがクラッシュしてた訳ではないと思われます
Android Security Marketing

iPhoneが数秒おきにクラッシュするんだけど