[AltServer] Updates LaunchAtLogin dependency

This commit is contained in:
Riley Testut
2021-06-04 14:49:54 -07:00
parent 558a3fc865
commit c6d1a040a1
22 changed files with 529 additions and 39 deletions

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,4 @@
#import <Cocoa/Cocoa.h>
FOUNDATION_EXPORT double LaunchAtLoginVersionNumber;
FOUNDATION_EXPORT const unsigned char LaunchAtLoginVersionString[];

View File

@@ -0,0 +1,67 @@
import Foundation
import ServiceManagement
import Combine
public enum LaunchAtLogin {
public static let kvo = KVO()
@available(macOS 10.15, *)
public static let observable = Observable()
@available(macOS 10.15, *)
private static let _publisher = CurrentValueSubject<Bool, Never>(isEnabled)
@available(macOS 10.15, *)
public static let publisher = _publisher.eraseToAnyPublisher()
private static let id = "\(Bundle.main.bundleIdentifier!)-LaunchAtLoginHelper"
public static var isEnabled: Bool {
get {
guard let jobs = (SMCopyAllJobDictionaries(kSMDomainUserLaunchd)?.takeRetainedValue() as? [[String: AnyObject]]) else {
return false
}
let job = jobs.first { ($0["Label"] as? String) == id }
return job?["OnDemand"] as? Bool ?? false
}
set {
if #available(macOS 10.15, *) {
observable.objectWillChange.send()
}
kvo.willChangeValue(for: \.isEnabled)
SMLoginItemSetEnabled(id as CFString, newValue)
kvo.didChangeValue(for: \.isEnabled)
if #available(macOS 10.15, *) {
_publisher.send(newValue)
}
}
}
}
// MARK: - LaunchAtLoginObservable
extension LaunchAtLogin {
@available(macOS 10.15, *)
public final class Observable: ObservableObject {
public var isEnabled: Bool {
get { LaunchAtLogin.isEnabled }
set {
LaunchAtLogin.isEnabled = newValue
}
}
}
}
// MARK: - LaunchAtLoginKVO
extension LaunchAtLogin {
public final class KVO: NSObject {
@objc dynamic public var isEnabled: Bool {
get { LaunchAtLogin.isEnabled }
set {
LaunchAtLogin.isEnabled = newValue
}
}
}
}

View File

@@ -0,0 +1,80 @@
import SwiftUI
@available(macOS 10.15, *)
extension LaunchAtLogin {
/**
This package comes with a `LaunchAtLogin.Toggle` view which is like the built-in `Toggle` but with a predefined binding and label. Clicking the view toggles launch at login for your app.
```
struct ContentView: View {
var body: some View {
LaunchAtLogin.Toggle()
}
}
```
The default label is `"Launch at login"`, but it can be overridden for localization and other needs:
```
struct ContentView: View {
var body: some View {
LaunchAtLogin.Toggle {
Text("Launch at login")
}
}
}
```
*/
public struct Toggle<Label>: View where Label: View {
@ObservedObject private var launchAtLogin = LaunchAtLogin.observable
private let label: Label
/**
Creates a toggle that displays a custom label.
- Parameters:
- label: A view that describes the purpose of the toggle.
*/
public init(@ViewBuilder label: () -> Label) {
self.label = label()
}
public var body: some View {
SwiftUI.Toggle(isOn: $launchAtLogin.isEnabled) { label }
}
}
}
@available(macOS 10.15, *)
extension LaunchAtLogin.Toggle where Label == Text {
/**
Creates a toggle that generates its label from a localized string key.
This initializer creates a ``Text`` view on your behalf with provided `titleKey`
- Parameters:
- titleKey: The key for the toggle's localized title, that describes the purpose of the toggle.
*/
public init(_ titleKey: LocalizedStringKey) {
label = Text(titleKey)
}
/**
Creates a toggle that generates its label from a string.
This initializer creates a `Text` view on your behalf with the provided `title`.
- Parameters:
- title: A string that describes the purpose of the toggle.
*/
public init<S>(_ title: S) where S: StringProtocol {
label = Text(title)
}
/**
Creates a toggle with the default title of `Launch at login`.
*/
public init() {
self.init("Launch at login")
}
}

View File

@@ -0,0 +1,50 @@
#!/bin/bash
HELPER_CHECKSUM="0a3d09438fb595802d554ce0a7c4ba8e1d2d91d5170362adc965da82e70d74cb"
HELPER_CHECKSUM_RUNTIME="98ef556b490e02f4084a11d8a07c33a880177a9816b355885a11f58c95876d62"
verlte() {
[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
}
if verlte "10.14.4" "$MACOSX_DEPLOYMENT_TARGET"; then
helper_name="LaunchAtLoginHelper"
checksum="$HELPER_CHECKSUM"
else
helper_name="LaunchAtLoginHelper-with-runtime"
checksum="$HELPER_CHECKSUM_RUNTIME"
fi
package_resources_path="$BUILT_PRODUCTS_DIR/LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources"
helper_path="$package_resources_path/$helper_name.zip"
contents_path="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH"
login_items="$contents_path/Library/LoginItems"
login_helper_path="$login_items/LaunchAtLoginHelper.app"
rm -rf "$login_helper_path"
mkdir -p "$login_items"
# Verify SHA256 checksum of LaunchAtLoginHelper.
zip_checksum="$(shasum -a 256 "$helper_path" | awk '{print $1}')"
if [[ "$zip_checksum" != "$checksum" ]]; then
echo "Wrong checksum of LaunchAtLoginHelper"
exit 1
fi
unzip "$helper_path" -d "$login_items/"
defaults write "$login_helper_path/Contents/Info" CFBundleIdentifier -string "$PRODUCT_BUNDLE_IDENTIFIER-LaunchAtLoginHelper"
if [[ -n $CODE_SIGN_ENTITLEMENTS ]]; then
codesign --force --entitlements="$package_resources_path/LaunchAtLogin.entitlements" --deep --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$login_helper_path"
else
codesign --force --deep --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
fi
# If this is being built for multiple architectures, assume it is a release build and we should clean up.
if [[ $ONLY_ACTIVE_ARCH == "NO" ]]; then
rm -rf "$contents_path/Resources/LaunchAtLogin_LaunchAtLogin.bundle"
fi

View File

@@ -0,0 +1,24 @@
#!/bin/bash
origin_helper_path="$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/LaunchAtLogin.framework/Resources/LaunchAtLoginHelper.app"
helper_dir="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems"
helper_path="$helper_dir/LaunchAtLoginHelper.app"
rm -rf "$helper_path"
mkdir -p "$helper_dir"
cp -rf "$origin_helper_path" "$helper_dir/"
defaults write "$helper_path/Contents/Info" CFBundleIdentifier -string "$PRODUCT_BUNDLE_IDENTIFIER-LaunchAtLoginHelper"
if [[ -n $CODE_SIGN_ENTITLEMENTS ]]; then
codesign --force --entitlements="$(dirname "$origin_helper_path")/LaunchAtLogin.entitlements" --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
else
codesign --force --options=runtime --sign="$EXPANDED_CODE_SIGN_IDENTITY_NAME" "$helper_path"
fi
# If this is being built for multiple architectures, assume it is a release build and we should clean up.
if [[ $ONLY_ACTIVE_ARCH == "NO" ]]; then
rm -rf "$origin_helper_path"
rm "$(dirname "$origin_helper_path")/copy-helper.sh"
rm "$(dirname "$origin_helper_path")/LaunchAtLogin.entitlements"
fi

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSBackgroundOnly</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>MIT © Sindre Sorhus</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,26 @@
import AppKit
// TODO: When targeting macOS 11, convert this to use `App` protocol and remove `NSPrincipalClass` in Info.plist.
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
let bundleIdentifier = Bundle.main.bundleIdentifier!
let mainBundleIdentifier = bundleIdentifier.replacingOccurrences(of: #"-LaunchAtLoginHelper$"#, with: "", options: .regularExpression)
// Ensures the app is not already running.
guard NSRunningApplication.runningApplications(withBundleIdentifier: mainBundleIdentifier).isEmpty else {
NSApp.terminate(nil)
return
}
let pathComponents = (Bundle.main.bundlePath as NSString).pathComponents
let mainPath = NSString.path(withComponents: Array(pathComponents[0...(pathComponents.count - 5)]))
NSWorkspace.shared.launchApplication(mainPath)
NSApp.terminate(nil)
}
}
private let app = NSApplication.shared
private let delegate = AppDelegate()
app.delegate = delegate
app.run()