I'm migrating a project from Cocoapods to SPM, but I'm stuck on an issue where we only need to use certain dependencies in conditional cases.
Cocoapods has an easy solution for this:
if ENV['enabled'].to_i == 1
pod 'Google'
end
As far as I know, conditional dependencies are only partially supported in SPM and it isn't enough for my problem:
https://github.com/apple/swift-evolution/blob/main/proposals/0273-swiftpm-conditional-target-dependencies.md
I was thinking about creating a build phase script to manually include the framework as a target member based on the environmental variable condition.
Looking for a working solution.
"Package.swift" is a regular swift file and you can write any code for your logic and conditions inside. For instance, you can check environment variables with ProcessInfo and assemble needed arrays of dependencies:
import PackageDescription
import Foundation
let useRealm = ProcessInfo.processInfo.environment["realm"] == "1"
let packageDependencies: [Package.Dependency] = useRealm
? [.package(url: "https://github.com/realm/realm-cocoa.git", from: "10.15.1")]
: []
let targetDependencies: [Target.Dependency] = useRealm
? [.product(name: "Realm", package: "realm-cocoa")]
: []
let package = Package(
name: "MyPackage",
platforms: [
.iOS(.v12),
.macOS(.v10_14)
],
products: [
.library(name: "MyPackage", targets: ["MyPackage"]),
],
dependencies: packageDependencies,
targets: [
.target(name: "MyPackage", dependencies: targetDependencies),
.testTarget(name: "MyPackageTests", dependencies: ["MyPackage"]),
]
)
Now you can build your package with no dependencies:
$ xcrun --sdk macosx swift build
Building for debugging...
[2/2] Emitting module MyPackage
Build complete! (0.77s)
And with the Realm dependency by setting realm=1 in the environment variables:
$ export realm=1
$ xcrun --sdk macosx swift build
Fetching https://github.com/realm/realm-cocoa.git from cache
Fetched https://github.com/realm/realm-cocoa.git (2.12s)
Computing version for https://github.com/realm/realm-cocoa.git
Computed https://github.com/realm/realm-cocoa.git at 10.32.0 (0.02s)
Fetching https://github.com/realm/realm-core from cache
Fetched https://github.com/realm/realm-core (1.37s)
Computing version for https://github.com/realm/realm-core
Computed https://github.com/realm/realm-core at 12.9.0 (0.02s)
Creating working copy for https://github.com/realm/realm-cocoa.git
Working copy of https://github.com/realm/realm-cocoa.git resolved at 10.32.0
Creating working copy for https://github.com/realm/realm-core
Working copy of https://github.com/realm/realm-core resolved at 12.9.0
Building for debugging...
[63/63] Compiling MyPackage MyPackage.swift
Build complete! (41.64s)
Related
I'm facing a problem with my lib using SPM.
I've developed it using a target into the project to test and works fine.
After finish I've added the lib using SPM into a final project using the branch develop and I was able to integrate lib and project.
When I saw that is all right, I made a tag from my lib and import into project using Up To Next Major (tag)
And using this way I'm getting this error:
I've checked all the code, compare Package.swift with other projects, change the name, change de folder and nothing.
Here my Package.swift
import PackageDescription
let package = Package(
name: "GloboUI",
platforms: [
.iOS(.v12)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "GloboUI", targets: ["GloboUI"]),
],
dependencies: [
.package(url: "https://github.com/rechsteiner/Parchment", exact: "3.1.0"),
.package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.0.0"),
.package(url: "https://github.com/airbnb/lottie-ios.git", from: "4.0.0"),
.package(url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", from: "9.0.0")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "GloboUI",
dependencies: [
.product(name: "GoogleMobileAds", package: "swift-package-manager-google-mobile-ads"),
.product(name: "Parchment", package: "Parchment"),
.product(name: "Kingfisher", package: "Kingfisher"),
.product(name: "Lottie", package: "lottie-ios")
],
path: "Sources/GloboUI"
)
]
)
I tried remove and change this path in target, change the target names...a lot of try
Here my folder structure of the lib
I've tried remove package.resolved form the main project, clean derivate data, cache, everything.
But I'm not know what is happening.
Anyone has a clue about this issue?
Regards
I tried different ways with different configurations and cannot make it run. Here is what I tried while creating the xcframework:
Add 1 framework dependency as pod
Add 1 framework dependency as Swift package (MKRingProgressView) and created also a swift package marking the dependency in the package dependency as follows:
name: "FirstFramework",
platforms: [
.iOS(.v15)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "FirstFramework",
targets: ["FirstFramework"]),
],
dependencies: [
.package(url:
"https://github.com/maxkonovalov/MKRingProgressView.git",
from: "2.3.0")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.binaryTarget(
name: "FirstFramework",
path: "./Sources/FirstFramework.xcframework")
]
Set build libraries for distribution to YES
I am always getting the error "No such module MKRingProgressView" when adding my framework to a Test project, so its not recognising the dependency of my framework.
Any ideas?
I am creating Swift Packages from various Objective-C Frameworks (via use of XCFrameworks).
I successfully created the SPs, but have run into an issue when it comes to the other SP dependencies it relies on.
If I only add the WrapperPackage to my DemoApp, the compiler fails due to missing the SubDependencyPackage frameworks.
If I add the SubDependencyPackage via SPM to the DemoApp, it compiles just fine.
Is it possible / How can I...
properly bundle the "sub-dependencies" (SubDependencyPackage) into the Swift Package (WrapperPackage) so that in the DemoApp I only need to add WrapperPackage via SPM and all dependencies are resolved?
Workflow
DemoApp adds WrapperPackage as a SPM dependency.
WrapperPackage contains 2 XCFrameworks.
The 2 XCFrameworks were generated from 2 Objective-C Frameworks.
The Objective-C Frameworks have "sub-dependencies" of a separate Swift Package (SubDependencyPackage).
DemoApp
|
--WrapperPackage (XCFrameworks)
|
--SubDependencyPackage (XCFramework Dependencies)
WrapperPackage.swift
// 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: "WrapperPackage",
platforms: [.iOS(.v13)],
products: [
.library(name: "ObjectiveCFramework1", targets: ["ObjectiveCFramework1"]),
.library(name: "ObjectiveCFramework2", targets: ["ObjectiveCFramework2"]),
],
dependencies: [
.package(name: "SubDependencyPackage.git", url: "git#github.com:user/SubDependencyPackage.git", .branch("main")),
],
targets: [
.binaryTarget(name: "ObjectiveCFramework1", path: "XCFrameworks/ObjectiveCFramework1.xcframework"),
.binaryTarget(name: "ObjectiveCFramework2", path: "XCFrameworks/ObjectiveCFramework2.xcframework"),
]
)
I am creating a simple Library Swift Package:
import PackageDescription
let package = Package(
name: "dpo-sdk-spm",
platforms: [
.iOS(.v10),
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "dpo-sdk-spm",
targets: ["dpo-sdk-spm"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.2.0"))
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "dpo-sdk-spm",
dependencies: ["Alamofire"]),
.testTarget(
name: "dpo-sdk-spmTests",
dependencies: ["dpo-sdk-spm"]),
]
)
I specifically did not create a project file, as working with that in source control is a pain - and its not required to develop a library that will be consumed in a iOS App, that will have the necessary build settings etc. My Library was created using swift package init --type library and here is the structure:
I specified under the platforms node iOS V10, then pushed the package to my git repo. I added my git account to Xcode, created a App project, added my package via Xcode 11's built in SPM and had no issues, however trying to build I got:
Showing All Messages The package product 'Alamofire' requires minimum platform version 10.0 for the iOS platform, but this target supports 8.0
I did specify the platform and version in my Package.swift, why is the build pipeline ignoring this variable?
When running:
swift package generate-xcodeproj
The fallowing defaults are set that create manual work every time we make changes the the Package.swift file.
The Base SDK is set to macOS instead of iOS
BaseSDKIssue
The Deployment targets are set to default values (iOS8 instead of iOS13 is the exact change)
DeploymentTargetsIssue
the modules where created with:
swift package init --name xyz --type library
//modify Package.swift to have dependencies xyz has
swift package generate-xcodeproj
How can I get the Base SDK set to iOS and the Deployment targets set to iOS13 when i run generate-xcodeproj
This is a simple structure of what I am trying to do SimpleStructure
Take a look at this page about setting up packages. In the swift package file you can define platforms, as seen here:
// swift-tools-version:5.1
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [
.macOS(.v10_13),
],
products: [
.library(name: "MyLibrary", targets: ["MyLibrary"]),
],
dependencies: [
.package(url: "https://url/of/another/package/named/Utility", from: "1.0.0"),
],
targets: [
.target(name: "MyLibrary", dependencies: ["Utility"]),
.testTarget(name: "MyLibraryTests", dependencies: ["MyLibrary"]),
]
)
I'm not sure there is anything beyond that to set up the Xcode project, as swift packages in general are set up to be pretty platform agnostic.