数秒でMacOSアプリに「ログインで起動」機能を追加する
アプリがMacOS 13以降をターゲットにしている場合は、代わりにこの最新バージョンをご覧ください。
通常、これを追加するのは非常に複雑でエラーが発生しやすいプロセスです(12歳以降)。もうない!
このパッケージは、サンドボックス化されたアプリと非サンドボックス化されていないアプリの両方で動作し、App Storeの互換性があり、Plash、Dato、Lungo、バッテリーインジケーターなどのアプリで使用されます。
このパッケージは、MacOS 13+の新しいSMAppServiceと、古いMacOSバージョンでSMLoginItemSetEnabled使用しています。
SMAppServiceが存在するようになったので、なぜこのパッケージを使用する必要があるのですか?MacOS 10.13+
Xcodeの「Swiftパッケージマネージャー」タブにhttps://github.com/sindresorhus/LaunchAtLogin-Legacyを追加します。
アプリがMacOS 13以降をターゲットにする場合は、この手順をスキップします。
以下の「ビルドフェーズ」に「バンドルリソースをコピーする」という以下の新しい「ランスクリプトフェーズ」を以下に追加します。
" ${BUILT_PRODUCTS_DIR} /LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh "「依存関係分析に基づいて」チェックを外します。
ビルドフェーズは、「ユーザースクリプトサンドボックス」を有効にしても実行できません。デフォルトで有効になっているXcode 15以降では、ビルド設定で「ユーザースクリプトサンドボックス」を無効にします。
(ビルドフェーズサンドボックスに準拠するためにスクリプトを用意するためにいくつかの追加の作業が必要です。) (実行スクリプトのCopy “Launch at Login Helper”名前を付けます)
状態をuserdefaultsに保存する必要はありません。
Mac App Storeのガイドラインでは、ユーザーアクションに応じて「ログイン時の起動」機能を有効にする必要があることに注意してください。これは通常、デフォルトで無効にされる好みにすることで解決されます。また、多くのアプリにより、ユーザーはウェルカム画面でアクティブ化できます。
import LaunchAtLogin
print ( LaunchAtLogin . isEnabled )
//=> false
LaunchAtLogin . isEnabled = true
print ( LaunchAtLogin . isEnabled )
//=> trueこのパッケージには、内蔵のToggleのようなものですが、事前に定義されたバインディングとラベルが付いたLaunchAtLogin.Toggleビューが付属しています。ビューをクリックすると、アプリの「ログインで起動」を切り替えます。
struct ContentView : View {
var body : some View {
LaunchAtLogin . Toggle ( )
}
}デフォルトのラベルは"Launch at login"ですが、ローカライズやその他のニーズのためにオーバーライドできます。
struct ContentView : View {
var body : some View {
LaunchAtLogin . Toggle {
Text ( " Launch at login " )
}
}
}または、 @ObservedObjectとのバインディングとして、 LaunchAtLogin.observable使用することもできます。
import SwiftUI
import LaunchAtLogin
struct ContentView : View {
@ ObservedObject private var launchAtLogin = LaunchAtLogin . observable
var body : some View {
Toggle ( " Launch at login " , isOn : $launchAtLogin . isEnabled )
}
} LaunchAtLogin.publisherを購読するだけです。
import Combine
import LaunchAtLogin
final class ViewModel {
private var isLaunchAtLoginEnabled = LaunchAtLogin . isEnabled
private var cancellables = Set < AnyCancellable > ( )
func bind ( ) {
LaunchAtLogin
. publisher
. assign ( to : . isLaunchAtLoginEnabled , on : self )
. store ( in : & cancellables )
}
} LaunchAtLogin.publisher.valuesを使用します。
コントロールをLaunchAtLogin.kvo露出プロパティにバインドします。
import Cocoa
import LaunchAtLogin
final class ViewController : NSViewController {
@ objc dynamic var launchAtLogin = LaunchAtLogin . kvo
} 
MacOS 12以前に、パッケージはアプリを起動するのに必要なヘルパーアプリをバンドルし、ビルド時にアプリにコピーします。 MacOS 13以降では、組み込みのAPIを呼び出します。
LaunchAtlogin実行スクリプトフェーズが「埋め込みフレームワーク」フェーズをまだ下回っていることを確認してください。注文は誤って変更された可能性があります。
ビルドエラーは通常、次のように表示されます。
cp: […]/Resources/LaunchAtLoginHelper.app: No such file or directory
rm: […]/Resources/copy-helper.sh: No such file or directory
Command PhaseScriptExecution failed with a nonzero exit code
残念ながら、これは予想される動作です。
ただし、MacOS 13以降に表示されます。
これは通常、システムのどこかに1つ以上の古いビルドを使用することが原因であり、Macosは代わりにそれらのいずれかを選択しますが、それは起動ヘルパーを持たず、したがって開始に失敗します。
あなたが試すことができるいくつかのこと:
DerivedDataディレクトリを削除します。いくつかの役立つスタックオーバーフロー回答:
LaunchAtLogin.bundle表示されないか、開発者IDディストリビューションの公証エラーが発生しますここで説明したように、このパッケージは、リリースを行っているか、デバッグビルドを作成し、それに応じてインストールをクリーンアップするかどうかを判断しようとします。デバッグビルドにバンドルが欠落している場合、または逆にリリースビルドにバンドルがあり、コード署名エラーが発生した場合、これは失敗しました。
スクリプトの決定は、ビルド設定の「アクティブアーキテクチャのみのみ」フラグに基づいています。これがYESに設定されている場合、スクリプトはDebugビルドのためにLaunchAtloginをパッケージ化します。コード設計でビルドを配布する予定がある場合は、このフラグをNOに設定する必要があります。