Skip to content

Instantly share code, notes, and snippets.

@4np
Last active August 5, 2024 11:06
Show Gist options
  • Save 4np/f0e811bc0fdeb17186088c47d5bead5a to your computer and use it in GitHub Desktop.
Save 4np/f0e811bc0fdeb17186088c47d5bead5a to your computer and use it in GitHub Desktop.
How to use a .xcconfig file and a .plist with a Swift Package Manager based project.

How to use a .xcconfig file and a .plist file with SPM

Worth a read for some more context.

Create a Package.xcconfig file

Create the file in the root of the project (where your Package.swift file lives as well), and use the following contents:

/// Package.xcconfig

/// macOS Deployment Target
///
/// Code will load on this and later versions of macOS.
/// Framework APIs that are unavailable in earlier versions will be weak-linked;
/// your code should check for `null` function pointers
/// or specific system versions before calling newer APIs.

/// Code signing
DEVELOPMENT_TEAM = ...;
CODE_SIGN_STYLE = Automatic;

/// Platform
SUPPORTED_PLATFORMS = macosx;
MACOSX_DEPLOYMENT_TARGET = 10.12;
VALID_ARCHS[sdk=macosx*] = x86_64;

/// Swift
SWIFT_VERSION = 4.2;

/// Use Info.plist
OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -sectcreate __TEXT __info_plist ./Supporting/Info.plist;

Create an Info.plist file

Create a folder called Supporting, and create a new Info.plist file inside it with the following contents:

<?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>CFBundleIdentifier</key>
	<string>com.i.and.myself.me</string>
	<key>CFBundlePackageType</key>
	<string>BNDL</string>
	<key>NSHumanReadableCopyright</key>
	<string>Copyright © 2019 Me, Myself and I. All rights reserved.</string>
</dict>
</plist>

Observe that you can define your PrincipalClass this way.

	<key>NSPrincipalClass</key>
	<string>MyProject.MyPrincipalView</string>

Generate the Xcode project

swift package generate-xcodeproj --xcconfig-overrides Package.xcconfig

Note that you can also include the Info.plist directly from the command line as well:

swift package -Xlinker '-sectcreate __TEXT __info_plist ./Supporting/Info.plist' generate-xcodeproj --xcconfig-overrides Package.xcconfig

Or if you use a Fish shell...

...you can use the following Fish Shell function (~/.config/fish/functions/swiftxcode.fish) to make building your SPM project a bit easier by just using swiftxcode:

function swiftxcode --description "Generate a Xcode project for a Swift Package Manager based project."
    if ! test -e ./Package.swift
        echo "This is not a Swift Package Manager project"
        return
    end

    set -lx linkerOptions
    set -lx options
    set -lx shouldLinkInfoPlist false

    if test -e ./Package.xcconfig
        set options $options --xcconfig-overrides Package.xcconfig
    end

    if test -e ./Supporting/Info.plist
        if test -e ./Package.xcconfig; and test (grep OTHER_LDFLAGS Package.xcconfig|grep "__info_plist"|grep -vi "^/"|wc -l) -gt 0
        else
            set shouldLinkInfoPlist true
        end
    end

    if test $shouldLinkInfoPlist = "true"
        set linkerOptions $linkerOptions -Xlinker '-sectcreate __TEXT __info_plist ./Supporting/Info.plist'
    end

    swift package $linkerOptions generate-xcodeproj $options
end
@tychop
Copy link

tychop commented Jul 25, 2022

Warning.... generate-xcodeproj is deprecated now...

@4np
Copy link
Author

4np commented Jul 26, 2022

Yes, this gist is a bit outdated now..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment