#potatotips 19はハンバーガーが美味しいcookpad社で開催!iOS/Android開発Tipsのまとめ!
iOS/Android開発のTipsを出し合う勉強会のpotatotips 19に参加してきたのでその時のメモです。
ハンバーガー食べそこねたのが悔しい…
[Android] RxT4Aの紹介
- RxAndroidのフォーク
- RxBindingの機能は実装しません
実装機能
- AndroidSchedulers : main threadでスケジューラを実行できる
- 特定のハンドラーで実行するスケジューラもある
- AndroidCompositeSubscription : CompositeSubscription をAndroidコンポーネントで使いやすくしたもの
- CompositeSubscription は同じインスタンスを再利用できない仕様だが、AndroidCompositeSubscriptionは同じインスタンスを再利用できる
- OperatorAddToCompositeSubscription : method chain中に AndroidCompositeSubscription#add() をするためのオペレータ
- OperatorFilterLite : filter() で戻り値のためのオブジェクト生成をしないようにするもの
- あらゆるところで様々なオブジェクトを作るので、それを減らすために作った
実装していないもの
- eventのobservable化
- AppObservable
[iOS] Making Your App Static
- swiftで静的な言語の機能を使えるようになったが、cocoaの特性上、まだ動的な部分は残っている
- UIViewControllerの場合
- storyboardからviewcontrollerを生成したい場合、いろんなところに情報を記載しないといけない
- code generatorなどは昔からあるが、作業フローが増えるのは嫌
- 1個のstoryboardに対し、1個のViewControllerでやるとファイル名が一致するので、ProtocolやGlobalFunctionを使って生成するようにする
- TypeNameFromTypeを使って、型の名前のstoryboardを使うことができるし、型推論が働く
- ProtocolExtensionでやった場合、ViewControllerじゃないやつにもプロトコルのが適用されてしまうのでtype constraintsを使って自身がVCだった場合のみ使ったりすることができる
- どのように型から名前を取るか
- ネストしたクラスから名前を取り出そうとするとうまくとれない
- DemangledTypeNameでやる場合はsummaryを使うのがいい
- swift2からStringで変換して型がとれます
- NSIndexPathはnestしたenumで定義できるのでそれでindexPathを作ると意味をはっきりもたせる事ができる
- cellを生成するところもクラス名、セルの名前、Identifierなどをすべて一致させると型のインスタンスを返したりができる
- まとめ
- コンパイル時に極力問題を発見しよう!
- genericsを使うといい感じ
[Android] Push通知を届けるために
- Agenda
- RegistrationID
- トラブルシューティング
- 実装についてはアプリアップデートや、端末の再起動でRegistrationIDが変更されるところもカバーされたドキュメント参照 cf: Deprecated: Obtaining Registration Tokens with gcm.register()
- manifestに記載後、ソースにも実装する
- トラブルシューティング
- GCM診断を使うとregistrationIDを入れると、過去にpushを送ったメッセージが正常に届いたかどうか確認ができる
- おまけ
- 節電アプリ、節電機能によるwifiの切断、serviceの停止があると届かなかったりする
- Dozeモードはpush通知に対してプライオリティをつけられるが、低いと表示されなかったりするらしい
[iOS] WWDCのチケット外れてもSFに行った方が良い理由
現地に行く前にやったほうがいいこと
- 費用は12,3万くらい
- チケットはあえて外す
- 外すと、Appleから「はずれたよ!おめでとう!!」のお祝いメールが届く
- ANAは56000マイルあれば3万で済む
- 宿はTechHouseがオススメ
- ミートアップ情報はParties for wwdcアプリを使う
- esta申請をしておく
- Uber認証をやっておく
- 現地訪問する企業を探す
- 現地企業との面接を申し込む
現地でやっておいたほうがいいこと
- simカードを買う
- Clipper(Suicaみたいなやつ)を買う
- Yosemiteに行く
- メインの作業場を見つける
- Realmには神エンジニアと美味しいランチ
- 夜はミートアップに参加
- チケットなくても入れるかも
- Yelp 使うと美味しいのが食べれます
帰国してからやったほうがいいこと
- 勉強会に積極的に行く
- WWDCの良さを自慢する
- 仕事でも新機能も使えるかも
- 1週間使ってWWDC関連の勉強ができるので効率よく学べる。わからなければ周りの人に聞ける
まとめ
- $1500割引で行ける
- 自由行動できる
- WWDC期間はSFに情報が集まる
- WWDC以外でもミートアップが盛り沢山
チケットなくて困ったこと
- ラボ, bashにはいけない
[Android] メソッドを外部から無理やり叩く〜開発中だからできる荒技〜
- センサーを使ったアプリを作る際に、deviceのメソッドを叩きたい
- MethodHttpExproter
- アプリでサーバーをたてて、PCのブラウザから叩いたら動作を確認したいメソッドをみれるのを作ってみた
- 目的のクラスとメソッドにアノテーションを入れて、HTTPサーバを起動させて叩くだけで確認できます
- Demo
- web経由でトーストを表示したり、ボタンをタップできたりしました
- センサ系のややこしいものはオレオレデバッガを使って開発効率を上げましょう
[iOS] Core Graphocs on watchOS2
- watchos1のときはCoreGraphicsは使えなかったが、watchOS2でCoreGraphicsがネイティブSDKに追加された
- しかし、具体的なcodeが見つからないのでいろいろ試してみた
できること
- 1本線を引いてみたら、UIGraphicsGetCurrentContext()でグラフィックコンテキストを取得できなかった
- そこで、CGBitmapContextCreateというメソッドでbitmapのコンテキストを生成してその上に線を描画して、UIImageに変換して取り出してWKInterfaceImageに描画してみたらうまくいった
- UIBezierPathを使って円もかけました
- SVG fileを読み込んでベゼルパスなどに変換して描画もできました
- グラデーションの描画も出来ました
できないこと
- UIViewとかCALayerに依存する処理(スクリーンキャプチャなど)はできない
- タップ位置を取得できないので手書きもできない
- CALayerオブジェクトにaddLayerできないのでキーパスアニメーションもできない
Android MからのWeb Messaging
- jsとjavaの通信のやりかた
- loadUrlをつかったり。。。
- JSから受け取るときは@JavascriptInterfaceアノテーションを書いたりする
- JSにちょっと値を渡すだけでもすごい手間だし、文字列なJSがJavaに入り込んでくる
- HTML5 wev messaging
- iframe/window間の通信を可能とする
- androidMより、WebMessage用のクラスとメソッドが追加された
android.webkit
- WebMessage
- 送信するメッセージを表したクラス
- MessagePortsを引数に取れる
- WebMessagePort
- MessageChannelで使うポート
- WebMessagePort.postMessage(webMessage)
- MessageChannelでpostする
- WebMessagePort.WebMessageCallback()
- MessageChannelで受信した内容を受け取る
android.webkit.WebView
- WebView.createWebMessageChannel()
- MessageChannelを作ってポートを返してくれる
- WebView.postWebMessage()
- webviewで表示中のpageにpostMessageする
- 例: チャンネルを使った例とチャンネルを使っていない例の紹介
まとめ
- Java内に文字列なJSが紛れ込まない
- HTML5の標準なので汎用的
[iOS] 新しいCoreDataライブラリ
- CoreStore というライブラリを開発しています
- swiftで書かれている
- メインスレッドのContextはRead-Onlyでフェッチするだけ
- 書き込みはすべてSerialにBackgroundContextで行われる
- 複数のSQLiteファイルが使用可能
- Observerが用意されているのでFetchResultControllerを書かなくて良くなる
- マイグレーションをサポート
Usage
- SQLiteに紐づくDataStackを生成する
- configurationごとにDataStackの生成が可能
- Fetch
- DescriptorやPredicateは使わずに、WhereやOrderByメソッドなどを使って取得ができる
- create-update
- ブロックで実行します
- commitを実行して書き込み
- 書き込み結果はetherタイプでかっこよく受け取れる
- ViewControllerでのFetch
- ControllerからCoreDataを使うときはManagerObjectListControllerを使う
- セクションの数や、objectの数取得、indexPathからobjectの取得などできます
- Observer
- addObserverとremoveObserverを使ってください
- 通知されたオブジェクトはGenericsで実装されているためasが不要
まとめ
- DataStackをベースに動作
- Fetchの記述がシンプル
- DataStackごとにシリアルキューで動作するため安全
- マイグレーションが充実
- Genericsで実装されているためダイナミックキャストが減らせる
- swift2.0も対応中
[Android] はじめようData Binding
- Android開発における課題としてView周りが煩雑
- RoboJuiceやButterKnifeのViewBindingが出てきている
- しかしそれでもたりなかったが、DataBindingLibraryが登場した
- viewを取り出して状態に応じて操作するのを大体勝手にやってくれる
- 導入は簡単
- LayoutXMLの記法を拡張してくれる
- 変数宣言と式の利用が可能になる
- コンパイルの時にcodeも生成してくれる
- binndingクラスを使ってviewを直接触らずに使える
導入
- View With IDs
- レイアウトにidを書くとBindingクラスに勝ってに生えるのでViewHolderの代わりになる
- バターナイフなどのようにインジェクトの必要がない
まとめ
- DataBindingLibraryは結構機能が多い
- ViewHolderの代わりに使っていくといい
[iOS] 画面遷移と私
- WatchKitでcontextを通して遷移先に値を渡せる
- 疎結合
- 値を渡すこときに遷移元と遷移先で依存関係ができない
- 同じinterfaceでなんでも渡せる
- optional bindingで簡単に受け取れる
- iOS9ではcontext実装されなかったし、watchKitのようにcontextで書きたいということで SegueContextを作りました
- 疎結合で型安産な値の受け渡しができる
- NavigationControllerとTabBarControllerを挟んでだいじょうぶ
- カスタムセグエでも渡せる
[iOS] Breaking changes for Foundation API in iOS9
- NSMutableDictionaryの添字に配列のような形でsetできるものにnullableになりました
- Foundationにはnullがsetできないにもかかわらずnullableになった
- nilを代入すると要素が削除されるように変わりました
- 以前はnilをいれるとcrashしていた
- 意図せずnilが入る可能性はあるのでそのまま要素が削除されて意図せぬ挙動になるかも
- ※しかしsetObjectは今までどおりcrashします!!!
- NS_REFINED_FOR_SWIFT
- メソッド名に_がついたり、ラベルがついたりする
- ※コメントより追記:恐らくObjective-Cのメソッドやプロパティのうち、Swiftから使ってほしくないものを退避する
- Swiftから使ってほしくないものを指定することができて、それについては別のもっとSwiftらしいインターフェースを提供する
[Android] GCM Topic Messaging
- Topic Messaging
- Topicに購読登録したユーザーに一度にメッセージを送る機能
- 開発者のアプリケーションサーバからメッセージを送るだけでtopicに登録された100万までのユーザに届く
- ニュースの配信などに使えそう
- GCM含めたGoogleAPIsの変更
- google-services.jsonというconfigurationファイルをとってくる必要になった
- GCMのdevサイトからフォームを入力していき、いくつかのGoogleAPIsのconfigratuionファイルをDLする必要がある
- google-services.jsonについて
- project_number = senderID
- 登録画面のAppNameごとにproject_numberは発行されるが、複数のアプリケーションの間で使いまわせる
- 使用するServiceには2を指定される
- project_number = senderID
- 新しいGCMではappの下にgoogle-services.jsonをいれておくとstringファイルを作ってくれる
[iOS] UTI
- UTI(Uniform Type Identifier)はpublic.pngなどのファイル名
- iOSなどで使われたりする
- 継承関係がある public.context/public.data -> public.image -> public.jpeg
- PHImageManagerで使われたりする
- UTIから拡張子を取得もできます
- MIMETypeからUTI, 拡張子も作れる
- しかしcodeが長い…
- UTIKitというのを作って、簡単に拡張子などが取れるように作りました
[Android] DeepLinkDispatch
- airbnb/DeepLinkDispatchのご紹介
- deeplinkのスキーマ起動をすごい楽にしてくれるライブラリ
- シンプルでアノテーションベースのAPI
- Usage
- gradleからいれる
- スキーマの起動はAndroidManifestのintent-filterに設定していく
- deeplink activity経由で起動させるようにする
- Activityでパラメータなども簡単に取れる
- ライブラリ経由で起動したかどうかも判断できる
- returnでintentを返すとintentを起動してくれる
- callbakcはApplicationにDeepLinkCallbackをimplementsしてハンドルする
- どこにも指定していないURLが来た時などはonErrorでハンドリングなど
- テスト方法
12<code>$ adb shell am start -W -a android.intent.action.View -d "wasabeef://deeplink/deeplink"</code>- genymotionなどでやると楽
[iOS] iPad MultiTasking
※内容については公開されているセッションで語っている内容でもあったので、NDAおじさん的にはきっと問題ないと判断しメモを公開しておりますが、問題あった場合はご一報ください
- iPad Multi Taskingは3種類ある
- Picture in Picture : youtbeなどの再生で何もせずにできちゃいます
- SlideOver : 引き出した部分だけ操作できる
- Split View : 半分になって両方共触れる
- safariはsplitviewに対応しているのでiPadなのにiPhoneで表示されることがある
- Webサイト側も検討しておきましょう
[Android] Flow, Mortar and Dagger 2 のTIPS
- square社が作ったフラグメントを使わなくてもレスポンシブなことができる
- Fragmentのライフサイクル問題が軽減される
- Flow : Viewを主体として画面遷移できる
- Mortar : 画面ごとに独自のスコープを作ってやって、viewのシリアライズをbundleでできるようになる
- parseralというのをいままでやってたのがなくなる!
- Dagger : コンポーネント間の疎結合ができる
- Dagger2からみたDaggerとの違い
- ランタイムリフレクションが一切ない
- ビルド前にアノテーションからソースcodeが生成できる
- 階層ごとのScope
- オブジェクトグラフを階層化可能
- オブジェクトの依存関係を他のオブジェクトグラフに依存できる
- アプリケーションごとと画面前のオブジェクトグラフで考えた
- オブジェクトグラフの検索
- withComponentをつけて、それをヒントにしてクラスを検索して実行時にオブジェクトグラフを生成する
- オブジェクトグラフの依存関係はハードコーディングした
- 頑張ればソースコード生成も静的にはできる
- サンプルコード
[iOS] Introducing Teiten
- OSX アプリ Teitenを作ってみた
- アプリを起動するとMacのウィンドウで自分の画像を10秒ずつ撮影して動画にする
- AVFoundation, CoreVideo, CoreMediaを使っている
- プレビューからドラッグアンドドロップでLGTM画像を生成できるように作ってみた
- NSTableViewにドラッグアンドドロップの機能がついていたので使った
- NSPaseteboardWriting
- NSPasteboardの仕組みを利用して書き込みができる
[Android] Introduction to APT
- Annotation Processor Tool
- アノテーションを使うとコンパイラがソースを生成してくれるやつ
- 実はJavaSE7でdeprecatedだったが、コマンドがjavacにとりこまれて、Pluggable Annotation Proccessing APIになった
- 便利annotationライブラリを作ってみた
- ライブラリの構成
- api: 利用者が触るやつで、クラスとか生成したりする奴
- processor: コンパイラが触るやつで、AbstractProcossorのサブクラス、その他コード生成に必要なロジックを書いていく
- javacのための入口を作るためにautoclassさんにお願いする
- 実際はJavaPoetというライブラリを使ってやってみたりする
- Compile TestingというのをGoogleが出してるので活用しましょう
@mogmetの所感
iOSエンジニアのため、iOSへの感想に偏ってしまいますが、以下の様なことを感じました
- swift2.0からprotocol extensionを使った実装が流行りそう
- CoreDataを使う機会があったら簡単に使えそうなCoreStoreを使うのは良さそうでした
- DataBindingLibraryは記述するcodeが減りそうで便利そうなライブラリでした。導入障壁も低いので中々良さそう
- TKRSegueOptionにはお世話になったこともありましたが、SegueContextももしかしたら今後アップルでもサポートされるかもしれないので是非使っていきたいと思いました。
- NSMutableDictionaryのsetObjectでのnil crushは一貫性がなくてよくわからない
- airbnb/DeepLinkDispatchのiOS版がほしい・・・
- iPadのMultitaskingでのweb表示は盲点でした・・・
今回もたくさんのライブラリやtipsなどが発表され、毎度ながら皆様のアウトプット意欲に感化されました。
自分もgithub活動など頑張らなくては・・・!