20210914のiOSに関する記事は2件です。

iOS 開発の頑張らないビルド用 Swift CLI ツール管理

TL;DR どうせ macOS 上でしか開発できないので、 直接ビルドツールの実行バイナリをダウンロードして利用する。 モチベーション XcodeGen SwiftLint LicensePlist といった最終成果物には含まれないが、ビルドプロセスで利用する Swift 製 CLI ツールの管理について、 Mint を利用してプロジェクトでバージョンを固定+開発者のローカルマシンに依存させないといった設定をよく実施するかと思います。 これまでは特に問題がなかったのですが、 Apple Silicon ( M1 Mac ) の登場によって、Homebrew 経由でインストールしたものを Build Phases で実行する際に PATH を通す必要があったり、 Mint で Permission 上の問題が発生 したりで若干のしんどさを感じたので、他の方法を模索してみました。 どうするのか 基本対応 大まかには以下のような感じです。 SwiftLint 0.43.1 の場合 $ curl -fsSL "https://github.com/realm/SwiftLint/releases/download/0.43.1/portable_swiftlint.zip" | bsdtar xf - -C "${インストール先}" $ "${インストール先}/swiftlint" lint curl コマンドで .zip ファイルをダウンロード、 bsdtar コマンドで展開して、指定の箇所に配置 バイナリをそのまま実行 という流れです。 前提として、 リリースページにて macOS 上でそのまま実行可能なバイナリファイルが配布されている macOS 標準の CLIコマンドで展開できる .zip 形式等でアーカイブされている といったあたりを要求されます。 ( 有名どころでは Carthage が .pkg での配布なのでちょっと厳しそうです ) 冒頭にも記載していますが、 iOS 開発においては macOS が前提であり、macOS においては Universal Binary や Rosetta 2 等の CPU アーキテクチャ間の差異を吸収して実行する仕組みが整備されているため、 配布されているバイナリをそのまま利用しようというのが主旨となります。 キャッシュ 上述の通り、基本対応としては .zip ファイルをダウンロード + 展開 + バイナリ実行するだけなのですが、これを Xcode の Build Phases 等で実行すると、ビルド毎にダウンロードが走ってしまうため、一度ダウンロード + 展開した実行バイナリファイルのキャッシュとしての利用を考えます。 とはいえ対応がシンプルな分、キャッシュ利用の判断に使える情報も少ないため、今回は 指定展開先にバイナリが展開されているかどうか 展開されたバイナリのバージョンが指定バージョンかどうか でキャッシュ利用を判断する方法を採用しました。 SwiftLint を例にすると、以下のようなシェルスクリプトによって、ダウンロードの抑制が実現できます。 swiftlint-execute.sh #!/usr/bin/env bash INSTALL_PATH="${インストール先}" NAME="SwiftLint" VERSION="0.43.1" ZIP_URL="https://github.com/realm/SwiftLint/releases/download/${VERSION}/portable_swiftlint.zip" BIN_PATH="${INSTALL_PATH}/swiftlint" VERSION_CMD="${BIN_PATH} version" EXPECTED_VERSION_FMT="${VERSION}" # version サブコマンドを実行して、期待するバージョン値が出力されるかどうかで判断 # バイナリ自体が存在しない場合も、バージョン不一致扱いとなる if [ "$(${VERSION_CMD} 2>/dev/null)" != "${EXPECTED_VERSION_FMT}" ]; then curl -fsSL "${ZIP_URL}" | bsdtar xf - -C "${INSTALL_PATH}" # そのままだと実行権限がついていないので chmod 755 "${BIN_PATH}" fi "${BIN_PATH}" lint --path "${Lint対象パス}" バージョンが一致しているかどうかで確認することによって、ビルドツールのアップデート時には再ダウンロード+インストールが行われることを期待しています。 メリット Mint への依存がなくなる 元々のモチベーションではあるのですが、ビルドツールの導入・管理で Mint を利用しないため、多少なりとも環境構築の手間は省けるはずです。 速い 特に CI/CD 環境でのビルドで顕著だと思うのですが、ビルドツールのインストールに関してソースコードからのビルドを実施しないため、インストールに掛かる時間が短いです。 ビルドツールのバイナリサイズについても、大体は数 MB 程度なので、ダウンロード自体も大した負荷とはなってきません。 また、 CI/CD 環境においても、インストール先を指定のディクトリ配下にまとめて、キャッシュ指定することで、ダウンロードをスキップすることが可能です。 問題点 キャッシュを求めると言うほど簡単にはならない 本来の目的としては、タイトル通り「頑張らない」で管理したいのですが、前述のサンプルコードの通り、キャッシュ動作の整備等を考慮するとだんだんと複雑になってきます。 比較対象の Mint 等では、 Mintfile 等のパッケージ管理用のファイルを用意して1行記載するだけなのに対し、今回の対応はシェルスクリプトでの諸々の実装が発生してしまいます。 特にビルドツール毎に多少の差異が存在するため、1行記載で導入完了ということはなく、ある程度のトライ&エラーが発生してしまうというのが辛いところです。 バイナリを信用できるのか メリットの裏返しにはなってくるのですが、ソースコードからビルドしているわけではないので、バイナリに怪しいコードが含まれている可能性を排除しづらいです。 主には GitHub のリリースページからダウンロードしてくることになるため、明らかに危険な内容ということはないはずなのですが、そのまま利用するかどうかは開発ポリシー次第な感じです。 ダウンロードせずとも Git リポジトリにバイナリ追加でよいのでは 途中で気づいたのですが、それでいい気はしています。。 一応、 Git リポジトリ内のバイナリファイルの出自が明示的ではない 一応、ダウンロードする場合はダウンロード元 URL の情報が残る バイナリファイルが頻繁に更新される場合は Git と相性が悪い といった問題はあるのですが、前者は PR レビューで抑える。後者はユースケース的にそれほど更新頻度は高くないので、影響は軽微だと思っています。 あとは Git でバイナリファイルを管理することに抵抗がないなら、ダウンロード時間の分だけ速度面でも有利になってくる認識です。 その他 ビルドツールの Apple Silicon 対応状況 軽く触れてきた通り、Universal Binary で x86_64 と arm64 に対応してくれていれば問題ないのですが、 x86_64 バイナリだった場合は Rosetta 2 が要求されてきます。 とはいえ実際の対応状況が不明だったので、ターゲットとなってきそうな有名どころのツールに対して、 $ lipo -archs ${調査対象ツール} で調べてみた結果をまとめてみました。 ツール バージョン lipo -archs Mint 0.16.0 x86_64 XcodeGen 2.24.0 x86_64 arm64 SwiftGen 6.4.0 x86_64 SwiftLint 0.43.1 x86_64 arm64 SwiftFormat 0.48.11 x86_64 arm64 IBLinter 0.4.27 x86_64 LicensePlist 3.13.0 x86_64 サンプルプロジェクト キャッシュ対応含めて一通りの動作を確認するためのサンプルプロジェクトを作ってみています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】ボイスチェンジャーアプリでBluetoothイヤホンを使用して録音再生できるようにしてみた

「おばけだぞう」と子供がしつこく言うので、変声機アプリを作ってみた。 サンプル画像: アプリ概要: -「Record」ボタンで音声を録音 -スライダー「Speed」「Pitch」、スイッチ「Echo」「Reverb」で声のエフェクトをかける -「Play」ボタンで再生、モーダルに画面遷移してお化けアイコンの表示 参考サイト: [Swift4.2]蝶ネクタイ型変声期作ってみた 課題: 再生時に「音量」が上がらない。 Bluetoothイヤホンを接続すると「録音・再生」が機能しない。 下記のサイトを参考: AVAudioSessionで録音する際に、音はbluetoothイヤホン、マイクはデバイスマイクを使いたい 追加したコード。 Audio.swift try session.setCategory( .playAndRecord, mode: .default, // オプションの内容は[]で閉じると良い options: [.defaultToSpeaker, // マイク/レシーバーからマイク/スピーカーに変更 .allowAirPlay, // AirPlayデバイスにストリーミング .allowBluetoothA2DP]) // Bluetoothイヤホンで録音再生可能 githubにコード全文を載せています。 (https://github.com/r-tattsu2060/Voicechange/tree/main/Voicechange)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む