Swift Package Manager(SPM)
[iOS Dependency manager]
Consume: [SPM manage dependency]
Produce: If you are developing library/module(modularisation) you should take care of supporting it
Package.swift
- manifest file.
- It is a hardcoded name.
- Should be placed on the same level or higher, in other cases:
target '<target_name>' in package '<package_name>' is outside the package root
Package.swift example
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "PackageName1",
//Supported platforms
platforms: [
.iOS(.v11)
],
//Product list - executable binary
products: [
.library(
name: "LibraryName1",
targets: ["TargetName1"]),
],
//Additional SPM dependencies declaration(packages) which are used in targets
dependencies: [
//Local package path
.package(name: "PackageName2", path: "../Feature1")
//Local package URL
.package(name: "PackageName2", url: "file:///some_local_path", .branch("master"))
//Remote package URL
.package(name: "PackageName2", url: "https://github.com/user/repo", .branch("master")),
],
targets: [
//Source code location. implicitly `Sources/<target_name>`(Sources/TargetName1) or explicitly `path:`
.target(
name: "TargetName1",
dependencies: [
//using dependencies from package.targets and package.dependencies
//package.targets
"LibraryName2"
//package.dependencies
.product(name: "PM2LibraryName1", package: "PackageName2")
]),
path: "Sources/TargetName1"
]
)
Observations for Swift dependency
- [SWIFT_MODULE_NAME, PRODUCT_NAME, EXECUTABLE_NAME] == package.targets.target.name
- package.products.library.name is used only for Xcode representation
- Library is used[About]
- When target has a dependency on another target source code will be included into single library with a kind of
explicit multi module
from .modulemap
[About] and access can be thought
import Module1
import Module2
- Swift library converts into single
.o format
[About] file and .swiftmodule
[About]
- Swift library exposes
.modulemap umbrella.h
[About] for exposing module for Objective-C consumer thought @import SomeModule;
- You are able to work with `Package.swift` in Xcode if double click on it
.swiftpm/xcode with .xcworkspace will be generated
- When you work with `Package.swift` you are able to check it, just save this file
- When you work with `Package.swift` you should specify schema and device(platform)
- When you build `Package.swift`
- library and .swiftmodule is located:
<path_to_derived_data>/DerivedData/<folder_name_where_Package.swift_located>-<randomizer>/Build/Products/<platform>
//e.g.
/Users/alex/Library/Developer/Xcode/DerivedData/someFolder-ccivqbbjujxuvdcxtuydyqfeepfx/Build/Products/Debug-iphonesimulator
- .modulemap and umbrella.header is located:
<path_to_derived_data>/DerivedData/<folder_name_where_Package.swift_located>-<randomizer>/Build/Intermediates.noindex/<project_name>.build/<platform>/<target_name>.build/<.modulemap> and plus /Objects-normal/<arch>/<tarhet_name-Swift.h>
- When you build consumer with `Package.swift` results files will be located:
<path_to_derived_data>/DerivedData/<target_name>-<randomizer>/Build/Products/<platform>
- When you work with consumer of `Package.swift` SPM clones it into
<path_to_derived_data>/DerivedData/<target_name>-<randomizer>/SourcePackages/checkouts
package.products.library.targets
You are able to specify several targets. It means that it is possible to use several modules from single executable binary(a kind of umbrella library)
producer:
package.products.library.targets: ["TargetName1", "TargetName2"]
consumer:
1. adds single library
2. several imports
import TargetName1
import TargetName2
package.targets.target.dependencies
If your target has dependency. You will have the same effect - Umbrella library.
1.Add another target from the same package
For example Explicit Dependency
[About] is used. Important: use the same names(module and SPM target). If you don't set dependency at package.targets.target.dependencies
you get next error
Undefined symbol
2.Add product from another package. All targets from the other package will be exposed
2.1 Local package path
You can not use on consumer side. But it allows you to debut it at least
package <package_name_1> is required using a revision-based requirement and it depends on local package <package_name_2>, which is not supported
2.2 Local package URL
Don't use space(
) in path or you get
The URL file:///hello world/some_local_path is invalid
If you don't specify // swift-tools-version:<version>
you get:
package at '<some_path>' is using Swift tools version 3.1.0 which is no longer supported; consider using '// swift-tools-version:5.3' to specify the current tools version
*Do not forget commit your changes and update[About] before testing it
Package.swift
file to you question – Fittedswift build
command, seems to be correct, but the import doesn't work. – Naifswift package init
i guess – Karolekarolina