kumamotone’s blog

iOS/Android アプリエンジニアです https://twitter.com/kumamo_tone

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で発表するプレッシャーがあって、懇親会で相談したらちょっと気分が軽くなってよかった。