わふうの人が書いてます。

iOSアプリケーション開発、BLEのファームウェアとハードウェア試作のフリーランスエンジニア。

WWDC20 What’s new in location

What’s new in location https://developer.apple.com/videos/play/wwdc2020/10660

CoreLocationの、ユーザ許可がiOS14で変わります。プライバシーの保護のために、位置情報の利用にはこれまでも考慮が重ねられてきましたが、iOS14ではさらに、利用者に正確な位置情報を要求した時に、利用者が低精度の位置情報利用を選択して許可できるようになります。

位置情報利用のダイアログに、位置情報を正確/低精度を切り替えるボタンが表示されて、ユーザはそれで切り替えができます。最初から低精度な位置情報を要求している場合には、このボタンは表示されません。

アプリケーションが、本当に正確な位置情報を必要とするときは、一時的に正確な位置情報を要求するなど、アプリの目的に合わせた位置情報取得の実装が必要になります。また、この位置情報の利用許可は、WatchアプリとiPhoneアプリ間で、同期します。Watchのコンパニオンアプリで位置情報の利用を許可すれば、iPhoneの本体アプリでもその許可が有効になります。

低精度の位置情報は、円の領域で与えられます。その中央にユーザがいるわけではありません。位置情報は、利用者の真の位置情報にノイズを加えたものではありません。その利用者は、その円のどこかに入っている、という程度の情報です。

例えば、車で移動しているとき、円の領域のなかを利用者が移動していき、円の縁にくれば、その円の領域は更新されて、次に利用者がいるだろう領域を示します。

低精度の位置情報で、Visit APIでバックグラウンド動作をするときは、移動がなければ通知はなく、移動があるときは1時間に4回程度の通知がきます。Visit APIは、正確な位置情報取得時でも、低精度な取得時でも、位置に入った時刻それ自体は、訪れた時刻が通知されます。低精度だからと言って、時間まで低精度になるわけではありません。

ビーコン及びそのほかの領域モニタリングが、.reducedAccurary では無効になります。

AppClipsではalwaysの位置情報は使えない。1日有効です。

Widgetでは、info.plistにNSWidgetWantsLocationを含めます。

ドイツのCOVID-19のシステムがすごいなって

ドイツのCOVID-19対策アプリのコードを検索したら、ガチだなって思ったので、ポエムを書きます。

ランディングページは https://coronawarn.app です。このアプリを使うことで得られるメリット、陽性判定時の登録や曝露通知の受け取りなどの使用フロー、プライバシーの保護、そしてオープンソースで運営していることが説明されています。20日時点で1000万ダウンロードを超えるようです。

開発の事業者

ホームページ、登録/検証サーバ及びiOSとAndroidのネイティブアプリなど、このシステム一式が https://github.com/corona-warn-app にあります。それぞれのライセンスを見ると、ライセンス形式はどれも Apache License, Version 2.0 です。著作権者は、ベリフィケーション・サーバーが Deutsche Telekom AG.、ウェブサイトが Deutsche Telekom AG and SAP SE or an SAP affiliate company.、サーバー及びモバイルアプリがSAP SE or an SAP affiliate company.となっています。主軸の開発はSAPで、後に出てくる認証サーバーはドイツテレコムが構築するチーム構成のようです。

システム構成

ドキュメントのなかに、全体アーキテクチャが説明されています https://github.com/corona-warn-app/cwa-documentation/blob/master/solution_architecture.md 。図を見ているだけで、ものすごくわかった気持ちになるドキュメントです。図はSAPが内部で使う FMC と UML を融合させたTAM http://www.fmc-modeling.org/fmc-and-tam という形式だそうです。なんとなく眺めてみます。

コンポーネンツ

登場人物は、利用者と、厚生省庁そして検査機関と医師の3つです。サーバーはオープンテレコムクラウドでホストされます。

ベリフィケーションのインタラクションフロー

左上から、利用者のアプリインストールと通知を受け取るためのサインアップ(オプショナル)、感染検査とその結果の受け取り、アプリの感染者のテンポラリキーの回収が書かれています。teleTANは、人が読むことができるトークン文字列です。

ベリフィケーションのデータフロー

ベリフィケーションのデータフローは、数字の順番に見ていくと、処理の流れがわかります。アプリとサーバー間で、GUIDや登録トークンを交換し、それらはハッシュ関数に通して保存されます。テスト結果サーバー/確認サーバー/テンポラリキー保存サーバがそれぞれあり、サーバーの中核になるのが確認サーバーです。

このドキュメントから、それぞれのサーバー及びアプリの開発に、チームごとに開発が下りていくのでしょうが、それぞれの関係が纏まっていて、わかりやすいです。また、Apple/Googleの曝露通知の仕組みを、識別子やBLEの振る舞いまで細かく説明をしていて、プライバシー保護などの根拠として十分な技術情報がまとめられています。よくできてます。

陽性判定者と接触したことを通知するときに、オプションで、その通知者のテンポラリキーも回収する作りになっていたりと、とにかく感染の可能性のある人を見つけようとする仕組みが細かいところに入ってる感じで、よく練られてるんだろうなと感じます。

iOSアプリ

欧米ではAndroidのシェアが大きくiPhoneは少数派ですが、私がiOSしか分からないので、iOSのコードを見てみます。 https://github.com/corona-warn-app/cwa-app-ios

アプリ画面

アプリ画面のデザインは、今時の全画面で有機ELなiPhoneらしい、白を基調として、アイコン的な画像と十分に大きな文字で説明、そして最後に確認ボタンを配置した、現代的なアプリデザインです。みやすいです。

コードを開くと、UIはパーツごとにxibファイルに分割されていて、チーム開発でコンフリクトが生じにくいよう範囲が最小になっています。シンプルなアプリのはずですけど、ものすごいファイル数です。

当然と言えば当然なのですが、UIテストなどのターゲットが作られていて、リリースサイクルも管理されていて、いい感じです。

wwdc2020 キーノートまとめ

キーノートを自分なりにまとめます

https://developer.apple.com/wwdc20/ から、WWDC2020のキーノートの要点と着目点を列挙していきます。キーノートの概要は、各ネットニュースで掲載されていますから、ここは自分の着目点とその理由を書いていきます。

COVID-19対策のため、プレゼンテーション会場に参加者がいない初めてのWWDCとなりました。WWDCのキーノートは全体に落ち着いたプレゼンテーションです。iOS登場時のような、熱狂的な雰囲気はありません。ですが、今年のキーノートは、ここ6年ほどのiOSデバイスの発展の歴史を、一度整理して、利用者の視点からシームレスで、使いたい機能を探さなくても、使いたい機能がすっと使える自然さにまとめ上げていく、次の10年を予感させる内容でした。

Apple Silicon

Apple製品全体のプロセッサを自社開発品に切り替えていく、Apple Siliconが発表されました。これまでIntelのプロセッサを使用し続けてきたMacも、iPhoneがそうであるように、Apple自社設計チップに切り替わっていきます。2年ほどを移行期間として、当面はインテルプロセッサ搭載Mac製品も出るようです。

Mac向けには、デスクトップにふさわしい消費電力と処理能力のバランスをとった新チップを設計するようです。AMD Ryzenを採用したMacが登場する可能性は、これでなくなりました。Macの中身がどうなろうが、MacがMacであることには違いがありません。利用者にとって、目に見える当面のメリットは何もないでしょう。

iPhoneのプロセッサの内部を見ると、演算処理をするプロセッサ部分は存外大きくはなく、その面積は、グラフィックのGPU、機械学習のニューラルチップ、外部と高速な情報のやり取りをするインタフェース、セキュリティ専用コア、そしてキャッシュメモリと、高速に情報をやり取りする構成要素の詰め合わせです。Apple Siliconが、ノートパソコン/デスクトップ/ハイエンドデスクトップに、どの製品から、どのようなチップを提供するのかは、興味があるところです。TSMCの7nm及び5nm、ローパワーライブラリ/ハイパフォーマンスライブラリで、ノートとデスクトップの製品分野でシングルスレッドの性能の違いを出すでしょうか。あるいはノートとデスクトップで、それぞれのローエンドとハイエンドで、性能の異なるチップを採用する、価格帯横串で違いを作るでしょうか。AMDのようにチップレットのパッケージ内高密度実装をベースに、必要な性能だけチップレットを増やす構成でしょうか、あるいはGPGPUのチップ間超高速接続のような仕組みで、パッケージを増やして全体処理能力を上げるのでしょうか。

Apple Siliconの登場で、開発者は、再ビルドでApple Silicon対応のバイナリを配布する必要があります。x86エミュレーション(ロゼッタストーン2)/iPadアプリをビルドでmacOSに移植もあります。また、Adobeのグラフィックソフトウェア、MS社のオフィスツール、Unityなど、開発やオフィスツールのネイティブ対応での協業が発表されていますから、ツールとしての問題はないでしょう。

パーソナルコンピュータ市場全体でのMacのシェアは7%程度のようです。iOSアプリなどの開発ツールを使う場合はMac以外のパーソナルコンピュータを選ぶことはありませんが、一般業務では、Macはいくつかある選択肢の1つです。iOSデバイスとのシームレスな機能などを利便性と感じて選ぶか、あるいは、もしも消費電力が小さければ、二酸化炭素排出量削減への貢献から企業として調達リストに入れるか、業務利用するMacの設定などの管理ソフトで管理費用などを考慮するかなど、いくつかの視点で選べばいいでしょう。

iOS14

豊富なiOSアプリケーションが、アプリストアに溢れています。この豊かさは、アプリ販売やアプリ内課金で収益が上げられるからです。開発者の新たなiOSへの機能の関心は、単純に新技術への好奇心に加えて、これらの収益が得られるか、収益をより大きくできるか、また新たな収益の場面が登場するかと、収益が関心の中心にあります。

iOS14では、アプリ拡張からウィジェットとAppClipsが作れるようになります。

ウィジェットは、iOS14以前からありましたが、ホーム画面に常駐できるようになります。ウィジェットの常時稼働は消費電力とメモリを消費しますが、ウィジェットのUIをシリアライズしてホーム画面アプリに渡し、ホーム画面アプリは非同期でそれを表示反映する仕組みにより、ウィジェットアプリが常に動作しなくてもよい仕組みを取り込んでいます。ちょうど、初代WatchOSが、Watch単体でアプリが実行できず、iPhoneでアプリ拡張が生成した画面イメージをWatchに転送することで、Watchでアプリが動いているかのように見せていましたが、あの仕組みを思い出させます。

AppClipsは、アプリストアからアプリをダウンロードしなくても、小さなアプリ拡張をその場で実行表示する仕組みです。Androidにある、Instant appsと同じでしょうか? 10MB以下とサイズが制約されています。例えば、買い物で1回しか使わない場合など、AppClipsで支払い画面を出し、そこで支払いを完了してもいいでしょう。継続して使うなら、アプリ本体をストアからインストールすればいいのです。AppClipsを簡単に見つけられるように、円形のバッジのような独特のQRコードのようなマーク、App Clipコード、も提供されます。

アプリをインストールしてもらう壁は、思うよりも高いものです。展示会向けにカタログ代わりのアプリケーションを提供する場合は、インストールに至る工夫が不可欠です。今は、カメラアプリがQRコードに対応しているので、ポスターにアプリストアへのリンク情報を含むQRコードを印刷してインストールを促進できます。App Clipsの優位性は、支払い処理がワンクリック、アカウント認証が組み込みやすいことで、リアル世界でのお金のやり取りが伴う、ちょっとした場面に最適に思えます。

オフライン動作する、音声とテキストの通訳ソフトが入ります。翻訳デバイスの市場を破壊してしまいそうです。

Mapは、自転車用と電気自動車用の経路検索が追加されます。電気自動車の充電スポットが表示されるなど、用途に合わせた経路上の情報が提示されます。利用可能としが、NYなど米国の都市と北京など中国の都市で、Appleにとっての中国市場の重要性が現れていました。

現行のiPhoneには、UWBでセンチメートル単位で距離がわかるU1チップが採用されていますが、これを使いiPhoneが車の鍵になります。BMWなどから、今年後半また来年にかけて対応車が登場します。午後に子供に車の利用を許す場合には、メッセンジャー経由で子供のiPhoneに許可データを送れば、子供のiPhoneでロック解除できるなど、ソフトウェア的な鍵の体験になっています。

FindMy Networkに、3rdのアクセサリがアクセスできる。3rdのApple関連機器に、FindMy Networkが解放。デバイスがどこにあるのか、iPhoneデバイスと統合されて表示される。これ、リアルデバイスのAppleへの紐付けですね。https://developer.apple.com/find-my/

HomeKitも、それ自体がオープンソース化、さらにAmazonのアレクサ対応機器など数多くのスマートホームのプラットホームとの連携、今まで対応機器が広まらない1ブランドだったのに、iPhone利用者にはユーザの接点としての統合窓口HomeKitみたいな橋頭堡を得た感じしますね。

iPadOS

検索窓に手書きで書き込むと、それがテキストデータになって入力される場面がありました。検索窓には、テキストを入力する細長いエリアがありますが、そのエリアを超えて手書き文字が書かれているのに、そのエリアに認識結果のテキストが入ります。

UIKitを使ったことがあるなら、UIの入力イベントはUIViewの矩形領域内部に限られるのを思い出すかもしれません。ですが手書きできる領域が、あの小さなテキスト入力領域だと、ものすごく不便です。その辺りにはそのテキスト入力エリアしかないのですから、その辺りに手書きすれば、そこにテキストが入るのが自然です。これをUIKitの考え方で実装するのは、ちょっとややこしく、だから手書き入力パッドを画面の別の場所に表示させて、そこで認識させたテキストが反映される、キーボード入力のペン代替みたいな、実現できる実装をします。そういう逃げをしないところが、いい感じです。

SwiftUI

AppClips、WatchOS、iOS、iPadOS、macOSと、いくつもの画面サイズにシームレスに対応していく必要が出てきます。SwiftとSwiftUIを使い始めるタイミングなのでしょう。もう、AutoLayoutでどうにかできる話では、ないようです。

日本独自のCOVID-19に対する曝露通知アプリケーションのソースコードを読んでみる

日本独自のCOVID-19に対する曝露通知のiOSアプリケーションのソースコードが、いろいろ勉強になると思ったので、読んでみるメモです。
レポジトリ: https://github.com/mamori-i-japan/mamori-i-japan-ios

ポイント:

フォルダ配置

Xcodeのフォルダ配置は、アプリケーションのトップの下にリソースとソースコードがあり、それぞれその下に細分化したフォルダが並びます。

  • Resources
    • Config
  • Sources
    • Models
    • Navigations
    • Networks
    • Screens
    • Services
    • Utilities
    • Views

Sourcesの下には、データモデル、画面遷移のナビゲーション、ネットワーク関連、UIViewControlに相当するScreens、ネットワークアクセスなどの機能の窓口となるサービス、ユーティリティ、Viewがが並びます。よくあるグループの分け方で、わかりやすいです。

ライブラリのライセンスの自動生成

アプリケーションで使用しているライブラリのライセンスを、設定画面に一覧表示する部分を、自動生成しています。

iOSの”設定”アプリに、それぞれのアプリケーションごとに通知などの設定画面があります。Settings.buldleで、その画面にアプリケーション独自の項目を追加できます。Settings.bundle, https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/UserDefaults/Preferences/Preferences.html

自動生成に、A license list generator of all your dependencies for iOS applications, https://github.com/mono0926/LicensePlist を使っています。ビルド時にシェルスクリプトを動かして、Settings.bundle以下に、ソフトウェアラインセスの一覧を追加します。

デバッグと本番の設定分け

Firebaseの設定など、デバッグと本番とで必ず設定が異なる部分は、xcconfigを使っています。ちょっとした差分設定で、かつXcodeがデフォルトで対応していない設定項目には、この使い方はいい感じです。

サーバを利用するアプリケーションは、デバッグで用いるサーバと、本番運用で用いるサーバが異なります。Xcodeで、デバッグと本番とで設定を変える方法は、ターゲットを使う方法があります。ターゲットそれぞれは独立したものですから、1つのターゲットの変更は、その他のターゲットに何らの影響を与えません。これは、もしもデバッグと本番でターゲットを作っていた場合、その両方に共通した設定変更が出てきた場合には、手動でそれぞれのターゲット設定を変更しなければなりません。この構成は、ミスしたり忘れたりしてしまう原因になりえます。

xcconfigの使い方で、Xcodeが対応しているプロビジョニングなどまでxcconfigで仕込む場合もあるかもしれません。ビルドサーバーを管理運営する専任の人がいて、開発者がXcodeで何か変なことをしても影響させないなら、全てをxcconfigに持ち込むのもアリかもしれません。ですが通常は、Xcodeで扱えるものまで、設定ファイルに持ち込むと、Xcodeでいくら設定変更してもその変更が反映されず、原因がわからずに混乱してしまうだけです。

設定はその設定内容に適した場所で、かつ開発者ならどこで設定されているものが影響を与えるのかを思いつけるように、合理的に。

シェルスクリプトなどで、Mintというコマンドを使っています。

A package manager that installs and runs Swift CLI packages, https://github.com/yonaskolb/Mint

Mint で Swift 製のコマンドラインツールを管理する, https://qiita.com/usamik26/items/be813a224a2146daffb7

そんな場合に Mint が便利です。Mint は Swift Package Manager ベースで開発された Swift 製コマンドラインツールを管理するためのツールです。
例えば、SwiftLint や Carthage といったツールが管理できます。Mint を使うと、複数のバージョンをインストールしておき、バージョンを指定して実行することが可能になります。

Node.jsのnpmなどではデフォルトですが、開発で混乱を避けるためには、開発ツールやライブラリのバージョンを固定するなどして、どの端末でビルドしようが同じ結果になるようにしなければなりません。Xcodeのみを使うのであれば、最新版のXcodeでビルドできるようにメンテナンスすればよく、開発ツールのバージョン管理までは必要ではないかもしれません。ですが実際には、Xcodeにその時点ではない使いたい何かがあれば、外部ツールとして取り込んで使っていくでしょうから、Mintのようなツールは必要になります。

受託開発での iOS アプリプロジェクト新規作成プラクティス(上編:Xcode 編),https://qiita.com/lovee/items/38cdfd5d2f5827f27427

UIとストーリーボードの使い方

画面遷移は、ソースコードの内部に実装されています。画面遷移は、独立したファイルで指定されています。それぞれの画面は、UIViewContrllerを継承するクラス名と同じファイル名のSwiftファイルと、それと同じファイル名のストーリーボードで、1画面単位で作られています。画面のインスタンスは、依存性注入のライブラリを利用して、生成しています。

通常は、ストーリーボードに画面遷移も作り込みます。ですが、チーム開発では1画面の修正が、その1つのストーリーボードのファイルを変えてしまうために、コンフリクトがよく生じます。これは、1画面の修正が、その他の画面も含まれるストーリーボードを変えてしまうからです。ストーリーボード1つでの画面遷移管理は、見た目と遷移が一致するので、間違いが起きにくいのですが、コンフリクトの発生は厄介です。

ストーリーボードからUIViewControllerのインスタンスを、依存性注入しながら、生成するライブラリ, https://github.com/Swinject/SwinjectStoryboard

依存性注入は、デバッグと本番とで環境が異なる場合に、ネットワークなどの外部とのやりとり部分を、モックにするか実際に動くものにするかを、設定により切り替えができます。もしもテストで切り分ける必要がないならば、あるいはビジネス層はユニットテストで十分なテストができて、UI層は人間の目で確認していくものならば、このソースコードでサービスとなっている部分は、コードの中でそれぞれインスタンスしていけばいいのですが… その辺りは、開発運用の部分かなと思います。

使われている便利機能

Viewも、xibファイルとswiftでファイル分離しているけど、それをするとxibを反映させるためには、コードでViewをインスタンスして貼り付けないといけない。その時にコンストレインの設定などが面倒だけど、

HomeViewController.swift https://github.com/mamori-i-japan/mamori-i-japan-ios/blob/0a82ccb2bd8d31344ac936894740353e84fee31a/TraceCovid19/Sources/Screens/Home/HomeViewController.swift にあるように、

1
2
3
4
5
6
7
8
let header = HomeUsualHeaderView(frame: headerBaseView.frame)
header.set(contactCount: count) { [weak self] in
self?.pushToTraceHistory()
}
headerBaseView.addSubview(header)
header.snp.makeConstraints { make in
make.edges.equalToSuperview()
}

ダミーで空Viewを作っておいて、そのサブビューに追加して、エッジをsuperViewに貼り付けさせている。エッジのコンストレイン定義は、http://snapkit.io を使っている。

ログ出力は、Swift.log()などSwift名前空間のものを使うのが、今時なのかしらん? Obj-C時代からの週間で、今もdebugLog()などを使っていたけど。
https://github.com/mamori-i-japan/mamori-i-japan-ios/blob/0a82ccb2bd8d31344ac936894740353e84fee31a/TraceCovid19/Sources/Utilities/PrintUtility.swift

デバッグメッセージ表示は、UIWindowの上にテキストViewをスクロール表示させて、デバッグメッセージのアプリ内表示ができるようにしている、っぽい。その場確認は、確かに便利そう。
https://github.com/mamori-i-japan/mamori-i-japan-ios/blob/0a82ccb2bd8d31344ac936894740353e84fee31a/TraceCovid19/Sources/Utilities/PrintUtility.swift

iOSで全画面にウォータマークを入れるのにUIWiddowSceneDelegateを使うやり方

Appleが提供しているCOVID-19の濃厚接触通知のサンプルプロジェクトで、アプリのあらゆる画面に”REFERENCE ONLY”を表示させるコード部分が、面白い実装だと思ったのでメモします。

プロジェクトファイルは、Building an App to Notify Users of COVID-19 Exposure https://developer.apple.com/documentation/exposurenotification/building_an_app_to_notify_users_of_covid-19_exposure にあります。この中の ExposureNotificationApp/SceneDelegate.swift が次のコードです。

iOS13から、例えばiPadなどで1つのアプリで複数の画面を切り替えながら使う用途で、シーンという概念が導入されています。このシーンを扱う UIWindowSceneDelegate で常に前面に”Reference only”のテキストラベルを表示するUIWindowを生成して、アプリで使わせています。iOS13のSceneDelegate周りのアプリの起動シーケンス https://qiita.com/omochimetaru/items/31df103ef98a9d84ae6b が参考になります。

UIWindowSceneDelegate, Additional methods that you use to manage app-specific tasks occurring in a scene. https://developer.apple.com/documentation/uikit/uiwindowscenedelegate

アプリがシーンに対応しているのか、複数のUIWindowを扱えるのか、UIWindowSceneDelegateの実装クラス名は、Info.plistで指定します。

Application Scene Manifest、の下に Enable Multiple Windows NO があります。複数のUIWindowは持ちません。さらに下に、DelegateClassNameがあります。ここでクラス名を指定しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
See LICENSE folder for this sample’s licensing information.

Abstract:
The scene delegate.
*/

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: WatermarkWindow!

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
window = WatermarkWindow(windowScene: scene as! UIWindowScene)
window.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
(window.rootViewController as! UITabBarController).selectedIndex = 1
window.makeKeyAndVisible()
}

func sceneDidBecomeActive(_ scene: UIScene) {
let rootViewController = window!.rootViewController!
if !LocalStore.shared.isOnboarded && rootViewController.presentedViewController == nil {
rootViewController.performSegue(withIdentifier: "ShowOnboarding", sender: nil)
}
}
}

class WatermarkWindow: UIWindow {

let watermark = UILabel()

override init(windowScene: UIWindowScene) {
super.init(windowScene: windowScene)

watermark.text = "REFERENCE ONLY"
watermark.font = .boldSystemFont(ofSize: 48.0)
watermark.textColor = .quaternaryLabel
watermark.translatesAutoresizingMaskIntoConstraints = false
watermark.transform = .init(rotationAngle: -.pi / 4.0)
watermark.isAccessibilityElement = false
addSubview(watermark)
NSLayoutConstraint.activate([
centerXAnchor.constraint(equalTo: watermark.centerXAnchor),
centerYAnchor.constraint(equalTo: watermark.centerYAnchor)
])
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func didAddSubview(_ subview: UIView) {
super.didAddSubview(subview)
bringSubviewToFront(watermark)
}
}

COVID-19感染拡大防止とiOSの曝露通知の仕組み

Apple/Googleが提供する曝露通知について、その仕組みとその働きの考察をプレゼンしました。

仕組みの概要

SARS-CoV-2の感染の目安は、ウイルスを外部に排出している方との、1~2メートル程度の距離で15分以上という、濃厚接触を持ったかどうかです。

感染拡大防止には、実効再生産数、対策を行なっている状態で平均して1人あたりが感染させる人数、を1以下にすることが必要です。日本での感染拡大防止の活動は、陽性判定が出た方にインタビューをして、人の記憶を頼りにいつ誰と接触したかを調べて、潜伏期にあるかもしれない方々に人との濃厚接触を低減するようお願いをすることです。この濃厚接触を通知する仕組みが、曝露通知です。

曝露通知は、Apple/Googleが提供するフレームワークと、各国それぞれの行政が開発運営するアプリと通知サーバの、2つで構成されます。

フレームワークの機能は、識別子の生成と送信、識別子の受信と記録、識別子の照合の3つです。それぞれの端末が識別子をBLEでブロードキャストします。また同時に、周囲のブロードキャストをスキャンして、その識別子を記録します。陽性判定された方は、アプリを通じて、ウイルスを排出していた期間の識別子を、サーバーにアップロードします。陽性判定された方々の識別子は、それぞれのアプリに通知されて、デバイスの内部で識別子の照合が実行されて、濃厚接触があった場合はアプリにその旨が表示されます。

識別子の送出と記録そして照合という基本部分は、Apple/Googleが開発する部分で、アプリケーションが識別子などの具体的な情報を直接扱うことはできません。アプリケーションの機能は、曝露通知の利用を開始する、濃厚接触があった場合にそれを知らせる、陽性判定が出た時にそれを入力する、の3つです。これらの部分は、利用者の合意と運営が必要で、それぞれの国ごとの行政活動ですから、アプリケーションとして切り出しになります。

通知サーバーも、それぞれの国の運営になります。仕組み自体は、Apple Notification Serviceなど、スマホの通知の実装と同じようなものです。Apple/Googleが提供する通知サービスに、運営者が提供するサーバーから通知したい情報を渡せば、それが対象デバイスに配布されていきます。

質問と回答

Q: 感染していないのに陽性だと入力して、いたずらされるのでは?
A: 陽性の場合にアプリにそれを入力するには、日本では保健所が発行する認証コードが必要です。パスワードがない他人のアカウントにログインしようとするようなものですから、いたずらはできないのでしょう。

Q: アプリの配布6割とか無理では?
A: 人口が小さく教育水準も高そうなシンガポールで、政府が独自に提供した濃厚接触検出アプリがインストール率2割らしい(根拠未調査)です。シンガポールの人口は563万人、東京都の人口927万人の半分くらいの規模でもそれですから、国の単位で6割は、自然に達成できる値ではないと思います。

法的な根拠に基づきインストールを強制するのも困難でしょう。例えばですが、飲酒運転で検挙された場合に問答無用で解雇となるルールがある会社は少なくないでしょう。濃厚接触通知のアプリをインストールしていないことが、社会の利益に貢献しないこととして、なんとく空気感として、インストールせざるを得ない雰囲気にでもするのかもしれません。

Q: 標準アプリとして配布、あるいはヘルスアプリに機能統合してしまえないのか。
A: 濃厚通知の仕組みを初めて聞いた時に、通知サーバーまで含めてApple/Googleが提供するのかと思っていました。でも、それでは陽性だと入力するのが本当に陽性なのか、誰かがそれを保証しないと、いたずらする人がいれば、使い物にならなくなります。標準アプリにした場合、この陽性だと確認して保証する仕組み部分が、処理として入れられないでしょう。キャリアの端末は、自社サービスのアプリをプリインストールしていますが、そのようなプリインストールはありなのかも?

Q: 国を超えた移動をする方は、これを使えるのか。
A: アプリの運営が国単位になるため、訪問国のアプリをインストールして帰国後も2週間程度はアンインストールせずにおけば使えるはずです。

濃厚接触した誰かが陽性であった場合は、iOS/Androidのデバイス通知は国を超えて機能するでしょうから、曝露通知が得られると思われます。ですが、自分に陽性判定に出た時には、アプリに陽性だと入力するための認証コードは、日本の保健行政機関から認証コードを払い出してもらわなければなりません。国の間での行政連携でもないと、できそうにない気がしますが、それがどうなるかはわかりません。あとは、通知サーバーは国ごとの運営になるため、もしもファイヤーウォールなどのために、他国の通知サーバーにアクセスできない場合は、陽性判定が出た場合でもそれを知らせることはできなさそうです。

ダイソンの掃除機と旧型ブラーバが一緒に収まるスタンドがありました

タイトルでもう書くべきことが尽きていますが、ダイソンの掃除機と、iRobotの床拭きロボット、旧型のブラーバが、山崎実業(Yamazaki)コードレスクリーナースタンドにちょうど収まりました。ダイソンの掃除機は、3000円くらいからあるギタースタンドや、石膏ボードにギターのヘッド部分を立てかけるスタンドを利用するなど、ギタースタンドが結構使えるのですが、今回は専用のスタンドを購入してみました。

写真のように、このスタンドに、Dyson V6 Fluffy(フラフィ)と、ダイソンの掃除機の予備ヘッドをおけるスタンドの奥側の隙間に旧型ブラーバが収まっています。旧型ブラーバには充電用のスタンドがありますが、このスタンドが奥側の隙間にちょうど収まりました。

山崎実業のコードレスクリーナスタンドは、掃除機の先端ツールを差し込む部分が、単なる板のプレートと、板を四角に折り曲げたタワーの2種類があります。プレートとツールの2つの製品の違いは、ツールを差し込む部分の形状だけです。どちらも6000円ほどの販売価格ですが、たまたまかもしれませんが、2020年5月の時点ではプレートが4000円台と大きな割引価格になっています。ツールの方は、6000円台と本来の希望小売価格のままです。

プレートの方が、大きな割引価格でお買い得です。ですが、ツールが金属を折り曲げた四角の部分にしっかり挿さりそうなのと、単なる板だと頭をぶつけた時に顔に刺さりそうな不安感があるという、根拠のない理由でタワーの方を購入しています。

こちらが、プレートのツール差し込み部分。

こちらが、タワーのツール差し込み部分。

プレート

タワー

台所用品のまとめ

前提と目的

1LDKで、独身世帯が自炊をする台所の配置と用品のまとめをします。

台所のありようは、日々の料理が億劫にならない、気持ちよく作業できることです。それには、使いたい道具がすぐ手に取れること、そして片付けが面倒にならないことが必要です。合理的に整然とした写真写りも見た目にも美しい台所を、毎日維持できれば理想的ですが、それは面倒です。適当に道具を手に取り、適当に戻して、酷い乱雑な見た目にははならずに、毎日使い続けられればよいとします。

冷蔵庫と電気調理器を木製ラックにそろる

冷蔵庫と電気調理器は、毎日使うものです。また食器は、毎回取り出してまた収めるものです。これらは、木製ラックに納めています。

木製ラックは部品で組み立てるもの

収納はこんな感じです。無印のパイル材ユニットシェルフを使います。https://www.muji.com/jp/ja/store/cmdty/section/S02703

棚の1段あたりの高さは18センチメートルです。向かって右は、下3段は18センチメートル単位で、その上は電子レンジが収まるギリギリの36センチメートル、さらにその上は蓋を開けるため高さが必要な電気圧力鍋を置き、最上段はビニール袋やタッパーを入れておく重さがない籠を置くスペースにします。

向かって左は、下の段から、生ゴミ箱、調味料を入れる箱とカトラリーを置くスペース、そしてコーヒーメーカを置いています。入り口横なので、向かって左の棚は高さを抑えていますから、右の棚のような最上段はありません。

冷蔵庫は氷点下ストッカーのある3ドア

冷蔵庫は、MR-CX33C-Wを使っています。シリーズの製品は、毎年少しだけ仕様が変わり新型として型番のアルファベットが変わります。その入れ替え時期で旧機種となったものが安くなりますから、そのタイミングを狙います。10万円を切るくらいで購入できます。

https://www.mitsubishielectric.co.jp/ldg/wink/ssl/displayProduct.do?ccd=102010&pid=286948

独身世帯では300リットルから400リットルの製品で十分です。3ドアで冷蔵室のドアがどこからでも開けるものになりました。高さをちょっと低めの170センチメートルのものにして、冷蔵庫の上に物を置いています。

消費電力もチェックしておきます。同じ企業の冷蔵庫で同じような容積のものでも、型番によっては消費電力が妙に大きなものがあったりします。1kWhを20円として10年使うとすれば、1kWhの消費電力の違いは製品寿命の間で200円の違いになります。

動作音は気になるところですが、購入して見なければわかりません。カタログには、動作音15デシベルなどと数値化されて書かれていますが、音が小さくても気になる音もあります。カタログで数値で確認して、鵜呑みにはできませんがレビューがあれば参考にします。

氷点下ストッカーは、お魚や肉を凍るか凍らないか寸前の状態で保存してくれるので、もしも魚を捌くのが好きで魚を丸ごとで買うならば、2~3日は保存できますから便利です。

木製ラックにある調理器具など

木製ラックに置いている調理器具などをまとめていきます。

電気圧力鍋を使っています。ガスレンジの圧力鍋であれば火の前にいなければなりませんが、電気で自動制御なので、材料と調味料を入れて、あとは放っておくだけです。インターネットでレシピをダウンロードできる機能や、かき混ぜ機能がある機種もありますが、そういったものがない物を選んでいます。象印のものは、レシピ本があり、そこにある番号を選択すれば、調理時間と温度そして圧力が設定できます。

スマートホンでレシピが見られるのは、検索を活用するならば便利です。調理中にスマートホンを取り出して見たりするのは面倒です。紙の本では、何を作るか決まっていなくてぺらぺらと見る、調理中にページを開けておけば都度参照できるのは、便利です。

ティファール 電気ケトル 0.8Lは、温度調整ができる物を使っています。調理用であれば熱湯があればよいので、沸騰させるだけのものでよいのですが、紅茶用にお湯の温度を指定したいので、これにしています。温度設定機能は、鯛のアラを湯で洗う時に、臭みになるタンパク質が変質すればいいので、熱湯ではなく90度くらいのお湯が欲しい場合でも便利です。

デロンギ (DeLonghi) コンパクト全自動コーヒーメーカーを置いています。エスプレッソが飲みたいわけではないのですが、コーヒーの豆を入れておけば、全自動でコーヒーが入ること、そしてコーヒーの粉をその都度捨てなくても、数回でまとめて捨てるだけでよい、という手間のなさで選ぶとこれになりました。スチームでミルクを泡立てられるので、カフェオレを楽しめます。2杯分の豆を使う濃厚なジャポネーゼというものも入れられます。普段と違う物を飲みたくなれば、カフェオレやジャポネーゼを選べるのは、気分の切り替えになってよいです。

オーブン電子レンジには、ZITANGを使っています https://www.mitsubishielectric.co.jp/home/rangegrill/ 。これは、電子レンジと熱風を噴き出すグリルと上下の電熱線で加熱するオーブンの3つを組み合わせたものです。独身世帯で使いよい用に、庫内容量を小さくして加熱時間を短縮しています。本体の高さも、他社製品と比べて低くなっています。

冷蔵庫で冷えたコロッケを、電子レンジ+グリル+オープンで再加熱すると、電子レンジで温めて、グリルとオープンで外側をカラッと揚げたてのようにしてくれます。温度センサーで加熱を調整するので、冷凍したご飯やお刺身の解凍、牛乳の加熱もできます。250度でピザも焼けます。

生ゴミ箱は、simplehuman ダストボックス セミラウンドカン 30L。45リットルのゴミ袋を被せて使えます。密閉度が高く臭いが外に漏れません。内部には黒い別容器があるので、もしもゴミ袋から液体が外に出た場合でも、容器を取り出して洗うだけですみます。

荒澤製作所 アルファクト シャルル・プレーン http://www.alfact.co.jp/38900.html

KEVNHAUN カトラリーケース

台所周りの調理器具

引き出しの中

引き出しの中は、プラスチックの入れ物を入れて、3つの部分に分けます。計量スプーンなど細かいものは右の部分に入れます。そのほかの調理器具は真ん中か左の幅の広い部分に入れます。よく使う物を真ん中に戻すようにすれば、いつも使うものが真ん中に自然に集まります。

引き出しに入れているプラスチックの入れ物は、
ブリックス 9023〈350ミドルM〉https://likestore.like-it.jp/products/detail.php?product_id=236 と、ブリックス 9008〈280ミニS〉https://likestore.like-it.jp/products/detail.php?product_id=243 です。

この入れ物は引き出しの奥行きよりも短いので、この入れ物を引き出しに入れると奥の空間が少し余ります。スペーサーに適当にタオルを丸めて奥に詰めておくなりします。

引き出しに入っている調理器具

お助けスプーン。でっかいスプーンです。かぼちゃの煮物やボールで和えたサラダを皿に取り分けるとか、炒め物で混ぜる時など、適当に便利に使えます。

金属の持ち手が好みなので、お玉やターナーはツヴィリングのものを使います。

ツインキュイジーヌ ナイロンレードル

ターナー https://jp.zwilling-shop.com/jp/Kitchen-World/Kitchen-gadgets-storage/Cooking-frying/Lifters-Turners/Turner-ZWILLING-39711-000-0.html

計量カップは、アヒルの形をした、グースメジャーカップを使っています。計量スプーン付きで、いくつもありますが、実際に使うのは、200ミリリットルと100ミリリットルの2つです。それより小さな容積は計量スプーンを使えば足ります。この計量カップは円形ではなく、横向きの高さが低いので、引き出しにほどよく収まります。

計量スプーンは、マザーズセレクション 大さじ 計量スプーン イノブンスタンダード05 715円(税込) https://www.inobun.com/item-044657.html と 小さじ 605円(税込) https://www.inobun.com/item-044658.html を使っています。

計量スプーンでフライパンで焼いている物をかき混ぜたりするので、熱で溶けるプラスチックの計量スプーンは使えません。また金属のスプーンでも、計量スプーンというと、金属の薄い板を打ち抜いたような厚みのないものが多いです。これは分厚い金属の質感があり表面の質感もいい感じです。持ち手の上に、樹脂に縁取られた小さな穴があります。料理中にいく種類もの調味料を計っては入れていくときに、ボウルに計量スプーンを立てかけることがよくあリマス。この計量スプーンだと、この穴の樹脂部分がボウルの縁に引っかかり、スプーンがボウルの中に落ち込みません。地味に便利です。

計量スプーンは何本もセットになったものもあります。大さじ15ミリリットル、小さじ5ミリリットルですから、この2本があれば、あとは足し算で計算すれば足ります。この計量スプーンは半分の容量の線が入っています。

細かい調味料

細かい調味料は、小さなジップロックに入れて、プラスチックの入れ物に入れています。

プラスチックの容器は、大小それぞれ:

ライクイット(like-it)キッチン収納キッチンツールケース 深型 S 幅14x奥21x高12.5cmクリア

ライクイット(like-it)キッチン収納キッチンツールケース S幅10.5x奥14x高6.3cmクリア

シンク下

プラスチックのブックエンドを置いておくと、鍋の蓋やトレーを立てて置けます。

インジニオ・ネオ IHステンレス エクセレンス https://www.t-fal.co.jp/products/pots-pans/stackable/ingenio_ih_stainless_excellence/ 。取手の取れるティファールは、テフロンコーティングが2年程度で剥がれてくるので、消耗品になります。テフロンコートが使われていない、エクセレンスのソースパンのみが残りました。一度焦げ付くと、もう取れないので見た目は最悪ですが、汁物を作り、ソースパンに入れたまま冷蔵庫で保存できるのは便利です。写真のソースパンは18センチメートルのものです。ソースパンとハンドルを個別に購入することも、多分可能なはずです。

揚げ物は、この鍋を使っています。紙フィルタと粘土ベースの濾過材を使うと、油が汚れずいつもきれいです。
オークス 日本製 ウチクック オイルポット 揚げ 鍋 クイックフライヤー


タニタ 温度計

その他

ガスレンジは、火力が強いので、雑誌のクロワッサンとリンナイがコラボした製品を使っているのです。これは今では製造されていません。安全装置が必要になったりと要求性能項目が増えたので、新製品になり、今では、Vamo. 39800円(税抜き) https://www.vamo4000.jp になっています。

鍋やフライパンは、南部鉄器のものを使っています。ネイキッドパン 片手24cm 深さ4cm https://shop.oigen.jp/?pid=135209978 、マルット https://shop.oigen.jp/?mode=grp&gid=2125403 。周辺が茶色に焦げてパリッとした目玉焼きが、火加減の調整なく適当に焼けます。フライパンは2.45kgの重さがあるので、持ち上げて動かすのも大変なので、ガスレンジに出しっぱなしです。取手は熱くなります。ミトンは、つけたり脱いだりが面倒なので、布地の鍋おきで持ち手をくるっと巻いて使うのが便利です。

まな板は、イチョウの物を使っています。大きなまな板を置くと、台所がまな板に占拠されて使いにくくなるので、シンクに食器カゴとまな板を縦方向に並べて設置できる、18センチメートルの小さいまな板を使っています。

https://www.icyomanaita-futaba.com 18x32センチメートル、3000円(税抜き)。まな板立て 1000円(税抜き)。長く使っていると、それなりに黒くなっていくので、購入後に、まな板の側面や、まな板置きには、ウレタン塗装をしてもいいのかも。

水切りかごはラパーゼを。下の部分の金属ワイヤ部分が、ワイヤが縦横になっていると交点に汚れが溜まりそうなので、そうではない物を探すとラパーゼのものしかありませんでした。

包丁

包丁は、写真の上から:

Zwilling ツインプロHB 三徳包丁

貝印 KAI 三徳包丁 関孫六 10000CC 165mm

藤次郎 プロ DPコバルト合金鋼2層複合 小出刃 105mm

旬 Shun Classic クラシック ペティー 100

貝印 KAI 三徳包丁 関孫六 10000CCは、炭素鋼をステンレスで挟み込んだ物だそうですが、研げばものすごくよく切れます。関孫六 10000CCの持ち手の部分は、口金と樹脂加工した木材でできています。水気をちゃんと拭き取らないから膨張しているのかもしれませんが、口金と木材部分に、多分0.1ミリ以下だとは思いますが、手でさすると分かる段差があるのが少し残念です。ヘンケルスの包丁は、持ち手部分と口金の段差もなく、重さのバランスもよい感じで、手で触れると楽しい包丁です。

iBeaconの検出でバッググラウンドで何かを実行する(不成功)

iBeaconを検出して、バックグラウンドで何かを処理させる手軽な誰にでもできそうな方法を探しましたが、見つかりませんでした。

ビーコン販売と紐付けたアプリケーションもしくはサービスは、調べてはいません。今手元にあるiOSデバイスで、ビーコンとその検出の振る舞いをすぐに確認できる方法を求めているので、特定のビーコンを購入しなければ試せないものは、今回の調査対象外です。

iOSアプリあるいはPythonistaで、実行可能なアプリケーションを作れば、バックグラウンドでのビーコンの検出と、その検出を何かのイベントに紐付ける振る舞いは作れます。

iOS標準アプリの、ショートカットには、オートメーションの機能で位置をトリガーにする機能があります。ですが、トリガー条件に指定できるのは物理的な位置のみで、iBeaconは指定できません。

Launch Center Proというアプリケーションのランチアプリで、アプリ内課金640円ほどで、位置でフックするオプションを有効にして、iBeaconの検出をトリガーにして、通知画面にアプリへのリンクを表示させることはできました。ですが、アプリ自体の実行は、人間がロック画面から通知をタップして実行しなければならず、自動で内部で実行が進みません。Launch Center Proのトリガー実行は、URLで指定されるので、httpサーバを起動して、そのサーバにアクセスさえできれば外部フックとして使えるだろうと思い試しましたが、ブラウザへのURL表示の実行パスができるだけで、アプリを自分で実行するほかないのは、変わりませんでした。

httpsサーバの簡易なアクセスログ取りは、このサイトを参照しました。

Google Spreadsheet を簡易 Webサーバーとして動かして、手軽にWebHookを受け取る方法 https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3

HomeKitADKを動かしてみる

スマートホームは、機器のネットワークへの接続と、その応用場面の広がりの2つが揃わなければ、利用する価値が生まれません。ネットワーク接続という付加価値を求めた、家庭用機器がこれまでにいくつもの企業から発売されては、製品としてジャンルを確立しないまま消えていきました。

そのスマートホームの流れの中で、新たにAmazonとAppleとGoogleそしてZigbeeアライアンスなどの業界グループから、スマートホームデバイス向けのオープン規格を目指す発表がありました。

https://www.apple.com/newsroom/2019/12/amazon-apple-google-and-the-zigbee-alliance-to-develop-connectivity-standard/

また、HomeKitのデバイス側の開発コードがAppleから公開されています。

https://github.com/apple/HomeKitADK

HomeKitの通信仕様自体は数年前に公開されていて、非商用での開発ができましたが、今回はAppleからさらに開発用コードが提供される形になりました。

https://developer.apple.com/homekit/

HomeKitADKは、非商用で利用できます。製造販売を行うにはMFiの取得が必要です。アプリケーションのコードは、電球と鍵の2つが入っています。

ADKは、Darwin,Linux,ラズベリーパイで動きます。ラズベリにはDockerファイルも提供されています。ビルドは楽そうです。

ソースコードを見ると、Darwinの方は、BLEのペリフェラルとして動くようです。

https://github.com/apple/HomeKitADK/tree/master/PAL/Darwin

Linuxの方は、BLE関連はモックファイルを内部でインクルードしているだけですから、動きません。

ちょっとMacOSで動かしてみました。
READMEにあるビルド方法そのままで、すんなりビルドできます。
IPの方は動きますが、BLEの方はペアリング完了の段階でMac側のアクセサリのプログラムが止まります。
ペアリングの8桁のコードは、”111-22-333”です。

HomeKit ADKをうごかしてみる、Mac OSで。

% cd ~/tmp
% git clone https://github.com/apple/HomeKitADK
Download and install Xcode 11
install brew
% /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
% brew install openssl@1.1
% brew install mbedtls –HEAD
% make all

使ったのはこのブランチ
https://github.com/apple/HomeKitADK/tree/35c8adbb0dae4e44c694fc267dead68be936e65b

BLEのプログラムは、8桁のコードを入力した時点で、アクセサリ側のプログラムが止まるっぽい。こんなメッセージが最後に出ていた。中身まではみていない。
‘’’’
01a0 a0f3 ..
timer register 0x7fa851e1ab20
‘’’’