How to unit test iOS package with `swift test`?
swift test
only works for macOS testing. It does not support cross builds for iOS.
You do not need an existing Xcode project to use xcodebuild
. Run the command, xcodebuild -list
to initialize a Package.swift
file for testing.
See the example here.
Build error when adding a dependency using Swift Package Manager in Xcode for a Flutter project
I think I might have the fix for you.
Please close your workspace in XCode, and go back and open the .xcodeproj file INSTEAD of the .xcworkspace file.
(/yourApp/ios/Runner.xcodeproj most likely)
When the project is open, in XCode menu bar click File -> Project Settings -> Advanced.
Change the option from LEGACY to XCODE DEFAULT.
Now open the .xcworkspace again and it should work!
Use resources in unit tests with Swift Package Manager
Swift 5.3
See Apple Documentation: "Bundling Resources with a Swift Package"
Swift 5.3 includes Package Manager Resources SE-0271 evolution proposal with "Status: Implemented (Swift 5.3)".
Resources aren't always intended for use by clients of the package; one use of resources might include test fixtures that are only needed by unit tests. Such resources would not be incorporated into clients of the package along with the library code, but would only be used while running the package's tests.
- Add a new
resources
parameter intarget
andtestTarget
APIs to allow declaring resource files explicitly.SwiftPM uses file system conventions for determining the set of source files that belongs to each target in a package: specifically, a target's source files are those that are located underneath the designated "target directory" for the target. By default this is a directory that has the same name as the target and is located in "Sources" (for a regular target) or "Tests" (for a test target), but this location can be customized in the package manifest.
// Get path to DefaultSettings.plist file.
let path = Bundle.module.path(forResource: "DefaultSettings", ofType: "plist")
// Load an image that can be in an asset archive in a bundle.
let image = UIImage(named: "MyIcon", in: Bundle.module, compatibleWith: UITraitCollection(userInterfaceStyle: .dark))
// Find a vertex function in a compiled Metal shader library.
let shader = try mtlDevice.makeDefaultLibrary(bundle: Bundle.module).makeFunction(name: "vertexShader")
// Load a texture.
let texture = MTKTextureLoader(device: mtlDevice).newTexture(name: "Grass", scaleFactor: 1.0, bundle: Bundle.module, options: options)
Example
// swift-tools-version:5.3
import PackageDescription
targets: [
.target(
name: "Example",
dependencies: [],
resources: [
// Apply platform-specific rules.
// For example, images might be optimized per specific platform rule.
// If path is a directory, the rule is applied recursively.
// By default, a file will be copied if no rule applies.
// Process file in Sources/Example/Resources/*
.process("Resources"),
]),
.testTarget(
name: "ExampleTests",
dependencies: [Example],
resources: [
// Copy Tests/ExampleTests/Resources directories as-is.
// Use to retain directory structure.
// Will be at top level in bundle.
.copy("Resources"),
]),
Reported Issues & Possible Workarounds
- Swift 5.3 SPM Resources in tests uses wrong bundle path?
- Swift Package Manager - Resources in test targets
Xcode
Bundle.module
is generated by SwiftPM (see Build/BuildPlan.swift SwiftTargetBuildDescription generateResourceAccessor()) and thus not present in Foundation.Bundle when built by Xcode.
A comparable approach in Xcode would be to:
- manually add a
Resources
reference folder to the Xcode project, - add an Xcode build phase
copy
to put theResource
into some*.bundle
directory, - add a some custom
#ifdef XCODE_BUILD
compiler directive for the Xcode build to work with the resources.
#if XCODE_BUILD
extension Foundation.Bundle {
/// Returns resource bundle as a `Bundle`.
/// Requires Xcode copy phase to locate files into `ExecutableName.bundle`;
/// or `ExecutableNameTests.bundle` for test resources
static var module: Bundle = {
var thisModuleName = "CLIQuickstartLib"
var url = Bundle.main.bundleURL
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
url = bundle.bundleURL.deletingLastPathComponent()
thisModuleName = thisModuleName.appending("Tests")
}
url = url.appendingPathComponent("\(thisModuleName).bundle")
guard let bundle = Bundle(url: url) else {
fatalError("Foundation.Bundle.module could not load resource bundle: \(url.path)")
}
return bundle
}()
/// Directory containing resource bundle
static var moduleDir: URL = {
var url = Bundle.main.bundleURL
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
// remove 'ExecutableNameTests.xctest' path component
url = bundle.bundleURL.deletingLastPathComponent()
}
return url
}()
}
#endif
Error: The sandbox is not in sync with the Podfile.lock... after installing RestKit with cocoapods
I was able to fix that by updating CocoaPods.
I. Project Cleanup
- In the project navigator, select your project
- Select your target
- Remove all libPods*.a in Build Phases > Link Binary With Libraries
II. Update CocoaPods
- Launch Terminal and go to your project directory.
- Update CocoaPods using the command
pod install
Xcode Build and Archive from command line
I found how to automate the build and archive process from the comand line, I just wrote a blog article explaining how you can achieve that.
The command you have to use is xcrun
:
/usr/bin/xcrun -sdk iphoneos PackageApplication \
-v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" \
-o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" \
--sign "${DEVELOPER_NAME}" \
--embed "${PROVISONING_PROFILE}"
You will find all the details in the article. If you have any questions dont hesitate to ask.
Related Topics
Swift-Setting a Physics Body Velocity by Angle
How to Capture Multiple Arguments Weakly in a Swift Closure
Swift: Differencebetween a Typealias and an Associatedtype with a Value in a Protocol
Pattern Variable Binding Cannot Appear in an Expression
Ios15 Uttype Deprecations for Url-Extension
Dictionary of String:Any Does Not Conform to Protocol 'Decodable'
Adopting Customnserror in Decodingerror
Swift Protocol as Generic Parameter
How to Make a Segue to Second Item of Tab Bar
Expression Resolves to an Unused Function
Core Image Filter Cisourceovercompositing Not Appearing as Expected with Alpha Overlay
Behaviour of Protocols with Self
Textfield in Swiftui Loses Focus When I Enter a Character
Nonfailable Enum Initializer with Default Value
How to Convert an Anykeypath to a Writablekeypath
Type Check Operator (Is) for Check VS Homogenous Protocol: Why Can This Be Done for Optionals