「24歳まで」編はこちら。まぁまぁコントリビュートした。
メインスレッドでDBのIOが走ってて遅かったので修正した。テストを通すのに苦労した。また、ロック処理が甘くクラッシュの可能性があることも指摘した。
Pinterestの画像ダウンロード&キャッシュライブラリ「PINRemoteImage」の粗探しをしていたら行き着いてstatic抜けを修正した。
「Carthageサポートしてるよ」とREADMEには書いてたが、実際はサポートしてなかったのでサポートした。
CoreFoundationのパーセントエンコーディングにバッファオーバーフローのバグがあってクラッシュするのでワークアラウンドを追加した。
iOSではuserInfoのキーを定数化するのは割とルールとしてあるのだが、それがされておらず、扱いづらかったので修正した。
UIViewAnimationCurveがUIViewAnimationOptionsとして扱われてたためバグの指摘をした。
titleを指定している辞書を作ってるのに使ってなかったのでちゃんと渡すようにした。
また、ログイン画面がエッジスワイプで閉じてしまう問題を修正した。
プライベートな記事が自分のページ一覧に出ず行方不明になっていたので表示するようにした。
他にも、Gistも積極的に公開したり、Gistで公開したものについての質問がメールで来て答えたりもできた。Facebook iOS SDKにコントリビュートしたことや、iOS以外でもコントリビュートできたので、結構満足。引き続きiOS以外でもどんどんコントリビュートしていきたい。
Sumallyを退職してから随分経つが2016年やってたことをまとめる。
未登録でSumallyを使えるようにしたので、GitHubみたいにアイコンを自動で生成するプログラムを作った。お題は「ユーザーごとにユニークなアイコンを作るシステムを作れ」とそれだけだった。言語は何でもOK。普通に考えてサーバー側で生成するのが良いし、処理速度も必要だし、標準ライブラリがかなり整備されているGoを使った。作ったはいいがパターンが多すぎてユニットテストが遅すぎて話にならないので、無駄にGoルーチンを使った。
引き続き、Sumally Pocketの開発をしていた。招待機能などなど実装したが、一番大きかったのは、オプションサービスの実装。クリーニングやハンガー保管サービスをするということで、サービス自体の仕様を考えるところから参加した。最初はクリーニングしたいものを「クリーニング専用の箱で送る」みたいな話が進んでいたが、複雑で汎用性に欠けるので、「預けてるモノからオプションを選択する」というのを提案し、採択され、実現した。オプション選択画面はどんどんABテストしたいとの要望がありWebViewで作ることになった。そのブリッジング周りの仕様も決めた。この開発がまたまたかなりハードスケジュールだったが、なんとかすべての仕様を漏らさず入れられた。
Sumallyのゲストユーザー対応や、検索画面ソートなどなどのヘルプをした。iOSがほとんどだが、APIもエラーが出て開発ができないときなどは自分で直してとやっていた。また、倉庫スタッフ向けに、アイテムの画像からSumallyのカテゴリに変換するモバイルアプリを作ったり(RxSwiftを使った)、バーコードからアイテムの情報を自動入力するアプリなども作っていた。
404ページをリニューアルした。Sumallyハッカソンで作業を開始してから1年ぐらいPRが放置されていたが、退職に伴ったいろんな整理と一緒にやった。
2016年は割と時間はあったので、Pocket for iOSのSwift 2対応やObjectMapperからHimotokiへの移行などなどをできたし、退職前には事業開発MTGに参加したりなどしていて、より広い視野でサービス開発をしていたし、技術的チャレンジが色々できて、かつ、社内でそのような知見を共有する会を開いたりとしていた。懐かしい。
どうやら海外からの投稿に制限をかけているらしく、公開は日本に帰ってからになるけど、今、バリ島にいる。学生時代から何かを追っていたり、何かに追われてたりでずっと走り続けてきたので、こんな風に立ち止まって、ゆっくり・のんびりと過ごすのは、本当に久しぶりだ。
7月15日が最終出社日だった。7月31日が退職日で、インターンを含めると3年、入社から2年5ヶ月。たったこれっぽっちの期間だけど、その間、自分のほぼすべてを費やしてきたし、何を達成できたかはよく分かってないクセに、達成感で満ち溢れている。
インターンの時もだったけど、どんなに小さな機能でも、非常に高いクオリティでの開発が要求された。Sumallyのプロダクトのクオリティの高さは、国内でも最高レベルだと思っているし、実際、外部からもよく凄いと言ってもらえる。僕自身もSumallyで働いていると言うだけで凄いと言ってもらえた。Sumallyでの仕事は決して楽ではなかったけど、最高のプロダクトを作るいちメンバーとして戦ってきたことを誇りに思っているし、楽しく刺激的な日々を送っていた。
Sumallyではとにかく働いた(つもりでいる)。とにかく最短で自分の納得のいくクオリティのものを作り、時間を余らせ、細かいフィードバックへの対応をする時間や自分のやりたいこと(仕事に関係する)をやる時間を作るようにしていた。最短で行き着くために、スピードももちろん、遅くまで働いたり、土日も働いたりしてきた。仕事のことを考えない日はなかった。そんな働き方をしていたら、最初にできるもののクオリティはどんどん上がっていき、返ってくるフィードバックはどんどん細かくなり、プロダクトのクオリティはどんどん上がっていった。実現できるものの幅がどんどん広がっていったし、僕にしかできないことが少しずつ増えていった。いつの間にか、求められているであろうクオリティ以上のものを作るようになっていたし、細かいフィードバックをする側にもなっていた。
エンジニアの中では一番若かったけど、そんなの関係なく社内で一番パフォーマンスを出していると認めてもらい、信頼してもらい、大きなチャンスも与えてもらい、権限も大きくなっていった。iOSリードエンジニアはもちろん、名ばかりではあるけど、フロントエンド・モバイルチームのボスになったり、会社全体の開発フローを見直したり、APIの仕様を考えたり、事業の会議に参加したりというポジションになっていた。なにをしても(しなくても?)許されたし、とても居心地がよかった。一方で、まだまだやることはたくさんあったとは思うけど、「もう十分だな」「一区切りついたな」などなど、やりきったなと感じるようになり、次の目標を考えたり、そこまでの道標を考えるようになっていた。次の目標のことを考えれば考えるほど、焦りを感じたし、そうしていくうちに、次のステップに進む決断をするに至っていた。
新卒でSumallyに入り、スタートアップだし実際は不安でいっぱいだったけど、たくさんのチャンスを与えてもらい、他社では見られなかったような景色をたくさん見てこられた。かなり成長できた。頑張れば頑張るほど、次のステージを与えてもらった。感謝でいっぱいだし、自分で言うのもアレだけど、期待に応えるように本当によく頑張ったなと思う。新卒でもたくさんチャレンジができて本当に入社してよかったと思う。Sumally Haus(表参道時代)のなんともない風景から、深夜に翌日に審査提出予定のアプリにイースターエッグを入れろと無茶振りされたり、リリース日の早朝に会社に電話がかかって会社に呼び出されたり、Appleで登壇する日の朝までアプリを開発していたりと無茶苦茶なことまで、すべてがとてもいい思い出だ。Sumallyで得たことはどこでも通用すると思っているし、どんどん活かしていきたいと思っている。
“九州大学芸術工学部在学中に、短期の住み込みインターンとしてSumallyへ。いきなり重要なプロジェクトにアサインされるも、悠々と期待以上の成果を残すという大物感を見せる。当初Sumallyへの就職意思は無かったものの、経営陣からの三顧の礼を受け、2014年3月に晴れて新卒入社。主にモバイルアプリの開発を手がけ、CTOからの無茶な振りを淡々とこなすかたわら、高級ロードバイクで街中を疾走するスーパールーキー。”
さてさて恒例のウィッシュリストを作ってみた。何か届くといいな。
もう実装して1年以上経った気がするが、あまり気付かれていないようなのでバラすと、Sumally for iOSの「登録 / 出品」の画面にはイースターエッグが仕込まれている。他にもイースターエッグはあるが、そちらは結構バレてるみたいなので、今回の紹介はこちらだけにしておく。登録 / 出品の画面を開き、iPhoneを振ると発動する。iPhoneの傾きに応じて背景のアイコンが動く。
このデザインが来たときから、「これは動かしたい!」と思い、ウズウズし、時間を見つけてやった。社内でも内緒にするつもりが、嬉しくて、言いふらしてしまった。
物理演算にはiOS7からの新機能のUIDynamicAnimatorを使った。Apple様様のおかげでそれだけだったら超簡単にできるのだが、この背景のアイコンとそれらのポジションの情報、衝突判定に使うサイズの計算が必要だったので、IllustratorのプラグインもJSXで実装した。メニューを選ぶだけで各アイコンの各解像度(1x, 2x, 3x)の画像の書き出しやアイコン情報のJSONの吐き出しをする。AdobeのJSエンジン(でいいのかな?)ではJSONの書き出しが実装されていなかったので、JSON吐き出す仕組みも作った。初のプラグイン開発だったがドキュメントがしっかりしてたので案外すんなりできた。
「で?なんなんだ?」と言われたらそれでおしまいな機能ですが、ぜひ遊んでみて下さい。
ようやく今年分を書ける。そもそもやったことを書こうと思ったのは、サービスの開発だと、頑張って開発してもポートフォリオとかがないし、そういう記録に残ることがないので、やってることアピールができないのは残念だし、やったことは忘れるだろうしと…それがすごくもったいないなと思ったからだ。社外どころか社内でも、誰が何を担当してるか分からないことがあるし、そのせいもあって、サービスの開発を傍から見ると、「ものすごい量の人がひとつのものを一緒に開発していて、担当範囲中でひとりが担当するのはその機能のほんの一部程度」みたいな印象が強い気がする。
去年は書くのサボってしまい今回インターン時代分からまとめるのが割と大変だったので、来年からはきちんと書いていきたい。
実装が完了してから「やっぱ違う…」ってなって作り直しになった辛い思い出がある。結構な回数作りなおしたような気がする。付随していろいろな不具合が修正できた。アイテム一覧のページも含めすべて担当した。
「開発したい」という声は上がっていたがなかなか時間がなかったので、勉強を兼ねて休日作り、「あれ?意外といける?」となり、リリースした。こちらもすべて担当。
大杉さんから声をかけてもらったので、またとない機会だったこともあり、登壇した。iOSアプリの開発フローについて実装パート周りを担当。スライドを作ったりもした。マイサマリー画面のリニューアルとWatchアプリ対応版のアプリ審査提出をこのイベントの日の早朝にするといったスケジュールだったので、結構忙しかった。
プロダクトオーナーに任命されたので、実装はもちろんすべての実装設計や実装方針、API仕様の一部などを決めた。今年はほぼこの開発のタスクをしていた。上の忙しさの比じゃない忙しさだった。アプリ内でガッツリDBを使うことは初めてだったし、Swiftもある程度はキャッチアップしていたが使うのは初めてだったので、言語仕様から掴まないといけなかったしと、いろいろとチャレンジングだった。3ヶ月でテストフライトベータリリース(ほぼ完成版)、4ヶ月で正式リリースした。ベータリリース段階で8割のコードを書いていた。ベータ期間も4回ほどアップデートしたが、その間に仕様が変わったりして、しかもそれがめちゃくちゃタイトで、ご飯食べる暇がない日があったぐらい忙しかった。ベータリリースからはすべてひとりで実装を担当している。あとFastlaneの導入もした(もともとSumallyの内部ツールはRuby製だったので楽にできた)。更にサウンドデザインもした。
詳しくはこちら。Sumallyでは全てのパスでアプリを開くような設定をしたので、Safariに戻すパスのパターンリストをアプリ内でキャッシュして持っていて定期的に更新している。
コンバージョントラッキング周りの実装を少しだけ手伝いした(ただの今年はAndroidも久しぶりに触ったよアピール)。あとAPI仕様だとかを多分いちばん把握しているので、その周りのデバッグを手伝った。
今年は中村さんがご退職されたこともあり、Sumally for iOSとSumally Pockt for iOS両アプリのプロダクトオーナー(要は開発リーダー)になり、実装ももちろん、ミーティングに出ないといけない回数が増えたり、僕主導でのiOS人事技術面接をしないといけなかったり、問い合わせをしないといけなかったり、スケジュールと役割を決めないといけなかったり、実装方針の相談に乗らないといけなかったりと役割が増え、いろいろと勉強になった(もう少しただただ技術を磨いていたかったという思いはあるが、いつまでもそうは言ってられない)。まだまだ両アプリのプロダクトオーナーとしては、キャパシティ的にふさわしい対応ができていないと思ってるので、その辺り2016年は意識して頑張っていきたい。技術面でも関数型プログラミングだとかリアクティブプログラミングだとかの勉強もギリギリでできたしCore Dataも把握したし、アプリもそうそうないクオリティで作れたと思うしで、十分やったと思う。Android、Webフロントエンドと、フロントエンド系はアサインされたら一応こなせる技術はついたと思うので(Androidは一番苦手だけど)、来年はもっと表現の幅を広げたいし、OpenGLだとか低いレイヤーの復習をしていきたい。仕事的には、Pocketの開発で得た知見を本体アプリに反映させていきたい(いろいろ大変そうだが…)と思っている。あとシリコンバレーで働く夢を叶えるために引き続きいろいろと下準備していきたい。今後もたくさん吸収していく予定なのでもしシリコンバレーの方で僕に興味があるという方がいらっしゃったら、連絡をお待ちしております。
前回の続き。流石に全部はあげられないが、主に下のようなタスクをしていた。
初日、出社して皆さんが来るまで暇だった(弊社は朝がとても緩い)ので、自分が使っていて一番欲しかった検索候補の実装をした。
注文履歴一覧画面のアップデート、出品商品詳細画面、取引画面、画像のフィルタリング機能などを実装した。またそれに伴い、カテゴリフィルタ画面のアップデート、アプリ内通知、売っているアイテム一覧画面の実装、出品周りやアプリの告知メールなどなどたくさんメールテンプレートの実装をした。アプリの実装をしながら、コードレビュー中にメールテンプレートの実装をしと、とても忙しかったのを覚えている。審査提出後、C2Cアプリのティザーサイトも、アプリ審査提出後の打ち上げで「作ろう!」となったので、超特急で作った。
それまでカスタムURLへの対応が、正規表現など使っていなかった(hasPrefixとhasSuffixでされてた)ので全部正規表現に置き換えた。それとテストを簡単にできるようにWEBフロントエンドにテストページを作った。
それまでドロワーメニューだったが、中村さんが「タブバー以外といけそう」とチョチョイと実装してみせたことがきっかけでタブバー化することになり、実装を担当した。またスクロールに応じてタブメニューが消えるような実装をしたり、ナビゲーションバーが消えるような実装をしたりもした。それまで曖昧だったiOSのビューのヒエラルキーなどを初めて完全に把握した。
画像先読みをもっとチューニングしたいということで、画像先読みロジックの再検討と実装をした。SDWebImageの内部実装をすべて読み把握したうえで、バグを修正したりしながら、ブラウザを参考に独自のPrefetcherを実装した。
拡大したときに大きな画像を裏でダウンロードして表示を差し替えるというタスクがあったので、ついでにそのまま画像がシームレスに拡大される動きや閉じる動きなどなどその周りの実装をした。
オートページャライズに対応する目的もあったが、全体がUITableViewで組まれていてスクロールすると関連アイテムの表示(グリッド)の部分やフォルダー一覧の部分でかなりカクついてたため、見直した。入社する前から直したいところだったので達成感は大きい。
それまでUIWebViewが立ち上がり、わざわざログインしないといけなかったので、そのあたりのコードがイケてなかったこともあり手が開いてるときに勝手に実装を進めていたのだが、導入したところ、後々「なんかこのタイミングでコンバージョンめちゃくちゃ良くなってるけどなんでだ?」となり、TwitterKitの導入によるものだと判明した。処理もすっきりしたし、数字にもつながったしで嬉しかった。
アプリ内から+Sumallyできる機能をサイト内で実行するJSも含めて開発した。加えてこれまでのすべてのWebViewをすべてこの+Sumally機能付きのものに変えた。JSの開発はGrunt+WebPackで行い、どこでも使えるように徹底的にモジュール化をした。その後Share Extensionの実装もしたが、そこでもほぼ同じJSを使えたのでモジュール化での開発は大成功だった。いつかリファクタリングしてプラグインをどんどん追加登録できる仕組みにしたい。
Sumallyアプリは、内製化してからもしばらくAuto Layoutを使っていなかった(ちなみにAuto Layoutのキャッチアップと導入も僕がした)。ということでかなり苦しい作業になったが、「320」を置き換える作業や、それまで全く使っていなかった画像スライスの導入などをした。
QRコードリーダー(カメラ)や、QRコードの描画(結構凝ったデザインになっているので見て欲しい)など、QRコードでの招待機能一式の実装をした。
内容はひみつ。
入社当時のコードレビューなどを久しぶりに見て、いろいろとひどくけちょんけちょんにされているが、2014年の終わりごろには、逆にコードレビューで質問されるようになってるし、特に技術面でとても成長した年だったと思うし、成長を感じられて嬉しい。iOSだけでなく、Webのスキルも実務で活かせてよかったと思う。
年1回まとめようと思ってたけど去年めんどくさくてやらなかったので、とりあえずインターン時代のから振り返る。去年の分は来週中にでもまとめて、今年の分は、大晦日ぐらいにあげる予定。
インターンは7月下旬ぐらいから2月中旬までしていた。そのうちの8月上旬から10月中旬ぐらいまではオフィスの2階に住み込みで仕事をし、他は学校も共同研究と自分の研究とで結構忙しかったので暇があるときにリモートで仕事をする、といった感じの参加だった。
Skypeでのインターン面接合格通知後のいきなりのタスク。福岡からのリモートでコーポレートサイトを実装した。
新アプリに実装されたメールでの招待機能のテンプレートを実装した。メールテンプレートの実装は初めてだったのでこのご時世にグリッドレイアウトをPHPで組むことになるとは思ってもいなかった。割と複雑な実装だったので入社後もしばらくメールテンプレート開発おじさんをする羽目になった。
非ログユーザー向けにサインアップやログインを促す画面の実装とボタンのJS側のアップデートをした。何故かここだけありがたいことにCoffeeScriptで実装されてたので、すぐに全体を把握できた。
まさかAndroidアプリ開発の経験が全くないのに全部を把握してないとできなさそうな実装タスクが降ってきた。頑張った。
トークンの登録から表示するパーツまで含めて実装した。トークン取得周りはいろいろと苦労した。
当時ほぼすべてWebViewだったが「引っ張って更新したい!」と言ったら「じゃあやって」となったので頑張った。
少しずつネイティブ化していこうという話になり、佐藤さんが夏休みに入ったタイミングで、僕だけで一番簡単そうな通知画面のネイティブ化を進めた。
割とAndroid SDKのコツを掴んだ気がしたので検索補完機能を実装した。
表示崩れを直したり不具合を直したり、UICollectionViewが使われてなくて無理やり実装されていた部分を置き換えたりしてるところで福岡に戻り、リモートでCore Animationを使ってwant/haveボタンのアニメーションの実装をしたりした。
卒論でヤバイときにタスクが降ってきた。そもそも使っていたライブラリがスレッドをバカスカたてて読みに行くライブラリだったのでSDWebImageに置き換えようと思っていたがそれどころじゃなかったので一旦保留。卒論提出直後会社から電話があり、東京に呼び出されたので、日曜出社し、SDWebImageへの置き換えやSDWebImagePrefetcherを使ったプリフェッチの実装をした。
3月入社まで卒論とインターンのタスクの消化などしてて、卒業旅行などいけなかったのは人生で一番後悔していることだ。4年の夏までは勉強のためにインターンしてよかったと思うけど、それ以降はなにが何でもインターンやバイトはやめて、研究も適当に終わらせて旅行に行くべきだったなぁ…と。
24歳になった。堤修一さんの記事を読んで僕も掘り起こしたくなったので(GitHubページでコントリビュートしてるリポジトリは5件しか出ずアピールできないので定期的にまとめた方が良さそうだ)、キリがいいしとりあえずこれまで(24歳まで)でコントリビュートしたリポジトリを上げていこうと思う。
「LINEで共有する」のアクティビティのライブラリ。人生初の公開リポジトリへのプルリクエスト。しかもiOS開発始めて2ヶ月ぐらい。見て分かるようになぜか修正した行だけタブインデントになってるしこの修正では不十分だしで、初心者感丸出しでヤバイ。
Pinterest風のグリッドレイアウトのライブラリ。FlickrとかTumblrとかでも使われてるみたい。ピクセルパーフェクトじゃない計算を修正し、ついでに64bit対応し、さらにstatic抜けを修正した。
言わずと知れた、画像ダウンロード&キャッシュをするライブラリ。ほぼすべてのアプリで使われていると言っても過言ではない。スレッドのロックが不十分でダウンロード完了のコールバックが呼ばれないことがある不具合を修正した。この修正では不十分だったのでもう一つPRを作りマージされた。
THE GUILDの深津さんたちが作ったアニメーションライブラリ。グローバル変数になっていたのをメンバ変数に変えた。TODOが多かったので導入には至っていない。もっとコントリビュートしていきたい。
堤修一さんが作ったwatchOS 2のサンプル集。CoreGraphics周りのブログ記事を読んで少し違和感(動きそうな気がする)があり、試したところきちんと動いたので、関連するところを修正した。ついでにメモリリークの修正とサンプル未実装の部分を実装した。
言わずと知れた、今はAppleで働いてる方が作ったネットワーク周りの処理がものすごく簡単になるライブラリ。ほぼすべてのアプリで使われていると言っても過言ではない。いつの間にかnullabilityをサポートしていたが、指定ミスが数か所ありSwiftとの互換性上の問題があったので修正した。
アプリ内ルートをものすごく簡単にするライブラリ。externされておらず、Swiftからアクセスできない変数があったので修正した。
AWSのiOS SDK。ひとまずCoreモジュールだけstatic抜けを修正した。他は誰かがやってくださるはず!
APIクライアントを作るための一通りの処理をアブストラクト化した感じのライブラリ。RequestにBodyがない場合もヘッダでContent-Typeを送っていて無駄だったので修正した。ついでにハンドラが非同期でしか呼ばないようにした(条件に応じて同期で実行されたり非同期で実行されたりしないように)。
有名なライブラリにコントリビュートしてるので、弊社アプリだけでなく、世の中のほとんどのアプリで僕の書いたコードが数行入ってると思うとすごく嬉しい。いろんなライブラリやサンプル集があってこそ開発やキャッチアップが楽になってるので、恩返しという意味も含めこれからも積極的にコントリビュートしていこうと思う。あと、ライブラリを読んだりするのは一番いい勉強になる。
とりあえず分かってるのはTwitterとFacebookで、カスタムURLスキーマがブロックされる。両アプリともiOS8でカスタムURLスキーマを開こうとするとアラートを出していたので、下のようにその実装がそのまま残っていたとしたらバグだ。
それか、わざとブロックしているかなんだけど、この辺りはリバースエンジニアリングしないと分からないし調査したところで報告する以外どうしようもない…。
ということでSumallyもこの現象で困った(一ユーザーとして使い勝手が悪くて不便だった / ユーザーからの問い合わせがあった)ので、ちょうどその頃別の問題から実装を進めていたUniversal Linksを使ってどうにか対応できないか、Webフロントを担当している奥山さんと考えることにした。Universal Linksを使うと、TwitterやFacebook内で意図的にブロックしていたとしてもブロックする手段がなくなるはず。
Sumallyでは、sumally.comとm.sumally.comでユニバーサルリンクを有効にしていてパスはすべてを指定している。この場合、結論からいうと、「UIWebViewまたはWKWebViewまたはSFSafariViewController内のユーザーのタップによる遷移で、ドメインが変わり、かつ遷移先のドメインがUniversal Linksに対応していた場合で、更に運が悪くなかった場合」に発動する。JavaScriptやリダイレクト、Meta Refreshなどでは発動しない。タップをトリガにlocation.hrefを指定するJavaScriptでは発動するが、タップをシミュレートするJavaScriptでは発動しない。ユーザーが本当にタップする必要がある。そして何故かたまに発動しない(タップをJavaScriptでトリガしてる場合のみな気がする)。あと実機じゃないとダメだし証明書のチェックもしている(mitmproxyなど挟むと発動しない)ようだった。
右の画像ようなモバイルサイトの「アプリで開く」ボタンがTwitter / Facebookアプリ内ブラウザで動作しない。Twitterでは何も起きず、Facebookでは読み込みエラーのページが表示される。
iOS9以上の端末で「アプリで開く」ボタンを押したらPCサイトに遷移するようにしたら良いことに気付いた(例: m.sumally.com/p/1 → sumally.com/p/1)。PCサイトに移動するタイミングでアプリが入ってる端末ではUniversal Linksが発動し、入っていない端末ではsumally.com/p/1が開くが、Sumallyはnginxで再度モバイルサイトに戻るのでただページがリロードされただけのような挙動になる。細かい実装をしたらApp Storeに飛ばすとかもできそう。
この動作がうまく動作してるかどうか気付きにくいので、定期的にJenkinsでテストする仕組みを作った。テストではXcode 7の新機能のUIテストを使った。
コード読めば分かると思うが、http(s)しか読み込みを許可しないWebViewのアプリを作ってUIテストでボタンタップしてアプリが切り替わるか(≒Universal Linksが発動しているか)というテストの内容だ。これに加えてSumallyアプリ側では、受け取ったURLがアプリ内で開けるものか開けないものかのUnit Testを作って上のUIテストと一緒にJenkinsで定期的にテストしている。前で述べたけど実機で動かす必要あり。
一ユーザーとしてひとつ問題を解決できてよかったが、この対応ができているサービスがなかなかなく、今のところSumally以外でできている例を見たことがない。そもそもTwitter / Facebookがブロックしないようにして欲しいんだけど、意図的にブロックしている気もするので(TwitterはAndroidアプリでもブロックしている)、この方法(もしくは近い方法)が広まっていって欲しい。TwitterやFacebookアプリを使っていて「アプリで開く」ボタンが使えないのは本当に不便だ。
追記(2015/12/03): いつの間にかTwitterではAndroid版含め開けるようになっていた。Facebookは相変わらず開けないようだ。
追記(2015/12/14): Xcode 7.2でアプリのstateのpropertyがなくなりテストが通らなくなっていたため、applicationImplから持ってくるように修正した。あとDEBUG版(デフォルトでは)のビルド設定じゃないとstateが変わらない。
追記(2015/12/21): 上のapplicationImplを使うと不安定でテストにならなかったので、Objective-Cを使って例外をキャッチする仕組みにした。失敗するかどうかのテストも追加したら完璧になる(弊社プロジェクトでは追加した)。
追記(2016/03/19): Exceptionを投げるかどうかのテストも追加した。
iPhone 5sのカメラの内部にホコリが入っていて、たまにくるInstagramをおしゃれにしたい欲を満たせなくなったので、iPhone含めたスマホのカメラ性能について調べてたら、いつの間にかNexus 5Xを買っていた。記念に表参道の一番好きな場所をパシャリ。
AndroidはOS自体がとても賢く、普段良く使うGmail、Calendar、PhotosなどのGoogleのサービスとAndroidが最大限に同期されていて、その結果がGoogle Nowに表示されたり、写真を端末に保存しなくて良かったりと未来に生きている感じがする。
まぁ、とりあえずはiPhone 7が出るまでの間だけAndroid生活をおくろうかなと思っている。RoughsのAndroid版開発も捗るだろう。
追記: Android版リリースした。Kotlinで開発した。
Core DataのモデルからSwiftを書き出す機能はXcodeにもあるが、いちいちGUIでする作業がめんどくさいのと、@objcが付かないのでMagicalRecordとの相性が悪かった(SwiftでMagicalRecord使うなよって話は置いておいて…)。
もちろんmogeneratorも試したけど、こちらは吐出されるコードが冗長なのと(そもそもextensionで十分)、Scalarの値を使わないのでいちいち変換するのがめんどくさかったし、サブクラスとか使った場合のSwiftのコードにバグがあった。
ということで、その辺りをどうにかできるツールを作った。nokogiriとcolorizeとerubisをインストールしてお使いください。Core Data初心者なので網羅できてるか分からないけど…バグや改善点などなどあったら教えて下さい。
追記(2015/04/29): mogeneratorを参考にして、Orderedに対応した。
追記(2015/07/22): 色々実装が足りてないので結論mogeneratorがいい感じになるのを待つのが良さそう…。ちなみに社内プロジェクトでは上のを事あるごとに改良して使っている。
2週に1度、お題は自由(リクエストがどんどん書かれていくのでその中から選ぶ)な社内勉強会があり、Processingのリクエストがあったので発表した。発表内容のリクエスト欄に、デザイナの大杉さんから「こういうの作りたい」と要望があったが、Processingは大学の授業でさらりと触ったのと卒論で音の生成に使ったっきり触っていなかったし、曲線は円以外書いたことなかったしで、「こんなのできるかっ!!」か見て見ぬふりで流そうと思っていた。でも「なんだ〜。できないんだ〜。」って思われたくなかったので、頑張った。案外すんなりできて嬉しかった。とはいえロジックも実装も雑すぎるので、コードは社内だけの公開に…。
発表はハンズオン形式で、全員で一緒にこういうのを作る目標で進めた。classの説明をいい感じにできなかったので、そのあたりから「?」が頭の上に浮かんでる方が出てきてしまい、最後には2名ほど「動かない…」となってしまったのが主な反省点だが、少なくとも僕は楽しかった。またやりたい。
旧TestFlightがまもなくサービスを終了しますよとメールが届いたので、移行した。ちょうどそのぐらいにアプリの審査提出が終わってきりが良かったのでささっと。
Sumallyでは、ipa作成 & TestFlightへのアップロードにShenzhenを利用していたので、移行先の候補は、このShenzhenが対応しているサービスに絞った。Shenzhen導入時に、これもMatttさん作なことを知り、中村さんがぼそっと「Matttさんって何人居るんだろ…」とおっしゃった場面、今でも思い出して笑ってしまう。
まず、有料サービス候補から消えた(理由は言わずもがな…)。次に、新TestFlight(iTunes Connect)だが、iOS7の対応はまだ切れそうにないのでボツ。ってやっていくと、安心して使えそうなのがもうCrashlytics Betaしか残らない。Sumally for AndroidもBetaを使っていたので文句なしで決定した。
決まってしまえば簡単で、Sumallyでは社内テスト配布するシェルスクリプトがあるので、ShenzhenのコマンドのTestFlightに配布アップロードする部分をCrashlytics Betaに変える感じで終わった。と思いきや、Shenzhenにipaのファイル名にスペースがあるとファイル名を正しく受け取れないバグがあるらしいので、アップロードは直接Crashlytics.framework内のsubmitを使うことにした。詳しくはこちら。submitにあるオプションも一部対応していないものがあるし、アップロードに関してはあまりShenzhenを使う利点がない。”and click on the links right underneath the org’s name.”(組織名のすぐ下のリンクをクリックしてね)を見落としてて、API_KEYとBUILD_SECRETを見つけるのに一番苦労した。
使い勝手だが、インストールする側の初期設定が、若干TestFlightにめんどくさいのと、アプリのダウンロードがTestFlightに比べ遅いの以外は、ほぼ同じ(もしくはそれ以上)といった印象だ。いちいちアニメーションが凝ってるので、社内での評判も良い感じ?
他も含めいろいろお世話になります、Fabric。
Sumally for iOS v7.0ではiPhone 6 / 6 Plus対応及び、+Sumally Share Extensionの開発などを主に担当した。6 / 6 Plus対応に関しては、10月半ばに、Share Extensionも11月頭にほぼ終わったのだがほかもいろいろ盛り込んで審査待っているうちに、今日になってしまった。アプリ開発を内製化して間もないので、いろいろ大変なのだが、こういう対応が遅いのは、少しずつ改善していきたい。
多分、Share Extensionでちゃんと画面から作っているのアプリは国内でもあまりなく、手探りで開発した。Share Extensionの開発にあたり引っかかったポイントを上げる。
どこでも書いてるから落とし穴ではないが…容量を考えると、共通で使うパーツはフレームワーク化したほうが良い。結構大掛かりな作業のためSumallyでは諦めてしまった。いつかターゲットの分け方から見直したい。他にもログイン情報やキャッシュファイルを共有するための対応も必要になる。
サイトで実行するJavaScriptのファイルを指定できる。ただこのJavaScript内でのwindowとブラウザ内でのwindowは完全に別物なことには驚いた。ちなみにSumallyの場合、データを収集するスクリプトを常に最新の状態に保ちたかったので、そのスクリプトをサーバーからロードするJavaScriptをアプリ内に持ち、データが完成次第、ネイティブに渡す実装になっている。
Supported DevicesをiPhoneだけにしててもiPadで拡大モードではなく普通に動作してしまう。Auto Layoutで作りましょう。必要だったらSize Classesも使いましょう。
様々なアプリがあるので当然のことなんだけど、どこにも書いてなかったので驚いた。やっぱりAuto Layoutで作りましょう。
iOS8で画面回転の受け取り方が変わったのだが、開発中いくらやってもだめだった。方法が悪かったのかOSのバグかな…?Auto Layoutでほぼ解決できるけど、横向きでiPhoneの場合だけこうするってのはどうしても出てくるので、SumallyではframeをKVOすることで解決した。
アプリ内で使っているインジケータなどは使えない。というより、Window Lebelがどのあたりだったらいいか分からない。なので全部UIViewの階層のみで実装した。
iPhoneはポップアップでのUIViewControllerの表示に対応していないので、表示のアニメーションやら閉じるアニメーションやらは自前で実装した。
Sumally for iOSは、開発中に接続先を変えるために、ローカル / ステージング / プロダクションのターゲットがある。毎回これらのバージョンナンバーを書き換える作業が面倒だったし、今後どれかだけ変更し忘れるとか起こり得る。ターゲットが増えれば増えるほど、暗くなっていく未来が見えたので、スクリプト化した。ちなみに、当たり前なことかもだけど、Sumallyではこういうめんどくさい作業はよくスクリプト化する風習があり、iOSプロジェクトには他にも12ほどスクリプト(Shell ScriptとPython)がある。
実用的なレベルでの初Rubyなので、Ruby業界ルール完全無視になってるかもしれない…xcodeprojとplistをインストールして、いい感じにカスタマイズしてお使いください。
追記(2016/07/31): FastlaneのActionにあるのでそちらを使った方が良さそうだ。SumallyではFastlaneのを使うようにした。
いろんなアプリプロトタイプツールがあるけど、Sumallyではいろいろ試し、結局Flintoが一番いいよねって話になった。でも、Flintoはアプリがなく、毎回HipChatからリンクを開いてSafariで開きなおしてSafariでホームスクリーンに追加してようやく起動、とモック表示までの手間が多く、パッと見られないのが唯一の欠点だった。
ということでFlintoのプロジェクトを管理する&表示できるプロジェクトを作った。誰かひとりがFlintoのプロジェクトのURLを登録しさえすれば、あとはみんなのアプリに反映されてアプリ内でモックを確認できる。FlintoはAPIがないので、スクレイピングしてデータを持ってきている。
会社に持っていったところ想像以上に好評だったため、オープンソース化した。ホントはサーバー側をもっとちゃんと作ってiOSアプリをストアでリリースできたらいいんだけど、Flintoが仕様を変えたら動かないしAppleの規約に引っかかるのでこれが限界みたいだ…
セットアップの方法など、お問い合わせは@chuganzyまで。アップデートも可能性はあるので、その連絡もTwitterでする予定。
1ヶ月ぐらい前にSumally for iOSの画像ロードを高速化しようという話になり、Sumally専用の画像先読みのロジックを組むことになったのだが、completeBlockが呼ばれないので今どれだけプリロードしているかを正しく計測することができなかった。ということで内部実装を読んでみた。
昔は呼んでたっぽい実装はちらほら見かけたが、もう完全に呼ばないようになっている。その代わり、キャンセルの時だけNSNotificationCenterにSDWebImageDownloaderOperationがselfをpostNotificationするようになっている(他の時はnilでpostNotificationされる)。それを使ってキャンセルを判別する。
上ので確か解決するはずだったんだけど、デバッグしてると極稀にキャンセルを受け取れてないのがあるっぽかった。こちらは完全にバグ…自信がなかったので、社内用のだけ修正しようと思ったら既にコミットが見つかった。要するに、完了時にblockを辞書から取ってきて消す間に追加されて、すぐさま実行されず消えてしまう可能性があるというバグ。
このパッチを当ててゴニョゴニョして完了。
今回、内部実装を読んで、SDWebImageのイケてない部分が幾つか(結構?)あるっぽいことが分かったし、勉強にもなった。あと、ロジック見直しで画像ロードは早くなった気はするが、パフォーマンスチューニングまでできなかったので、また今度暇な時にやります…
昔のバージョンではSDWebImagePrefetcherのダウンロードとUIImageView+WebCacheでのダウンロードの管理は別だったので、二重ダウンロードがされる可能性があったが、どこかのバージョンででそれらが同じマネージャーで管理されるようになり、重複ダウンロードの問題が解決された。これ自体はいいことだけど、弊害として、SDWebImagePrefetcherのcancelPrefetchingを呼ぶと、表示しようとしている部分でもダウンロードがキャンセルになり、結果、画像がところどころ表示されなくなるというバグがあった。そもそもSDWebImagePrefetcherはprefetchURLsをすると、これまでのプリロードをキャンセルする仕組みなのでこの不具合に遭遇する可能性は高い。試行錯誤したので、どう解決したかはヒミツ。
追記(2015/02/25): 2つ目の見出しの件について、SDWebImageにPRを出し(見つけたコミットだとパフォーマンスに影響が出るのと変更し過ぎなので最小限の修正のPR)マージしてもらえた。
ofxLibwebsocketsのバージョンによっては動くみたい(謎)だが、基本的に接続できない。Socket.ioを使っている場合も同様だ。ローカルでは動くのに…と不思議に思っていて、ローカルとHerokuとの違いを探してもなかなか見つけられず…友人から、「ヘッダの解釈でコケてるみたい」と言われて、他ライブラリでブレークポイント仕掛けてずっと見たら「Sec-WebSocket-Accept」が「Sec-Websocket-Accept」になっててException投げてた。これは気付かない…
で、このヘッダを書き直すのにhttpのupgradeでヘッダーを自分で書いても消えてしまうのでサーバー側で解決するのは不可能そう…C++のライブラリを書き直すのもアレだし、一番の解決方法はサーバーを変更することでopenFrameworksの方に手を入れるべきではないと思ったため、とりあえずの対応として、HerokuとローカルサーバーでWebSocket通信をし、ローカルサーバーとoF間でWebSocket通信をするような仕組みで解決した。
それと、Herokuは60秒で接続が切れる。なので、この辺りの実装が素晴らしいSocket.ioを使うことを超おすすめする。上のは切れたらリコネクトしまくる仕組みなので危険だと思った方はいろいろちゃんとやって下さい。
追記: どうも、HTTPのheaderはcase-insensitiveらしい。ということで、ofxLibwebsocketsの方を直すべきだ。内部でlibwebsocketsのまだcase-sensitiveだったころの古いやつを使ってるのをどうにかしたらいいと思う(適当)。
追記2: 0.8.4で対応したみたいだ。試していないが上のワークアラウンドは完全に不要になったっぽい。めでたしめでたし。
結構他のアプリでも、モーダルを複数重ねることは避けられていて(UX的にあまり良くないからもあるんだろうけど)、使っていてもaddChildViewControllerで回避していたりするっぽいので、てっきり一気に閉じることはできないのかと思っていたが、いろいろやってみたらできた。
というか最初からこれだろうと思ってたのだが、なんかの手違いからかできなくて、ワークアラウンド探しの旅から戻ってきて、もう一回やってみたらできたという感じでポカーンとしている。
卒業研究がうまく行かず、かなりギリギリまで卒業できるかどうかでヒヤヒヤしていたが、無事大学を卒業できた(今更だけど)。あまりにヒヤヒヤしていたので、大学の思い出の大半がそのときのことになってしまった気がする。
3月頭にSumallyに入社したため、卒業式には休みを取り行った。卒業が確定したのが3月中旬より少し前だったので、卒業できてなかったらどうしようという不安でいっぱいだった。
卒業研究は、まず、超音波を使ってスマホの位置特定を室内でも超高精度でやろうってことをしてたが、あまりうまく行かず…更にはiBeaconも登場してしまい、同じ概要の技術も特許が取られたり、OSC通信より音速が速くて距離計算出来ない(できるが制限が多過ぎる)しで、もうダメダメだったので12/26に断念。ちなみにiBeaconも試したけど、単純な音の距離減衰を使った場合に限っては超音波の方が余裕で精度は高かった。
1月末が論文提出締め切りだったため、そこから大慌てでテーマを変更。年末実家でヒヤヒヤしながら、iPhoneとiPadでの360度どの方向でも見られるビデオ会議システムを作り、年明け大学で評価実験、論文を書いたら、結構余裕で終わった。結局約1ヶ月で終わったことになり、何かずっと無駄な時間過ごした気分だ。
PodfileがRubyなので、CoffeeScriptかけるし、ちょろっとRubyを書けるようになっとこうと勉強し始めた。ところがどっこい、なかなか癖があり、1時間でつかめるだろうと思ってたのだが、全くそう簡単にはいかなかった。
一応「書け」って言われたら書けるだろうってレベルまでは勉強したが、こういうのはすぐ忘れるのでメモしておく。
うっかり親のprivateをoverrideしてしまったらprivateメソッドにも依存関係が出てしまい消したり出来なくなる。ということで、内部実装を知らない場合は継承をしない方がよく、委譲を使うのが安全らしい。IntelliJレベルの賢いエディタ使ってたら、回避できそうな問題だけど。ちなみにObjective-Cも同じような問題があるので_からのメソッドは使ったらダメとかなってる。というか内部実装が見えないケース数で考えるとObjective-Cの方が深刻だな…
二重コロンといえばC++だとかPHPのクラスのstaticなのにアクセスするときのアレを想像してしまうが…普通にインスタンスへのアクセサみたい。ドットと二重コロンでそこまで違いはないみたいだけど二重コロンは定数へのアクセスも使えるらしい。classやmoduleは定数。
なんか同じそうなのがたくさんある。こういうのが一番困る…まぁ、ざっと見てる感じ==さえちゃんとしてれば使えそうだ。
で、結論なんだけど、どうも遅いらしいし、どうしてもRuby on Railsを使いたい人だけ使えばいいと思った。良さは凄く分かるけど。
気になって調べたけど、Node.jsが速い!
追記(2015/11/08): なんだかんだで開発ツール作るときは真っ先にRuby使うようになった。ライブラリの豊富さがすごいしなんとなくで動く。
インターンでは初にも関わらずAndroidのアプリ開発のヘルプをしていたのだが、プッシュ通知の実装は結構手間取った。基本的にここを見ながらやったのだが、ここに書いてるGoogle Play Servicesとやらが登場したばかりだったので情報が少なかったこと(当時はこのサイトの記事はGoogle Play Servicesを使ったものではなかった)や、従来のGoogle Cloud Messagingを使う方法はライブラリの出来があまりよろしくなかったこと、Android SDKはほんと初めてだった上にJavaは2週間ぐらい授業で勉強した程度だったことから、悩みに悩んだ。更にSumallyの場合は開発用と本番用のアプリがあるため、その住み分けなども考えなければならなかった。
最初はGCMしか存在を知らず、それで実装していた。割と実装方法は簡単だったけど、deprecatedとか書いてるし、Androidマニフェストを開発環境と本番用とで書き換えても同じところに取りに行くし(要はライブラリがAndroidマニフェストを見ていない)で、こりゃダメだ…となった。ちなみにAndroid開発をはじめて1週間ぐらいは、デバッガーという超便利なものを知らなかったのも苦労した原因のひとつだ…
その後、Google Play Servicesを使う方法を見つけたので実装。こちらは前者に比べて実装が面倒くさかったけど、ライブラリがしっかりしていた(印象だけど…)ので、開発用と本番用とで悩むことはなかった。ただ、これを使うには、ユーザーが「Google Play開発者サービス」とやらをインストール、または更新しないといけなくなる(右のようなアラートが出る)。名前がおかしいし、比較的新しいものなのでほとんどの端末でアラートが出るだろうしで、入れないユーザーが出てきて、プッシュ通知出来ないのは避けたいということに。更にはググったら分かるが、このGoogle Play開発者サービスのアプリに対する評価はかなり低い。「なんで勝手に入ってるの?」とかいう人も多く、わざわざ停止させているユーザーもいるようだ。
ということでdeprecatedだけど、従来のGCMを使う方法に戻した。再度、上の問題に突き当たり、悩みに悩んで…Androidマニフェストを参照する(はず)のクラスをextendsして@overrideして何とかした。
iOSとは違い、Androidは様々な方法でプッシュ通知を表示できる。というかPush通知を受け取ったらそれを表示するコードや音を出すとか振動を指せるとかLEDをピカピカさせるとかまでオプションを付けて実装しないといけない。Sumally for Androidでは、プッシュ通知時のサーバーからの値によって、表示方法を切り替えられたり、振動やLEDをつけたりとできたり、通知の画面から直接ユーザーをフォローできたりという実装をした。今思えば頑張ったなぁ…プッシュ通知。
openFrameworksで加速度情報やらジャイロのデータを使って色々しようとなったとき、ofxAccelerometerを使うのが普通と思っていたけど、どうもうまくデータが取れないし、ブラックボックスだしで、そんな複雑なこと考えずに、iOSの場合どうせObjective-C++なのだから、最初からCoreMotionを使った方が楽だと言うことに気付いた。
と言ったらもうこれ以上何も説明することがないような気がするけど、一応コードを書いておく。CoreMotion.frameworkの追加をお忘れなく。今回はデバイスの姿勢だけだけど、他にも色々取れる。
あとどうやら2つ以上startDeviceMotionUpdatesするともっさりするらしいので、ちゃんと止めるべきときにには止めましょう。
一部の方々にはお伝えしたが、実はこの夏、タイトルの通りのことになっていた。ひとつ下の就活が始まったことだし、そろそろ報告しないと…
夏休み2ヶ月程、九州のゆっくりした時間の流れの中でぼーっとしたまま社会人になることに不安を感じた僕は、修行を積みに、今日本で最もいけてるサービス運営会社で有名なSumallyのインターンシップに参加した。南青山の一軒家のオフィス(Sumally Haus)に住み込みで、コーポレートサイトの実装 / メールの実装 / Androidアプリの実装 / iOSアプリのバグ修正などなどをした。Androidアプリについては触ったこともなかったのだが、この期間、色々と機能をぶち込んだ。keitapさんの無茶ぶりは毎日冴えており、どんどんタスクが降ってくるもので、僕は、keitapさんが「ヤバイ!もう中元寺くんにやらせることが!ない!」と、困ってるシーンを想像し、目標にして、毎日猛烈にカタカタした。終わりなんてあるはずないのに…まぁでも、お陰様でスキルの伸びっぷりは我ながら凄かったと思う。
その期間中のある日、色々と事情ありで朝からピリピリモードだったkeitapさんから、社員面談の最後にSumally Hausの2階に呼び出された。ただインターンで居るだけなのに、呼び出しとなると色々と不安で、「今朝起きるのが遅かったことかな…?」など謝罪文を考えながら、恐る恐る「Androidの引っ張って更新実装できましたよー」とか良いニュースを持って2階へ上がった。そんな予想に反して、結構褒められ、「どうよ?Sumallyで働かない?」と言われ、ポカーンとなったシーンははっきり覚えている。
プロダクションへの憧れがあったし、若い内しかできないという考えでいた。そのため「若くて早い時期からプロダクションに参加しないと」と焦っていたのだが、その面談でそれは全然違うことを教えてもらった。「あぁ。確かに。」と思ったし、それから色々と考えるようになり、その頃頻繁にしていた散歩の途中で、深く座り込んで考え事をするようになった。
実際、その時はネガティブな答えをした。その理由に、Sumallyはまだまだスタートアップでこれからのサービスで、それが不安だったことがある。しかしこうやって、色々と考えるようになるにつれ、逆に、そのような重要な時期に22歳で飛び込み、社運を背負うメンバーのひとりとなることができるというのも、凄く貴重な経験だなと思い始めた。それに加え、少なくとも日本では、Sumally程の段階までチャレンジな段階に来ているサービスはそうそうないこと、やりがいなどから、入社を決意した。他にも、自分の欲しいスキルを伸ばす環境や、そういう将来のことについてなど、考えたことはまだまだたくさんあるが、楽しく、厳しく、速くと、とても「部活」みたいな感覚での職場の環境の居心地が良かったのだと思う。実際、約10名しかいない会社なのに、それぞれの分野でのスペシャリストが居て、会社内に足りない技術があれば、質問しに行ったりするつてがある、半端ない環境だと思う。
一方で、未だにプロダクションへの興味というか、結局進路はサービスに決めたわけだし、憧れという方が近いのかもだが、そういうのはあるし、未練がないとは言えないが、そんなことより、まだまだ伸びてゆくであろうSumallyを、これから成長させていくメンバーに加わることは凄く楽しみだ。
最後に、遅い時期にも関わらず、内定辞退を了承してくださった、元内定先の関係者様には、深く謝罪、及び、了承してくださったことに感謝致します。
全てとはいえないが、Android端末で<div>や<p>などのブロック要素の幅が勝手に狭まる問題を見つけた。Androidを持っていないので、検証などできていないが、恐らくDPIなどの計算に、バグがあるのだと思う。対策方法を見つけたので、困っている方が居たらぜひ。
幅が勝手に狭まってしまう要素に対し、背景を指定すれば、なぜか分からないが直る。ただ、transparentやrgba(0,0,0,0)などの透明色の指定ではダメだった。上の対処法では、Base64に変換した透明なGIFを指定している。検証はきちんとできていないが、多分これでいける。いけなかったら色を指定するなどするといけるかも。
iOS6からiOS7になり、かなりの変更があった。特にデザインに関する変更点が多く、iOS6向けに作ったアプリをそのままiOS7用にビルドすると、かなりの表示崩れが出る。iOS7対応の作業をし始めた時、まったく参考資料がなかったが、血眼で探しまくって、収集できたサイトをペタペタ貼っとく。
iOS7である場合とそうでない場合の判別をすることが多くなるため、ページの下の方にあるマクロがとても役にたつ。
iOS7のナビゲーションバーの仕様が最悪なので、iOS7対応をする上で、誰もが通る道だ。対応手段がかなりまとめられているかなり良いサイト。
ボタンの位置がずれるのだ。原因特定で、かなり悩んだ。
そもそもUITableViewCellのdrawRectは上書きすべきではないという話。iOS6までは、特に問題なかったが、ついにiOS7ではNGになった。ちなみに処理は走るため、UITableViewCellの背景色の塗りつぶし処理のタイミングが変わったのだろうと予想している。drawRectをどうしても使いたい場合は、セルの背景色を透明にすればいける。ちなみに、iOS7でセルのデフォルトの背景色が白になっているっぽい。
UIStatusBarも大きく変更されていて、初期設定では、setStatusBarStyleで変わらないようになっている。まぁ整理したというわけだね。
これ読んだら、バッチリいけるけど、要はアルファ値がないとブラー効果がでなくなりました、ということ。
対応作業の中で、一番面倒なのは、やはり潜る問題で、これはひとつひとつちまちま対応するしかなさそう。特に、ブラー効果を出したい場合は、他のViewの位置なども変える必要が出てくるので、とても面倒な作業になる。その他にも、特に、UITableViewまわりの変更点が多いなと感じた。
UIRefreshControlをUITableViewにaddSubViewすると使えるとよく見かけるが、これでは更新の瞬間カクツキが生じてしまい、気持ちが悪く、それへの対応方法だ。恐らく、単純にaddSubViewするだけではダメなのだろう。この方法から、現状、UIRefreshControlはUITableView向けにしかできていないことが分かるのだが、それをどうにかして他でも不具合なく使う方法を探している。単純にaddSubViewではない方法、誰か教えて下さい。
追記(2014/05/10): UIRefreshControlのガクッとなる問題はどうしようもないことが分かった。自分でRefreshControlを作るしかなさそう。
ブログなんてどうせ書かないからと、やめていたのだが、やっぱ書きたくなることがあることに気付いたので、何度目か分からないが作りなおした。更新頻度はともかく、きちんと続けてゆく予定だ。多分、日記や作ったものの紹介だとかの他に、新しい発見だとか、凄いものの紹介だとか、現状の不満だとかの、140字で収まらないものを投稿していくと思う。