11 Commits

Author SHA1 Message Date
Christian Tietze 9a894d7992 Consistently use macOS 10.13 as deployment target for 'modern' Xcode (#103) 2024-06-25 02:03:32 +02:00
Sindre Sorhus f326e3d9be Change repo name 2024-05-28 18:38:05 +02:00
Sindre Sorhus 22923d3354 Meta tweaks 2024-03-25 02:35:28 +09:00
Sindre Sorhus 0615d2f292 Tweaks 2024-03-25 02:35:19 +09:00
Dave DeLong cf9770cd43 More robust ONLY_ACTIVE_ARCH comparison (#101) 2024-03-25 02:35:10 +09:00
UeharaYou d811817ce3 Update note for Xcode 15 (#97) 2023-10-07 11:13:34 +07:00
UeharaYou 8e28b5e5a9 Add Xcode 15 note (#96)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
2023-07-21 21:28:46 +02:00
Sindre Sorhus 7ad6331f9c Support SMAppService for macOS 13
Fixes #76
2022-11-13 23:48:46 +07:00
Sindre Sorhus d473e16953 Document Xcode 14 requirement
Fixes #81
2022-09-25 12:20:49 +07:00
Sindre Sorhus fe1c59e088 Drop support for macOS 10.12
It’s no longer supported by Xcode.
2022-09-22 23:51:24 +07:00
Sindre Sorhus 05168c04c9 Meta tweaks 2022-09-05 14:02:50 +07:00
14 changed files with 142 additions and 106 deletions
-4
View File
@@ -1,4 +0,0 @@
github: sindresorhus
open_collective: sindresorhus
patreon: sindresorhus
custom: https://sindresorhus.com/donate
-10
View File
@@ -1,10 +0,0 @@
name: CI
on:
- push
- pull_request
jobs:
build:
runs-on: macOS-11
steps:
- uses: actions/checkout@v2
- run: swift build
+24 -5
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 60;
objects = {
/* Begin PBXBuildFile section */
@@ -167,8 +167,9 @@
E32E9B5A1EB87D7B000FEEE9 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 1200;
LastUpgradeCheck = 1500;
ORGANIZATIONNAME = "Sindre Sorhus";
TargetAttributes = {
E32E9B621EB87D7B000FEEE9 = {
@@ -190,7 +191,7 @@
};
};
buildConfigurationList = E32E9B5D1EB87D7B000FEEE9 /* Build configuration list for PBXProject "LaunchAtLogin" */;
compatibilityVersion = "Xcode 12.0";
compatibilityVersion = "Xcode 15.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -262,6 +263,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -292,9 +294,11 @@
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -309,7 +313,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@@ -326,6 +330,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -356,9 +361,11 @@
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -367,7 +374,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
@@ -385,11 +392,13 @@
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_MODULE_VERIFIER = YES;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = Sources/LaunchAtLogin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -399,6 +408,8 @@
"@loader_path/Frameworks",
);
MARKETING_VERSION = 4.2.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLogin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -415,11 +426,13 @@
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_MODULE_VERIFIER = YES;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = Sources/LaunchAtLogin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -429,6 +442,8 @@
"@loader_path/Frameworks",
);
MARKETING_VERSION = 4.2.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLogin;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -444,6 +459,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Sources/LaunchAtLoginHelper/Info.plist;
@@ -451,6 +467,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLoginHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -467,6 +484,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Sources/LaunchAtLoginHelper/Info.plist;
@@ -474,6 +492,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.LaunchAtLoginHelper;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1200"
LastUpgradeVersion = "1500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1200"
LastUpgradeVersion = "1500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+2 -2
View File
@@ -1,10 +1,10 @@
// swift-tools-version:5.3
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "LaunchAtLogin",
platforms: [
.macOS(.v10_12)
.macOS(.v10_13)
],
products: [
.library(
+85 -10
View File
@@ -1,8 +1,14 @@
import Foundation
import ServiceManagement
import Combine
import os.log
private let hasMigratedKey = "LaunchAtLogin__hasMigrated"
public enum LaunchAtLogin {
@available(macOS 11, *)
private static let logger = Logger(subsystem: "com.sindresorhus.LaunchAtLogin", category: "main")
public static let kvo = KVO()
@available(macOS 10.15, *)
@@ -15,7 +21,80 @@ public enum LaunchAtLogin {
private static let id = "\(Bundle.main.bundleIdentifier!)-LaunchAtLoginHelper"
private static var hasMigrated: Bool {
get { UserDefaults.standard.bool(forKey: hasMigratedKey) }
set {
UserDefaults.standard.set(true, forKey: hasMigratedKey)
}
}
public static func migrateIfNeeded() {
guard
#available(macOS 13, *),
!hasMigrated
else {
return
}
hasMigrated = true
if isEnabledLegacy {
isEnabledModern = true
}
unregisterLegacy()
}
public static var isEnabled: Bool {
get {
if #available(macOS 13, *) {
return isEnabledModern
} else {
return isEnabledLegacy
}
}
set {
if #available(macOS 10.15, *) {
observable.objectWillChange.send()
}
kvo.willChangeValue(for: \.isEnabled)
if #available(macOS 13, *) {
isEnabledModern = newValue
} else {
isEnabledLegacy = newValue
}
kvo.didChangeValue(for: \.isEnabled)
if #available(macOS 10.15, *) {
_publisher.send(newValue)
}
}
}
@available(macOS 13, *)
private static var isEnabledModern: Bool {
get { SMAppService.mainApp.status == .enabled }
set {
do {
if newValue {
if SMAppService.mainApp.status == .enabled {
try? SMAppService.mainApp.unregister()
}
try SMAppService.mainApp.register()
} else {
try SMAppService.mainApp.unregister()
}
} catch {
logger.error("Failed to \(newValue ? "enable" : "disable") launch at login: \(error.localizedDescription)")
}
}
}
private static var isEnabledLegacy: Bool {
get {
guard let jobs = (LaunchAtLogin.self as DeprecationWarningWorkaround.Type).jobsDict else {
return false
@@ -26,19 +105,15 @@ public enum LaunchAtLogin {
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)
}
}
}
@available(macOS 13, *)
private static func unregisterLegacy() {
isEnabledLegacy = false
try? SMAppService.loginItem(identifier: id).unregister()
}
}
// MARK: - LaunchAtLoginObservable
+3 -3
View File
@@ -25,7 +25,7 @@ extension LaunchAtLogin {
}
```
*/
public struct Toggle<Label>: View where Label: View {
public struct Toggle<Label: View>: View {
@ObservedObject private var launchAtLogin = LaunchAtLogin.observable
private let label: Label
@@ -46,7 +46,7 @@ extension LaunchAtLogin {
}
@available(macOS 10.15, *)
extension LaunchAtLogin.Toggle where Label == Text {
extension LaunchAtLogin.Toggle<Text> {
/**
Creates a toggle that generates its label from a localized string key.
@@ -67,7 +67,7 @@ extension LaunchAtLogin.Toggle where Label == Text {
- Parameters:
- title: A string that describes the purpose of the toggle.
*/
public init<S>(_ title: S) where S: StringProtocol {
public init(_ title: some StringProtocol) {
label = Text(title)
}
+1 -1
View File
@@ -45,6 +45,6 @@ else
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
if [[ $ONLY_ACTIVE_ARCH != "YES" ]]; then
rm -rf "$contents_path/Resources/LaunchAtLogin_LaunchAtLogin.bundle"
fi
+1 -1
View File
@@ -17,7 +17,7 @@ else
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
if [[ $ONLY_ACTIVE_ARCH != "YES" ]]; then
rm -rf "$origin_helper_path"
rm "$(dirname "$origin_helper_path")/copy-helper.sh"
rm "$(dirname "$origin_helper_path")/LaunchAtLogin.entitlements"
-2
View File
@@ -1,7 +1,5 @@
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!
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+23 -65
View File
@@ -2,62 +2,31 @@
> Add “Launch at Login” functionality to your macOS app in seconds
It's usually quite a [convoluted and error-prone process](before-after.md) to add this. **No more!**
**If your app targets macOS 13 or later, check out [this modern version](https://github.com/sindresorhus/LaunchAtLogin-Modern) instead.**
It's usually quite a [convoluted and error-prone process](before-after.md) to add this (on macOS 12 and older). **No more!**
This package works with both sandboxed and non-sandboxed apps and it's App Store compatible and used in apps like [Plash](https://github.com/sindresorhus/Plash), [Dato](https://sindresorhus.com/dato), [Lungo](https://sindresorhus.com/lungo), and [Battery Indicator](https://sindresorhus.com/battery-indicator).
<br>
**This package uses the new [`SMAppService`](https://developer.apple.com/documentation/servicemanagement/smappservice/3945412-mainapp) on macOS 13+ and [`SMLoginItemSetEnabled`](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled) on older macOS versions.**
---
### Why should I use this package now that [`SMAppService`](https://developer.apple.com/documentation/servicemanagement/smappservice/3945412-mainapp?changes=latest_minor) exists?
<div align="center">
<p>
<p>
<sup>
<a href="https://github.com/sponsors/sindresorhus">Sindres open source work is supported by the community</a>
</sup>
</p>
<sup>Special thanks to:</sup>
<br>
<br>
<a href="https://keygen.sh">
<div>
<img src="https://sindresorhus.com/assets/thanks/keygen-logo.svg" width="210" alt="Keygen">
</div>
<b>A dead-simple software licensing and distribution API built for developers</b>
</a>
<br>
<br>
</p>
</div>
---
<br>
- Backwards compatibility with older macOS versions
- Nicer API
- Included SwiftUI component
## Requirements
- macOS 10.12+
- Xcode 12+
- Swift 5.3+
macOS 10.13+
## Install
#### Swift Package Manager
Add `https://github.com/sindresorhus/LaunchAtLogin` in the [“Swift Package Manager” tab in Xcode](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).
#### Carthage
*Warning: Carthage is not recommended. Support for it will be removed at some point in the future.*
```
github "sindresorhus/LaunchAtLogin"
```
Add `https://github.com/sindresorhus/LaunchAtLogin-Legacy` in the [“Swift Package Manager” tab in Xcode](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).
## Usage
#### Swift Package Manager
**Skip this step if your app targets macOS 13 or later.**
Add a new [“Run Script Phase”](http://stackoverflow.com/a/39633955/64949) **below** (not into) “Copy Bundle Resources” in “Build Phases” with the following:
@@ -65,16 +34,11 @@ Add a new [“Run Script Phase”](http://stackoverflow.com/a/39633955/64949) **
"${BUILT_PRODUCTS_DIR}/LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh"
```
*(I would name the run script `Copy “Launch at Login Helper”`)*
And uncheck “Based on dependency analysis”.
#### Carthage
Add a new [“Run Script Phase”](http://stackoverflow.com/a/39633955/64949) **below** (not into) “Embed Frameworks” in “Build Phases” with the following:
```sh
"${PROJECT_DIR}/Carthage/Build/Mac/LaunchAtLogin.framework/Resources/copy-helper.sh"
```
The build phase cannot run with "User Script Sandboxing" enabled. With Xcode 15 or newer where it is enabled by default, disable "User Script Sandboxing" in build settings.
*(It needs some extra works to have our script to comply with the build phase sandbox.)*
*(I would name the run script `Copy “Launch at Login Helper”`)*
### Use it in your app
@@ -157,6 +121,10 @@ final class ViewModel {
}
```
#### Swift Concurrency
Use [`LaunchAtLogin.publisher.values`](https://developer.apple.com/documentation/combine/publisher/values-1dm9r).
#### Storyboards
Bind the control to the `LaunchAtLogin.kvo` exposed property:
@@ -174,7 +142,7 @@ final class ViewController: NSViewController {
## How does it work?
The package bundles the helper app needed to launch your app and copies it into your app at build time.
On macOS 12 and earlier, the package bundles the helper app needed to launch your app and copies it into your app at build time. On macOS 13 and later, it calls the built-in API.
## FAQ
@@ -190,16 +158,12 @@ rm: […]/Resources/copy-helper.sh: No such file or directory
Command PhaseScriptExecution failed with a nonzero exit code
```
#### The size of my app increased after adding `LaunchAtLogin` when using Carthage
The bundled launcher app is written in Swift and hence needs to embed the Swift runtime libraries. If your project targets macOS 10.14.4 or later, you can avoid embedding the Swift runtime libraries. First, open `./Carthage/Checkouts/LaunchAtLogin/LaunchAtLogin.xcodeproj` and set the deployment target to the same as your app, and then run `$ carthage build`. You'll have to do this each time you update `LaunchAtLogin`.
This is not a problem when using Swift Package Manager.
#### My app doesn't show up in “System Preferences Users & Groups Login Items”
[This is the expected behavior](https://stackoverflow.com/a/15104481/64949), unfortunately.
However, it will show there on macOS 13 and later.
#### My app doesn't launch at login when testing
This is usually caused by having one or more older builds of your app laying around somewhere on the system, and macOS picking one of those instead, which doesn't have the launch helper, and thus fails to start.
@@ -215,13 +179,9 @@ Some helpful Stack Overflow answers:
- https://stackoverflow.com/a/53110832/64949
- https://stackoverflow.com/a/53110852/64949
#### Can you support CocoaPods?
CocoaPods used to be supported, but [it did not work well](https://github.com/sindresorhus/LaunchAtLogin/issues/22) and there was no easy way to fix it, so support was dropped. Even though you mainly use CocoaPods, you can still use Swift Package Manager just for this package without any problems.
#### I can't see the `LaunchAtLogin.bundle` in my debug build or I get a notarization error for developer ID distribution
As discussed [here](https://github.com/sindresorhus/LaunchAtLogin/issues/50), this package tries to determine if you're making a release or debug build and clean up its install accordingly. If your debug build is missing the bundle or, conversely, your release build has the bundle and it causes a code signing error, that means this has failed.
As discussed [here](https://github.com/sindresorhus/LaunchAtLogin-Legacy/issues/50), this package tries to determine if you're making a release or debug build and clean up its install accordingly. If your debug build is missing the bundle or, conversely, your release build has the bundle and it causes a code signing error, that means this has failed.
The script's determination is based on the “Build Active Architecture Only” flag in build settings. If this is set to `YES`, then the script will package LaunchAtLogin for a debug build. You must set this flag to `NO` if you plan on distributing the build with codesigning.
@@ -229,8 +189,6 @@ The script's determination is based on the “Build Active Architecture Only”
- [Defaults](https://github.com/sindresorhus/Defaults) - Swifty and modern UserDefaults
- [KeyboardShortcuts](https://github.com/sindresorhus/KeyboardShortcuts) - Add user-customizable global keyboard shortcuts to your macOS app
- [Regex](https://github.com/sindresorhus/Regex) - Swifty regular expressions
- [Preferences](https://github.com/sindresorhus/Preferences) - Add a preferences window to your macOS app in minutes
- [DockProgress](https://github.com/sindresorhus/DockProgress) - Show progress in your app's Dock icon
- [create-dmg](https://github.com/sindresorhus/create-dmg) - Create a good-looking DMG for your macOS app in seconds
- [More…](https://github.com/search?q=user%3Asindresorhus+language%3Aswift)
- [More…](https://github.com/search?q=user%3Asindresorhus+language%3Aswift+archived%3Afalse&type=repositories)
Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB