blog.haranicle.net

Collabo Tips #1 にいってきたよ

FiNCさんで開催されたCollabo Tipsという勉強会に行ってきました。

connpass

Collabo Tips(コラボチップス) – connpass

  • デザイナとエンジニアは切っても切り離せない職業
  • 垣根を取り払いたい人のための勉強会

Togetter

@koogawaさんがまとめてくださっています。仕事早い!
2016/8/3 #CollaboTips(コラボチップス) – Togetterまとめ

グラフィックレコーディング

会場ではリアルタイムに発表内容が絵でまとめられていました。すごい!
IMG_7452 2

ストレッチ

勉強会の前にストレッチタイムがありました。体が伸びて気持ちよかったです。

LT

お互いのツールを使ってみよう

Motoki Naritaさん
iOSエンジニア

  • マサカリ禁止!
  • エンジニア/デザイナそれぞれが大切にしていることを知ることが大事
  • ツールが大事なのでは
    • Xcode, Sketch, PhotoShop…
  • エンジニアもデザイナも仕事は、問題を解決すること, 良い解決方法を提供すること
  • お互いのツールを使ってみる
    • 完璧に使える必要はない
  • エンジニア/デザイナどっちがやるべきなのか曖昧な仕事はいっぱいある
    • お互いに歩み寄ると、お互いにできる仕事が多くなる!

デザイナーさん向けSizeClass

yucovin(SAKUMA Nino)さん
デザイナ兼iOSアプリエンジニア

  • 同じようなデザインでも、画面サイズによって制約を変えたいことがある
  • 工数やメンテナンスのしやすさも大事
  • SizeClassを使えばStoryboardを使って画面サイズごとに異なる制約を変えることができる
  • SizeClass使ってみよう!
  • Xcode8でももっと便利になっている

エンジニア主導でMaterial Design化を進めた話

Hiroyuki Setoさん
ノハナ Androidエンジニア

エンジニアでもデザインがちょっと楽しくなるフォントのはなし

cocoponさん
Developer/Designer

  • あるある
    • デザイナがラインハイトの変更をしたいけど、エンジニアがめんどくさがって変更しない
    • もったいない
  • エンジニアがフォント沼にはまった話
  • エンジニアリングもデザイナも同じぐらい深くて面白い
  • お互いの領域のおもしろさを知って

コードが書けるようになる

yoneappさん
フリーランス iOS & Rails

  • コードが書けるとは
    • 自分が作りたいものが作れること
    • 報酬がもらえるようになること
  • Webは難度低〜高の技術が必要
    • まずは、HTML+CSSからはじめてみよう
  • アプリは難度中〜高の技術が必要
  • バックエンドにチャレンジにするには、サービスをリリースしてみるといい
  • エンジニアとデザイナで教え合うことが大事

GitHubすら知らなかったデザイナーがデプロイするまでなったわけ

Ryo Usamiさん
Wantedly デザイナ

  • Wantedlyでもデザイナもコードを書く
    • Rails
    • iOS
    • Android
  • 何のためにデザイナがデプロイするのか
    • 仕組みとして良いUIを保てるようにするため
  • Development Flow
    • デプロイする前にデザイナのチェックがる
    • UILGだとデプロイ
    • デザインの保守のためにコードの提案までしていく
  • どうやったらコードを読めるようになるのか
    • issueはすべて、diffも9割みている
  • すべては良いプロダクトにするため

Creativeな時間を確保せよ!

Kenさん
Androidエンジニア

  • FiNC
  • Creativeな時間を確保する
  • Creativeとは”こだわり”
  • Less is more
  • iPhone4sは名機
    • デザインを分解すると少ないパーツでできている
  • アプリで考えると
    • いろんなコンポーネントを作りまくらずに、できるだけ共通化する
  • God is in detail
    • 細かいところに時間をかけられる様にしておく
  • 共通化によりこだわるべきところが見えてくる
  • 共通化はエンジニアとデザイナが協力しないといけない

自分でできることを増やしてみるというのは結構楽しかったという新米iOS開発者の小話

ReikoGotouさん

  • 先方がデザインして、開発だけ担当している
  • デザインがイケてなくて開発のモチベが上がらないことがある
  • デザイナには…
    • HIGを読んでもらう
    • 全部だと200ページ以上あって大変なので、読んで欲しい場所を指定した
    • iOS標準のアプリを使ってもらう
    • そこに正解のデザインがある
  • 企画xデザインの段階でHIGを理解してもらっていると開発も楽
  • デザイン部に頼むより自分でやったほうが速いことがある
    • 素材の書き出しなど、デザインの変更がないものは自分でやったほうが速い
    • Sketchを使ってみた
  • Sketch
    • iOSアプリ設計のために作られたようなツール
    • 学習時間は2時間ですむくらい簡単

共創をドライブさせる

共創をドライブさせる、ユーザーを向いたモノづくり

yoshiki_kojima_7さん

  • technical-creator.comというブログを書いている
  • モバイルアプリの開発現場は徐々に肥大化してきている
  • コラボレーションツールが大事
    • コミュニケーション
    • ドキュメント共有
    • プロジェクト・タスク管理
    • プロトタイピング
  • ツールの導入では根本的な問題は解決しない
  • チームを支えるのはユーザ
  • ユーザには簡単に会える
  • いいものを作りたい
    • 広告主、上司、株主 < ユーザ
  • アベンジャーズを目指そう!
  • iOSエンジニア募集中

1年間で起きたデザイナーとエンジニアの変化

h_matsuhisaさん

  • みんなのウエディング
  • みんなの大切な日を増やす
  • 買収を契機にいろいろ変わった
    • サービスのParlからRailsに移行
    • ユーザ価値の設計をGitHubのissue上で議論している
    • プロトタイプの導入
    • デザインガイドライン
    • アジャイル
    • 1週間スプリント
    • できるだけ小さいチームで開発する
  • 起きた変化を考える
    • エンジニアがデザイナの仕事をするようになった
    • デザイナはより深いことができるようになった

デザイナーだけどコーディングできないとダメ?

mazco/matsu_saoさん
デザイナ

  • はてな
  • コーディングをはじめたのは1年前
  • デザイナーもコーディングできないといけないのか?
    • どっちでも良いと思う
    • プロに任せたほうが良いのでは
  • 問題点の整理が大事
  • 会社と個人の興味が一致しているので、いまはコーディングしている
  • できることが増えると話題がひろがって楽しい!

エンジニアからデザイナーさんへお願いしたいこと

tomomasa_masuzawaさん
エンジニア

  • フォントは大きめに、できればシステム設定にも対応してほしい
    • 画面にいっぱい情報を出すために小さくするのはやめて
    • IBのデフォルト値は17pt
  • 独自フォントはやめたほうがいい
    • Dynamic Typeが動かない
  • ボタンには文字を入れましょう
    • iOSでは文字が入っている
    • Androidでは文字が入っていない
    • プラットフォームごとの違いも考慮しよう
  • iOSとAndroidの操作系は別物なのでUIを別にしよう
  • 見えない機能はつかわれない
      - Long Pressは気づかれない

新米デザイナーが学んだこと

おかぴーさん
デザイナ

  • 高校の時は仕訳帳ばかり書いていた
  • デザイナーになって苦労してきたこと
    • 指示書がぐちゃぐちゃ
    • 素材の命名がぐちゃぐちゃ
    • 素材のサイズが間違っている
  • 開発スピードが遅くなる
  • ガイドライン
    • Zeplinを使ってデザイン指示
  • コミュニケーション
    • 密に 席が近い
    • 漏れなく デザインレビュー会
    • 丁寧に 指示書
  • エンジニアもデザイナに寄り添ってほしい

Sketchとその仲間たち

Daiki Matsudateさん
iOSエンジニア

  • Zeplin
    • エンジニアがほしい情報が全てある
  • Simpli
    • エンジニアがUIを作るには時間がかかる
    • 自動でUIパーツを作ってくれる
    • StoryboardにD&Dで配置するだけでいい
    • 画像を自動でAssets Catalogに入れてくれるので便利

エンジニアには本当にデザインのセンスが無いのか?

akio0911さん
iOSエンジニア

  • デザインの原則
  • ソースコードに似ている!
    • 反復 = シンタックス
    • 整列 = インデント
  • エンジニアはきれいなコードを書きたいと思っている
    • この感覚をデザインに持ち込めばいい
  • アプリのアイコンを作ってみた
    • 作ればわかる

懇親会

豪華なケータリングと🍺をいただきました。ごちそうさまでした!
IMG_7453

cocoponさんの発表で紹介されていた本を見せていただきました(もう売ってないらしい…)
IMG_7457

FiNCさんのオフィスを見学させていただきました。
おしゃれオフィスで、エンジニアには高級な机と椅子が提供されるらしい。(羨ましい..!)

オフィス内に簡単なジムのようなものがあって、仕事終わりに運動できるらしいです。(羨ましい..!!!)
IMG_7460

Pocket

potatotips#26に行ってきたよ

ブログまとめ枠で参加したのでまとめます。

connpass

potatotips #26 (iOS/Android開発Tips共有会) – connpass

会場はSupershipさん

supership

青山にあるオシャレなオフィスでした。
会場ではお寿司や、オードブル、ビールが用意されていました!
おいしかったです!

発表

Can we live in pure Swift world?

@TachibanaKaoruさん
株式会社VOYAGE GROUP所属

  • KotlinでAndroidアプリ作ってる!
  • iOS/Androidエンジニア募集中!
  • Swift書きたい
    • 既存アプリだとobjcとSwift共存してたりする
      • objcとSwiftを共存させていると困ることがある
        • Swiftの一部機能はobjcからは使えないなど
  • pure Swiftでも困ることもある
    • selector指定ができない
      • コンパイルは通るが unrecognized selector になる
    • objcから呼べないものはselector指定ができない
      • objcから呼べるかどうかは、objcのmember tableに入っているかどうかで決まる
      • 中間ファイルを見るとobjcから呼べるかどうかわかりやすい
        • objcで #import "MyProduct-Swift.h" と書いて、コマンド+クリックするとXcodeで見れる

感想

  • objcから見えるSwiftのメソッドでラップしてあげれば、selector指定できるようになりそうだと思いました
  • Swiftで書くとobjcにはなかった問題が発生してしまうのは、あるあるネタですね

5分でわかるTextKit

@hayashi311さん
bitFlyer所属

  • (図が多くてうまくまとめられませんでした)
  • iOSエンジニア募集中
  • TextKitで文字をレンダリングしている
  • グリフ: レンダリングするときの一番小さい単位
  • 文字とグリフは 1:1 ではない
  • 文字列 != グリフ
  • レイアウト = グリフの座標
  • NSLayoutManagerがレイアウトの描画や、タッチイベント(どの文字が選択されたか)なども管理している
  • 自分で実装しようとすると大変なのでTextKitはえらい

感想

  • グリフとレイアウト、全く意識していませんでしたが、非常に興味深い内容でした
  • こういう理解しにくい概念を図つきで解説してくれる発表はありがたいです

PUSH通知の許可をよりもらうためのUI考察など

@yoneappさん
iOS & Rails フリーランス

  • Techinsightをリリースした!
  • 今からParseは無い
  • OneSignalを使うことにした
    • 完全無料
  • 不安点
    • Push通知が遅れることがある
    • ビジネスモデルが不明だからいつまで継続するかわからない
  • Push通知の許可について
    • UIパターンを調べてみました
         – 唐突に表示系
         – 事前説明系
         – 事前説明 + 擬似アラート系
         – 通知許可許可系
    • どのパターンが一番効果が高いのかわからない
    • 唐突系以外は、Push設定をリセットされたときのことも考えないといけない

感想

  • 実際に試して、結果がどうなるかが気になる内容でした
  • 意外とユーザはPush通知の許可ダイアログについて理解しているのかもしれないなと思いました

NSURLProtectionSpace Authentication Methods

@niwatakoさん
はてな所属

  • はてなからは2人のエンジニアがtry!Swiftで登壇!
  • ちゃんと認証のdelegateを扱ってないとWKWebViewが真っ白になることがある
  • 認証の種類を確認(チャレンジするという)
  • 認証の種類がいっぱいある
  • Webブラウザを作る場合以外は、全部サポートしなくてもいい
    • HTMLFormは実装する必要がない事が多い
    • iOS8,9で挙動が異なることがあるので注意
  • 結局Appleのサンプルコードを見るのがわかりやすい
  • 続きは次回yidevで!

感想

  • UIWebViewではなかった、WKWebViewのつらみのお話でした
  • 5分じゃ理解しきれなかったので、yidevでの発表が楽しみです

皆に相談したい「私の現場での試行錯誤後のiOS開発方針」

私の現場での試行錯誤後のiOS開発方針 – Qiita

@satoshi0212さん

  • 開発方針についてシェアしながら相談したい
  • 未だにMRC
  • オープンソース試用は控えめで直接プロジェクトに追加
  • 基本的にviewDidLoad内で画面レイアウト生成
  • 画面表示変更用メソッドrefreshを用意し、それを使用 <- protocol
  • はてなでは2日間でデザイナにStoryboardの使い方を教えて、デザイナがStoryboardをいじっているチームもある

感想

  • 個人的に、viewをカスタムするコードは量が多くなるし、テストできないコードだと思うのでできるだけstroyboardに書きたいかなと思いました
  • storyboardコンフリクトはそんなに怖くないので、バンバンstoryboard活用していけばいいと思います

脱swift初心者するための2つのきっかけ

@mogmetさん

  • 関数型言語を使ってみよう
  • {}を減らそう
    • guardを使って早期リターンするとインデントを減らせる
    • ifのかわりにwhereを使って、インデントを減らせる

感想

  • @mogmetさんのバッチリスーツかっこよかったです
  • whereでインデントを減らすというのは、いいアイデアなので使っていこうと思います

HTTPリクエストをフックしてハック

@yukiasaiさん
マネーフォワード所属

  • iOS,Android,Rubyのエンジニア募集中!
  • WebAPIできてないけどアプリ側開発しないといけない
  • WebAPIをモックできるKageeを作った
    • https://github.com/yukiasai/Kagee
  • NSURLProtocolを使えば、NSURLSessionの通信をモックできる

感想

  • Kagee便利そうだとおもいました
  • ライブラリの使い方だけでなく、仕組みについても理解できたのでよかったです

古き良きsendAction

@tokoromさん

  • UIApplicationのsendAction
    • iPhone OS 2のころからあるメソッド
    • app.sendAction(“hoge”, to:xx, from: sender, forEvent: nil)
      • 使いドコロある?
      • RxSwift使ったほうがいいんじゃない?
    • Responder Chanin in UIKit
      • 奥まった階層でも発火
      • 階層のどこでも受けられる
      • 階層が複雑化する昨今では使いやすいかもしれない
    • インタフェースが古い
      • 引数にObjectを渡しづらい
      • 新しいインタフェースでラッピングすれば使える

感想

  • みんなちがってみんないい
    • UIApplicationのsendAction
    • NSNotificationCenter
    • Delegate
  • どれを採用するかは、好みの問題が大きいと思いました

宣伝

全体の感想

  • iOSはSwift, AndroidはKotlinの話題が多い印象を受けました
  • 一方で、トレンドに流されないコアな話題もあり、勉強になりました
  • 話しやすい雰囲気で、非常に楽しい勉強会でした
  • 運営のみなさま、お疲れ様でした!ありがとうございました!
Pocket

第20回 potatotiosにいってきたよ

potatotips

毎回人気で発表枠でもなかなか参加できない勉強会potatotipsにいってきました。
(発表者枠で申し込んでたけど、抽選に外れて参加できそうになかったのでブログまとめ枠で滑り込みました)

詳細はこちら
【第20回】potatotips(iOS/Android開発Tips共有会) – connpass

会場はVOYAGE GROUPさん。
会場には、ポテトチップス、ピザ、ビールだけでなく寿司まで用意されていて豪勢でした。

発表の数が多くて、タイピングが追いつかなかったのでiOSの発表だけまとめてます。


CoreSpotlight Optimization

@sakmtechさん
VOYAGE GROUPの人

CoreSpotlightとは

  • iOS9新機能の1つ
  • アプリ内の検索結果をSpotlightで表示することができる
  • タイトル、説明、キーワードを設定できる(キーワードは非表示)

どうやったら上に表示されるか

  • タイトル、説明文、キーワードの順で優先してマッチしたものが上に表示される
  • ひらがなで検索した時もカタカナや漢字も検索でマッチする
    (例)なつ->夏,懐 etc..
  • トップヒットに乗るのは1アプリ3つまで
  • 先にインストールしたアプリが上に表示される
  • まだまだbetaなので結果は変わる可能性あり…

watchOS1のアプリをwatchOS2移行する

@mo_to_44さん
ネクストの人

  • watchOS 2 Transition Guideが提供されている(ここに重要な事がさらっと書かれているらしい)
  • watchOS1から2への最大の変更点はWatchのExtensionが動作する場所ががiPhoneからWatchに変更になっていること
  • データストアはiPhoneとwatchの両方にあるようになった
  • iPhoneとwatchのデータを同期するWatch Connectivityを使用する

とにかく明るいCore Spotlight

@yimajoさん
エンジニアアウトプットランキング – Stargazerの人

TweetRainというアプリでニコニコ動画みたいに#potatotipsハッシュタグが付いているTweetがスライドにオーバーレイ表示されていました。

ユーザ目線での使いどころ

  • 電子書籍リーダのタイトル
    • KindleとかiBooks両方に書籍を入れているので、CoreSpotlightで両方を検索できればうれしい
  • サンプル(iOSDayByDayというものがある)
  • キーワードだけじゃなくてEメールなど検索できるものが160個ぐらいある

参考資料(見たほうが良い資料)


英語版リリース前に知っておきたいこと

@horimislimeさん
トレタの人

NSLocalizableString

  • Localizableの使い方をミスると大変
  • こんな風にすると姓名が逆になっちゃうことがある
[NSString stringWithFormat: @&quot;%@ %@&quot;, NSLocalizedString(@&quot;lastName&quot;, @&quot;&quot;),  NSLocalizedString(@&quot;firstName&quot;, @&quot;&quot;)]

NSPersonNameComponents&Formatter

  • アプリを実行しているロケールに応じて、いい感じに姓名の順番を整えてくれる
  • suffixで”Mr”,”Mrs”や”様”などをいい感じにつけられる
  • iOS9からしか使えない

stringsdict

  • 複数の時に〜sをつけたりしないといけない
  • stringsdictを使えばXMLを書いておくだけで、〜sを付けられる

NSDataIntervalFormatter

  • 時刻の区間をいい感じのフォーマットの文字列にできる

画像リソース

  • ButtonにBackground Imageを使っているとボタンのサイズが変わった時に大変
  • 使わない方がいい(文字のタイトルはLabelで!)

Crowdin

  • 翻訳支援サービスCrowdinが便利
  • XLIFFを書き出してアップロードするのみ
  • 外部翻訳者とのコミュニケーションとか進捗管理が楽
  • APIもあるのでCIと連携することもできる

PUSH通知証明書作成ツールを作った

@tomzohさん
デジタルサーカスの人

iOSのPUSH通知のための証明書作成

  • 3ヶ月に1回更新しないといけない
  • Macじゃないとだめ
  • 黒い画面での操作

ツールを作った

  • WebからPush通知の証明書をDLできる
  • Dev/Prod対応
  • テスト送信もできる
  • p12ファイル対応
  • CakePHP製

今日から使える!

monotty


CommandLineTool

@kitasukeさん
メルカリの人

SwiftでCommand Line Tool

  • Xcodeで作ることができる
  • Cathegeのコードを見ると作れる(最初の方のコミットがかなり細かいので、それを追えばわかりやすい)

  • プロジェクト設定のコマンドラインツールのテンプレからは作れない
  • Embedded Content Contains Swift Code for framework targetがデフォルトでNOになっているけどYESにしないとSwiftコードが実行できない

2時間の暗号化済み動画データはどうやって再生するのか

@satoshi_0212さん

問題

  • 2時間の番組はメモリ上に乗るのか
  • 暗号化&復号化が必要
  • オフライン再生

方針

  • 標準のAVPlayerのクラス+HLSを使用する方法
  • ffmpegのコードを使用する方法
  • 納期が短かったため前者を採用

実装

  • 動画ファイルを暗号化キーで暗号化して分割してtsファイルを複数作成
  • tsファイルの再生はAVPlayerで再生できないのでcocoaHttpServerでiPhone内にHTTPサーバを立ててストリーミング再生
  • 再生はAVPlayerにHLSの再生リストを渡すだけでOK
  • 無事にAppStoreに公開できた

SFSafariViewControllerとOAuth

@huinさん
フリルの人

SFSafariViewController

  • Safariと同じだから、使い慣れたインタフェース
  • SafariのCookies情報を利用可能
  • PW/クレジットカードのオートフィル
  • ATSに引っかからない

OAuth認証

  • アプリ内のWebView認証はユーザからみて安全でない
    • JSつかってid/pwを抜いたりできてしまう
  • SafariViewControllerをつかってOAuthしましょう(Appleもこれを推奨しているらしい)

感想

WWDCからしばらくたって、みなさんが収集したiOS9の知見が聞けて非常にためになりました。
ブログまとめ枠で参加すると、枠が空いているし、強制的に集中して聞くようになるので、結構良かったかなと思いました。

Pocket

ベストアプリ勉強会にいってきたよ

今日、SmartNewsさんで開催されたベストアプリ勉強会にいってきたのでメモ。

ベストアプリ勉強会

ベストアプリ勉強会 – connpass
#startups_best_apps

登壇者

株式会社VASILY 村田さん

iQON(アイコン) – コーディネート・レディースファッションアプリ

メンバ構成

iOS x2 ObjC
Android x2 Java
Web x6

DL数はiOSがAndの倍

株式会社Wantedly 杉上さん

Wantedly(ウォンテッドリー)「はたらく」を面白くする

メンバ構成

iOS x4
Android x1
Web x4
Designer x1

株式会社SmartNews 町野さん

SmartNews

前身はCrowsnest。

2つの決断

CrowsnestからSmartNewsに変更するにあたって、2つの決断をした

  • アプリオンリー化
  • パーソナライズをなしに

メンバ構成

社員全体の半分以上は50%以上にする。
全体 x40
エンジニア x20
iOS x2
Android x2
来月引っ越し予定(渋谷 明治神宮寄り)

パネルディスカッション

なぜベストアプリになれたか?

SmartNews

ユーザからの評価はGoogleもAppleも見てるはず。
継続的に使われているかも見ているはず。かっこよさ。

VASILY

2012年当時にないアプリをつくることが出来た。
良くも悪くもプラットフォームのルールに沿ったアプリを作った。
Android特有のUIを採用した。

Wantedly

今までにない価値を提供できた。
UI/UXにこだわった。わくわくしながら使えるようにした。
最新技術をできるだけ早く取り入れた。iOS8の新機能やiPhone6,6plus対応も早めに出せた。

KPIはどうしているか?

Wantedly

ユーザが会社に遊びに行ってかどうかを測定している。
1年間で2倍ぐらいになっている。

VASILY

DAU。女の子が雑誌を持ち歩かなくてもファッションメディアに触れられることが大事なので。

SmartNews

アクションの数/DAU。滞在時間に近い値。競合はゲーム会社。

競合?

SmartNews

ニュースアプリだけが競合ではない。
時間の取り合い。

Wantedly

転職大手が競合だが、違った価値を提供している。

VASILY

zozoのWEARとか、女性が好きそうなアプリ。

グローバル展開は?

Wantedly

linked.inとかfacebookとやりあっていきたい
アジアに向けて展開していきたい。

SmartNews

今、一番力を入れている所。
アメリカに拠点を作っている。
現地のパブリッシャーとやりとりしている。
現地でも採用活動している。

VASILY

海外展開も確実にしていきたい。
1年、2年後ぐらい目標。

海外対応の難しいところは?

VASILY

海外のECサイトのつなぎ込み。
準備は進めているが苦戦している。

Wantedly

ローカライズが大事。
転職に関する考え方が国によって違う。
Androidから参入予定。
サーバは日本に

SmartNews

英語圏からの展開。

開発手法について

VASILY

Androidファースト。
ボタンの色を思い切って変えてみるとか。
機能全体をガッツリ見なおしている。
ストア公開に待ち時間がないのがいい。いっぱい試作できる。

Wantedly

iOSファースト。
海外はAndroidファースト。

SmartNews

特に何ファーストかは決めていない。
実験的なことは、Androidでやってる。

リリースマネジメント

SmartNews

リリース日は決めているけど、柔軟に。
Android、iOSともにTravisで自動ビルドしている。
リリース前にQA期間をとっている。

VASILY

Androidは毎週リリース。
週のはじめにタスク決定。
両方自動ビルド。常に開発者の端末には最新のビルドがある状態に。

Wantedly

Pjを発足させる。2週間-2,3ヶ月ぐらい。
Pjごとに人をアサイン。
2週間Pjなら2,3日、2,3ヶ月なら1週間ぐらいQA期間。
テストコードはかけていない。
人手でテストしている。

デザイナとの協業はどうしているか?

SmartNews

デザイナ専業の人はいない。
iOSのエンジニアが元デザイナ。
アドバイザがいる。

Wantedly

エンジニア、デザイナが同一人物。

VASILY

フルタイム2人+フリーランス1人+fladdictさん(週1)
イメージで発散させて、デザイナ、エンジニアが協力して実現していく。

マネタイズは?

Wantedly

募集をかける企業からお金をもらっている。
ユーザからはお金をとっていない。

SmartNews

広告用のサービスがある。
Qiitaチーム、Slackとかを全員同じアカウントで使っている。

VASILY

提携先ECサイトからお金をもらっている。数億/月。
広告事業。

プラットフォーマとのミーティング

SmartNews

ベストアプリ取るにあたってプラットフォーマとの付き合いも大事。

Wantedly

Swiftでアプリを出すときにサポートがあった。

VASILY

稀にミーティングが有る。

プロモーションはどうしているのか

VASILY

TVCMをやっていた。ユーザからの誘い込みをやりたい。

Wantedly

応援。応援とAppStoreからの流入が半々ぐらい。

SmartNews

とってきたユーザをいかに逃さないかに注力している。

ユーザの行動追跡はどうしているか

SmartNews

横スワイプの数。PV。
Google Analyticsと自前ので計測。

VASILY

何番目のカードがLIKEされたかなど、細かい行動を取得している。

Wantedly

Google Analyticsを使っている。
栞では、記事を読むのにどれくらい時間をつかっているか計測。
アプリによって異なる。

ベストアプリをとるためのアドバイス

SmartNews

ユーザに対して向き合うこと。

VASILY

プラットフォームのいうことをきくだけでなく、ユーザのためにツールとして使用する。

Wantedly

作っていてわくわくするものが作れていること。

感想

いつもつかってるアプリの開発者の人の話がいっぱい聞けて良かったです。
もっと技術よりな話もききたかったなぁ。

Pocket

WatchKitでWKInterfaceImageを使ってアニメーション

この投稿はWatchKit Advent Calendar 2014の13日目の記事です。

WKInterfaceImageとは

WatchKitで画像を表示するためのクラスです。
単に画像を表示するだけでなく、アニメーションさせるための仕組みもあります。

静的な画像を使用したアニメーション

静的な画像を用いてパラパラ漫画のようにアニメーションさせる場合は、Watch AppのStoryboardとアセットカタログだけで実装できます。

動作イメージ

moonanime
※シミュレータではもうちょっとぬるぬる動きます。

アセットカタログ

アニメーションさせたい画像を下図のように、<画像名><連番(0はじまり)>のImage Setを作成します。

xcassets

※Xode6.1のスクリーンショットです。

Storyboard

WKInterfaceImageをInterface Controllerに配置し、プロパティに以下のように設定します。

Image:<画像名>
※連番は含めないので注意
Animate:Yes
Duration:1コマを表示する時間(秒)
Animate on Load:チェック

これだけでパラパラ漫画のようにアニメーションできます。

再生制御

WKInterfaceImageの以下のメソッドを使って、再生の制御をすることもできます。

動的な画像を使用したアニメーション

WatchKit Extension側でUIImageを動的に生成して、WKInterfaceImageでApple Watchに表示することもできます。

今回は1秒ごとにランダムな色で塗りつぶされたUIImageを生成し、Apple Watchで表示してみました。

動作イメージ

dynamicanime

UIImage作成処理

func generateImage() -> UIImage {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(100, 100), false, 0)
    let context = UIGraphicsGetCurrentContext()
    
    func colorValue() -> CGFloat{
        return CGFloat(arc4random_uniform(255)) / 255.0
    }
    
    CGContextSetRGBFillColor(context, colorValue(), colorValue(), colorValue(), 1)
    
    CGContextFillRect(context, CGRectMake(0, 0, 100, 100))
    
    let generatedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return generatedImage
}

タイマーの設定

var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateImage", userInfo: nil, repeats: true)

func update() {
    // dynamicImageはWatch AppにあるWKInterfaceImageをOutletで参照したもの。
    dynamicImage.setImage(generateImage())
}

これだけ!

まとめ

現状のWatchKitでは、ダイナミックに画面を更新するには、WKInterfaceImageを使う必要がありそうです。
動的にUIImageを作る方法をしっかりとマスターしておいたほうが良いですね。

参考

宣伝

Swiftでカスタムキーボードアプリ作りました。買ってね!
特殊文字キーボード

Pocket

iOSでAppExtensionを使わずにカスタムキーボード

この投稿はiOS Advent Calendar 2014の13日目の記事です。

こんにちは。13日目担当のharanicleです。
先にあやまっておきますが、小ネタです。。

iOS8のカスタムキーボード

iOS8になってAppExtensionという仕組みで、カスタムキーボードを作成できるようになりました。
僕も1つカスタムキーボードアプリをリリースしています。
良かったら買ってね!

特殊文字キーボード

カスタムキーボードは便利だけど、自分のアプリだけで使えるカスタムキーボードがほしい!
カスタムキーボードもいいけど、標準キーボードが一番使いやすい!
そうだ、標準キーボードを拡張すればいいんだ!という奇特な人のためにこんなものを作ってみました。

customkeyboard

解説

UITextEffectsWindow

UITextEffectsWindow

iOSアプリのキーボードは、UITextEffectsWindowという、
AppDelegateが持っているUIWindow(簡単のためメインウインドウと
呼びます)とは、別のUIWindowで表示されます。
なので、キーボードの上に何かを表示するためには、
メインウインドウとは別のUIWindow(簡単のためにサブウインドウと呼びます)
を作成し、UITextEffectsWindowの上にサブウインドウを表示する必要があります。

サブウインドウの開閉

UIWindowを開く

UIWindowを開く処理のコードです。
sushiWindowを作成し、windowLevelをUIWindowLevelNormalより少し大きい値をセットして、UITextEffectsWindowよりも上にsushiWindowを表示しています。
objc_setAssociatedObjectでsushiWindowのオーナーを設定しています。
sushiWindowは閉じるときにnilを代入して開放したいのでOptional型にしています。
また、windowにお寿司の絵文字を入力できるボタンを設置しています。
(ゴリゴリのハードコーディングですみません…)

func openSushiWindow() {
    sushiWindow = UIWindow(frame: CGRect(x: 230, y: 621, width: 42, height:42))
    sushiWindow?.windowLevel = UIWindowLevelNormal + 5
    sushiWindow?.makeKeyAndVisible()
    sushiWindow?.addSubview(sushiButton as UIView)
    sushiWindow?.backgroundColor = UIColor.orangeColor()
    
    objc_setAssociatedObject(UIApplication.sharedApplication(), &sushiWindowKey, sushiWindow, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
}

UIWindowを閉じる

objc_setAssociatedObjectでnilをセットして、サブウインドウの所有権を開放しています。
sushiWindowにnilを代入してオブジェクトを開放しています。

func closeShushiWindow() {
    // サブウインドウを破棄
    objc_setAssociatedObject(UIApplication.sharedApplication(), &sushiWindowKey, nil, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
    sushiWindow = nil
    
    // メインウインドウをキーウインドウにする。
    UIApplication.sharedApplication().windows.first?.makeKeyAndVisible()
}

キーボード表示、非表示のイベント

NSNotificationCenterで取得できます。

Observerの設定

キーボード表示、非表示のイベントを受け取るObserverの設定と除去です。
今回は、viewDidAppearとviewDidDisappearで実行しました。
キーボード表示時にサブウインドウを開き、非表示時にサブウインドウを閉じるようにしました。

override func viewDidAppear(animated: Bool) {
    // キーボード表示、非表示の通知を受け取る。
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardDidShow:", name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardDidHide:", name: UIKeyboardDidHideNotification, object: nil)
}

override func viewDidDisappear(animated: Bool) {
    // 通知を受け取らないようにする。
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

/**
キーボードが表示された時の処理
:param: notificaiton 通知
*/
func keyboardDidShow(notificaiton:NSNotification) {
    println(__FUNCTION__)
    openSushiWindow()
}

/**
キーボードが非表示になった時の処理
:param: notificaiton 通知
*/
func keyboardDidHide(notificaiton:NSNotification) {
    println(__FUNCTION__)
    closeShushiWindow()
}

サンプルコード

以下に今回のコードを置いておきます。
haranicle/CustomKeyboardWithoutExtension

まとめ

この方法だとAppExtensionを使っていないので、iOS7以下でも使用できますね。
きっと、LINEのスタンプを選択するUIはこの方法でやってるんだと思います。

参考

Pocket

Apple WatchのNotification画面のカスタマイズについて

この投稿はWatchKit Advent Calendar 2014の10日目の記事です。

Custom Notification Interfaces

Apple Watchのnotificationの画面は2種類あります。
詳しくは以下参照。
Apple WatchでのNotification受け取りについて | blog.haranicle.net

Watch Appのターゲットを作るときにNotificationにチェックを入れておくと、Storyboardに以下のようなものが出来上がります。

notification_static_dynamic

Dynamicの方はOptionalなので削除することもできます。
また、削除したあとに、以下の手順で手動で作ることもできます。

  • Interface ControllerをStoryboardを配置し、Staticから配置した Interface ControllerにSegueを伸ばし、”dynamic controller interface”をクリック
  • または、後述のカテゴリ編集画面のチェックボックスで追加することもできます

NotificationはGlanceと異なり、1つのWatch Appで複数持つことができます。

Notificationが届くと、WatchKitはDynamicのInterfaceを表示しようとします。
あなたがDynamicのInterfaceを提供しなかった場合、または何らかの理由でDynamicのInterfaceが利用できない場合は、Staticのinterfaceを表示します。
また、あなたがStaticのInterfaceを表示するように明示することもできます。
DynamicのInterfaceを構成するためには以下のメソッドを呼び出す必要があります。

  • didReceiveRemoteNotification:withCompletion:
  • didReceiveLocalNotification:withCompletion:

これらのメソッドが”WKUserNotificationInterfaceTypeDefault”を返すと、明示的にStaticのInterfaceを表示することができます。

Configuring the Notification Type of a Custom Interface

各NotificationのInterfaceは、Apple Watchにいつ使用するかを教えるために、割り当てられたNotificationタイプを持っている必要があります。
Notificationはカテゴリの値をPayloadに含むことができます。
もし、Notificationがカテゴリの値を含んでいない場合は、デフォルトのNotificationの画面を表示します。

届いたNotificationとInterfaceを対応付けるために、それぞれに同じカテゴリの値を設定する必要があります。
Interfaceのカテゴリの値はStoryboardで設定できます。
Nameの値は一意である必要があります。

notification_type_config

リモートNotificationを生成するときに、Payload内にカテゴリの値を含めます。
カテゴリの値はStoryboardで指定したものと同じである必要があります。

Configuring the Static Notification Interface

StaticなNotificationのInterfaceを作る上でのルールは以下です。

  • すべての画像はWatch Appのバンドルに含めなければいけません。
  • Interfaceに操作できる何か、テーブル、地図を含めてはいけません。
  • InterfaceのnotificationAlertLabel outletはLabelに接続されていなければいけません。そのLabelのテキストはNotificationのメッセージがセットされます。その他のラベルの文字はStoryboardで設定した値しか表示できません。(!?)

StaticなNotificationのLabelと画像は変更できません。(だからStaticなのか!)

notification_design

Configuring a Dynamic Notification Interface

DynamicなNotificationのInterfaceを実装するためにはWKUserNotificationInterfaceControllerのサブクラスを作成する必要があります。

Designing Your Dynamic Interface

WKUserNotificationInterfaceControllerのサブクラスで実行時にLabel、画像、その他のオブジェクトをOutlet経由で変更することができます。
Notificationをタップすると、Watch Appが起動するので、インタラクティブなコントロールを含むべきではありません。

  • 基本的にLabel、画像、グループ、セパレータを使用してください。
  • テーブルや地図を含むこともできます。
  • ボタンやスイッチ、その他のインタラクティブなコントロールを含めないでください。

Configuring Your Dynamic Interface at Runtime

初期化後、WatchKitはあなたのNotificationInterfaceControllerの以下のメソッドにPayloadのデータを渡します。
このメソッド内で渡されたデータに対応するようにInterfaceを書き換えます。

  • Remote Notificationの場合 didReceiveRemoteNotification:withCompletion:
  • Local Notificationの場合 didReceiveLocalNotification:withCompletion:

このメソッドでInterfaceの書き換えがおわったら、WatchKitにInterfaceの準備が完了したことを伝えるために、Completionハンドラブロックを実行する必要があります。

notification_event_cycle_2x

didReceiveRemoteNotification:withCompletion:の実装例です。

- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler {
    // Get the aps dictionary from the payload.
    NSDictionary* apsDict = [remoteNotification objectForKey:apsKeyString];
    // Retrieve the title of the invitation.
    NSString* titleString = [apsDict objectForKey:titleKeyString];
    [self.titleLabel setText:titleString];
    // Extract the date and time from the custom section of the payload.
    // The date/time information is stored as the number of seconds since 1970.
    NSDictionary* customDataDict = [remoteNotification objectForKey:customDataKey];
    NSNumber* dateValue = [customDataDict objectForKey:invitationDateKey];
    NSDate* inviteDate = [NSDate dateWithTimeIntervalSince1970:[dateValue doubleValue]];
    // Format the date and time strings.
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    // Call a custom method to get the localized date format string for the user.
    // The default date format string is "EEE, MMM d".
    dateFormatter.dateFormat = [self dateFormatForCurrentUser];
    NSString *formattedDateString = [dateFormatter stringFromDate:inviteDate];
    // Call a custom method to get the localized time format string for the user.
    // The default time format string is "h:mm a".
    dateFormatter.dateFormat = [self timeFormatForCurrentUser];
    NSString *formattedTimeString = [dateFormatter stringFromDate:inviteDate];
    // Set the date and time in the corresponding labels.
    [self.dateLabel setText:formattedDateString];
    [self.timeLabel setText:formattedTimeString];
    // Set the location of the meeting.
    NSString* locationString = [customDataDict objectForKey:invitationLocationKey];
    [self.locationLabel setText:locationString];
    // Set the invitation's notes (if any).
    NSString* notesString = [customDataDict objectForKey:invitationNotesKey];
    [self.notesLabel setText:notesString];
    // Tell WatchKit to display the custom interface.
    completionHandler(WKUserNotificationInterfaceTypeCustom);
}

Testing Your Custom Interface

シミュレータでDynamicなNotificationのInterfaceをテストするには、ビルドスキームを作成します。
そして、Xcodeのテンプレートで提供されたRemoteNotificationPayload.jsonをPayloadのデータとして使用します。
詳細については以下を参照してください。
WatchKit Programming Guide: Configuring Your Xcode Project

参考

WatchKit Programming Guide: Custom Notification Interfaces

宣伝

Swiftでカスタムキーボードアプリ作りました。買ってね!
特殊文字キーボード

Pocket

Apple WatchでのNotification受け取りについて

この投稿はWatchKit Advent Calendar 2014の9日目の記事です。

Notificationを受け取ったら

あなたのiOSアプリがLocal NotificationかRemote Notificationをサポートしていたら、Apple WatchもNotificationを表示します。
もし、ユーザのiPhoneにLocal NotificationかRemote Notificationが届いたら、iOSはiPhoneかApple WatchのどちらにNotificationを表示するかを決定します。
Apple WatchにNotificationが送られた場合、システムはユーザにNotificationが来たことを微かに知らせます。
(たぶん、バイブレーション)
もし、ユーザがNotificationを見ることを選んだら(たぶん、腕をあげたら)、システムはShort-Look Interfaceを表示します。
もし、ユーザがNotificationを見続けたら(しばらく腕を上げたままだったら??) ※、システムはLong-Look Interfaceを表示します。
Watch AppはNotificationをカスタマイズしていなければ、システムがデフォルトのNotification画面を用意してくれます。

※ Short-Look InterfaceをタップするとLong-Look Interfaceが表示できるようです。
(@koogawaさん情報有り難うございます!)

Short-Look Interface

notification_short_look

通知が来た時に、ユーザが最初に見る画面です。
Short-Look Interfaceはスクロールすることはできません。
デフォルトでは、アプリ名、アイコン、Notificationのpayloadに含まれるタイトルを表示します。

Long-Look Interface

notification_long_look

Long-Look InterfaceはNotificationの内容と関連するアクションボタンを表示するスクロール可能な画面です。
デフォルトでは、Apple Watchがアイコン、タイトル、メッセージを含む画面を表示します。

Long-Look Interfaceの3つの領域

sash

アプリアイコンとアプリ名が表示されます。
デフォルトでは、一部透明ですが色をカスタマイズすることもできます。

content area

Notificationの詳細な情報を表示します。
このエリアはある程度自由にカスタマイズ可能です。

bottom area

Dismissボタンとアプリで設定したいくつかのアクションボタンを表示します。
Dismissボタンはシステムが自動的に常に表示してくれます。

アクションボタンを追加する方法

まず、任意のアクション(UIMutableUserNotificationAction)を作成し、
カテゴリ(UIMutableUserNotificationCategory)の中に複数のアクションをセットします。
NSMutableSetにすべてのカテゴリをセットして、Notificationの設定(UIUserNotificationSettings)
にNSMutableSetとNotificationの属性(バッジや音の有無など)をセットします。
最後に[UIApplication sharedApplication]にNotificationの設定を登録します。

- (void)registerSettingsAndCategories {
    // Create a mutable set to store the category definitions.
    NSMutableSet* categories = [NSMutableSet set];
    // Define the actions for a meeting invite notification.
    UIMutableUserNotificationAction* acceptAction = [[UIMutableUserNotificationAction alloc] init];
    acceptAction.title = NSLocalizedString(@"Accept", @"Accept invitation");
    acceptAction.identifier = @"accept";
    acceptAction.activationMode = UIUserNotificationActivationModeBackground;
    acceptAction.authenticationRequired = NO;
    UIMutableUserNotificationAction* declineAction = [[UIMutableUserNotificationAction alloc] init];
    declineAction.title = NSLocalizedString(@"Decline", @"Decline invitation");
    declineAction.identifier = @"decline";
    declineAction.activationMode = UIUserNotificationActivationModeBackground;
    declineAction.authenticationRequired = NO;
    // Create the category object and add it to the set.
    UIMutableUserNotificationCategory* inviteCategory = [[UIMutableUserNotificationCategory alloc] init];
    [inviteCategory setActions:@[acceptAction, declineAction]
                    forContext:UIUserNotificationActionContextDefault];
    inviteCategory.identifier = @"invitation";
    [categories addObject:inviteCategory];
    // Configure other actions and categories and add them to the set...
    UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:
                                            (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound)
                                                                             categories:categories];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}

アクションボタンをタップすると

システムはアクションを処理する方法を決定するために、登録されたUIUserNotificationActionオブジェクトを使用します。
アクションはフォアグラウンドまたはバックグラウンドで処理できます。

フォアグラウンドで処理する場合

あなたのWatch Appを起動し、メインのInterface ControllerにタップされたアクションボタンのIDを受け渡します。
WKInterfaceControllerのサブクラス(メインのInterface Controller)では、アクションを処理してはいけません。
WKInterfaceControllerのサブクラスでは、以下のメソッドを実装する必要があります。

  • handleActionWithIdentifier:forRemoteNotification:
  • handleActionWithIdentifier:forLocalNotification: methods

バックグラウンドで処理する場合

iOSアプリをバックグラウンドで起動し、以下のどちらかのメソッドで処理をします。

  • application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
  • application:handleActionWithIdentifier:forLocalNotification:completionHandler:

参考

[UIApplication sharedApplication]

宣伝

Swiftでカスタムキーボードアプリ作りました。買ってね!
特殊文字キーボード

Pocket

Apple Watchで初めて登場した新UI「Glance」について

この投稿はWatchKit Advent Calendar 2014の8日目の記事です。

Glanceとは

glance_lister_2x

GlanceはユーザがあなたのWatch Appから重要な情報を表示するための補助的な機能です。
(つまり、実装しなくてもいいです。)
iOSでいう、通知センターのようなものだと思っています。
1つのWatch Appにつき、最大1つのGlanceを持つことができます。
GlanceはWKInterfaceControllerオブジェクトですが、ユーザの操作を受け付けません。
タップすると、あなたのWatch Appを起動します。
Handoffで起動するWKInterfaceControllerを設定することもできます。
(詳細は以下を参照)
WatchKitでHandoff | blog.haranicle.net

Youtubeに動画がありました。
ちょうど2分ぐらいからGlanceの挙動を見ることができます。

Glanceインタフェースガイドライン

  • すぐに情報を伝えられるように設計します。大量の文字を表示してはいけません。グラフィックス、色、アニメーションを適切に使用してください。
  • 最も重要な情報に焦点を当ててください。Glanceはアプリに変わるものではありません。重要な情報のみをトリミングして表示してください。
  • インタラクティブなコントロールを含めないでください。(含めても操作できないので)
  • テーブルとマップの使用は避けたほうがいいようです。禁止はされていませんが、限られたスペースはテーブル、マップは有用ではありません。
  • 表示する情報をタイムリーにしてください。ユーザに情報を提供するために、時刻や位置情報など利用できるすべてのリソースを使用してください。

Glanceの作り方

2通りあります。

Watch Appのターゲット作成時に自動生成

まだプロジェクトにWatch Appのターゲットがない場合はこの手順でGlanceを作成できます。こっちのほうがおすすめ。

File > New > Target… >
Watch Appを選択してNext >
Choose options for your new target:でInclude Glance Sceneにチェック >
Finish

これで、以下のものが作成されます。

  • WatchKit Extensionグループ内にGlanceController.swift
  • Watch Appグループ内のStoryboard内にGlance Interface

手動でGlance作成

すでにプロジェクトにWatch Appのターゲットにある場合はこの手順でGlanceを作成できます。

  1. Watch Appのグループを右クリック > New File… > Cococa Classを選択してNext > Class: 適当なクラス名、Subclass of:WKInterfaceControllerにしてNext > TargetsでWatchKit ExtensionのみにチェックしてCreate
  2. Watch Appのグループ内にあるStoryboardにGlance Interface Controllerを追加します。
  3. StoryboardにGlance Interface Controllerと 1. で作成したクラスのファイルを紐付け

iOSシミュレータでのGlanceの起動方法

Glance起動用のSchemeを作成

簡単にGlanceを起動できるようにするために、Schemeを作成します。
Product > Scheme > Edit Scheme… >
左上で”プロジェクト名 Watch App”のSchemeを選択 >
Duplicate SchemeボタンでSchemeを複製 >
“Copy of プロジェクト名 Watch App” SchemeのRunを選択 >
Info > Executableで”Glance – プロジェクト名 Watch App.app”を選択 >
Close

Run

“Copy of プロジェクト名 Watch App” Schemeを選択してRunボタンを押すと、
Glanceが表示されます。
Scheme名は、Product > Scheme > Manage Schemes… で変更できます。

宣伝

Swiftでカスタムキーボードアプリ作りました。買ってね!
特殊文字キーボード

Pocket

Apple Watch Appのライフサイクルまとめ

この投稿はWatchKit Advent Calendar 2014の7日目の記事です。

前提知識

Watch Appのアーキテクチャ

Apple Watch側にStoryboardやリソースファイルを置いて、iPhoneのWatchKit Extension側で処理を行います。
UIの更新などApple WatchとiPhone間の通信はWatchKitが行います。

app_communication_2x
(via WatchKit Programming Guide: Watch App Architecture)

Watch Appのライフサイクル

ユーザがApple WatchであなたのWatch Appを起動すると、自動的にiPhone側のWatchKit Extensionを起動します。
ユーザの操作が終わると、iOSはWatchKit Extensionの実行を中断します。
つまり、WatchKit Extensionは、ユーザがApple WatchであなたのWatch Appを操作中の時のみ実行できます。

launch_cycle_2x
(via WatchKit Programming Guide: Watch App Architecture)

WKInterfaceControllerでのライフサイクルハンドリング

下記図のとおりです。

watch_app_lifecycle_simple_2x
(via WatchKit Programming Guide: Watch App Architecture)

initWithContext:

WKInterfaceControllerが作成されて、最初に呼ばれるメソッドです。
データのロードや、ラベル、画像、テーブルなどのオブジェクトを更新するために使用します。
contextでHandoffや他の画面から値を受け取ることができます。

willActivate

ユーザにUIが表示されたタイミングで呼ばれるメソッドです。
UIの更新や、UIがアクティブなときだけ発生するようなタスクの実行に使用します。
例えば、タイマーのセットや、アニメーションの開始、ビデオのストリーミング開始(ぇ、そんなのできたっけ?)などです。

didDeactivate

ユーザがApple Watchであなたのアプリを操作することをやめると呼ばれるメソッドです。
クリーンアップの処理を行います。
例えば、タイマーの停止や、アニメーションの停止、ビデオのストリーミング停止などです。
次にwillActivateが呼ばれるまでの間は、UIに値をセットしても無視されます。

複数画面ある場合は?

実験してみました。
First、Second、Thirdという名前のWKInterfaceControllerを作成し、
First->Second->Third->Second->Firstの順に画面遷移し、ライフサイクルハンドリングするメソッドでログを吐いてみました。

以下ログ。

FirstのinitWithContext
FirstのwillActive
SecondをPush
SecondのinitWithContext
SecondのwillActivate
FirstのdidDeactivate
ThirdをPush
ThirdのinitWithContext
ThirdのwillActivate
SecondのdidDeactivate
ThirdをPop
SecondのwillActivate
ThirdのdidDeactivate
SecondをPop
FirstのwillActivate
SecondのdidDeactivate

次の画面がwillActivateになったら、自身がdidDeactivateになるようです。

宣伝

Swiftでカスタムキーボードアプリ作りました。買ってね!
特殊文字キーボード

Pocket

« Older posts

Copyright © 2016 blog.haranicle.net

Theme by Anders NorenUp ↑