Optional(2018)年あけましておめでとうございます

iOS エンジニアの西信です。

新年早々、大変お騒がせしております。申し訳ありませんの一点に尽きます。

はてブや、Twitterなどで大きく話題にしていただいたので、この機会に、恥は承知の上で、なぜこんなことが起きてしまったのか、筆をとらせていただくことにしました。

この問題は昨日 (2018年1月4日) リリースしました、バージョン 9.1 にて修正済みです。iOS のみで発生していました。
蛇足ですが、当バージョンから、ホーム画面が新しくなり、カードの引き落とし額決定や、使い過ぎなどをお知らせする『MY通知』がさらに便利になりましたので、ぜひお試しください。

さて、今回の起因となったのは、昨年 2 月に行った Swift 3 への対応でした。

この PR 以前までは、該当のNotificationを表示する時に、年月日を個別に取得するためにNSCalendarクラスでタイムゾーンなどを指定し、 NSCalendarcomponents APIに NSDate
を指定し、年・月・日を個別に扱える NSComponents クラスを取得して西暦を表示していました。

これに関して、Swift 2 系までは NSComponents クラスの yearmonth プロパティは下記の通り非 Optional 型だったので問題はありませんでした。
https://developer.apple.com/documentation/foundation/nsdatecomponents/1412462-year

しかし Swift 3 系より NSCalendar クラスが Calendar 構造体、 NSComponents クラスがDateComponents 構造体に変更され、DateComponents 構造体のyearmonthプロパティが
Optional 型になりました。
https://developer.apple.com/documentation/foundation/datecomponents/1779943-year

では、なぜ「あけましておめでとうございます」以降の年は Optional(yyyy) になっていなかったのでしょうか。該当コードがこちらです。

該当の箇所は dayComponents.year! - 1Optional 型である dayComponents.year を強制アンラップしています。つまり、後者のみ dayComponents.year - 1 のままでは警告ではなくコンパイルエラーになるため気付くことができ、ここだけ強制アンラップしました。

じゃあ、この時点で dayComponents.yearOptional 型になったことが分かったのだから、前半部分の \(dayComponents.year)年あけましておめでとうございます。 もきちんと Optional を外せよ!と思うのはごもっともですし、そもそも強制アンラップ使うなよとか、Optional Bindingできちんと yearOptional を外す処理をして前半・後半部分に同じものを使えという意見もあるでしょう。

非常に大きなサイズの PR であったことや、破壊的変更が行われた Swift 3 への対応だったこと、そもそも古くから運用されているプロダクトであるがゆえの大量の警告を全て潰しきれておらず、そのまま埋もれてしまったとしか言いようがなく、とても恥ずかしい限りです。

重ね重ね、お騒がせしてしまい、大変、申し訳ありませんでした。
ご安心ください、マネーフォワードは 2018 年が来ない可能性を考慮したことはありません!

最後に

このようにまだまだ未熟な部分もありますが、マネーフォワードでは、こういった事を前向きに捉え、どんどん改善してくれるiOSエンジニアを募集しています。
ご応募お待ちしています。

【採用サイト】
マネーフォワード採用サイト
Wantedly | マネーフォワード

【マネーフォワードのプロダクト】
自動家計簿・資産管理サービス『マネーフォワード』
Web
iPhone,iPad
Android

「しら」ずにお金が「たま」る 人生を楽しむ貯金アプリ『しらたま』
Web
iPhone,iPad

ビジネス向けクラウドサービス『MFクラウドシリーズ』
会計ソフト『MFクラウド会計』
確定申告ソフト『MFクラウド確定申告』
請求書管理ソフト『MFクラウド請求書』
給与計算ソフト『MFクラウド給与』
経費精算ソフト『MFクラウド経費』
入金消込ソフト『MFクラウド消込』
マイナンバー管理ソフト『MFクラウドマイナンバー』
資金調達サービス『MFクラウドファイナンス』

メディア
くらしの経済メディア『MONEY PLUS』

Pocket