#potatotips 23回目はペッパーが受付しているFiNC社で開催! iOS/Android開発Tipsのまとめ!
久々にぽてちに参加してきたのでその時のまとめです。第23回potatotipsは銀座のFiNC社での開催となりました。
状態管理とビューデータバインディング [iOS]
- 状態とUIをスタックするやり方の際にコードをシンプルにするやり方の紹介
- 1画面でロード画面だとか多様な状態がある時に、それぞれのviewをstackとして管理するお話
- ENUMで管理された状態とviewが紐付いていて、例えばblank stateをいれたら自動的にblank表示にするといった、状態によって特定のviewを自動的に表示したい等の画面の状態の整理にはビューデータバインディングが使えます
ViewDataBinding
- コンテンツを保存するitemsの配列が空の状態のときはインジケータを見せるが、itemsがある場合はステータスバーのインジケータをまわすなどできる
- SwiftBondを使うとどういう状態でどういう画面を出すのかというロジックを宣言的に記述できる
- 画面を一意に表示することを書ける
- DynamicHiddenを紐付けすると自動的にインジケータの非表示などできる
まとめ
- アプリの状態をスタックで管理
- ある状態における画面表示ロジックを宣言的に記述
- 状態が変化したら自動的に画面も表示
- cf: MVVMをベースに複雑な振る舞いをしっかり把握できるアプリ開発
FAQ
- MVVMを導入してみてやりにくくなったことや困難などはあったか?
- デメリットはあまり感じなかったがデータ永続化のためにビューモデルをマッピングするところが冗長化している
AppIndexing API [Android]
- Googleの提供しているdeeplink(検索結果からアプリの特定の画面に遷移できたりする)のAPIの紹介
AppIndexing API [Android]
- Google Play Servicesのコアの機能の一部
- 実装が簡単
実装法
- manifestを書く
Activity
- Activityでの実装が推奨されています
- onStartでAppIndex.AppIndexApi.startのメソッドにタイトルやURLなどを設定したアクションとクライアントを渡す
- onStopのライフサイクルでタイトルとstartのようにactionとクライアントを設定してdisconnectするだけ
- 文字列はなんでもいいそうです
- 登録した文字列がユーザに入力されると検索結果に出る
Fragments
- ドキュメント見ると、onStartとonStopで実装してほしいが、必須ではないとのこと
Tips
- アプリURLとweb urlをアクション作る時に渡すのだが、これがNULLだとおちます
- clientのconnectのメソッドを書かないと一見実装できてるようにみえて実装できてないように見えます
- Googleの発表で検索結果にいい方向になるといっているので実装したほうがいいです
tvOSネイティブアプリを作る [iOS]
- apple tvでできること
- プリインストールアプリで動画・音楽を再生
- airplayで音楽を再生したりミラーリングしたり
- appstoreからインストールして実行 <- new!
- xcodeでアプリを作成 <- new!
tvos開発概要
- TVML + JavaScriptで作る方法とCocoaTouch + obj-c/swiftで作る方法がある
- シミュレータも出るし、実機も繋げれば実機での実行もできます
- UDIDもあるのでもちろん登録します
- 開発でtvosをつなげるときはlightningでもmicroUSBでもなく、TypeCでした
- 基本的にはiosのobj-c/swiftライブラリは使える
- :tvos, ‘9.0’と指定すればcocoapodsも使えるが、使えない!とエラーがでても、podspecにtvos_targetを加えるだけで使える
ハマリポイント
- アプリが200MBいない
- データ永続化にディスクは使えない
- UIWebViewがない!
- デバイストークンは取れるし送信してもエラーにはならないがpush通知は使えない
Demo
iphoneアプリで選択するとtvosで動画が再生されるデモでした
隕石という名のスクリーンショットをSlackに落下させる話 [Android]
- テストなどでスクリーンショットをredmineにはるのは大変
- アプリのスクリーンショットを簡単にslackにすぐにpostできるライブラリMeteoriteを作った
- notificationからSSを簡単に取得できるライブラリMeteorも作った
- このライブラリを使えば好きなサービスへ投下できるようになります
- 各サービスのつなぎこみは自分でやる
Demo
まとめ
- Meteor: 好きなサービスにSSをPostしたい時に便利
- Meteorite
- Slackにpostするなら楽
- postするUIも提供してます
Health Kitでまとめてデータを取得する(仮) [iOS]
- 日毎のデータを取得したい時のお話
- health appというアプリだと日付ごとに歩数がでている
- 期間をきめてクエリを作るのはめんどい
- コードにするとすごい長い cf : HealthKitのHKStatisticsCollectionを使った一週間分のデータを取得するデモ
- 最近自分の歩数や睡眠時間をwebになげて競うサービスを作ろうとしていた
HKStatistics
- startとendとその間のデルタの時間がひとつのデータ構造になっている。
- メソッドにsum, min maxなどのメソッドがある
- 歩数はデバイスごとにある
- 決められた範囲でとりやすくしている
- collectionとしてデータを取り出したい時
- 3日前から今日までを取ろうとした時
- startDateを22日の0:00, endDateを今にし、anchorDateを0:00にセットすると日付ごとの歩数値が取れるようになる
anchorDate
- ⊿tを1日にした時に、0:00-23:59の間の指定だったらそこから1日を始める
ソース別重複データ
- デバイスがかぶると歩数がかぶるが、デフォルトで重複を省いたデータが取れるので意識せずコードが書ける
- statistics.sumQuantity()では、重複データを省いたものが取れる
- statistics.sumQuantityForSource(source:)でははデバイスを指定して歩数が取れる
- .SpeareteBySourceはソース別でデータを取得したいかどうかをクエリに渡すオプション
“Predictable state container” and Data Binding [Android]
- Front-end JSはここ三年くらいでreact.jsやangular.jsなどなどフレームワークがたくさん出てきている
- JSとandroidの共通点を考えた時、UIを作る、ユーザーインタラクションのハンドリング、アプリ状態の管理と共通化するものがある
- 今回はユーザーをどうインタラクティブするか、アプリ状態の管理についてのお話
Application architecture
- androidはMVC、MVPなどで書かれる
- JSはMVW、FluxやReduxなど書かれる
- FB曰くMVWはつらい
Droidux
- Reduxをandroidにいれてみたライブラリを作った「Droidux」
- Reduxerを定義するとactionをつけたらそれを自動的に通知してくれる
- undo/redoがさくっとできる
- cf: Droidux/examples/todos-with-undo
- JSの爆発的な成長を取り入れるために作ってみた
- データバインディング使ってるのでデータ更新されたらviewも更新されるということもできる
- droid会議受かればもっと話すかも・・・!
FAQ
- androidのビューもimutable/ mutableもっている?
- データバインディングを利用して更新したら勝手に通知してくれるというのを利用しています
- @Bindableをつけてあげるといい感じに通知してくれる
Simple Graph [iOS]
- グラフの書き方は、CorePlot、iOS-Chart、PNChartなどがあるが、そんなにたくさんグラフ種類はいらない。
- オプションが多くてwarpして使うのは複雑
- すごい微妙なレイアウトが調整しにくい
SimpleGraphSample
- SimpleGraphSampleというライブラリを自作してみた
How to use
- graph frameと線に分けて作った
- strokeとframeとオブジェクトを渡してあげるといい感じに引いてくれる
仕組み
- X軸の点の幅は一番配列の広いところを使い、Y軸はheightの高いところを使って描画した
- 線自体はUIBezierPathで描画する
- プロトコルを使い、x座標とy座標を求めるロジックを分けた
- 一文だけかえれば棒でも線でも書けるように。
まとめ
- シンプルなグラフなら自作のほうが楽
- protocolを使って基本ロジックを切り出す
手軽にHTTPでJSONにアクセスできる環境を用意する [Android]
- サーバとjsonで連携するアプリはサーバ側の準備が遅れていたり、仕様が不明瞭などがある
- jsonファイルにHTTPでアクセスできればいいんだという問題についての解決法
Android studioのローカルHTTPサーバを起動
- 適当なHTMLをandroid studioでひらくとローカルサーバが立ち上がる
- genymotionで、エミュレータからhttp://10.0.3.2:port/pathでアクセスできます
- AVDでもいいが遅い
- macはapacheが入っているのでそのほうが速いかも
Gistの利用
- android studioでgistにupできるのでそこにアクセスする
- githubにコミットする形
ローカルでNode.jsを起動
- Expressアプリケーションのpublicディレクトリにjsonファイルをおいてlocalhostにアクセスする
- やろうと思えばロジックも実装できる
- JSはJSONを扱いやすい
- 頑張ればherokuなどにもアップできる
Amazon S3にJSONをアップする
- S3に静的ファイルを置いてホスティングするだけ
View観測tips [iOS]
- ViewMonitorというviewの位置やフォントサイズなどがアプリを実行する時に見るライブラリの紹介
- ViewMonitor.start()のメソッドを1行呼ぶだけで実行時にレイアウトの詳細が出るようにしています
- method swizzlingを使ってviewDidAppearをフックして、表示しているviewを全て撮ってきて位置情報を取得している
- viewの上に情報を出すviewを表示しているが、overwrapしているのはUIButtonで、タップされたらUIButton自体に重ねたviewを表示する
- userInterractionEnabled=Falseだとタップが取れないが、一旦ライブラリでtrueに置き換えて、ライブラリの機能をOFFにした時に元に戻している
今までにきたPR
- swiftのライブラリで作っていたが、obj-cで使いたいと来た時にNSObjectを継承させてやったがpure swiftじゃなくなった。。。
- ReadMeの文字修正が来たりもした
行けてないところと今後
- storyboardでやりたかったが、codeで無理くりやってます
- 実際のフォントや文字の大きさなどを動的に書き換えるようにしたい
Design Support Libraryをいじる際に気をつけていること [Android]
- デザインを調整できないかといわれたときに気をつけれれば楽かもといった事の共有
レイアウトの指定をいじる順番について
support LibraryのLayout属性は親のほうを優先する
- SupportLibraryのコード上で色やテキストなどを取得するときはSupportLibraryのLayout要素の値を優先して取得する
SupportLibraryのクラス用Viewの配置が優先
- SupportLibraryの要素を入れ替えたい時に、ツールバーの中にimageviewを入れるといった例
- title属性が指定されているのでtitle文字が前に挿入されてしまってうまくいかない
- 自クラスで扱うviewの位置の計算をするとき自分のview以外は見ていないし、自クラスのviewの手前の要素がなければつめるようになっているために起こる
- 入れ替えたい要素があった場合は周りの要素も削る覚悟する
SuppertLibraryでやりにくい・できないこと
- StatusBarとNavigationBar
- 吹き出しバーの色を変えれそうが、ActivityのStyleからいじる
- アニメーション変更はON/OFFくらいしかいじれないので、オーバーライドするかライブラリをつくる
- RippleのアニメーションはRippleDrawableを背景に使って下さい
SwiftScriptingのすゝめ [iOS]
- realmのswift scriptingかけるという記事を見つけた
- 準備はshebangをいれて、実行権限をいれておしまいなのですごい簡単
splatoon web scraper
- Splatoonの武器の種類と名前を抽出してくるライブラリ
- HTML解析にはKannna、ライブラリ管理にはCarthageを使っている
苦労したとこ
- ライブラリのインポートに苦戦
- shebangでフレームワークのパスを指定してあげてimportするだけ
- 非同期処理が終わるまで待ってくれない
- SwiftScriptRunnnerという待ち合わせができるライブラリを使った
- Accountsフレームワークがエラーを吐いて使えないのはEl Capitanのエラーらしい
- ファイル単位でのimportが出来ないので自分でライブラリを作成して読み込むしかない
- 使用できないライブラリがある。シンボルが解決できない?
おまけ
- お気に入りのtaylor.swiftを流して癒される
- app kitも使えるのでGUIツールもさくっと作れます!
FAQ
- UIKitのUILabelの高さを計算できる?
- AppKitの場合はNSLabelになるがおそらくできる
Androidでライブラリを作る [Android]
- 良いライブラリの条件とは便利な機能を提供していて、使うのが簡単で、容量が少なく、速度が早くて、他ライブラリに依存していない
- androidライブラリ特有の問題についてのお話
OSバージョン問題
- 幅広いOSバージョンが有り、どこまでサポートするのかが悩みどころ
- APIのdeprecated対応などのバージョンごとのif文が大変
- 古いOSで使いたい場合の実機テストに困る!端末が手に入らない
65k問題
- メソッドの数は65k超えるとアプリが作れない問題がある
- アプリのファイルを小さくしないといけない
- 回避する方法はあるが、古いOSだと動かない
- 65k問題に引っかかるので、ライブラリを作るのに他ライブラリを使えない
- testで65k問題に引っかかったりもする
非同期処理問題
- 生Threadはよくわからない
- executor serviceは使うのに熟練が必要
- AsyncTaskLoaderはactivityやfragmentなどがないと使えない
- AsyncTaskも、とあるバージョンから直列になったり並列になったり、ライフサイクルを無視して動いたりするので使うのが怖い
結果
- android2.3からwebviewテスト
- HTTPUrl connectionを使う
- JSONParseは標準APIで頑張る
- 非同期処理はHandlerとHandlerThreadで頑張る
学んだこと
- ライブラリを作ると標準APIに詳しくなる
- 実装スキルの訓練になる
- ライフサイクルを意識できるようになる
HandlerとHandlerThreadの違い
- Handlerは自分自身をnewsしたスレッドか、UIスレッドで動き、HandlerThreadは別スレッドで動かせるもの
Xcode7時代のアプリ配布 [iOS]
Xcode7時代のアプリ配布 from toyship
- エンジニアが少ないのでアプリ配布を自動化したい
- 配布に求められるもの
- その時リリースするコードのモジュールを用意しておく
- 端末登録は排除したい
- ビルド配布は自動化したい
Xcode Bot
- Apple公式CI tool
- 最近使いやすくなった
- 自動ビルドしてくれる
- 静的解析もしてくれる
- xcode7からはUITestの実行もできる
- ipaファイルの作成と配布も可能
構成例
- Mac OS X Serverをたてて、構成し、ソースをクロールさせる
使用例
- Xcodeの画面からビルドエラーの回数やテストは何個パスしたかなどがみれる
- この画面からipaもDLできる
- safariからも見れる
- サーバにmobile safariでアクセスするとそこからインストールもできる
- ビルドサーバ兼配布サーバになる
メリット
- ビルドの単位がブランチを指定してできる
- コミット毎にビルドの生成が可能
- テストも同時に運用もできます
デメリット
- 配布はテスト端末の開発用デバイス登録が必要
- cocoapodsと相性が悪いので設定が必要
External Test
- iTunesConnectから配布します
メリット
- appstoreと同じモジュールを使える
- テスト用にデバイス登録が必要ない。AppleIDだけ教えてもらうだけでいい。
- 社外のユーザにリリースすることができる
- xcode botは契約上外部のユーザに配れない
デメリット
- テスト用に外部に配信する時に審査がある
- 1アプリにつき1度に一つのモジュールしか配布できない
- apple idを教えてもらう必要がある
- iOS8以上にしか配布できない
審査
- 審査は全てのリリース毎に必要ではなく、1.1.~1.2に上げるた時に1回審査が必要なだけ。
- 1回通ればビルド番号を変えた時には審査は不要
- 審査時間は数時間〜5日
- 通常審査よりゆるいがrejectもある
注意点
- 1日2回しかリリースできなかったが、1日4回までになった
- アメリカ西海岸時間での1日なので要注意
Internal Test
- externaltと同等
エンタープライズ配信
- AppStoreを利用しない社内向けのアプリ配信
- エンタープライズ契約が必要
メリット
- デバイス登録が必要ないが、最近はアップル側もセキュリティを厳しくしている
デメリット
- 対象は自社の社員のみ
- 社内ツールの配信に使っている
まとめ
- テスト配布はXcodeBotで配布
- リリースモジュールはExternalTest
- 社内ツールの配布はEnterprise配布
Don’t Reinvent The Wheel ~ For All Android Beginners ~ [Android]
- ユーザーIDを引数と受け取ってnullじゃないか、長さが0じゃないかなどをUtilクラスに書いたのをレビューしてもらった
- 車輪の再発明はするなといわれた
- TextUtils.isEmpty()に置き換えた
- TextUtils.isEmpty()のソースコード見てみたら同じことやっていた
- ライブラリーを知り、ライブラリーを使う
- 標準ライブラリを使用することで専門家の知識と使用した人の経験を知れる
- 場当たり的なっ解決策を書くことで時間を無駄にする必要がない
- 多くの人に繰り返し書き直されるコードは時間とともにパフォーマンスが改善される可能性はすごい少ない
- Androidライブラリをすごい読み込んで、ライブラリを使って、ソースコードを見て勉強するというステップが良かった
- どういうスタイルで書いてどういうコメントをかいているかなど勉強になった
tvOSを拡張する [iOS]
Noritaka Kamiya様
- Type-Cの先端が太いとHDMIと干渉します
- airbnbを起動すると、ログインして下さいと、ワンタイムのコードが出てくるが、ここでiPhoneなどを取り出す必要がある
- しかしキーボードやwebのexperienceがよくない!
- 使えると思ってたものが使えないということがおおい
- airbnbのテレビで表示している情報をどうやってiPhoneにわたすのかと考えた時に思いつくのはNSUserActivityだが対応していない
- CoreBluetoothなら使えたが、Centralの役割しか動かない。AppleTv側がhostになる。
- さらに2つのデバイスしかつながらない。ゲームのコントローラ含めて2台なので実質1台
- BLE Deviceと接続できる
- HomeKitは直接使えないが、TCP/IPで通信するものは動くと思う
- CBCentralManagerを作ってpreferalで接続しに行くが、BTLE Central Peripheral Transaferというサンプルがあるので、appletvからiphoneに情報を渡せる
- BLEで普通に使えるデータは20bytesまでなのでJSONをのせるのは無理
- rowlevelなデータを書くことになる
- 暗号化はできるが、ペアリングしたiPhoneが解除できないという問題に直面している
まとめ
- Bluetoothのcentralとして稼働できる
- asyncの地獄に陥りがち
UI optimization for night [Android]
- 夜にスマフォをいじっている時のお話
- 車を運転中にナビをつけながら出しているとどんだけ調整しても眩しい
- システムにもディスプレイの明るさを調整できるが、それだけじゃたりない
- ディスプレイの色の輝度が明るさを持っている
- 暗いところではくらい色を使いたい
- androidのテーマを利用しよう
動的にテーマを変える
- 普通ならテーマはandroid.manifestに書いて使うが、動的にするときはActivity#setTheme()を使えばできる
- setThemeを呼ぶのはonCreateを呼ぶ前という制約がある
- テーマの切り替えはいつやるか?
- 照度センサーがついているデバイスで、センサーの数値を使ってしきい値をきってテーマを切り替える
- 日の入りと日の出の時間を計算して切り替える -> 計算で求められる
- AOSPで使える
- 日の出入りは緯度経度と日時で計算できる
- 日の出日の入りをいつ計算するか
- 日付変わった瞬間でやるとbloadcastがバグってます
- AlarmManager#setExact()かset()におまかせしましょう
- UiModeManager使えるのでは?
- 楽だが、android autoのロゴが出たり、謎のハンドルアイコンがでる
watchOS2 tips [iOS]
Complicationはショートカットとして配置できる
- 自分のアプリのデータを文字盤に表示できる
- アプリ内のデータを表示しないといけないように感じるが、起動のショートカットとしても置くことも問題ない
- 入れられるならcomplication全部対応していれてもいいかも
WCSessionの機能を使い分ける
- データ送信方法が用途に応じて用意されている
- 大体はsendMessageでとってくる
- サイズの大きいデータはtransferFileメソッドを使用する
WCSessionで渡すデータはターゲット間で共有する
- WCSessionのsendMessagaのデータは[String:AnyObject]で送れるが、Dictionaryで送るので、キー名の定義が両方に存在することになるので、型を共通定義にしておくといい
- お互いの送信時に[String:AnyObject]から共通データ型にして渡すようにすると定義が一つにまとまって変更が楽になる
- Dictionaryからの変換処理がまとまってるのでバグをみつけやすい
ビルド時間の終わりにHaptic
- 実機でのデバッグはすごい時間かかる
- 起動したときにhapticを使用してアプリ起動時に音がなるように仕込んでおく
@mogmetの所感
今回はデモをやっている方が結構多く感じましたが、やはりデモをやるとどういったものなのかがイメージをつかみやすくていいなと思いました。
デモは現地に行った人しか体験できない特典みたいなものですね!
また、今回もライブラリを制作している方がたくさんいらっしゃいましたが、ライブラリを制作するのはスキルがアップするというお話がすごくその通りだなぁと思ったので自分も機会があったら積極的にライブラリを提供してみようと感じました。