简体   繁体   中英

How to add a Swift package manager as a dynamic library in xcode 13?

I am currently working in switching dependency manager of a project from Carthage to Swift Package Manager,

We have for example realm dependency that used to be a dynamic framework when building with Carthage,

But in SPW when I try to add realm it by default gives a realm static framework and I could not find a way to switch to dynamic,

Since we have some submodules in our project dependent on each other trying to link the static library gives duplicate symbols errors.

I would be much easier if I could download realm directly as dynamic framework as I can get with Carthage,

No options to choose在此处输入图像描述

在此处输入图像描述

Does anyone knows how to do that?

Thanks in advance for any help:)

Packages can produce dynamic libraries but they have to explicitly tell Xcode that they want the library to be made into a dynamic library. Realm does not do this. Instead, the folks at Realm go with the default behavior which lets Xcode decide which whether it will construct a static or dynamic library. As far as I know, Xcode always chooses to build a static library.

To get around this you can create your own package that includes the Realm package as a dependency and explicitly make your library dynamic. You can find plenty of tutorials that show you how to make a package so I won't get into that here.

If you create a package and load the following content into your Package.swift file, then import the package into your project, you will have solved your problem. I named my package "RealmUmbrella" but you can call yours whatever you like.

import PackageDescription

let package = Package(
    name: "RealmUmbrella",
    platforms: [.iOS(.v14)],
    products: [
        .library(
            name: "RealmUmbrella",
            type: .dynamic,
            targets: ["RealmUmbrella"]
        ),
    ],
    dependencies: [
        .package(name: "Realm", url: "https://github.com/realm/realm-cocoa", "10.0.0"..<"11.0.0")
    ],
    targets: [
        .target(
            name: "RealmUmbrella",
            dependencies: [.product(name: "RealmSwift", package: "Realm")]
        ),
    ]
)

Notice how I specify .dynamic here:

        .library(
            name: "RealmUmbrella",
            type: .dynamic,
            targets: ["RealmUmbrella"]
        ),

Once I added my umbrella package into my project, I clicked on the project file in the project navigator, selected my target, then navigated to "General" tab and scrolled down to "Frameworks, Libraries, and Embedded Content". Then I specified, "Embed and Sign" in the "Embed" column for my package.

在此处输入图像描述

And that's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM