72

I have a Package.swift in my project like:

import PackageDescription

let package = Package(
    name: "ProjectName",
        dependencies: [
           .Package(url: "https://github.com/example/repo.git", majorVersion: 0)
        ]
 )

When I run swift build I get errors like…

/project/Packages/WebViewController.swift:1:8: error: no such module 'UIKit'
import UIKit
       ^

Where should I tell the swift package manager where to find UIKit?

1

7 Answers 7

55

You have to change some swiftc options to build the project against proper sdk and target

swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios13.0-simulator"
Sign up to request clarification or add additional context in comments.

6 Comments

This should be the accepted answer! I can confirm it works with iOS 14 using the following too: swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios14.0-simulator"
For the tvOS: swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk appletvsimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-tvos14.3-simulator"
This worked for me, but then Xcode doesn't recognize the binary inside the project that I want to use the library dependency for that was specified in the Package.swift. I think I'm missing an obvious step...?
I'm trying to build for watchOS and macCatalyst. I've figured out I can use watchsimulator and macosx in place of iphonesimulator, but I can't figure out the list of available -target values. How did you find x86_64-apple-ios13.0-simulator?
UPD: Still works with Xcode 14.2 and iOS 16.2: swift build -Xswiftc "-sdk" -Xswiftc "xcrun --sdk iphonesimulator --show-sdk-path" -Xswiftc "-target" -Xswiftc "arm64-apple-ios16.2-simulator"
|
45

Make it work without limit the platforms:

You should select an iOS-based target to make it available:

Demo

If you leave it selecting macOS (by default), you will get the error.


Limit to a specific platform

if you want your package to be available only for specific platforms (for example only for iOS), you should specify the platform in the package.swift file:

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v10)
    ],
    products: [
,,,

Support Multiplatform

If you need your framework to be available on multiple platforms, don't forget to check the availability of the imported framework like:

#if canImport(UIKit)

import UIKit

#endif

4 Comments

Thats the answer!
LMAO I spent like 1h without realizing I was trying to build for macOS... ridiculous
actually, you can't limit for what platform the package is compiled for, but you can say the minimum version. So having platforms: [.iOS(.v10)] means all macOS, tvOS etc... and iOS 10 and above
“Limit to a specific platform” doesn't seem to work (current latest: Xcode 14.2, Swift 5.7.2). When opening the package in Xcode, it still displays the My Mac and Any Mac devices, and when building from command line with swift build it still assume macOS and will fail with errors like “error: no such module 'UIKit'”.
27

Currently Swift Package Manager has full Xcode support. I was able to get around this error by specifying in my Package.swift manifest that the platform was iOS.

let package = Package(
    name: "MyPackage",
    platforms: [
        .iOS(.v8)
    ],

Then you can open the Package.swift file in Xcode and it will just work.

4 Comments

I am having the original issue, even when defining the platform.
Unfortunately no- I had to use git submodules for my in-house framework. :(
After defining the platform, make sure you have an iPhone simulator selected at the top when you build.
How do you open the Package.swift in Xcode? It didn't just work when I tried opening the file in Xcode. Does the file need to be added to the project?
13

The Swift Package Manager builds executables to run on OS X (or Linux); UIKit is a framework in iOS and won't be accessible.

It may be iOS, tvOS and others become accessible as Swift Package Manager evolves.

On Dec 4, 2015, at 5:39 PM, Daniel Dunbar (@apple.com) wrote:

...

Right, now we only compile for the host platform (OS X or Linux, currently). Among other things, we currently have no knowledge (or options to choose) what SDK or architecture you are targeting. We also have no mechanisms for specifying what platforms targets are compatible with in the manifest.

8 Comments

Can you point to documentation that Swift Package Manager is only meant for MacOS and Linux?
Well, even if you could build an iOS executable, how would you ever get it onto and running on an iOS device? swift build --help shows no architecture option. Documentation at swift.org/package-manager/#conceptual-overview does only mention Darwin and Linux.
I was expecting it to build a framework like Carthage does.
The Swift Package Manager is not only meant for OS X and Linux; those are just the current platforms it supports. Support for other platforms is planned.
|
7

enter image description here

Make sure you select an iPhone as a simulator target. a Mac target is the default and that won't work...It would be awesome if Xcode could look at the manifest and choose a default simulator based on that...

Comments

2

Use conditional compilation blocks:

#if canImport(UIKit)

// Code specific to platforms where UIKit is available

#endif

Source: https://developer.apple.com/documentation/xcode/creating_a_swift_package_with_xcode

1 Comment

OP needs a solution for a swift build error, not conditional imports...
-2

SPM error

no such module 'UIKit'

I run on this problem when used umbrella header(<module_name.h>)[About] which contained

#import <UIKit/UIKit.h>

it means that you can skip specifying import UIKit in every file. But it seems that SPM doesn't support it. Also I am not a supporter of using @_exported attribute

You can use next approach

#if canImport(UIKit)

import UIKit

#endif

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.