kumamotone’s blog

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

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

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

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

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

会場はFOLIOさんでした。

f:id:kumamotone:20180621193041j:plain

f:id:kumamotone:20180621182347p:plain

最初から FOLIOGoogle の著名なスピーカーの発表が決まっており、申し込みは大人気でした(当日の 18:30 に撮ったキャプチャ。+59 人キャンセル)。

個人的にも気合を入れて臨んだ回だったが、発表陣も異様に気合が入っており、明らかに5分ではない分量のスライドだったり、理解が困難なマニアックでハイレベルなトピックが続出するという状況が、22時ごろまでひたすら続きブログ枠の私は完全に精神が崩壊した

そんなわけで当日にまとめきれず遅くなってしまいましたが、別に溜めたからといってブログのクオリティは上がったりしないんですよね…つらい…

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

基本的に発表内容どおりですが、一部、個人的に理解しやすいように勝手に順番を並び替えたり、補足の情報を加えたりしているため、実際の発表内容と違う部分があります。気になるところや間違いなどあればご指摘ください。埋まっていない資料は公開されたのを見つけ次第反映します。

Room のできるまで 〜InvalidationTracker 編〜 / yaraki さん

Room は AndroidSQLite をラップするORマッパー。

@Dao
interface UserDao {
  @Query("SELECT * FROM User")
  fun all(): LiveData<List<User>>>
}

みたいな感じに interface で定義できる。

この User の変更の通知を受け取れるわけだが、 Room は SQLite からどうやって通知を受けているか?

  • 候補1: DAOから通知する
    • 書き込みメソッドの実装はRoomが生成しているので、自分が生成しているコードの中から通知することはできるはず
    • ☓ execSQL で直接クエリを投げたときにも対応できないし、トリガーにも対応できない
  • 候補2: SQLite拡張機能を使う
    • void *sqlite3_update_hook という、何か変更があったときに通知を受け取れる C 言語のAPIがあって、完璧じゃんとなるが、
    • Android ではAPIが開いていない
  • 実際に採用した方法: トリガーをつかう
    • 変更ログのテーブルを作っておき、各テーブルに変更があるたびに変更ログに記入されるようなトリガーを仕掛ける。トランザクション終了時にログを確認して(Roomではすべての書き込みはトランザクションで処理される)、Observerに通知する。

Livedata でテーブルに変更があったときに通知を受け取る場合、 invalidationTracker を使えば良いです

WWDCのセッションから、パスワードのAutofill、エクステンションの紹介 / kishikawakatsumi さん

speakerdeck.com

Web では iOS12 以前から使えた機能だが、パスワードの自動生成というのができるようになった。 勝手に強力なパスワードをSafariが考えてくれて、Keychainに保存しておいてくれる。また、iOS12 から、Safari を使っていれば 2段階認証で SMS で受け取ったコードを自動入力してくれる。

アプリ開発者が対応すべきことはなにか。 AccosiatedDomains というのを設定する。

Textfieldをつくって、Content Type に Username と Password を設定する。すると入力時に鍵のマークが出る。ちゃんとAccosiatedDomainsが設定されていれば、候補が鍵マークの左に出る。鍵マークをタップして、KeyChainから選んで入力することもできる。

Automatic Strong Passwords。iOS12からの機能で、サインアップをするときにOSが自動的にパスワードのサジェストをしてくれる。

Content Type を New Password にすると、これはサインアップ画面で使われるものだという認識をしてくれて、自動でパスワードを考えて強いパスワードを設定してくれる。Keyboard の type を email にすると、emailになるし、デフォルトだとユーザー名っぽい感じになる。

サーバーの方のパスワードのルールと合わない場合は、 Password Rules Validation Tool というのを使うと、 IB Password Rule (セッションではIBで設定できるよと言っていたが、今のところコードからしか設定できない)

困っていることとして、パスワードを保存してくれるタイミングが全然わからない たぶん自動で保存してくれるはずなのだが‥

Two factor auth も同じような感じでできる(関係ないSMSにも反応する)。対応コストは小さいので、対応しておくと離脱を防げて良いのでは。

KotshiからMoshi-codegenに乗り換えた経緯 / duane0728 さん

speakerdeck.com

今年の2月のpotatotips で、moshi-kotlin がリフレクション使っていて遅くて、Kotshiを使ったら早くなったという話を @magie_pooh さんがしていた 。

Moshi-codegen もそうで、リフレクションフリー。Kotshi とどちらを使えば良いのか?

  • 速度
    • 速度の検証、0.2MBのjsonのパースを20書い行った時間の平均msecを測った 大差なし
  • 安定性
    • codegen のほうにバグがあるのに気づいた nonnull な string に null が入ってしまう
    • ただ最新版 Kotshi でも同じバグが起きている
  • 将来性
    • Moshi-codegen は Moshi 本家がオーナー
    • Kotshi の issue で Kotshi の作者が deprecated になるかもと言っている

これからcodegenを導入するなら、kotshiも導入していない場合、最初からmoshi-codegenのほうが良さそう。

How to Manage Edge Gestures / TachibanaKaoru さん

speakerdeck.com

画面をなぞるときの操作には3つある。

  • Pan
  • Flick
    • HIGいわく、速くPanすること(ので実質パン)
  • Swipe
    • HIGいわく、画面をなぞること

Edge Pan Gesture というのはエッジからジェスチャーするやつ。iOS7あたりから UIScreenPanGestureRecognizer で取ることができる。

これですべての Pan Gesture を扱えることを期待したいが、実際には、画面上部や画面下部はシステムジェスチャ(通知センターが出る)が優先されてしまうという問題がある。

f:id:kumamotone:20180715182309p:plain

prefferedScreenEdgesDeferingSystemGestures というiOS11から使えるメソッドをoverride して方向を返す実装を書けば、システムジェスチャを一回ブロックすることができる(ベロみたいなのが出て確認できる感じ)。たとえばデレステ音ゲー)はこれをやっている。

HIG を読むと、やるなとは書かれている。でもゲームとかだとしょうがないよね。

Kyashで使っているTutorial Library / konifar さん

speakerdeck.com

世の中に出ているチュートリアルライブラリ下記の3点が不満で、ライブラリを作った。

不満な点と、作ったライブラリがした対応は以下の通り。

  1. ハイライト部分に角丸のものがなかった
  2. interpolatorやdurationをセットできる
  3. ハイライト部分のアニメーションしか対応していない
  4. interpolatorやdurationをセットできる
  5. テキスト部分のレイアウトをカスタマイズしにくい
  6. setMessageLayoutResId で作ったレイアウトをセットするだけ

よかったら使ってみてください。

github.com

enum as Option / r_plus さん

speakerdeck.com

Swift には Optionset という複数のフラグを管理するためのプロトコルがある。こんな感じで実装して使う。(developper.apple.com/documentation

struct ShippingOptions: OptionSet {
    let rawValue: Int

    static let nextDay    = ShippingOptions(rawValue: 1 << 0)
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)
    static let priority   = ShippingOptions(rawValue: 1 << 2)
    static let standard   = ShippingOptions(rawValue: 1 << 3)

    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}

Int 型の rawValue を数値ではなく、1か0のフラグを表す bit の列として使う。

使う側はlet option: ShippingOptions = [.priority, .standard] みたいな感じで定義して、 if option.contains(.priority) 判定できる。

Foundation でもよく使われている(DispatchQueueのAttributesなど)。

この OptionSet、単なるオプションを判定したいだけにしては記述が面倒ではないかと思うようになってきた。

そのような場合にはOptionSetを使う必要はくて、シンプルにenumを定義して管理すれば良い。複数のオプションの判定をしたい場合は可変長引数にすれば良い。こうすると、 OptionSet を引数にとった場合と 可変長引数の enum を引数にとった場合の実装側の書き方は一致する。

ただ、 OptionSet にあった Union の処理などができないので、そのような複雑な要件の場合には OptionSet を使ったほうが良いかも。

XML Object Mapping / hiroyuki_mori_1217 さん

speakerdeck.com

Swift4 で Codable が追加され、 JSON をモデルに簡単にマッピングできるようになった。

Java はこういうの得意で、 Android には Gson, Jackson, Moshi, SimpleXML... など色々ライブラリある。

これらのライブラリは、空のインスタンスを作って後からセットするというのが基本のロジックであるが、Kotlinでは「イミュータブル」で「非Null」なオブジェクトを扱うため、この方法は相性が悪い。

これを克服しているのが Moshi であるが、 XML には対応していない。仕方ないので、仕事で XML のマッパーを作った。

自分で作る場合には3つのアプローチが考えられる。

Reflection

f:id:kumamotone:20180715185728p:plain

型パラを受け取って内部構造を監査してオブジェクトグラフを作ってオブジェクトグラフの末端からインスタンスを作っていく。

これは楽でいいが、Reflection は遅かったりしてあまり好まれない。

APT

javac にクラス追加するチャンスがある。データクラスがあった場合に目印としてアノテーションをつけておいて自動生成する。重要なのは名前に規則性があるところ。

拡張性高めで Reflection でないのは良い。

Transform API

techblog.yahoo.co.jp

3つめはTransform APIなのだが、既存の処理を修正することができる 難読化しても影響がないが、超めんどくさい。記事を書いたのでそちらを参照してください。

作ろうぜORマッパー

GDPRについて / yoichitgy さん

GDPRとは何か?ヨーロッパに住んでいる市民の個人情報を適切に扱うための決まり。

データ取得と用途について明示的な同意を取得、情報漏えいや不正アクセスが会った場合は3日以内に通知するとか…

個人情報には、氏名住所は当然として、位置情報やクッキー、病歴など…色々ある。

違反すると全世界での売上の4%、最大25億円を支払わなければならない。EEAのユーザーが対象で、今年5月25日以降からすでに有効 こわい

Crashlytics レポートのユーザ情報、これ危険。レポートで個人情報 が見れてしまう。オプションで見れないようにできますが、注意が必要。

今年のWWDC2018から、ユーザーの行動記録を取る場合は視覚的に明示して同意を取らなければならないというのが書いてある。(2.5.14) 注意が必要。

Tips for Bitrise Android / shaunkawano さん

もともと Circle CI を使っていたのだが、問題としてメモリが足りなくて落ちる、独自のスクリプトを書かないといけないという問題などがあった 今は bitrise を使っている

メモリ不足でなやむことはなくなった、独自のシェルスクリプトに関しては fastlane で解決

tagが切られたときになにかしたい、bitrise.ioのときにはymlでやってたのだが、問題があった。

たとえばタグが切られたタイミングでGithubのドラフトリリースを作って、file-downloaderという機能を使って、KeystoreとGradleのファイルを落としてきてさもローカルで署名してるみたいにできる

fastlaneのほうにはset_github_releaseというレーンがあるのでそれでできる。今後は gradle ファイルのキャッシュなどをやりたい

bitrise Fastlane, file-downloader, おすすめ

Turi Createを試してみる / tattn さん

speakerdeck.com

Turi Create は Apple が買収した Turi という会社

CoreMLのモデルを出力できる 実装済みのアルゴリズムや調整済みパラメータを使って特定の問題を解くという思想で、Create ML の思想に近い

画風変換の学習に必要なデータは、Contant Images と Style Images

github.com

High Sierra でも動く。モデルを続きから学習される機能が現在ないので作って欲しい… 現在対応する気はなさそう

Colaboratoryでも使える (apt install で必要なものを入れられたり、GPUが無料で使えたりして良い)

Android P - Restrictions on non-SDK interfaces / operandoOS さん

speakerdeck.com

非 SDK インターフェースの制限  |  Android Developers

Android P から non-SDK へのアクセスに制限ができるようになった。

リフレクションとか使ってアクセスするようなフィールドやメソッドは、使うと落ちる場合がある。直接リフレクション、またはJNI経由でnon-SDKを使用する場合に適用される。

しかしすべてのnon-sdkがそうなるのか?と言われればそうではない。light-graylist、dark-greylist、blacklistという風に区分けされている。

light-graylist はまだ普通にアクセスできる。dark-greylist は targetSDK によってはアクセスできない。blacklist は targetSdkVersion に関係なくアクセスできない。non-SDK はそもそも使わないほうがいいが、今後はもっと気をつけましょう

見落としがちなVoiceOver対応 / jkatayama さん

speakerdeck.com

カスタマーサービスへ、「アプリ内のほとんどがVoiceOver対応していてありがとう、でも一部使いものにならないよ」という問い合わせがきた

なるほど、しかし VoiceOver なんて実装した覚えはない‥

調べてみると、 VoiceOver でほぼ対応されていて、UILabel,UIButton, TableView の Cell の内容は読み上げてくれるようだった。

しかし、UIButton で画像だけ、のような場合にはリソース名がそのまま読み上げられてしまう。

設定は簡単で、Interface Builder から、 Accessibility > Label にテキストを指定すると良い。

VoiceOver で読み上げられる内容を逐一確認するのは大変だが、 Accessibility Inspector を使うと、カーソル当てると Quick Look が見れて、読み上げられるテキストが確認できて便利である。

What’s new in Google Play Billing / ymnder さん

speakerdeck.com

Google Play Storeのアプリと、Billing Library に変更があったので変更点の紹介。

Play Storeアプリでは、定期購入コンテンツのリコメンドや、何の定期購読コンテンツを購読するか管理する画面が使いやすくなりました。

また、Deep Link によって、我々が作ったアプリから Play Store アプリの管理画面に直接遷移させることができたり、ユーザーが定期購読コンテンツを解約するときに理由を聞いたりできるようになりました。このアンケートの分析結果は Play Console で見ることができます。

Billing Library では、以下のような変更があった。

  • 定期購読のプランを月の途中で変更することができるようになった
    • proration (編注: 比例配分) modeが指定できるようになった
  • launchBillingFlow()を行ったときに、失敗時にもレスポンスを受け取れるようになった

proration mode には以下の 3 つのモードがある。

  • IMMEDIATE_WITHOUT_PRORATION
    • 追加請求なしで移行する
    • 2ドルのプランを月初めに購読開始して、月途中で3ドルにしたとしても、その月は2ドルのままの太っ腹モード。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE
    • 日割りで追加請求を行う
    • 2ドルのプランを月初めに購読開始して、半月後3ドルにしたら、2ドルの半分の1ドルと、3ドルの半分の1.5ドルで、その月の請求は2.5ドルになる。
  • IMMEDIATE_WITH_TIME_PRORATION
    • 既に支払った分をクレジットとみなし、日割り計算で使い切ったら新しい課金サイクルで課金が開始される
    • 2ドルのプランを月初めに購読開始して、月途中で3ドルにしたら、1ヶ月未満で次のプランに切り替わる その結果、月途中から新しいプランの課金サイクルが始まったりする

少々ややこしいが、スライドに図解がある。

Swiftで高カインド多相 / inamiy さん

speakerdeck.com

型コンストラクタは「型」を引数に取り、「型」を返す。 カインドは「型の型」。 高カインドは「カインド」を引数に取り、「カインド」を返す。

Swift 4.2 現在、高カインド関数には対応していない。Kotlin では ARROW というライブラリで Functor, Applicative, Monad などの基本的な typeclassをサポートしてる。

github.com

Swiftで高カインド関数を実現するにはどうすればよいのか?

qiita.com

Qiitaに記事があるが、どれも Lightweight Higher-Kinded Polymorphism という論文が元になっている。この論文を元にライブラリ作った。

github.com

これによって Array から List への自然な変換ができたりする。

let list = [1, 2, 3].kind
               .naturalTransform {
                    List($0.value).kind
                }
               .value

list == List.cons(1, .cons(2, .cons(3, .nil)))

Pay attention to the HUGE logs / Ryo Sakaguchi さん

端末内に存在するデータをサーバーに送信する機能を開発していて、データの規模を聞くと、1000件ぐらいだった。長めのbackground jobになるなという感じ。

この機能を実装するために、I/Oで発表された WorkManager を使おうと思った。Worker を継承したクラスを実装して、インスタンスにenqueue するだけ。あとは適切なサイズにデータを加工すればOK。

しかし動かしてみると、 byte[]-> String でOOMで死んでた。forkして出力するログサイズを制限できるパッチを当てたものを使用することで回避した。StethoもRequestBodyが巨大で死んでたりしたがまだ対策できていない。

これが参考になった

in.fablic.co.jp

めっちゃでかいログには気をつけましょう。

Contributing to Swift in WWDC / kitasuke さん

WWDC、Technology Labs というのがある。OSSをあまりやってこなかったAppleだが、ここではエンジニアと話できる。

いろんなLabあるので色々質問できる Swift Open Hours に行った。2日目以降は暇そうだったので色々聞けて良かった。

ラボでは、事前に用意してきた Bug report と、それに対してこういうプルリクを出そうと思うのだが、みたいなことを話して合意を取ったりした。これがめちゃくちゃ良かった。

Swift Open Source Workshop by try! Swift San Jose でワークショップあったのでプルリク出せた。

github.com

Hey Guys, I am... / mhidaka さん

エンジニアリングマネージャーをやるという話。

マネージャー、最初はあんまり興味がなかった。エンジニアリングに集中したいという気持ちがあった

しかし組織の急拡大により、ミドルマネージャーが足りない問題があった。Androidエンジニアのマネージャーがいない。適切なアサインが難しい。技術的な評価が難しい。施策の選択と集中が難しい。

ということでエンジニアリングマネージャーをやることになった。エンジニアリングマネージャとは技術に責任を持つ職能。お試しでというエクスキューズがあるのでやっていけている。人間なのでコミュニケーション、働きやすさが大事。どうすればモチベーションが上がるのかとか教えてほしい。

現在のところは、Slack, スプレッドシートをやっている。俺に任せていけという感じ。

Hey Guys, I am an engineering manager.(タイトル)

Video decode on iOS. / noppe さん

speakerdeck.com

透過動画再生ビューライブラリを作っている。

透過動画とは何かというと、こういうやつ。(引用元: Kitsunebi/animation.gif at master · noppefoxwolf/Kitsunebi · GitHub )

f:id:kumamotone:20180623202531g:plain

2つ動画ファイル用意してあげて、マスク合成して描画している。

今日はビデオファイルのデコードについて話す。ビデオファイル、それはコンテナの集まりであるが、デコードとはメディアコンテナを再生できる状態にすること。

コーデックの違いによって圧縮率などが変わる。AVAssetReader, VTDecompression ffmpeg などの方法がある。

これらのフレームワークでは、内部でOS/端末のデコーダの実装を利用しているのだと思う。OSや端末によってサポートが異なるので注意。たとえばHEVCは一部のチップでしかハードウェアデコードをすることができない。

対応コーデックの確認をすることが今のところできないように見える。AVSessetReader を使うと対応コーデックであればコーデックを意識せずにできるので簡単。

VTDecompressionSessionはもっと低レイヤーなやつで、やや複雑だが柔軟性は高い。特徴としては以下のようになる。

  • ストリーミングでもキャプチャが取れる
  • AVAssetReaderにバグが有っても大丈夫
  • 分散してエンコードしたいときとかに便利
  • エラーチェックとかちゃんとしないといけない

VTDecompressionSessionの流れとしては

  • h264/avcを分割
    • nal file format
  • 映像が含まれるチャンクを取り出す
    • nal unit type は ISO/IEC 14496 に定義
  • VTDecompressionSession を生成
  • チャンクをSession にわたす
  • デコード済みのImageBufferがコールバックに返される

サンプルはgithubにあります

感想とか

ハイレベルなトピックが多く本当にエキサイティングだった。言わずもがな、勉強になったし素晴らしい会でした。

懇親会ではアプリ界の名立たる著名人とコンタクトを取れる貴重な機会であったが、

ブログのために情報の濁流を整理するのに疲弊していた私は、知人とばかり話し、挙げ句シラフであるにも関わらず

「もう東京で消耗しすぎたから1ヶ月ぐらい何もかも忘れて海外に行きたい」

「どうしたら楽してお金が手に入りますかね?」

といった生産性のない話題ばかり降っていた。

これらの話題に、懇親会で嫌な顔せずに応えてくださった優しい方々にこの場を借りて感謝いたします。

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

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

f:id:kumamotone:20180523232304j:plain

会場はCAMPFIREさん!渋谷ヒカリエからすぐという超好立地なのに道に迷ってギリギリになってしまった…

f:id:kumamotone:20180523232317j:plain

写真撮り損ねて閉会後になってしまったけど会場の写真 芝あって良い雰囲気

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

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

Firebaseで頑張ったこと / nakajijapan さん

Presentations by nakajijapan // Speaker Deck

Firebase Authentication、Tokenの有効期限が1時間であることを考慮して実装しなければならない。getIDTokenForcingRefresh() を使ってリフレッシュすることになる。

retry処理をRxSwiftのretryWhenで実装していた。ただ成功しても失敗しても.nextして.completed してしまっていたので、うまく行ってなかった。

ちゃんとエラーハンドリング実装したら動いた。FirebaseもRxSwiftもちゃんと理解して使おう。

モバイルアプリための通信デバック入門 / imota さん

Presentations by simota // Speaker Deck

通信デバッグのためのHTTPプロキシを紹介。

FiddlerWindowsユーザー向け。Windows使っているならこれがおすすめ。Charlesは無料版だと時間制限がある。

mitmproxyというPythonで書かれているやつがあって、おすすめ。pipで入る。TUI、GUICUI版がある。SSLで暗号化された内容でも、内容を見たり、スクリプトを書いて書き換えたりすることができる。

App Protection ( iOSアプリからVPN接続の検出をする ) / noppe さん

speakerdeck.com

Charles for iOS 出ましたね

うっかり Charles 起動したまま Twitterアプリ開いちゃったんですけど、Charles開いてる状態では読み込めなくしているっぽい。これどうやったら再現できるだろうか?

Charlesは自体は、NetworkExtensionを使ってVPNコネクションを張り、これを使ってIPトラフィックがトンネリングできるという仕組みなのだが、再現する方法は割りとシンプルで、

CFNetworking.frameworkCFNetworkCopySystemProxySettings() という古くからあるものでプロキシ設定が取れる。

CFDictionary という型で返ってきて、__SCOPED__tun という文字が含まれる設定はトンネリングされているものなので弾いても良いのでは?という仮定で実現することができた

コードは公開しています↓

github.com

What's CodeSigning / scenee さん

Presentations by Shin Yamamoto // Speaker Deck

CodeSigningとは?公開鍵暗号方式で、電子署名を付与すること。これをやることで、開発者自身が作成したアプリケーションだということを保証する。

署名はどこに保存されている?Mach-O(実行ファイル)だと CMS形式で署名が埋め込まれている。

Provisioning Profileはアプリプロセスに権限等リソースを提供するためのファイル。これもCMS形式

App起動時にMach-Oの署名情報と、Provisioning Profile を照合しているので、開発者自身が作成したアプリケーションだということを保証できる。秘密鍵がIdentity、公開鍵がProvisioning Profileにあたる。

ほか細かいTips(Provisioning Profileの中身を確認するコマンドなど)

Flutter 入門 / toshihirooya さん

speakerdeck.com

Google が作ったクロスプラットフォーム開発フレームワーク Flutter の紹介。DartAndroid Studio で書けるぞ!

例を紹介。 void main() => runApp(new MyApp()); から始める。 StatelessWidget な MyApp でアプリタイトルとかテーマとか設定する。MyApp から StatefulWidget なクラスを呼んで State を表示する。宣言的な感じになるのでMVVMのVMっぽいイメージ。

今年の I/O の内容だが、 FlutterFire というFlutter用のFirebaseプラグインというのがあってよさそう

github.com

Flutter、素早く両OS開発できる可能性に溢れている 期待!

あると便利な動作検証用機能 / 5mingame2 さん

www.slideshare.net

前回のpotatotips iOSで紹介した、C++(Cinder)でゲームを作る話の続き。

作ってるゲームで動作検証用に付けてる機能を紹介するよ

  1. print機能
  2. asset機能
  3. 一時停止・コマ送り機能を付ける
  4. 表示抑制(切り替え)機能 ゲーム画面ではなくUIだけ動作したいとかその逆とか
  5. ソフトリセット機能
  6. macOS固有の読み込みパス変換 プリプロセッサで頑張っている
  7. 画面解像度一発変更機能 Release ビルドでは消滅する
  8. リアルタイムUI調整機能 これも Release ビルドでは消滅する

別になくてもゲームは作れるが、こういうのは作ると捗る!

Remove Unused Resources / konifar さん

speakerdeck.com

Android Lint の unused resources、ウソをつくので使えない とくにdatabinding とか使っていると、こいつの言うとおり消してくとビルド通らなくなってつらい

でも不要なリソースは消したい… いつかなおると思っていたが、いつまで待っても出ないのでGradleプラグインを作った

github.com

実行するだけ。小さなプロジェクトだとすぐ終わるが、大きなプロジェクトだと、やはり時間がかかってしまうこともある(5分とか)。gistに貼っているスクリプトを定期実行すれば定期的に消せる。

gist.github.com

オプションが2つあって、1つめはサポートされてないリソースファイル、たとえばtext_appearanceの <style> とか消したいとき、createXmlValueRemover()関数でカスタムの設定を書ける。

2つめは excludeNames に設定すると、除外できる。

投げ銭アプリを会社で作っているので、消えた行数を目安に投げ銭してもいいのよとのこと。

Xcode Templateを使ってチームで生産性を上げる / ngtk さん

speakerdeck.com

Xcodeにテンプレート機能がある。一般に、テンプレート機能は共通の記述を書かずに済むようになるので、生産的。

もちろん protocol extension や コード自動生成をまっさきに検討するべきだが、残る温かみをテンプレートでやるということもできる

ただXcodeのテンプレート、カスタムで追加する方法や共有する方法が公式に書いてなくて分かりづらい‥

テンプレートファイルは、適切な位置に __FILEBASENAME__.swift TemplateInfo.plist とか決まった構成で置くことになる。

gitとかで共有したテンプレートファイルをここに置けば良いのだが、結構込み入った場所にあるので、スクリプトを書いた。さらにこれだと使いづらいのでコマンドにした。 brew で入れることもできる。

github.com

Visual Studio App Centerの始め方 / nakasho さん

www.slideshare.net

Visual Studio App Center というMS製 CI/CDツールの紹介。HockeyAppのリブランディングになる。

Android/iOS, UWP, macOS(Preview)に対応していて、Github/Microsoft/Facebook/Googleアカウントとかでログインできて、Visual Studio Team Service, Github, Bitbucketに対応、みたいな結構手厚い感じ。

クラッシュ情報の取得や、Visual Studio Team Services, Github, Jiraと連携してクラッシュ時にチケット起票したり、アナリティクス機能あったり、Flutter向けのプラグインもある!すごい!

ARKit 表示改善 / satoshi0212 さん

Presentations by satoshi0212 // Speaker Deck (基本的にデモベースの発表だったので資料上がらないかもです)

ARKit, 段階を分けて工夫してみたのでサンプル7つを見てもらいたい

  1. ライトなし 単に丸が表示される
  2. autoenablesDefaultLighting = true にする 影がついていい感じ
  3. CIFilter 背景のみ 2とは別の
  4. CIFilter オブジェクトも なじんでくる ただ60fpsでない
  5. Metal SCNTechnique を使う
  6. Physically Based Rendering (PBR SceneKitにあるやつ) CIFilterでもMetalでもないアプローチ
  7. Physically Based Rendering + ARKit 60fpsで出るし、映り込みもある(ただ設定した写真の映り込みではある)

今後やりたいこととしては、

  1. Lightingの方向と色のリアルタイム化、
  2. PBR+ARKit でリアルタイム画像の使用

Material Components for Android触ってみる / kirimin さん

speakerdeck.com

I/O 2018 でマテリアルデザインが更新された。App bars:bottom, Backdrop, Banners, Extended FAB, Text Field…どうやって実装する?

Material ComponentsというマテリアルデザインのComponentを実装する公式ライブラリがあって、これを使うと良い

準備、mavenのいつもの、compileSdkVersionをandroid-Pに、Material Compoments Themeを使う、リファクタリングメニューからRefactoring to AndroidXを選択。準備完了

TextFieldsは普通のEditTextと同じように使うだけで、TextInputLayoutのstyleを @style/Widget.MaterialComponents.TextInputLayout.OutlineBox 変更するだけで、あたらしい見た目になる

ただ新Componentは見た感じまだあんまり実装されていないっぽい…そのうち用意されるはず

Carthage移行した話 / aboyさん

ビルド、フルビルドで4並列で360秒かかっていた。ビルド時間長いと嫌

CocoaPods使ってて毎回FrameworkのビルドしてたのでCarthageに移行した。CocoaPodsのライブラリが38個あったが、これが16個になり、無事80秒速くなった。

ハマったところとして、CocoaPodsから移行していないライブラリがAlamofireに依存していて、call of deleted methodになってしまっていた。これは全部Carthage経由にして解決した。

忘れないで!mac app!! コマンド編 / Akkey さん

speakerdeck.com

1時間ごとにプロ生ちゃんが時間を教えてくれるmacOSアプリを作っている。

mkdir, cp をどうするかというやりかたを紹介

mkdirする方法 NSHomeDirectory() ホームディレクトリが取れる NSTask()インスタンスを作って、絶対パス/bin/mkdir を呼び出す 注意点としては、Sandboxの有無で取得できるディレクトリが違う

cp する方法 GUIアプリなので、ファイルを選択するのに、ファイルを選択するダイアログみたいなものを出したい これを出すにはNSOpenPanel()のインスタンス作って、設定してbeginのcompletionHandlerで結果受け取る これを引数に、同様の方法でまたNSTask()で /bin/cp を呼び出せばOK これもSandboxの場合は設定変更が必要なので注意

iOSアプリではない領域でSwiftで遊べるのでおすすめ。

感想とか

  • Visual Studio App Centerの話は iOS Test Night でも拝聴したのだけどMS手厚いなーという印象 どうやったら流行るんだろう
  • konifar/gradle-unused-resources-remover-plugin はふつうに今後お世話になりそう
  • Flutter は最近のpotatotipsでも毎回誰か触れているので熱高まっているなーと感じる 自分もちょっと触ってみたけどたいへん良かった
  • 懇親会楽しかった‥

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

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

f:id:kumamotone:20180420011750j:plain

会場はWantedlyさん。めっちゃおしゃれ(語彙) すごく見やすくて聞きやすい環境でしたし、持ち時間時間が見やすく表示されていて発表しやすそうでした。

f:id:kumamotone:20180420011818j:plain

50回目ということでスピーカーの方々もはじめて発表したときのこととか振り返ったりされてました。

以下発表内容です。参加枠としては iOSブログまとめ枠でしたがAndroidの発表内容に関してもまとめてみました。間違いや気になるところなどあればご指摘ください。

埋まっていない資料は公開されたのを見つけ次第反映します。

"Hello Flutter"の次におさえたいFlutterのポイントその3 / Kenichi Kambara さん

www.slideshare.net

その2

www.slideshare.net

その1

www.slideshare.net

Flatterの概要、特に今回はUIに焦点を絞った話。

FlatterではDart言語でWidgets Treeというものをガリガリ書いていくことになる。Scaffoldというテンプレートクラスを使って作っていく。ScaffoldにはAppBarとBodyがぶら下がっている。

Columnというのを使うと、AndroidでいうLinear Layout の Verticalみたいなものが実現できる。Columnにまたボタンとかテキストフィールドがぶら下がっている。

Flutter向けのGUIビルダーが Google I/O で発表されることを期待しています!

recyclerview-selection / kgmyshin さん

speakerdeck.com

recyclerview-selectionの概要と、つかいかたについて。

recyclerview-selection とは?

28.0.0 alpha1から導入された、複数選択の機能の。ドラッグして複数選択みたいな機能が簡単に作れますよみたいなライブラリ。マウスなどにも対応しているらしい。

使いかた

Recyclerview, Viewholder, Adapterは一旦ふつうに作る。ただ、stableIdを使うようにする。SelectiontrackerインスタンスSelectionTracker#Builder でつくる。各引数に、Key、使うRecyclerview、StateIdKeyProvider、今どこのアイテムを選択している解決するItemDetailsLookUp、StorageStrategy、必要だったらリスナーを与える。あとはViewに選択状態を反映しておわり。

ブログにもっと詳しく乗ってるよ

inside.dmm.com

サンプルコード

github.com

Yet another simple Logger / ngtk さん

speakerdeck.com

XcodeのConsole log使ってますか?なるべくデバッガーをつかわずに問題解決したい。たとえばログとか。

ただログ機構に不満がある。ロギングのレベルが指定できない。ライブラリの標準出力がコントロールできない。

github.com

ライブラリ色々見たが、Swiftybeaver がオッとなった

:star: 3500 ぐらいで、ログレベルに対応してて良い。一方出力先も指定できる。文字列をコピペできない、有料のプラットフォームとセットになっている、とか概ねいいけど微妙なところもあった。

欲しい機能ぐらいであれば自分で作れるかもということで作ってみた。ざっくり実装紹介。

Glide 4 with Kotlin / hkusu さん

speakerdeck.com

画像ライブラリGlideの使い方とGlide4の機能の話。

hkusuさんのプロジェクトではpicassoがメンテされないのでGlideに乗り換えたという経緯がある。

Transformation。Glide4 では クロップ、角丸は標準で用意されている。また Glide Transformations使うとBlur, BrightnessFilter とか凝ったやつも簡単にできる。Glide4でアニメーションのデフォルトがフェードなしになったことに注意。

Glide Optionではよく使うオプションを定義して再利用できて便利。便利なんだが、Transitionや、サムネイル・リスナーの設定などはできない。これはGlide Typeとして定義できるがGlide Optionに比べると制約がある(複数指定できない、引数指定できない)。

しかし、Kotlinなら拡張関数があるので、GlideRequestとかに生やしてしまえば同じように処理をまとめられる。

Tagged / to4iki さん

speakerdeck.com

Idを型化したい。たとえば Userって型とSubscriptionっていう型があって、それぞれにidがあるのだが、これらは違うもの。なのでStringとかじゃなくて型にしたい。

ほかの例として、 Codable を使う場合は、decoderを実装すればよい。ただ、これいちいち書くのめんどいし、Userの比較するのにEquatableをIdにも実装せんとあかんのかよとなる、

structの各要素のEquatableの実装めんどくさい問題は、Swift4.1のConditional Conformanceで解決した。

github.com

さらに、この機能を使ったTaggedというライブラリがあり、これを使うことでプリミティブな型を簡単に型として扱うことができる。

DiffUtil and ListAdapter / kubode さん

speakerdeck.com

DiffUtil と ListAdapter の紹介。

github.com

DiffUtilでは、2つのListの差分をO(n)で計算できる。これは1000個のリストのうち50個の変更があったとき、Nexus5Xで4.6秒で計算できる速さ。

ListAdapterは、Support Library に 27.1.0で追加された、DiffUtilをつかうRecyclerView.Adapter。デモ。簡単。注意点としては、MutableListと一緒に使ってはならない。

From ObjectMapper to Codable / kobakei さん

speakerdeck.com

APIが返してくるJSONをObjectMapperでやってた部分をCodableにおきかえた。

Codableの基本的な説明。ネストしたJSONのパースの仕方、CodingKeyの話、日付String→Dateに変換など。JSONがつらい形で返ってきても、Decoderを自前実装すればよしなに対応できる。

ちなみにCodableAlamofireというのを使うと、responseDecodableObjectというのがrequestに追加されて、そんまんまCodableの型のオブジェクトを受け取れる。

github.com

Viewのキャプチャを撮ってみる / e10dokup さん

www.slideshare.net

特定のViewだけをキャプチャしたいときどうする?こういうときは、android.R.id.contentでActivity全体をキャプチャできる。これやると通知領域のないスクショが撮れる。

android.R.id.contentで画像としてキャプチャする場合。View#getDrawingCache()でViewのキャッシュを作成してBitmapで取得する(android-ktxならView#toBitmap()でもOK)。これ使うと、子になってるViewもまとめて実行される。注意点としては、使う前にView#setDrawingCacheEnabled(true)しよう。

画像ではなく、PDFとしてキャプチャする場合。PDFのいいところとしては、テキストをテキストとして保存してくれる。PDFDocumentというクラスを使ってキャンバス芸でキャンバスにゴスゴス書いていく感じになるが、たぶんPDFDocumentはこうやって使うものではない…

ほかにもMediaProjection API(API 21〜)を使うという方法がある。MediaProjectionは仮想のディスプレイにミラーリングしてやるという方式(こっちは自前のアプリだけでなくServiceとして起動して任意のアプリのキャプチャ撮ったりできる)。

iOSは自動生成の夢を見るか? / Nonchalant さん

speakerdeck.com

自動生成の前にDIの話。Swinjectを使っている。

github.com

container.register()をゴスゴス書くことになる。動的DIなので参照されるまで気づけなくて、間違うとクラッシュするとかありうる。

github.com

Sorceryは自動生成ツールで、これを使うとボイラープレート自動生成してくれる。Stencilテンプレートというのをテンプレート言語としてつかう。

紹介したコードでは、命名規則を利用したが、Sourceryはあるプロトコルに適合している型だけを抽出するとかできるので、Prefixとかずれても大丈夫なはず。

SourceryにおけるStencilの文法は以下にあります。

github.com

Preferences as a Service / izumin5210 さん

speakerdeck.com

アプリで使用する設定値、どこに保存する問題。結局サーバー側の挙動に影響するものが多いので、Shared PreferenceやRealmなどを使う方法もあるが、結局ローカルだけに保存するという選択肢が取れない場合もある。

しかしアプリごとに毎回同じような設定用のサーバーを立てるのはつらい…なので汎用的に設定値を管理するサービスないわば、Preferences as Serviceをつくった。

また内製なので、外に出したくない情報も使うことができる。またアプリでViewにそのままマップできる形で返すとか、A/Bテスト用の機能などをつけたり、色々便利に使っている。

今更C++でアプリを書く / 5mingame2 さん

www.slideshare.net

専門学校でゲームの作り方を教えたりしている。現在はCinderというのを使ってボードゲームカルカソンヌっぽいアプリを作っている。

github.com

あまり手厚いサポートはないが、学生がはじめて3Dを触るのに丁度よい規模感。UnityやUnrealEngineだと便利過ぎる。公式リファレンスは割りと充実しているが、ネットでググってもほとんど情報がないので、教育的(?)。

OpenGLの薄いラッパーとして使える、便利な点として、OSの違いを吸収してくれる。特にサウンドとか自分でやるとエグいので良い。またUnrealEngineなどと比べて良いところとして、ライブラリの再ビルドでトラブルが少ない。XcodeやVS2017が使えるならC++14が使える。

iOS SDKが使いたい場合は、Objective C++つかえばC++のコードからObjective-C使える。

ゲーム作れるが、手間がかかるのであまりお薦めはできない(編注:おすすめはできないと言いながらも楽しそうだった)。

消費型課金を導入する / morizooo さん

Presentations by morizooo // Speaker Deck

課金方式、消費型課金、非消費型課金、購読型課金がある。今日は消費型課金の話をする。

Play Billing Library。おすすめの習得法、play-billing-codelabさわって感触を掴んでからTrivialDriveV2を使うのが良い。

できること。課金できる端末か調べる、購入情報の取得、商品情報の取得、Google Playの購入画面を出すなど。

課金フロー。クライアントGoogleに→レシートを受け取る→サーバーに対してレシートの検証を行う(このとき購入したユーザー、アイテムの情報も送る)→Googleに検証してもらう→レシートの検証結果をクライアントに投げる→消費リクエストをクライアントからGoogleに送って終わり

複数端末で操作するとか、色々なクラッシュ要因があるがあるので、色々考えつくのはやるとして、フェールセーフになるように気をつけたほうがいい。

キーボードの切り替えをいい感じにしたい / wakwak3125 さん

speakerdeck.com

Facebook Messengerアプリとかで見る絵文字とか表示するキーボードの切り替えをしたい。適当にやったら豪快にViewが動いたのでやり方を考えた。

まずMessengerアプリを参考にした。単純にView構造のdumpを adb shell dumpsys activity top でとってみてひたすら切り替えてみた。そうすると気づいたのだが、特に変わったCustomViewを使っている様子はなかった。キーボードの裏にViewがある雰囲気を掴み、キーボードを閉じる際に高さが変わらなければ、View豪快に動くことがないのではと考えた。

実際にやってみた。toAdjustNothing(), toAdjustResize()を適切に使うようにしたら、キーボードを閉じる際に高さが変わらなくなり、問題が解決した。が無理矢理感があると思っていて、やりかたを募集している。

コードは以下に置いてあります。

github.com

Introducing Izumo / nakajijapan さん

speakerdeck.com

Izumoという、macOS, iOSで動くMarkdownエディタを使ったので紹介。CloudKit + CoreDataを使用してクラウドと同期をとるのと、リアルタイムMarkdownパーサを実装しているのが特徴。

Swiftが発表されたタイミングで発表されたCloudKitだが、なかなか同期処理がつらい。Markdownのパースも正規表現ゴリゴリでつらい。同期もCloudKitというフレームワークを使っているからといって単純に出来るわけではなく、結構やることある。

色々つらいが普段できない体験ができてよかった。

ディープリンクを実装した / Takasy さん

speakerdeck.com

通知から該当ページを起動する、という機能をつくる。

起動している/していない、登録している/登録しないの組み合わせパターンでそれぞれ違うことする。たとえば起動していて登録済みならページを開く、起動していないなら起動画面を見せてからページを開く、未登録で起動中なら何もしない、未登録で起動していないなら起動するだけ、という感じ。

どう実装したかというと、起動画面を透明なActivityにする、条件分岐をして適切な処理をすると言う流れ。

透明にする方法はStyleを設定する(windowsistrunscrentをtrueに)。条件分岐の方は、起動activityにdataをつけて、oncreateでintent.dataにuriが入ってるのでスキームをパースする。

ただホーム画面をスタックに積むというところで詰まって、droid girlsの方に質問とかして解決した。TaskStackBuilderというのを使うとActivityを起動せずにスタックにつめる。FlagにはSINGLE_TOPを設定しておく。

RxSwift, Codable, Moya で API クッキング! / Akkey さん

YoutubeAPIを叩くアプリ。軽い気持ちで技術選定して、RxSwift, Codable, Moya を使ってみた。

github.com

Moyaではenumでエンドポイントを定義して、リクエストごとにcaseを定義する。

MoyaにはTargetTypeというプロトコルがあって、エンドポイントはこれに準拠させて extension で baseURL, path, method, parameters を実装することによって設定する。

RxMoyaを使う場合、注意点としてリクエストを行うAPIクラスは、シングルトンでProviderが開放されないようにする必要がある(結果をSubscribeできなくなるため)。MultiTargetというのを使うと、Providerごとに型が違っても共通で使えるようになる。

webviewが辛かった話 / aboy さん

WebViewがつらかったという話。「Webサービスのアプリ版がほしいな〜」という案件を任された。

Web版できることはやりたい、ログイン状態は保持したい。ということで、WebViewでやることになった。

しかし案の定、WebViewの謎の挙動に悩まされ大変な目に…

なぜこんなことになったのか、ヘッダーリクエストまわりをいじったせいで、戻るの機能が使えず自前実装になって実装が複雑になっていった。またもともとページ数がかなりあるWebサービスなので、動作を担保する範囲がめちゃくちゃ広かった…

WebViewは安易につかうとつらいです。ちゃんとWebViewを使うべきなのかよく考えましょう。

感想とか

github.com

  • Taggedは早速Swift4.1の機能を活かしていて面白いライブラリだなと思いました。

  • iOSはいい感じのデファクトっぽいロギングライブラリが出て来ると良いですね…Timberやlogger的な…(あるのかな?)みんな各々実装してそう

  • AlamofireとRxSwiftは個人的に使っているのですが、RxMoyaと組み合わせるとすごく良い感じになりそうなので参考になりました。

  • Webサービスのアプリ版がほしいな〜」みたいな案件、今後遭遇するかわかりませんが、恐ろしそうなので気をつけようと思いました…

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

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

メルカリさんの会場。

f:id:kumamotone:20180313202426j:plain

f:id:kumamotone:20180313202404j:plain

大変良さ。

f:id:kumamotone:20180314011310j:plain

f:id:kumamotone:20180314011318j:plain

成城石井の高めのポテチとヘルシーピンチョス。良さ良さ。

以下発表内容です。iOSブログまとめ枠でしたが今回もAndroidの発表内容に関してもまとめてみました。間違いや気になるところなどあればご指摘ください。

埋まっていない資料は公開されたのを見つけ次第反映します。

XCTestを目的別に分けるすすめ / gaopin さん

speakerdeck.com

数ヶ月前、チームにジョインしてあることに気づく。自動テストコケとるやん。

gaopinさん「自動テストこけてるよ」

チームの人「問題ないw」

gaopinさんのプロダクトは、膨大で複雑なログの絡むプロダクトで、スプリントごとにテストを回していて、スプリント途中はテスト通らなくてもしょうがないみたいな感じになってた。

でもこれテストターゲットを分割すれば良いだけの話。

方法も簡単で、

  1. (プロジェクトの↙にある+)ターゲットを追加 iOS Unit Testing Bundle を追加

  2. 分割したいテストのファイルのメンバーシップを変更

みたいな感じ。これで個別に実行できるようになった!

おすすめの分割タイミングは以下。

  • 実行タイミングが違う
  • 実行する範囲が違う
  • 別チームで作業している(これは微妙かも)

OK google, プロジェクトのbuildして」 / satsukies さん

speakerdeck.com

前回のpotatotipsの Alexa、APKを配布して // Speaker Deck が面白かったのでやってみた。

流れ。我々「プロジェクトHogeをビルドして」→GoogleHome「わかりました」→GAS等使って「プロジェクトHoge」に対応するBitrise起動→Bitriseでビルドしてapk配布。対話を通じてプロジェクトIDを聞き出す。

DialogFlowで、Agentの作成して、Entityの登録して、Intentの登録する。Entityの取り出しはTraining Phrasesにユーザーの発言を入力するだけ。するといい感じにパラメータを学習してくれる。最後にResponse定義する。Default Fallback Intent(うまくいかなかったときの反応)もここで定義。

その先の内容は飛ばしてActions on GoogleのSimulator を使ったデモ。

ExoPlayerで音遊び / daasuu さん

予習。ExoPlayerとは

Google の動画ライブラリ。

github.com

shunirr.hatenablog.jp

ExoPlayer とは:

従来の MediaPlayer (Stagefright / NuPlayer) は C や C++ で実装され、かつ実装は Android フレームワークに組み込まれているので、 MediaPlayer 内部で不具合があったときに修正や、 MediaPlayer そのものを修正して新たなフォーマットやプロトコルに対応させることをアプリ開発者が自由に行なえず、端末や OS のアップデートが必要でした。

ExoPlayer は Google が開発している Android 向けの新しいメディアプレイヤーで、全て Java で実装されており、またアプリケーションに組み込んで利用するライブラリの形式で配布されています。

これにより従来の MediaPlayer で不可能だった、アプリ開発者によるプレイヤーの拡張や修正が可能になっています。

内容

Presentations by Masayuki Suda // Speaker Deck

Androidでの音再生の方法おさらい。MediaPlayerはBGM等の長い音の再生に使える。SoundPoolは5秒未満なら良い。AudioTrackはバイナリ直なので難易度が高いが、自由度は高い。

ExoPlayerというライブラリがある、これは動画のライブラリ 動画再生だけでなく音の再生にも使える。

最近では音程や倍速にも対応できるようになってきた。ピッチではなくスピード、音程だけでも設定可能。すごい。

TD PSLOLAアルゴリズムを使っている。これは音のスペクトルをある程度保ったままピッチやテンポを保ったまま上げれる。

具体的には、以下のような感じでやってる。

  1. ピッチに対応した波形の1周期をみつける
  2. 周期を切り出す
  3. 切り出した周期を使って音声を再合成

これをやっている部分だが、ExoPlayerでSonicで検索すると良い。ちなみに48k→44.1kのリサンプリングなどもできる。

たった2行で本格アプリ!?挫折しないSwift勉強会の裏側 / AkioItaya さん

iOSアプリの作り方を教えたりされているAkioItaya さん。

github.com

教え方の一例を紹介。キャラクターと一緒に記念撮影を行えるシンプルなカメラアプリ↑をcloneしてもらう。2行書くだけで完成、という状態にしてある。

なぜ2行の実装で終了するのかというと、2行追加するViewControllerの継承元のクラスやextensionに実装が隠蔽されていて、それらを種明かしをしながら動作を理解してもらっている。

とりあえずちょっと何か書いて動く状態にしてわくわく感を得た後、逆順に説明することによって挫折しない工夫をしている。

shared element基本のき 〜パターンで見るshared element〜 / e10dokup さん

予習。shared element とは

developer.android.com

f:id:kumamotone:20180313180730p:plain

Shared Elements 遷移は、2 つのアクティビティで共有されているビューが、各アクティビティの間でどのように遷移するかを決定します。 たとえば、2 つのアクティビティで同じ画像を異なる位置とサイズで使用している場合、changeImageTransform 共有要素の遷移によって、2 つのアクティビティの間でスムーズに画像が変換されスケーリングされます。

re-engines.com

Airbnbとかで使われてるUIらしい。ぽよんって遷移するやつ。API 21から使える。

内容

speakerdeck.com

Shared Element Transitionはガン遷移前後で共通になっているviewをアニメーションさせるもの。Google Play Storeのアプリリスト->詳細とか。

Shared Elements viewにtransitionNameを着ける

Activity-Activityの場合、Fragment-Fragmentの場合、RecyclerView-Activityの場合、RecyclerView-ViewPagerの場合をそれぞれ説明。

RecyclerView-ViewPagerパターンめっちゃめんどくさい。

あとShared Element Transitionしないほうがよさそうなときもあって、遷移前後でshared element対象のViewのVisibilityが保証できないとき、遷移前後で保持するリストの内容が違うときなどがある。

リポジトリ

github.com

App Store 予約注文を使ってみた / toshinarin さん

App Store、予約注文としてリリースができる。24時間以内に(時間は指定できない)自動的にユーザーの端末にダウンロードされる。

予約注文数が見れてPR・マーケティング的に良いし、利用可能になったら自動的にダウンロードされてメールとPushがくるのでユーザビリティ的にも良い。

実際の設定の仕方は簡単で、価格及び配信状況のバージョンのリリースでできる。

注意点としてはアプリを使い始める時間を完全にはコントロールできない。

ちなみにアプリ自転車が必要で審査できないので、動画で撮影して App Reviewに関する情報>メモに動画を添付とした。

動画編集についてだが、iPhoneで撮影、iMovieで編集すればPinPとかもできるので良い。

Swiftバグレポートレポート / kazuhiro4949 さん

speakerdeck.com

bugs.swift.orgからXcode 9.2 で再現できるバグをピックアップ!

SR-7090 Codable に関するバグ

  1. クラスAがCodableを実装している
  2. クラスBがAを継承している
  3. Bを初期化orデコードして、プロパティにアクセスするとランタイムエラー

SR-7102 パフォーマンスに関するバグ

Swiftでは複雑な式を書くとコンパイルが中断されることがあるのだが、似たような式を書いても中断されるとき、されないときがある。

SR-7115, SR-7120 キャプチャリストに関するバグ

SR-7115。クロージャのキャプチャリスト内で??を使用してコンパイルすると確実にセグフォになる。

SR-7120。キャプチャリストがついていないクロージャ内でrethrowするとコンパイラエラーにならないが、ついているとエラーになる。

バグレポート眺めると意外と簡単に発生してしまうバグを知れて楽しい!!

ReactiveSwiftに習うCollectionの最適化とパフォーマンスチューニングパターン / ryo_aoyama さん

speakerdeck.com

ReactiveSwiftにBagというのがあって、Signal(Observableっぽいやつ?)をKeyで管理している(たぶん)なのだが、これがどういう高速化をやっているかという話。

1。ContiguousArrayを使う。classか@objcのときにメモリの連続した領域に格納し、イテレーションを高速化できる

2。最適化済みのstdlibをそのまま利用することにより自前実装よりも高速化出来る場合がある

3。デフォルトで実装されるIndexingIterator内部で関数呼び出しにコストがかかるため

4。あとから追加されたもののほうがremove(for: )されやすいという考えで逆順に探索。

実験。add, iteration, remove を10,000件に対してやったら200倍高速化していることを確かめた。

配列はパフォーマンスチューニングしやすいので重い場合はおすすめ。

“Hello Flutter”の次におさえたいFlutterのポイント / Kenichi Kambara さん

練習に作ったアプリの紹介と、Hello Flutterの次にするとよさそうなこと。

Flutter 書くの、Android Studio使うと便利。SDK入れる。flutter doctorでチェックできる。Flutter用のプラグイン導入で簡単。これでDartも入る。起動時のダイアログでStart a new Flutter projectできる。良い。

Perform hot reload on save で Save 時に Hot reload も可能。View 例で出てきたアプリだと、ScaffoldにAppBar, body, FAB がぶら下がっている感じ。

OS別テーマ切り替えなどもできる。DartでViewを書くっていうのがちょっとつらいかもだが、ハマると良さそう。

独自Documentクラス / 村上幸雄 さん

fr.slideshare.net

MVC、よく批判される古典的なMVCと、AppleCocoa versionとして提唱しているViewとModelが干渉しないタイプのMVCがある。

Macアプリの場合NSViewとdataがNSDocumentとNSViewControllerを介して連携することになりそう。Document(Controller)部分に使えるものとしてiOS5から使えるUIDocumentクラスというのもあるが少々オーバースペックなので、Documentを独自実装したときの反省点などを紹介。

Spannable芸〜郵便番号編〜 / HiroYUKI Seto さん

予習。Spannableとは

weide-dev.blogspot.jp

Spannable はテキストをマークアップするためのインターフェースです

CharacterStyleなどのクラスを使って文字列の一部を 下線を引いたり、下付き文字にしたり、 上付き文字にしたり、URLを付けたり... と様々なことができます

内容

speakerdeck.com

最高の郵便番号入力欄を作りたい。

  • 3桁目と4桁目の間にハイフンを表示させたい
  • 3桁目を打ったらハイフンの後にカーソル移動
  • シームレスに移動。7桁ペーストしたらペーストされるし4桁目で文字削除したら左に移動。カーソル移動も。

EditTextでは解決しきれない。それでSpannableを使う。これは文字列のデコレーションのinterfaceで、未確定文字列の色などもSpan。ReplacementSpan、これはTextViewの文字列を置換するSpanで、独自絵文字なんかはこれで作られている。

ReplacementSpan で気合入れつつ実装 サンプル↓

github.com

UITableViewControllerの利点を最大限に活かす使い方 - コードでAutoLayoutを記述する場合 - / masashi-air さん

speakerdeck.com

ContainerViewを使えばUITableViewControllerの利点を最大限に活かしてレイアウトできる。

UITableViewController、UIViewControllerにtableView貼り付けるに比べて色々利点があって、

公式ドキュメントに書いてある

  1. tableViewプロパティに非オプショナルでアクセス可能
  2. delegate, dataSourceがデフォルトで設定済み
  3. clearsSelectionOnViewWillAppear
  4. 表示時にテーブルのスクロールインジケータを点滅
  5. setEditing(_: animated :)

のほかに、なぜ書いてないのかわからないがキーボードの高さを考慮して入力範囲を隠さないようにスクロールしてくれたりする。

ただ、難点あって、画面下にView置きたかったりしてaddSubViewしたりすると表示おかしくなったりする。

が、ContainerView使うとうまくいく。iOS10以前だとtableViewのInsetに設定が必要だが、ContainerViewを持っているVCにif #available(iOS 11.0, *) { } else { /* ほげほげ */ } とかやっておけば後々コード整理しやすい。

サンプルです↓

github.com

try! Flutter / Rui Kowase さん

docs.google.com

Flutter 書くの、Android Studio使うと便利。SDK入れる。flutter doctorでチェックできる。Flutter用のプラグイン導入で簡単。ビルド速くて良い。Hot Reload良い。オフィシャルドキュメントが充実している。

サンプルアプリの紹介。Scaffoldというのが使える。async/await使える。

github.com

おまけ。Flutterはときめきますという意味らしい。エラーのスクリーンのカラーコードが #7C160E とかで比較的心温まる。

Introduction to LLVMSwift / kitasuke さん

予習。LLVMSwiftとは

github.com

LLVMSwift is a pure Swift interface to the LLVM API and its associated libraries. It provides native, easy-to-use components to make compiler development fun.

内容

持ち帰って欲しいtips

LLVMSwiftの紹介。LLVMSwiftはLLVM C APIのSwiftのラッパー。Swiftコンパイラーのコミッターが2人居て主にその人達が書いてる。

サンプルのシンプルなプログラムとその出力のLLVM IR見てみると、まぁただのSwiftのラッパーだな〜という感じ。わざわざCのコード読んで勉強するより分かりやすいはず。

Cで使えばいいじゃんってなるけど本人達も名言してるかどうかしらんがLLVM、Swiftで書いたぜっていうそういう勢いが大事。

README.md に書いてあるIntroductionの説明。

界隈でSwiftコンパイラ流行っていて、silとかASTとかLLVMコンパイラとかいろんな層ある。でこういうのあると勉強に良さそうなので紹介しました。

感想とか

iOSでShared Element Transitionっぽいやつ

もっと気軽にUITableViewController使いてぇよ

Flutterさん我々を救ってください