kumamotone’s blog

https://twitter.com/kumamo_tone https://github.com/kumamotone http://qiita.com/kumamotone

potatotips #59 に参加しました (iOS, Androidブログまとめ) #potatotips

potatotips #59iOSブログまとめ枠で参加させていただきましたのブログです。

f:id:kumamotone:20190301002053j:plain
会場

会場は GREE さんでした。

f:id:kumamotone:20190301001957j:plain
採用強化中+KMNZのチャンネル登録よろしくとのこと

以下発表内容です。参加枠としては Androidブログまとめ枠でしたが iOS の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

Page Object Pattern with XCUITest

speakerdeck.com

Page Object Pattern は DRY かつ Readable な UIテスト を実現できる

Firebase A/B Testingを使ってサーバ側までA/Bテストした話

Firebase A/B Testing エンジニアじゃなくても条件変えれるので便利

ModelをLayerで分けてUnit Testの観点を明確にする

speakerdeck.com

Layered Architecture にしてテスタブルにしてる 各層のテストの書き方を紹介

簡単にARアプリを作ってみよう

ARCore / SceneForm のおかげで3Dモデルの知識なくても簡単にARできる!ありがてぇ

SwiftでVRMファイルを表示してみた話

speakerdeck.com

github.com

VTuberKit 作った VRM読み込んでSceneKitで表示できるぜ! 実装を紹介 今はUnityのアニメーションをimportするのをやってる

ViewPager2をちょっとさわってみよう

speakerdeck.com

ViewPager2のIFはほとんど同じ RecyclerViewを使って実装されてる RTLサポート、縦方向ページングサポート、1のバグが治っているなど まだalpha

RxSwiftに対応したバリデーションをGenericなProtocolで実装してみた

extension ObservableType {
  func validate<V: Validator>(_ validator: V.Type)
    -> Observable<ValidationResult<V.ErrorType>> where V.ValueType == Self.E {
      return map { validator.validate($0) }
  }
}

RxSwiftのチェーン中に protocol Validator を実装したやつを実装したクラスを与えてバリデーションできるように、 ObservableType に extension 生やして解決した シンプル

github.com

AndroidX Navigationを導入した話

speakerdeck.com

そろそろstableのNavigation safeArgsでの方安全なFragmentArgsの生成、Deep Link、Transition Animation、Shared Element

Navigation 使うと常にバックキーで戻れるようになってしまうが Activity#addOnBackPressedCallback() を使ってハンドリングできる

逆引きRxSwift: 編集画面のViewModel設計と実装

note.mu

編集画面のViewModel設計。 startWith使うと双方向バインディングしながら初期値設定できる

AndroidアプリのUI/UX改善例その2

speakerdeck.com

項目が多いので https://github.com/mirrajabi/search-dialog というのを使ってフィルタリングできるようにした

教えて!Xcode

speakerdeck.com

Address Sanitizer は配列外アクセス等を検出できる Diagnostics から有効にできる(ObjCのみ) 詳しくは以下を見ると良い

qiita.com

Androidの状態管理をするライブラリOwlの紹介

speakerdeck.com

Reduxライクな状態管理ライブラリを作っている Coroutineを使った非同期処理の導入、Jobの管理、ViewModelとの統合

画面遷移が絡む値の受け渡しをRxSwiftで直列化してみた

speakerdeck.com

github.com

subscribe複数回書かないと行けなさそうな処理を呼び出すVCにObserverを置く→呼び出し処理をprotocolのextensionにして直列化した

あらためてLiveData

LiveData, MutableLiveData, MediatorLiveData の説明 わかりやすい

OWASP MASVS

OWASP MASVS は モバイルアプリケーションの基準となるセキュリティ要件

Immutable data holder

speakerdeck.com

Immutable な LiveData のみを公開しよう LiveDataならswitchMapで変換できる 拡張関数でより簡潔にできる

感想とか

f:id:kumamotone:20190301001938j:plain
すし

RxSwiftの話が何故か多かった気がする

NavigationやViewPager2とか新しいライブラリのTipsが知れてよかった

RxSwiftのバリデーション用のextensionは簡潔に書けてすき

VRMKitはシンプルにすごい

今回も最初からへとへとでついにちょっとしたコメントを書くのがやっとになってしまった

懇親会では個人的にも最近導入したLiveDataの話できたりとか、インターネッツではお見かけするREALITYの人ともお話できてなんだかんだよかった

potatotips #58 に参加しました (iOS, Androidブログまとめ) #potatotips

potatotips #58iOSブログまとめ枠で参加させていただきましたのブログです。

会場は FiNC Technologies さんでした。

f:id:kumamotone:20190128233606j:plain

個人的には今月のApp Client Melting PotというFiNCさん主催のイベント以来だったのですが、なんか重大発表でも始まるんかってぐらいおしゃれ会場でした。

以下発表内容です。参加枠としては iOSブログまとめ枠でしたが Android の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

RxSwift - テストスケジューラの解像度について / y.imajo さん

speakerdeck.com

RxSwift で .debounce() をテストする話。

debounce(0.3)なら 3.3 秒のタイミングとかでちゃんと発火されるかとかを調べたい。ただ仮想時間は整数なので現実時間指定の0.3と合わない… →仮想時間に変換すればOK

qiita.com

今からはじめるrobolectric / moriiimo さん

speakerdeck.com

RobolectricでUIテストを書いてみる。 @Config(sdk = [LOLLIPOP])sdkのバージョンを指定できる。.start() や .resume() とかでライフサイクルを呼べる。performClick クリックイベントを模することができる

Roomのテストを書いてみたい。書いてみた。context には InstrumentionRegistry.getInstrumentation().targetContext をつかう

アプリ内の絵文字をカスタム絵文字化した話 / RyoIzumi さん

iPhoneでもTwemojiを表示したい。Apple絵文字をちゃんとTwemoji化するのは意外と大変で、家族の絵文字をconvertすると家族分裂したりする。

詳しくはUnicode Emojiのことを勉強してくれという感じなのだが、emojicaというライブラリがあるのでこれが使える。

github.com

UILabel や UITextView 上のiOS絵文字をカスタム絵文字に変換できる。

日本語入力で UITextViewのmarkedTetRange が考慮されていないとか emoji 11.0 に対応してないとかあったが、パッチを送ってなんとかした。(emoji 11.0に関しては今送ってるところ)

Flankでテストを爆速にする / Kubode さん

speakerdeck.com

Flank はFirebase Test Lab を並列化するテストランナーで、Android/iOSに対応。導入が結構簡単。

github.com

なぜ導入したのか?CIテストに28分とか掛かる… そのうちgcloud(Firebase Test Lab)に18分掛かっていた。

導入した経緯としては、CI/CD Test Night #2 でBitriseの中の人が紹介していたので。

Flankの機能。YAMLによる設定の管理ができる。gcloud公式のYAMLと互換性のある記述が可能。FirebaseTestLabでやってれば移行が簡単。

シャーディング。これがメインなのだが、指定した数に自動でテストを振り分けることができる。各シャードで必ず実行するものを指定したりもできる。 testShards=-1にすると最速だがテスト数*1分の課金が発生し、270個のテストだと4.5ドルも掛かってしまう。いいあたりで調整する必要がある(8とか16とか)。

コストレポートが出せる。テスト結果はHTMLやJUnitXMLで出せる。

fastlane+Bitriseでやったが、./results/*/をコピーすればテスト結果をbitriseですぐ見れる。

もともとFirebaseを導入していたのでほとんどやることなかった。flank.jarは24MBもあるのでgit管理しない。

Flankでshard=16にしたら28分が8分になった。やったね

CI上で結果が見えやすくなりテスト項目の見直しに繋がった 速くなっただけでなく、未使用コードの削除や無駄なwaitに気づけるなど副次的な効果もあった

導入コストも金銭的コストもやさしいので、iOSにも導入したい

SceneKitでふんわりした影を描画したい / noppe さん

speakerdeck.com

iOS12 から usdz をサポートするようになった。

File アプリで プレビューやAR配置ができる。

Fileアプリで見ると影がきれいについている。これはWWDCで語られていた Contact Shadow(設置感・重なり感を出すもの)だと思われる。これをやってみたい!

SCNLight の castsShadowをONにして、directionalかspotタイプを使う。するとかなりはっきりした影ができてしまう。shadowRadiusというプロパティを使えばふんわりになるがなんか雑な感じ…

さらに調べていると、Contact Shadowとは耳慣れた言葉で言えばAmbient Occlusionのことであるという記述が見つかった(耳慣れたってなんだよ)

SSAO…ScreenSpaceAmbientOcclusionはカメラに生えとって実装できるが、ふんわりしない…ふんわりした影は自前でやらないと無理そう

SCNTechniqueという、マルチパスレンダリングのためnクラスがある。これは画面1回の更新の間に、異なるシーンを複数回レンダリングして合成した結果を表示する機能で、MetalやOpenGLESでシェーダを書くことができる。カメラを2つ配置して、下からの入力を深度に変換しブラーをかけるみたいなのを作ってみたが、モアレ(縞模様)ができたりしてうまくいかなかった。シェーダ真面目に書こうとするとサクッとできなさそう

最終的には、gobo(SCNLightの影を自前の画像で描画する機能?を使って、SCNTechniqueで深度画像に変換→SCNViewのsnapshotでUiimageで取得→ブラーかけて→goboに渡した

これではまだFileの表現に達してはいないが、今までのに比べればまぁまぁ見れるものができた

MDCのBottomAppBarのShadowの実現方法 / HiroYUKI Seto さん

speakerdeck.com

OSがShadowを描画する条件。

  • Android 5.0↑
  • elevation が 0 より大きい
  • Viewのアウトラインが四角形か、凸図形(凹んでいる部分がない=CONVEX_PATH)

BottomAppBarは明らかに凹んどるけど影がついてる。これどうしてるの

MaterialShapeDrawableを使ってるっぽい。でTopEdgeがMaterialShapeBottomAppBarTopEdgeTreatment。これはarcでくぼみを表現していて、TreatmentのgetEdgePathを見れば分かる。

setShadowCompatibilityModeをSHADOW_COMPAT_MODE_ALWAYS にすればOSがつける影以外が使える。ShadowRendererというのを使ってて、便利じゃんと思ったが、残念ながら @hide (IDE上で見えなくする?)や @Restricto(LIBRARY_GROUP) (ライブラリ内から呼ばないとwarining出る的なやつ?)アノテーションがついており、リフレクションとかしないと使えない。

スクリーンタイムと仲良くなる / 5mingame2 さん

speakerdeck.com

iOS11から純正のカメラアプリでQRコード対応している

ところで、スクリーンタイムというiOS12からアプリの使用状況を集計したり、時間制限をかける機能がある。時間制限が掛かっているとアプリ起動直後に落ちることがわかった。

どうやら制限掛かっていると、AudioSessionのコンテキストが取得できてない様子 didFinishLaunchingWithOptions: で初期化処理をしてたのだが、ここで落ちてる感じだった

UnityでiOSアプリをビルドするとXcodeのプロジェクトとソースが生成される。これを参考にした。するとここら辺 applicationDidBecomeActive: に書いてたのでそこに移動した。

いまさらWorkManager / どくぴーさん

speakerdeck.com

適宜実行されたり実行されたことの保証が必要なバックグラウンドタスクを扱う。compileSdkVersion 28。

シンプルでこれまで自前で実装しないと行けなかった要件、たとえばAPIレベル、Play Servicesの有無によるJobScheduler/AlermManager/FirebaseJobDispatcherの使い分け、バッテリ・通信状態などに合わせた処理などとかを自動でなんとかしてくれる

Workerについて。Worker を継承したクラスを作る。override fun doWork() 内で必要な処理を記述し、成功・完了に応じてWorker.Result.success/failureを返す(これ以前は定数だったので codelabs のコードを直接使うと死ぬ)

WorkRequestについて。Workerへ実行に必要なデータを与える(DataクラスをbuilderクラスでbuildしたものをsetInputDateでsetする)。注意点としては、でかいデータは与えられない。一度だけ実行できるものと定期的に実行させるものがある。

生成したWorkRequestの実行はWorkManager#enqueueするだけ。

複数のworkを連結したいときがある。WorkManager#beginWithでContinuationが返ってくるのでthenで連結とかすると、重複することがある。なのでWorkManager#beginUniqueWorkに変更する。でExistingWorkPolicyで実行中の処理に対する処理を変更する。

Workの実行状態を制限したいときは、実行時に制約(通信状態や、充電中かどうか‥など)が付けられる。uniqueIdを与えたContiuationはキャンセルできる。LiveDataとの連携、Rxサポートもある。

UIViewPropertyAnimator and Easing / TachibanaKaoruさん

speakerdeck.com

UIVIewPropertyAnimatorはiOS10〜なのでそろそろ入れてもいいんじゃないという感じ。

UIView.animate は都度アニメーションのようすを設定するが、 UIViewPropertyAnimatorは動きを宣言して、好きなタイミングで実行するようになった。イージングが簡単にできる。

制御点を設定できるのだが、結構難しい。カスタマイズするときはデフォルトで定義されているやつをちょっといじるのが良さそう。

既存のライブラリのパラメータを拝借してイージング用のUIViewPropertyAnimatorをいっぱい生やしたextensionを書いたので難しさ感じる人は使ってみてください。

github.com

既存プロダクトにダークモードを実装した話 / Hakuto Suzuki さん

ダークモード、目に優しいだけでなくコンテンツを目立たせることができる。(画像がいい感じに見える)

夜間の利用ユーザーが多いので導入した。CVR にも良い影響があった。

実装は AppcompatDelegate.setDefaultNightMode(AppcompatDelegate.MODE_NIGHT_YES) を設定。

WebViewへの画面遷移を挟むとなぜかDarkmodeじゃなくなるというバグがあった(GoogleのIssue Trackerに登録されている)遷移する前にWebViewの初期化を再度行うと回避できるっぽい

WebView怖い

Hint of “Passcode Lock” Screen and Logic (with LocalAuthentication). / fumiyasac さん

www.slideshare.net

パスコードロック画面作った。設計を紹介。

バックグラウンドに入るタイミングで上に画面かぶせる感じ。AppDelegate のライフサイクルでなんかやってる場合は処理がかち合うので注意という感じだった

詳細はQiitaで:

qiita.com

5プラットフォームをサポートしているプッシュ通知SDKをFCMに移行した話 / konyavic さん

speakerdeck.com

SDK開発者として実装に必要なステップを減らし、ドキュメントをシンプルに保つことを意識している。

アプリのグロスのためのSDKを作っていて、プッシュ通知、ABテスト、アナリティクスなどが利用できる。5プラットフォームに対応している。このSDKを2019年4月までにGCMからFCMに移行しないといけないことになった。

トークンの取得部分を変更することになったが、FCM、Tokenの取得メソッド多すぎ問題。FirebaseInstanceIdのgetToken()というのがあるがdeprecated。getInstanceId()は推奨されているけど新しすぎて、SDK利用側が利用できないかもしれない。結局はgetTokenなどでも使えるAPIは維持しつつ、getInstanceId()でtokenを取得するようにした。

つかおう!Storyboard / coffeegyunyu さん

speakerdeck.com

コードでUI書いてるとつらいときある。StoryBoardを使うと、iPadのときの文字サイズ、横向きにしたときの指定などが簡単に指定できる。

これにより、iPhone/iPadや横向き対応はもちろん、Container View、UISplitViewController、Pop Over、Form sheet、Slide Over、Split View、iPad ProのPortrait+SplitView+UISplitViewController、tvOS…などなど色々な UI の表示形式に対応することができる。

github.com

Visionとモザイクで遊んでみた / ochimさん

WWDCの資料とクラスメソッドのブログ見て実装した。VNDetectFaceRectanglesRequestで顔取れる。boundingBoxに位置が入っている。この座標系は左下起点のやつでUIKitと違うので注意。

CIFilterを使うとモザイクかけれる。boundingBox使うと顔だけモザイクかけれる。

感想とか

最近へとへとになりながら会場向かってへとへとになりながらメモりがちで懇親会の頃にはへとへと度高めだけど最終的には懇親会でいい感じに刺激受けれるしやっぱり今回も色々知らないこと知れたりして良かったな〜ってなるので良い

potatotips #57 に参加しました (iOS, Androidブログまとめ) #potatotips

potatotips #57iOSブログまとめ枠で参加させていただきましたのブログです。

会場は アイスタイル さんでした。

f:id:kumamotone:20181218192411j:plain
アイスタイルさん

以下発表内容です。参加枠としては iOSブログまとめ枠でしたが Android の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

[iOS] テストデータ自動生成方法の別解 / tattn さん

speakerdeck.com

ユニットテストでMockAPIClientを作るときに 特にViewModelなんかしんどい。ネストしたテストデータの初期化なんかが特にしんどい。

APIのレスポンスをテストデータに差し替える方法としては、たとえばprotocol で差し替えたMockAPIクライアントにデータを差し込む方法がある。

乱数で初期化してテストデータにするというのが良いんじゃないかと思った。

github.com

コード生成を使う方法と、リフレクションが考えられる。コード生成は外部ツールを使うことになるので今回はできればしたくない。

Swiftのリフレクションには、Mirrorというのがある。しかし使う前にインスタンス化が必要。というわけでCodableを使うのを思いついた。Randomizable というのを作った。

Randomizable に適合したやつのrandomValueを呼ぶとプロパティのランダムな値を返してくれて便利。ランダムのルールはカスタマイズできる。

実装は、RandomDecoder() っていうのを作っている。Randomizable に適合させると、 Decodable に適合している型であれば、randomValueの実装がいらなくなる。

実装はひたすら各型について書かないといけないので結構大変だが、とにかく乱数を返しているだけである。

ランダムなJSON文字列がほしければ、ランダム生成してDecoder使えば良い。コマンドラインツールとして活用できそうなので、SPM対応した。

Codable はリフレクションにも使える。黒魔術やリフレクション、コード生成など使えるものは何でも使って楽していこう

[Android] Firebaseで解決するAndroidの機種依存 / gyamoto さん

speakerdeck.com

Androidには機種依存がある。たとえばBLEのアドバタイズをおこなうと、出力強度とアドバタイズ感覚が機種によって異なるなど…

たとえばXperia 系は BLE の強度が弱い、Galaxy系は出力を挙げないとアドバタイズ系が安定しない、などBLE のパラメータは機種依存があることがわかった。

機種によって設定を変えてやりたいが、これをハードコーディングしていくのはつらい。

なので Firebase UserProperty と RemoteConfig でパラメータ設定した。

Firebase UserPropertyは言語や地域などユーザー層を示す属性を設定できるプロパティ。RemoteConfigなど、Firebaseの他のサービスでユーザー判定のフィルタリングとして使える。

RemoteConfig管理画面で設定した値を配信する仕組み。アプリから設定された値を取得して永続化、参照できる。

この2つを組み合わせる。以下のような流れでやれば良い。

  1. まず機種を特定できる端末情報をUserPropertyに設定
  2. UserPropertyから機種ごとの値をRemoteConfigに保存
  3. RemoteConfigによってアプリの振る舞いが変わるように実装

[iOS] RxSwiftとMVVMパターンと仲良くなる次のステップ / fumiyasac さん

www.slideshare.net

MVVM でアプリ作った。以下のようなことをした。

  • UICollectionViewをベースにしたカルーセルを表示する
  • ドロップダウンメニューから表示内容を変更する
    • メニューを Observable で表現
  • 初回表示状態からボタンを押すとまつ尾に10件ずつデータを表示する
    • BehaviorRelay で通信状態やリストを表現
  • インクリメンタルサーチで該当したデータを最大10件表示する
    • Debounce や Throttle を利用する

サンプル:

github.com

Qiita:

qiita.com

[Android] Empty State表示共通化の事例 / kentaro さん

speakerdeck.com

Empty State(○○はありません的な)の表示を共通化した。

Empty State表示、画面作成時に都度デザイン・実装していたのだが、画面によって表示がバラバラだし、そのたびに考えることが増えたりして大変だった。

通化することによって表示を統一して、コスト削減になった。

具体的な実装は、何がemptyなのかをenumで表現、Viewはカプセル化プロトコルとデフォルト実装などを使って綺麗に実装した。

楽できるところは楽して注力すべきところに注力できると良い。

[Android] Behavior of nested async in Kotlin Coroutines / URI さん

speakerdeck.com

Kotlin 1.3 になってCoroutineがstableになった。アップデートしたら、アップデート起因の不具合を埋め込み(流出はしていないが)、修正することになった。

バグ対応から学んだ、ネストしたasyncのふるまいと対応方法について簡単に説明する。

ver 0.30.0 から、ネストしたasyncのキャンセルが親のcoroutineにも伝播するようになった。たとえばlaunchで直接呼び出したasyncの例外が親のlaunchに伝播する。

解決方法を4つ紹介。1.withContext でコンテキスト切り替える。2.Globalscope.async でスコープを変える。3.CoroutineExceptionHandlerを渡して集約する。4.SuperVisionを導入する。キャンセルの伝播の方向を制御できる。supervisorScope {} というので囲めば、asyncを使っていても、asyncの例外が親のlaunchに伝播しないようになる。

以下の記事を参考にしました。

qiita.com

sys1yagi.hatenablog.com

[iOS] 生きた仕様書としてのUIカタログアプリ運用 構想編 / hiragram さん

speakerdeck.com

==前置き==

仕様書は死ぬ。

仕様書死なないでほしい。

なぜ死ぬのか?

ちまちま仕様書を更新しても死にゃせんから。

では短期的なメリットがあればいいのでは?

==前置き終わり==

仕様書に求めるもの

  • 画面にある全ての機能が網羅的に残されている
  • 画面にある全ての状態変数が網羅的に残されている
  • それぞれの状態のときにそれぞれの機能がどう振る舞うかが網羅されている

そして

  • 常に最新である

で、構想なのだが、UIカタログ的なアプリをシュッと作れる環境を用意したらいいんじゃない?と思っている。

各画面は表示に使うための情報を外から注入されるインターフェースをもつ。たとえばObservableとか差し込む。

何が嬉しいのか?

UIカタログを見てデザインチェックができるとか。開発的にも便利。疎結合になるのでAPIクライアントとかと別にビルドできる。とか。

[Android] KTSで社内マルチモジュールライブラリを配信する / Kubode さん

speakerdeck.com

なんで社内ライブラリの配信するのか?社内のデザインシステムのため。AARライブラリ化してmavenで配信したい。

デザインシステムっていうのはデザインの原則やコンポーネント群。これがあるので共通化できて楽。

Atomic Designはデザインシステムの設計手法の一つ。これをモジュールに落とし込んでみる。

mavenリポジトリをどうするか。GradleはS3のURIをサポートしている。認証ありもサポートしていて、S3にした。あとbitriseにアップロードするworkflowを書いた。

Androidはそのままではアップロードできない。できないというか pom.xmlの設定をめちゃくちゃ大量に書かないといけない。android-maven-gradle-pluginを使えば楽。

groupとartifactIdとversion を指定する。がアップロードしようとしたらだめだった。android-maven-gradle-pluginを使っていると古い方のがデフォで参照されて、新しいmaven-publishを使わないとS3の配信がサポートされないらしい。

maven-publishを使う版は無いのか?と思って探したらあった。android-maven-publish を使ったら良い。これで ./gradlew publish できた。

なにげに例に KTS が出てたけど KTS は問題なく使えるよ

[iOS] Appleの標準アプリで使われている半モーダルビューについて / idonuntius さん

半モーダルビューの定義だが、iOS8 の Apple Music で使い始められて、今ではメールやマップなど色々なところで使われているやつ。

半モーダルビューは「現在のタスクやワークフローをコンテキスト内で自己完結する機能を提供する」ものらしい。

モーダルビューは、タスクに戻るためにはサブタスクを終了しなければならない。

半モーダルビューに関してはキャンセルとかない。 WWDC で紹介されていた Redirect UI っちゅうやつだと思う。タスクとサブタスクを並列に実行できる。

iOS の標準アプリで半モーダルビューが増えているので、これから増えていくとおもう。

[Android] RecyclerViewとGridLayoutについて学んだ話 / nagais さん

1カラムのViewと2カラムのViewが混ざっている画面を作った。

GridLayoutManager をセットした RecyclerView を使用して、モデルごとにViewTypeを設定、 GridLayoutManager が SpanSizeLookup というのを持っているので、モデルの持っているViewTypeごとに変えれば良いことがわかった。

[iOS] 久々のiOSリリースあるある / 5mingame2 さん

久々のiOSリリースで色々ハマった。

GameCenterでエラー。ios10でgemecenterにログインしているはずなのにスコア送信とかできない‥ボードとかも真っ白これはGameCenterからサインアウトして再サインアウトしたらなおった。利用規約の変更でアカウントで止まっていたっぽい

審査出す時のValidationでエラー。Launch Screnn File のファイル名から.xibを削除したら通った。

審査でリジェクト。ゲーム中にスナップショット取ってストレージに保存することができるのだが、ユーザーに使用用途を明確に伝える必要がある。Info.plistのNSPhotoLibraryAddUsageDescription/NSPhotoLibraryUsageDescriptionに設定すればOK。

ソースコード公開したよ:

github.com

[Android] Android開発でmitmproxyを使った話 / bigbackboom さん

speakerdeck.com

responseの値を書き換えて本番環境でアプリの強制アップデートのテストがしたい。Charlesがなんかうまくいかないのでmitmproxyでやってみた。

https が拾えてなかったけど、 app/src/main/res/xml/network_security_config.xml を作って信頼する証明書を設定、AndroidManifest.xml で networkSecurityConfig を設定すればOK。

実は以下でハマってただけでCharlesでもできた。

qiita.com

[iOS] 読んで良かった本をiOSエンジニアに紹介する / よっしーさん

いろいろ紹介。

感想とか

f:id:kumamotone:20181218211256j:plain

最近 Kotlin Coroutines を書いていて、ちょいちょいどうすればいいのか迷ってることとかあって懇親会で聞けてよかった。

potatotips #56 に参加しました (iOS, Androidブログまとめ)

potatotips #56iOSブログまとめ枠で参加させていただきましたのブログです。

会場は スマートニュース さんでした。

f:id:kumamotone:20181218154453j:plain
地球くん

地球くんかわいいですね。

以下発表内容です。参加枠としては iOSブログまとめ枠でしたが Android の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

Best Bugs 2017 in SmartNews iOS / aramaki さん

www.slideshare.net

スマートニュースであった2017年の面白いバグ(単純なバグではなく、ちゃんと書いているのに予想外の動きをするもの)を3つピックアップ。各々ワークアラウンドで解決して対処。

Android 8.0のPush受信時のサービス起動について / hideoさん

speakerdeck.com

Pushを受けた後に処理をServiceに委譲し、別途我道を取得してNotificationを出していた すると、Android8.0でstartService()したときにIllegalStateExceptionになってた どうやらpush受けてからstartServiceまでに時間がかかりすぎると起こったりするらしい

おそらくアプリではどうしようもないところで時間を食ってしまっているので、startServiceに失敗したらとりあえずService使わないことにした(画像が表示されなくなることにはなったが、画像が表示されなくてもリアルタイムで通知することを優先した)

Redirectable in App? / ushisantoasobu さん

speakerdeck.com

Redirectable =思考の方向転換や割り込みに対応(ジェスチャーしているときのジェスチャーに対応する)。

iPhone X が出て1年、徐々にRedirectable なUIが浸透してきたのではという持論。

How to contribute GPUImage-android / kettsun0123 さん

speakerdeck.com

iOS の GPUImage framework を 参考にしたライブラリがある。

github.com

contributeするにはどうしたら良いか?一番簡単なのはフィルタを追加すること。本家に比べてまだまだFilterがたりない。

リストからまだ作ってないフィルタを選んで、作って、sampleを作って試して、PRを出せばOK。

静的な定義で動きのあるレイアウトを作る(AutoLayoutライブコーディング) / kishikawa katsumi さん

speakerdeck.com

blog.kishikawakatsumi.com

のライブコーディング。

  • 親の親のViewとの制約つけるときは Align 使うとやりやすい
  • 優先度の異なる複数の制約を同時に定義することで、静的な定義だけで切り替え(動的な振る舞い)を実現できる

5分でわかるKotlinコルーチン / shogo.yamada さん

speakerdeck.com

  • Coroutineは関数の途中で中断させたり、再開させたりするやつ。Retrofit と組み合わせて使えるよ
  • 単純に RxJava の代替とはいえない

UIGestureRecognizer と UIResponder の違い / やまださん

speakerdeck.com

以下のようなことをしたい。

  • タップ位置に点を描画
  • ドラッグで描画したものを移動
  • ダブルタップで拡大縮小

  • UIGestureRecognizerで良いんでは?と」思ったけど遅い 時間もはかってみたが、 ワンテンポ遅れて描画される

  • タップした瞬間に描画したい場合は UIResponder を使ったほうが良いかも

OSS開発のリテラシー / Android編 / gfx さん

gfx.hatenablog.com

Orma を例に、OSS を開発するときに満たさなければならない/満たしててほしいこと

MUST↓

  • ライセンスを明記
  • READMEを置く
    • Ormaを参考に
  • リリースしたら git tag を打って push する
    • 手でやると忘れるので自動化できると良い
  • CIを設定してバッヂをREADMEに置く
    • テストがなくてもCIの設定はすべき
  • アーティファクトのgroupIDはライブラリ固有のものにする
    • artifactIdにも ライブラリ名を含めるほうが良い
  • bintray に成果物を公開するときはライブラリごとにorgをつくる

Fluid Interfaceの実践 / SCENEE さん

speakerdeck.com

Map とかにある下からにゅっと出るやつのライブラリを作った(ありがたや)

github.com

ScrollView はプリミティブな Fluid Interface。予測可能な動きを実現する処理のひとつとしてprojectionがある。物理法則をコードに落とし込んで実装。

Appstoreconnect api with Open API Spec / d_date さん

speakerdeck.com

AppStore Connect API 出た

github.com

Open API Spec。Swagger Codegen 作ってた人たちが fork して作ってる。今のバージョンは3。

バージョン3の oneOf なのだが、Swiftのコード生成に関してはAnyに変換されてしまいCodableに適合できていない状態 みんなで作りましょう

もっと! Alternative Resources / takasfz さん

speakerdeck.com

良い年月日入力フォームを作るみたいな記事があって、英語圏の PC Web の話だが、以下とかを満たすのが良い入力フォームだと言われてた。

  • 月/日/年にわかれてる
  • 適切なラベルが付いている
  • テキストフィールドのサイズが入力するもののサイズと合ってる

日本語圏なら 年/月/日にしたい…こういうリソースの出し分けってどうする?Alternative Resourcesつかえばできるよ。

作り方。リソース追加ダイアログでぽちぽちする。

言語や国、キャリア、画面サイズ、APIラベルによって、画像、レイアウト、文字列、とかとか出し分けれるよ!便利

Dribbbleで見つけたコンセプトデザインの実装 / edm さん

dribbble.com

を実装した。

  1. スクロールと合わせて数値を表示
  2. 背景色のグラデーションを追加

とかあるが、2について話す。

touchesMoved でスクロールに応じての水温の計算したりする。

github.com

おそらく解説↓

qiita.com

Dynamic Links 知られざる?Firebaseの秘技 / なかてぃる さん

speakerdeck.com

Dynamic Links は Firebaseが提供しているアプリに対するすごいリダイレクトリンク。AndroidiOS、PCに応じてリダイレクトしてくれる。

アプリのインストール有無を判定できる上、ストアからのインストールを挟んでもディープリンク発火できる。使い方。パラメータをクエリでつめてく。d=1 でデバッグ

アプリ側もふつうに対応する必要はあり、iOS→ユニバーサルリンク、Android→Intent Filter でスキーム起動できるようにしておくようにはする必要ある。

RxSwiftのエラー分岐Tips / y.imajo さん

speakerdeck.com

異常処理系のパターンはいろいろあるが、 materialize() を使うとひとつのObservable から正常系とエラー系のObservableに分けられる。

-AndroidiOSどっちが早く作れるか-今夜くらべてみました / kboy さん

note.mu

  • ぽちぽちやってたら Firebase につながるので IDEでFirebase使うのはAndroidのほうがはやい
  • ドロワー デフォルトであるので Androidのほうがはやい
  • Firebase の JSONパース toObject メソッドがあってAndroidだと楽

Koin x AndroidでMVIアーキテクチャを採用する / itome さん

speakerdeck.com

github.com

MVIはModel-View-Intent(android.content.Intentではないよ)。RxJava / Kotlin での実装例を紹介。

良いと思ったとこ。

プログラマーに対する制約が強く、テスタブル、エラーハンドリングが容易(Rx使ってるので)で良い。

良くないかもと思ったとこ。

1回きりのイベントを伝えるのが難しい、複雑なレイアウトではViewStateの更新の処理が重くなる、冗長になりやすい。

感想とか

余裕がなく記事まとめ雑になり申し訳ない気持ちがありますが、なんだかんだ行くと懇親会とかで刺激を受けてやっぱポテチええな〜となりますね

Xcode 10 にして Swift 4.2 対応した

iOS12 対応やってた方々からすると今更感あるかもしれないけど、本日(日付的には昨日) Xcode 10 が正式リリースとなったので、重い腰を上げて(本業とは別でやってる)アプリの Swift 4.2 対応した。

All Fix Issues

思ったより名前が変わったンゴよというやつがあったので、めんどいなーと思いながら、そういやファイル内のぽちぽち全部自動でやってくれるやつなかったっけ?と思って調べた。

あった。Editor > All Fix Issues (ctrl+option+cmd+F) でいいっぽい。

これを使って一括でやっていった。

このメニュー、 Xcode 9 あたりではなんか一時的に無効になってた気もするのだが(気のせい?)、普通に使えた。

自動で書き変わらんかったやつ

ほとんど All Fix Issues するだけでよかったのだが、そうじゃないのももちろんあった。

UIEdgeInsetsInsetRect(rect, insets) → rect.inset(by: insets)

ググったら https://github.com/dani-gavrilov/GDPerformanceView-Swift/pull/20/files が 出てきたので参考にした。

NSNotificationName. UIDeviceOrientationDidChangeNotification → UIDevice.orientationDidChangeNotification

長い…

NSNotificationName を NSNotification.Name に変えるだけでXcodeくんが満足してしまったので、オイオイ待ていとなって、

うーんどうしようかなと思ったのだけど、 1回前半を削って「UIDeviceOrientationDidChangeNotification」にしてみたら正しいのをサジェストしてくれるようになった。

このアプリ画面回転することは無くなったので、結局これは死にコードなのだが…

New Build System

リネーム以前にとりあえずプロジェクト開いたときにビルドを拒否られた。

:-1: The new build system doesn’t yet support On Demand Resources; if you require ODR, the legacy build system can be reenabled in File > Workspace/Project Settings…. (in target 'xxxxxx')

言われるがままに File > Project Settings (WorkSpace Settingsの場合もあるかも)から「Legacy Build System」にしたら一応通った。

ググったけど全然情報が出ない アタイも New Build System とやらを使ってみたいよ

(追記)ODRはリソースが必要になったときに追加ダウンロードするようにできる仕組み。使ってないけどなぜかONになってた。Build Settings > Assets の Enable On-Demand Resources を切ればいいっぽい(参考: App Thinning メモ

f:id:kumamotone:20181012001034p:plain

へーってなったやつ

  • bringSubview(toFront: titleLabel) → bringSubviewToFront(titleLabel)

  • sendSubview(toBack: mainColorView) → sendSubviewToBack(mainColorView)

これ昔に戻ったって感じなんかな? どっちでもいいけど

toggle()

これでコンパイルは通るようになったが、 Swift 4.2 の機能を先取りして生やしとるもんがあったなと思ったので掃除した。

その1。

extension Bool {
    @_inlineable
    public mutating func toggle() {
        self = !self
    }
}

Swift 4.2 のプロポーザル見てこれええやんってなって入れてたやつ、役目を終えたので消した。

extension Int {
    @inlinable
    public mutating func toggle() {
        if self == 1 {
            self = 0
        } else if self == 0 {
            self = 1
        }
    }
}

派生してこんなもんも生やしていた。

こんなもんを使わんといかん状態がまずダメじゃね?っていう話もあるのだが、これは消すとコンパイル通らんのでひとまず残した。

CaseIterable

その2。

人のを参考に EnumEnumerable という名前で生やしていた。

protocol EnumEnumerable {
    associatedtype Case = Self
}

extension EnumEnumerable where Case: Hashable {
    private static var iterator: AnyIterator<Case> {
        var n = 0
        return AnyIterator {
            defer { n += 1 }
            
            let next = withUnsafePointer(to: &n) {
                UnsafeRawPointer($0).assumingMemoryBound(to: Case.self).pointee
            }
            return next.hashValue == n ? next : nil
        }
    }
    
    static func enumerate() -> EnumeratedSequence<AnySequence<Case>> {
        return AnySequence(self.iterator).enumerated()
    }
    
    static var cases: [Case] {
        return Array(self.iterator)
    }
    
    static var count: Int {
        return self.cases.count
    }
}

結構使っているところが多く cases を allCases という名前にするのがめんどくさかった。 cases という比較的何かしらに混ざってそうな名前を一括で置換するのは若干こわいので、目視で確認しながらやってた。

しかし、やり終わってから気づいたが、予め Xcode のリネーム機能で EnumEnumerable の cases を allCases にしておけば、EnumEnumerable を CaseTerable に置換するだけで良かったんじゃねともおもった。

そんなに規模の大きいアプリでなかったのでこの程度ですみました。おわり

potatotips #54 に参加しました (iOS, Androidブログまとめ)

potatotips #54iOSブログまとめ枠で参加させていただきましたのブログです。

会場は eureka さんでした。良いオフィス。個人的に今年割とよく来ている気がする。

f:id:kumamotone:20180823195824j:plain

以下発表内容です。参加枠としては iOSブログまとめ枠でしたが Android の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

1日でできる!ARCoreことはじめ / zukkey59 さん

speakerdeck.com

ARCoreの話。SceneForm について。シーンを構築して生成される仮想オブジェクトであるNodeを追加する。

SceneForm でできること。

  1. AndroidWidget を表示
  2. 丸、四角、円柱などの表示 (MaterialFactory)
  3. 3Dモデルの表示 (objファイルを import してつかう)

やり方はスライド参照。Unity 使わずに Android Studio だけでも割と簡単にARできる。

Swifty range operator and CIDetector power / aymenworks さん

speakerdeck.com

いろいろな Tips を紹介。

  • ~= 演算子について。区間演算子というパターンマッチに使えるやつで、 Swift 4.2 で allSatisfy が コレクションに生えたので、みんなの年齢が18〜25歳に入るかみたいなのが ageArray.allSatisfy { 18...25 ~= $0 } みたくすっきり書けるようになってよかった。
  • CIDetector で簡単に表情とか目の動きが取れるようになった。
  • bwhiteley/JSONShootout というのがあって、Swift JSON mapper のパフォーマンスを比較している。

OculusGoの開発Tips / 五代さん

Oculus Go で VR テニスゲーム作ってる。Unity で開発した。

Oculus Go はあんまりスペックの高くないAndroid端末で、高リフレッシュレート維持しないと酔うという特徴があるので、軽くするために頑張った。

  • シェーダーのすげ替え
    • スマホは画面小さいのでハイクオリティなシェーダーは不要。たとえばUnityちゃんの場合UnityChan/Skin以外のシェーダーはすべてMobile/Diffuseでそれなりに見える。
  • ドローコール軽減
    • Unity のUIはドローコールが多くて重いので、UIパネルをテクスチャ化

開発の極意は、適切なチェックボックスにチェックを入れる。もしくは外すこと。

edirrevro tfeL-ot-thgiRa / daybysay さん

speakerdeck.com

U+202E に注意。VTuber用ライブアプリを作っていたのだが、表示がおかしくなることあった。なんかユーザー名とコメントがひっくりかえっている?

よく見ると、ユーザー名の戦闘にU+202E(Right-toLeft override, RLO)が入っていた 強制的に右から左に文字をやるやつ。

どういう挙動かは Playground で確認できて、 \u{202e}Hello \u{202e} World とかやると表示だけでなくカーソルまでしっちゃかめっちゃかになる。

どうすればよいか?まあトリム or 拒否という感じになる。たとえばユーザー名はTwitterは不正な文字判定してエラー、投稿の場合トリムして投稿としている。判定は str.contains("\u{202e}") で可能。

モバイルアプリのアクセシビリティ / stzn3 さん

speakerdeck.com

情報アクセシビリティとは、方法と状況によらず、誰もが情報を等しく取得できること。

アクセシビリティは障害がある人のものと思われがちだが、健康な人も悪状況で情報にアクセシブルにならなくなることはある。アクセシビリティは万人に対して必要。

Web Content Accessibility Guidlines(WCAG) が 今年 2.1 になって、モバイル(Web)関連の項目が強化された。

ネイティブアプリも同じで、Material Designや HIG 読めば、アクセシビリティについて記載がある。

できることはいろいろあるが、全部やるべきというわけではない。自分のアプリに必要なものはなにか、考えてみましょう。

uber/motif / shaunkawano さん

speakerdeck.com

github.com

Uber が10日ぐらい前にだしたDIのライブラリ。

わかりやすいAPIを提供する。Componentがネストしているような場合でも簡潔に書ける。内部でDaggerを使っている。絶賛開発中。どのくらい絶賛開発中かというと、毎日リリースあるみたいな速度感。

使い方紹介。interface とその内部クラスで表現する。 Daggerでいうと、 @motif.Scope が Component、@motif.Object が Module、定義している関数が @Provides みたいなノリ。

生成コードはDaggerにかなり似ている。中でDagger使っとるので。

じゃあDaggerと何が違うか?覚えていないといけない概念の数が違うと言われている。

Dagger、成し遂げたいことに対して覚えないといけないことが多すぎる。それに対して、motifは、拡張性をある程度犠牲にして、使いやすさ、シンプルさを追求している。

UICollectionViewを便利にかけるライブラリを作りました / bannzai さん

speakerdeck.com

qiita.com

UICollectionViewを便利にかけるライブラリを作りました。どう便利か。

UICollectionView の嫌なところ。switch でパターンマッチしないときがfatalError、散らばるForced Unwrap、コードの近いところに書いてある要素の関連性が薄い。

conv 使うとこうなります。

collectionView
        .conv()
        .create(for: SectionType.elements) { (sectionType, section) in
                switch sectionType {
                case .users:
                        section.create(for: users) { user, item: Item<UserCell> in
                            item.reusableIdentifier = "ACell"
                            item.size = ...
                            item.configureCell({ cell, _ in
                                cell.configure(with: user)
                        })
                }
                case .hobbies:
                    section.create(for: hobbies) { hobby, item: Item<ItemCell> in
                            item.reusableIdentifier = "BCell"
                            item.size = ...
                            item.configureCell({ cell, _ in
                                cell.configure(with: hobby)
                        })
                }
                case .teams:
                    section.create(for: teams) { team, item: Item<ItemCell> in
                            item.reusableIdentifier = "CCell"
                            item.size = ...
                            item.configureCell({ cell, _ in
                                cell.configure(with: team)
                            })
                }
        }
}

不満な点が解消されて良い感じですね。スターください。IGListKit と同じ差分更新のアルゴリズムを採用しているのでパフォーマンスが良い。

Androidにおける歩数取得とバックグラウンド制限 / KensukeIzumi さん

www.slideshare.net

歩数取得どうするか?Google FitAPI使うか、センサーから取得。センサーならSensorListenerか加速度センサーと自磁気センサーで頑張る感じになる。

ただ、ビジネス要件が満たせなかった。FitAPI から取得できる歩数とGoogleFitアプリで表示される歩数が異なったりして困る。

歩数センサーから取得するの、Android従来はゆるふわだったがだんだん取締り厳しくなってきた。Android 6.0でDozeモード、Android P ではついに backgournd からセンサーに一切アクセスできなくなってしまった。

サービス終了時にAlarmManager再起動とかバッドノウハウで頑張ってたが、結局ForegroundService で起動するという正攻法に落ち着いた。ただこれやると通知に居座られるので鬱陶しいので注意が必要。

FitAPIで実現できなければおとなしくForegroundServiceでSensorをobserveしましょう。

AndroidエンジニアがiOS開発を始めてつまずいたこと / nankiti さん

scrapbox.io

Androidエンジニアだったがリソースの関係でiOS開発始めるようになった。いろいろ違いを紹介。

運用の差異、IDEや言語など違うとこがいろいろある。ライブラリとか、あと画面遷移がプッシュ/モーダル型かバックスタック型かみたいな違いとか。

(仮)Ripple再考 / yiwaisako さん

Ripple(Material Design の波紋エフェクト)の実装について。

実装 Lolipop 以上は Ripple, Kitkatは別のタッチフィードバックを表示する。

CardView の foreground に Ripple のリソースを指定してやることになる(RelativeLayoutだとLolipopで動かないので注意)。Kitkat も対応したい場合はコードで出し分け。

C++で作ったアプリのローカライズ手法について / 5mingame2 さん

Presentations by Nobuyuki Nishiyama - Speaker Deck

ローカライズほぼ翻訳なのだが、他の地域の人が快適に使えるようにする、みたいな意味もある。鉤十字はだめとか

今回は翻訳の話。まずFont Awesome とか使ってなるべく文章量を減らしてアイコンを多用するとローカライズの手間が減るよ。

あとは Localizable.string を使って、 Objective-C++ 経由で C++ からでも利用することができる。

動作確認は、Xcodeのスキームに設定があるので、ここで切り替えればわざわざOSの言語環境替えなくても良い。

Share apk via Bitrise / kaelaela さん

speakerdeck.com

Bitrise + Slack で簡単に apk 配布したい。

f:id:kumamotone:20180823203702p:plain

やり方。トークン作ってprojectに追加。Bitrise start build step を追加。Deploy to Bitrise.io step の追加、Send a Slack Message の追加。

Slackに通知するためのURLとかはシェルスクリプト環境変数に登録する。

環境変数使いたいときの注意点なのだが、 bitrise だとenvman add という専用のコマンドがあるのでこれでやらないといかん。

ヘッダコメントを読む時 / kameike さん

speakerdeck.com

UIView.addConstraint のコメント見たら、将来deprecated になるよとか書いてた。それで思ったのだが、ドキュメントになくてヘッダコメントにある情報ってどういうものがあるんだろう?

見てみたとこの所感。

  • default値はヘッダ値が使われる際のデフォルト値とかも。
  • 一覧性が良い (ドキュメントはページ遷移)
  • ドキュメントよりコメントがラフ

ドキュメントになった際に省略されたりしてた情報。

  • ほかを参照すればわかる副次的な情報
  • 端的な例
  • 具体例
  • hugging , compression
  • 他のコメントへの誘導

ヘッダにしかなかった情報。

  • 将来deprecatedになりそうなやつ
  • 想像できる細かい仕様
  • 最適化の話

これはヘッダを読んで得られた豆知識ですが、2009年から IBは ver.3になったらしい。これも豆知識ですが、 alimentRectのデバッグをUserDefault つかえばコードからもできる。

ドキュメントはちゃんとまとまっているので、ヘッダにしかない情報というのはまあほぼない。が簡潔で分かりやすかったり、豆知識が手に入ったりして面白い。

ヘッダを読むのはこんなときがおすすめ!

  • default値が知りたい
  • ガイドラインとドキュメントの中間的存在として
  • 不可解につまづいたとき
  • 暇な時

Android/iOS端末間でデータを送る。BLEで。 / coffeegyunyu さん

www.slideshare.net

BLEでは大きなデータの送信はできない。データを分割することになる。MTUを調整することで最適化をはかる。

Android(Central) から iOS(Peripheral) にデータを送りたい場合。requestMtuで、MTU(一回の転送量)をPeripheralに要求することができる。BluetoothGatt.request(517)で要求するのが良い。Android側はMTU-5のサイズで送る。

逆の場合。iOSはMTU変更通知を勝手に行う。コントロールできない。なのでPeripheral側はCentral側のMTU値を覚えておく必要がある。iOS側はPeripheral柄にMTU値の読み込み要求を行う。データ分割は自分と相手のMTUを比較して、低いほうでデータ通信を行う。

端末の最適なMTUを取得する方法を教えてください。

感想とか

U+202E、あんま意識したことなかったので身近なところでこっそり試してみようかなと思った。

uber/motif、安定してきたらまた見てみたい。Dagger2は複雑すぎてほぼほぼ使えてないので、もっとシンプルなのがほしい。

私事ですが来週iOSDCで発表するプレッシャーがあって、懇親会で相談したらちょっと気分が軽くなってよかった。

potatotips #53 に参加しました (iOS, Androidブログまとめ)

potatotips #53iOSブログまとめ枠で参加させていただきましたのブログです。

f:id:kumamotone:20180727000359j:plain

会場はマネーフォワードさんでした。新オフィスきれい…

f:id:kumamotone:20180727000416j:plain

以下発表内容です。参加枠としては iOSブログまとめ枠でしたが Android の発表内容に関してもまとめています。

気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

Optional(2018)年...その後 / tamadon さん

speakerdeck.com

Optional(2018)年あけましておめでとうございますというプッシュを打ってしまったという事件があった。

moneyforward.com

これを機にwarningを撲滅すべく、iOSエンジニアを結集して取り組んだ。

最初warningが20,000件、ビルド時間1293秒とかあったが、インデントや、簡単なのを潰しただけで1000件強まで潰せた。

ライブラリをCocoaPods等利用せず導入していたが、ライブラリのバージョンをコミットログから推測して影響範囲を調査、CocoaPodsに乗り換えた。

ライブラリに独自実装を追加している部分は、そこを調査してforkしたライブラリに移行した。

そうこうして3ヶ月頑張ったら、ワーニングが2万件以上あったのが1件になり、ビルド時間も265秒になった。

最後残った1件は課金のレシートがiOS6形式だからというやつなのだが、現在取り組んでいる。ここらへんが可視化されただけでも良かった。

AndroidXに移行するために / syarihu さん

speakerdeck.com

みんな使っている Support Library、サポートされているのはv14以降だけなのに名前がv7とかになっていて混乱を招くので、support Libraryはv28で終了し、今後は Android X にすべて統合しようというムーブがある。

移行大変そうだが、移行ツールがあるのがあるので使ってみた。

やってみると shortcuts.xml と aapt2でエラーが出た。色々なパッケージ名それぞれで動的に切り替えるようにしてて、リソースの出力が生のxmlファイルだったのだが、圧縮されたflatファイルが生成されるようになったため、そこを迂回する必要があった。

また、Migrate to... を使ったら DeepLinkDispath でハマった。android.enableJetifier が true になったことによって問題が起きていた。これはissueとPRは立っているがまだ解決されていない。

とりあえず今のうちに一回Migrate書けてみて、どのくらいハマるのか見ておくのは良さそう。特にOSSをたくさん利用しているプロジェクトは注意。

Kotlin と比較して理解する Swift 5 で実装されるかもしれない async/await について / y.imajo さん

speakerdeck.com

Swift で今後導入される予定の async は、非同期関数にasyncをつける、awaitで結果を待って取り出すように記述できる。

Kotlin で同じように書こうとすると、Kotlin way にならない。基本は suspend fun でやって、並列処理の待ち合わせだけ async でくるむ。

Swift5でもFutureというものを自分で作って、それでくるんで.getで取り出せば複数処理の待ち合わせができるということがプロポーザルに書かれている。

Tips for migrating to Picasso2.71828 / chiiia12 さん

speakerdeck.com

Picasso を migrate したらつらかった話。

2.5.2 で、一部の端末で画像が表示されない問題があった。原因はわからんけど Jake は v3.0.0 で試してみてと言っている。3.0.0はまだメジャーリリースじゃないので2.71828 にmigrateすることにした。

withがgetになってたりしたりするが、あんまり難しくなく移行できた。

が、コールバック帰ってこないことがたまにあり、つらかった。

結局、Okhttp3Downloaderを使っているところで問題があることがわかった。Okhttp3Downloader は複数あるっぽくて、 JakeのものではなくPicassoのものに変更して解決した。

ブログにも書いたのでご参照ください。

chiiia12.hatenablog.jp

ゆるく学ぶARKit / mcz9mm さん

speakerdeck.com

ARKitでできることを紹介する。

まず平面、垂直、画像の検出。これはARKitがよしなにやってくれる。2.0では複数の画像を同時に認識できるようになった。

3Dオブジェクトの認識。あらかじめ物体のスキャンを行いモデルを作成する。他のアプリから読み込みも可能。オブジェクトの名前も取れる。

AR空間の共有(2.0〜)。Shared experience を用いて、複数人での共有、保存と呼び出し、ARMappingStatusで計測の状態を確認できる。

Quicklook(2.0〜)。これ使うとARKit使う必要なくなる。.USDZを読み込んでAR上に表示。表示だけであればアプリ側の実装は要らない。

Quicklook に関しては以下のページが良いので見ると良い(iOS12, Safariで閲覧できる)。

ARKitshop.magnolia.com

Cloud FirestoreでのClient Side Joinについて / shogo.yamada さん

speakerdeck.com

Client Side Join の概要と実装方法を紹介する。

Client Side Join とは、Firebaseの別コレクション同士の情報をクライアントサイドでjoinして画面に表示させること。

ユーザーが表示しているグループ一覧を表示したいという例を考える。ユーザーコレクションと、グループコレクションというが作られているはずで、これをJoinする

実際のAndroidアプリの実装としてはユーザーが所属しているグループIDを取得しにいく→取得したID一覧をRecyclerViewのセルを生成するAdapterに渡すという流れ。

qiita.com

Farewell SnapKit / kameike さん

speakerdeck.com

SnapKitよりもNSLayoutAnchorの方がDX(Developper Experience) が高いと感じるし、寿命も長いと思うので使っていったらいいんじゃないかという話。

SnapKit は equalTo の後に設定できる型が多様すぎて、書き方によってはありえない組み合わせのものが出来上がったりする。AnchorのほうはNSLayoutXAxisAnchorしか入らんとかになる。

SnapKit の edges が使いたいときは10行ぐらい extension を書けば良い。

SnapKit もまだ保守されているのでまだ慌てる時間ではなさそう。

J2Kコンバータをカスタマイズする / paraya3636 さん

speakerdeck.com

J2Kコンバートで苦労した点。J2KコンバータがNonNullに強制変換してしまう。

温かみのある方法はしんどい‥→J2Kコンバータをカスタマイズ すればいいんじゃないか

Kotlin の TypeConverter.kt を編集して実行すると、Nullable にしてくれるようになった。これで気軽にコンバートできるようになった。

Custom URL Schemeを支える技術 / ぎぎにゃんさん

speakerdeck.com

Custom URL Scheme に対応すると、Safariからアプリの特定の画面に直接遷移することができる。

しかし、Schemeの一覧性が低い、URL中に含まれる文字列やQuery Parameterのパースが面倒という問題がある。

pokedex://pokemons/25 というのをハンドリングしたい場合を考える。普通にやろうとすると結構めんどくさい。のでライブラリ化した。

github.com

これはURLスキームを開くと、open url に渡ってきてよしなにしてくれるというライブラリ。

使い方は Appdelegate で router というのを定義して、 func application()router.openIfPossible(url, options: options) を呼んでやるだけ。

: から始まるパスにマッチした文字列を任意の型で取得することができる。

値のキャストはどうなっているかというと、Extractableというプロトコルと実装している。

type=water というのを enum で受け取りたい場合があるが、これもできる。type=water,grass のようにタイプが複数になった場合も、Swift 4.1 の Conditional Conformance で [Extractable]Extractable に準拠させることで実現できている。

Swift 4.2 から実装される @dynamicMemberLookup を使うとプロパティを動的に生やすことができる。これを宣言すると、subscript(dynamicMember:)の実装を読みに行き、プロパティを生成できる。

そうすることによって pokedex://pokemons/:pokedexID のルーティングを let pokedexID: Int? = context.arguments.pokedexID で取るといったことができるようになった。

まだ master へはマージしていないが機をみて入れたいと思う。

今日話した内容はブログにも書いてあります。

techlife.cookpad.com

sharedUserIdを使った俺得開発ツールの作り方 / Takao Sumitomo さん

www.slideshare.net

アプリ開発デバッグ用の画面を作ることありますよね。そのために内部リリース版を作ったりする。

ここで課題「開発用のサーバーに向き先を変えたい」→これは設定画面に書き換え機能を作って解決した。

しかし、初回のプロセスの立ち上がり時の通信先を変えたいということがあった。これは設定画面では対応できない…

sharedUserId … AndroidLinux のユーザーIDを共有する仕組みがあり、通常アプリごとに異なるユーザーIDが割り当てられるが、意図的に同じユーザーIDにもできる。

これを使って開発ツールを作った。アプリを起動しなくても各種プリファレンスの書き換え、エンドポイントの書き換えができる。

はじめての VoiceOver 対応 / RyoAbe さん

speakerdeck.com

アクセシビリティの属性には5つある。

  • accessibilityLabel - ラベル
    • 画像のみのボタンには label をセットさせることが必須
  • accessibilityTraits - 特性
    • Cell にはデフォルトっではtraits は何も設定されていない
    • ボタンならbutton、リンクならlink みたいにする
  • accessibilityHint - ヒント
    • ラベル、特性だけでは補えない情報
    • たとえば「ここをダブルタップしてください」のようなもの
  • accessibilityValue - 値
    • UIButton の場合は空だがPickerなど値を持つようなコンポーネントには値が入っている
  • accessibilityFrame - フレーム
    • 独自でElementを作ったりしなければ不要のはず

UIAccessibilityPostNotificationは、Stringを読み上げたりviewにフォーカスをあてたりできるが、よく使うならextension にしておくと便利。

Accessibility Inspector Audit を使うと 大まかなAccesibilityの不備を確認することができる。

少し手を加えるだけで利用可能なユーザを増やすことができるし、 明日我々の目が見えなくなるかもしれない。UI設計に対する理解も深まるので、VoiceOverやっていきましょう。

SdkSearchのアーキテクチャ / stsn さん

github.com

SDKSearch は Android SDKのドキュメントを検索するためのJake製アプリ。

特徴:フルkotlin、coroutine を使っている、multiplatform。

SdkSearchの各コンポーネントの説明。(多かったので資料が出たらご参照ください)

全レイヤー感のイベントのやりとりはCoroutineのChannelで行っている。名前の付け方が全体的に独特と感じた。UIBinderとか‥

そんなに大きくないアプリなので、もっと大規模なアプリになると適切な設計というのは変わってくるかもしれない。

VoiceOverについて超語る / coffeegyunyu さん

www.slideshare.net

  • cellのImageViewにタッチイベントを登録するだけではVoiceOver状態だとタップできない、isAccessibilityElementをtrue
  • ラベルがない画像は、 accessibilityLabel
  • Traits = UIAccessibilityTraitImage にしていれば画像から判断して読み上げてくれる(iOS11〜、3本指タッチで)
  • UILabelも設定したほうが良くて、英語の読みがおかしいときがある。発音を設定できる(iOS11〜)
  • CFBundleSpokenName も設定しておけばアプリ名も任意の読みで読ませられる

感想とか

f:id:kumamotone:20180727000256j:plain f:id:kumamotone:20180727000308j:plain

行明けで体調ぶっ壊れ気味だったけど一応ブログ書ききってえらい