macOS 10.15 から有効な EndpointSecurity API(SystemExtension.framework)
https://developer.apple.com/jp/system-extensions/
macOS 10.15 から、従来のカーネル拡張(KEXT)を使わずに、ユーザーランドで動作するソフトでシステムイベントを監視(おそらくイベントの許可/禁止も)できるようになった。
https://developer.apple.com/contact/request/system-extension/
まず Apple に SystemExtension.framework / EndpointSecurity API の使用リクエストを出し、許可される必要がある。
https://developer.apple.com/documentation/endpointsecurity
プロジェクトで Endpoint Security API を使用するには、以下の2つをリンクする。
- SystemExtension.framwork
- libEndpointSecurity.tdb
entitlements に com.apple.developer.endpoint-security.client = YES を設定する。
※Apple に API リクエストが許可されていないと、アプリがただしく起動しない。
従来の KEXT を使用してシステム監視(アンチウィルスソフトなど)する場合より SystemExtension.framework を使用するメリット
- Kernel extension で機能を実現した場合、ソフトはカーネルランドで実行されるため、ソフトの処理が遅いと OS 全体も遅くなってしまうなど OS の安定性に関わる現象が起きる。その分、実装もシビアになる。
- ユーザランド実行になるとここが、そこまでシビアではなくなる?
- Kernel extension 由来のセキュリティ問題がある場合、カーネル空間でその問題は発生するので OS デベロッパ(Apple)、ソフトデベロッパの責務の線引きが不明瞭になる。
不明な点
https://developer.apple.com/documentation/endpointsecurity/client?language=objc
GitHub Action の Private / Public リポジトリの制限
GitHub Actionsの支払いについて - GitHub ヘルプ
Public リポジトリ
GitHub Actions の制限はない
Private リポジトリ
GitHub Actions の実行時間とストレージに制限がある。
アカウントに存在するすべての Private リポジトリの実行時間、ストレージ使用量の合算が制限の対象。個々のリポジトリごとに制限が計算されるわけではない。
- Free アカウントの場合
- ストレージ : 500 MB
- 実行時間 : 2,000分(月)
- Pro アカウントの場合
- ストレージ : 1 GB
- 実行時間 : 3,000分(月)
Private リポジトリにおける GitHub の Actions の使用状況(利用時間とストレージ使用量)はユーザアカウントから確認できる。
GitHub Actions の使用状況を表示する - GitHub ヘルプ
制限を超えて使用したい場合は、料金支払いが必要になる。
まとめ
GitHub ワークフローで環境変数、シークレットな情報を使用する
これは 2020/05 時点の情報をもとにした記事なので、最新では事情が変わっている可能性を留意すること。
ワークフロー内で使用できる環境変数
たとえば GITHUB_REPOSITORY
(所有者とリポジトリの名前 octocat/Hello-World
など)がある。
API キーなどシークレット情報の扱い
暗号化されたシークレットの作成と保存 - GitHub ヘルプ
ある Web API を呼び出すのに必要な API キーがあったとして、それをコード中にそのまま記載してしまうと API キーの漏洩になってしまう。これを避けるため、シークレット情報は GitHub に設定して秘匿して使用することができる。
シークレット情報は Organization / Repository ごとに設定することができる。
設定したシークレット情報は、以下のようにワークフローで参照することができる。
steps: - shell: bash env: SUPER_SECRET: ${{ secrets.SuperSecret }} run: | example-command "$SUPER_SECRET"
GitHub ワークフローを使って、プロジェクトを定期実行し、成果物をデプロイする(Python)
GitHub ワークフローを使ってプロジェクトの定期実行→成果物をデプロイする方法を調べたのでまとめる。
これは 2020/05 時点の情報をもとにした記事なので、最新では事情が変わっている可能性を留意すること。
目的
GitHub ワークフロー / アクションの意味
ワークフロー
ワークフローとは、GitHubで任意のプロジェクトをビルド、テスト、パッケージ、リリース、またはデプロイするためにリポジトリで設定できる、カスタムの自動プロセスです。 ワークフローを使用すると、豊富なツールとサービスでソフトウェア開発のライフサイクルを自動化できます。
「ワークフロー」に記述した内容で、ビルドやテスト、リリース、デプロイが自動化できるようになる。
ワークフロー自体は .github/workflow の下に yml ファイルで記述する。
アクション
https://help.github.com/ja/actions/getting-started-with-github-actions/about-github-actions
GitHub Actionsは、コードを保存するのと同じ場所でソフトウェア開発のワークフローを自動化し、プルリクエストやIssueで協力することを支援します。 個々のタスクを書き、アクションを呼び出し、それらを組み合わせてカスタムのワークフローを作成できます。
「アクション」は「ワークフロー」を構成する単位となる。
どんなアクションがあるかは Markerplace で確認できる。
GitHub Marketplace · Actions to improve your workflow · GitHub
たとえば git リポジトリからチェックアウトするアクション「Checkout v2」がある。
Checkout · Actions · GitHub Marketplace · GitHub
この Checkout をワークフロー内で使用するには、以下のように記述する。
name: workflow-name # リポジトリに Push したタイミングでワークフローを実行する on: [push] jobs: build: name: workflow-job runs-on: ubuntu-latest steps: # リポジトリをチェックアウトする - name: Checkout uses: actions/checkout@v2 # チェックアウトされたリポジトリで、ビルド、テスト、リリース、デプロイ、などをする。
その他
- GitHubの新機能「GitHub Actions」で試すCI/CD | さくらのナレッジ
- ワークフロー、アクションの概念がわかりやすく書いている
GitHub リポジトリのプロジェクトを定期実行する(Python)
今回のサンプル
GitHub - daisuke-t-jp/jma-hazard-xml2json
今回作成したリポジトリはこれになる。(Python プロジェクト)
この Python スクリプトは気象庁で提供されている災害情報(XML)を取得して JSON フォーマットに変換して、ファイルに保存する、ということやっている。
気象庁 | 気象庁防災情報XMLフォーマット形式電文(PULL型)
requirements.txt
Python スクリプトに必要な外部パッケージを requirements.txt ファイルを作成し、そこに記載する。
今回は XML を Python の辞書として扱うために xmltodict を requirements.txt に追加する。
xmltodict
ワークフローを作成する
ローカルでスクリプトの動作が確認出来たら GitHub ワークフローを作成して GitHub 上でも動作するようにする。
今回のワークフローは以下の機能にする
- 定期実行したい(10分に1回)
- 成果物である JSON ファイルを保存したい
yaml で記載したワークフローは以下になる。
# ワークフローの名前 name: cron-deploy # ワークフローの実行タイミング # この場合は 10 分に 1 回 # # cron のフォーマットは以下が参考になる # http://manpages.ubuntu.com/manpages/trusty/ja/man5/crontab.5.html on: schedule: - cron: '*/10 * * * *' # ジョブの記述 jobs: # job_id は "build" build: # ジョブの名前(GitHub 上で表示される) name: deploy # Ubuntu で実行する # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on runs-on: ubuntu-latest # ジョブのステップ steps: - name: Checkout # チェックアウト uses: actions/checkout@v2 - name: Setup Python 3.8 # Python のセットアップ uses: actions/setup-python@v1 with: python-version: 3.8 - name: Install dependencies # Python 外部パッケージをインストール run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run script # Python スクリプトを実行する run: | python jma-hazard-xml2json.py - name: Deploy # gh-pages ブランチに成果物をデプロイする uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./json
このワークフローを GitHub にコミットすると、ただしく10分ごとに gh-pages ブランチにデプロイされることが確認出来た。(前のファイルは上書きされる)
DuckDuckGo iOS アプリの「Find In Page(ページ内検索)」で入力文字の候補が選択できない問題を修正
DuckDuckGo の iOS アプリで「Find In Page(ページ内検索)」で日本語が入力できない現象があったので、原因を調べて修正した。
DuckDuckGo は iOS / Android 共にオープンソースなので、第三者でも実際にコードを動かして確認することができる。
https://github.com/duckduckgo/
問題の原因は、ページ内検索をする時に
- TextField に入力された文字で「ページ内検索」を実行する
- ページ内検索の結果を WebView に反映
- TextField に入力された文字を、再度 TextField に設定する(表示された検索結果と入力された文字を同期、確定)
ということになっていたので、このシーケンスでは、たとえば「鴨」をページ内検索したい場合
- 「か」と入力する。「か」でページ内検索を実行する
- 「か」のページ内検索を WebView に反映
- TextField に「か」を設定する
になるため
- 「か」の候補である「鴨」を選択できない
- 「かも」と続けて入力した時の候補である「鴨」を選択できない(「か」「も」でそれぞれ確定されるため)
という現象が発生していた。
最初は日本語の問題に見えていたが、強制的に入力文字が「確定」されてしまうため、「候補」が選べない問題だった。(つまり日本語以外にもこの問題は影響している)
https://github.com/duckduckgo/iOS/pull/608
この問題の修正を PullRequest を送って Merge された。
修正後
AppStore のレビューでこの改善に気づいている人がいて、よかったなと。。
iOS の TensorFlow サンプルを試してみる
TensorFlow(テンソルフロー) や iOS でのサンプル実行の方法を調べたメモ。
https://www.tensorflow.org/lite?hl=ja
iOS で TensorFlow を動かすには TensorFlow Lite を使用すると良い。
TensorFlow Lite はモバイルや組み込みデバイス向けにチューニングされた TensorFlow のバージョンである。
CocoaPods で導入するにはこうする。
platform :ios, '13.0' target 'TargetName' do use_frameworks! pod 'TensorFlowLiteSwift' end
https://www.tensorflow.org/lite/examples?hl=ja
実際にどんなことができるか、どんな動きになるかを試したい場合は、ここに各パターン(画像分類やセグメンテーションなど)のサンプルアプリのリンク(GitHub へのリンク)がある。
しかし GitHub 上にはあるが、上記のサンプルのコレクションページにはない物もあるので GitHub の examples を直接見た方が良いだろう。
https://github.com/tensorflow/examples/tree/master/lite/examples
AI / 機械学習というジャンルでは「推論結果を出したい」の前に、その推論に使用するモデルを用意する必要があるので骨が折れそうなイメージがあるが TensorFlow では、学習ずみのモデルを公開しているのでそれを使用することができる。
ちなみに Apple の CoreML で TensorFlow のモデルを使用したい場合は、 CoreML 形式にコンバートされたモデルが Apple のサイトにあるので、ダウンロードできる。
https://developer.apple.com/machine-learning/models/
実際にサンプルを試すには各サンプルのルートで pod install
してからワークスペースを実行するだけで OK。
たとえば以下のような物がある。
画像に含まれる物体を分解できる。 人と背景や犬などが画像上のどのピクセルなのかを特定できる。
ソースとなる画像にスタイルを適用することができる。
たとえば
ソースの写真がこれで
スタイル適用された画像はこう出力される。(ちょっとゴッホぽくなった)
という感じにサンプルとコードを見ている中でいくつか気になる点が出てきたので、プルリクエストを送ってみた。
https://github.com/tensorflow/examples/pull/214 https://github.com/tensorflow/examples/pull/215 https://github.com/tensorflow/examples/pull/216 https://github.com/tensorflow/examples/pull/217
内容は、ダークモード時に UI が一部見えなくなる、不要なメモリ確保をしている、など。
無事プルリクエストはマージされたので、今後サンプルから学ぶ人のちょっとした足しになれば、いいなぁ、、、と。
それと、「不要なメモリ確保を削除」の PR が受け入れられたということは自分の TensorFlow Lite の認識(の一部)が、正解とズレていなかった証明になるので、安心した。。
pod install と update の違い。あと deintegrate
pod install / update をいままで何となく使っていたので、違いを調べる。
https://guides.cocoapods.org/terminal/commands.html
コマンドのマニュアル↑をみると
- install
- Podfile.lock に記載されているバージョンで、依存関係をインストールする
- update
- 古い依存関係を更新し、あたらしい Podifle.lock を作成する
となる。
使いわけとしては Podfile.lock がプロジェクトにあり、そこに書かれているライブラリのバージョンにて開発する場合は pod install をする。 もし、ライブラリのバージョンを更新したい場合は pod update を使用する。という感じになる。
実際の使い分けのケースとしては、複数メンバで開発している場合だと、開発時のライブラリバージョンを統一したい時は、リポジトリに Podfile.lock を追加し、各自 pod install でライブラリをインストールする流れにすると、バージョン差異の問題が起きない、ということができる。
あと pod deintegrate
というコマンドもあるが、これを実行すると CocoaPods の統合を解除することができる。
具体的には
- Xcode のプロジェクト(xcodeproj)から CocoaPods の記載を削除する
- Podfile, Podfile.lock は残る
という感じなので、リポジトリに push したタイミングで自動ビルド(pod install から始まる)をしたい時は deintegrate された状態で、バージョン管理していくといいかもしれない。