ocmock icon indicating copy to clipboard operation
ocmock copied to clipboard

Swift Package Manager support is incomplete

Open scannillo opened this issue 3 years ago • 6 comments

Hello. I am trying to use OCMock via Swift Package Manager. I am on XCode Version 13.0 beta (13A5154h).

At first, SPM is able to recognize the URL https://github.com/erikdoe/ocmock.git as an available Swift Package. But once I click Add Package I get a Package Resolution Failed error message, preventing me from properly importing OCMock into my project.

Here is the full screenshot. I highlighted the parts pertaining to OCMock, and not my project.

Screen Shot 2021-07-08 at 11 52 03 AM

scannillo avatar Jul 08 '21 20:07 scannillo

This might be related to #496. To be honest, I haven't had a chance to look into that yet, but hopefully I can spend some time on OCMock next week.

erikdoe avatar Jul 20 '21 12:07 erikdoe

As mentioned in the other issue, this took a while but now there's a version (3.9.0) that should support Swift Package Manager.

erikdoe avatar Oct 26 '21 20:10 erikdoe

Versions 3.9.x can now be resolved by Swift Package Manager.

Unfortunately, this still doesn't mean you can use OCMock as a dependency that way. The problem first mentioned in the following comment over a year ago still exists: https://github.com/erikdoe/ocmock/pull/379#issuecomment-614610432

In summary:

  • OCMock does not use automatic reference counting (ARC).
  • It's unlikely that Swift Package Manager will add support for building without ARC (see https://forums.swift.org/t/support-for-disabling-arc/27998/4).
  • This means OCMock must be built with a compiler flag that Swift Package Manager considers unsafe.
  • But there are severe restrictions on how packages built with unsafe flags can be used (see https://forums.swift.org/t/confused-by-unsafe-flags-being-disallowed-in-dependencies/27359/19 and https://forums.swift.org/t/override-for-unsafeflags-in-swift-package-manager/45273).

In a different issue @paulb777 mentioned that it is possible to use dependencies with unsafe flags by referencing the commit hash, and there seems to be code for that, but I wasn't able to get this to work. Even when I add OCMock by commit hash I get the error message that "the package product 'OCMock' cannot be used as a dependency of this target because it uses unsafe build flags."

It might be an option to distribute OCMock as a binary framework, but given the amount of time I've already invested in trying to support Swift Package Manager, this is nowhere near the top of my list of things to work on.

erikdoe avatar Oct 31 '21 15:10 erikdoe

I'll shorten the title of this issue (because it's not only about resolution any more), and pin it.

erikdoe avatar Oct 31 '21 15:10 erikdoe

About this issue, this works when you use the revision in the swiftpm. Basically just take the commit from the tag and add ocmock like this:

.package(name: "OCMock", url: "https://github.com/erikdoe/ocmock.git", .revision("afd2c6924e8a36cb872bc475248b978f743c6050"))

MapaX avatar Nov 19 '21 07:11 MapaX

I can confirm this works as @MapaX says. To use OCMock in an Xcode project, create e.g. an OCMockWrapper folder with a Package.swift file that references a specific OCMock commit such as the following:

// swift-tools-version:5.3

import PackageDescription

let package = Package(
    name: "OCMockWrapper",
    products: [
        .library(name: "OCMockWrapper", targets: ["OCMockWrapper"])
    ],
    dependencies: [
        .package(name: "OCMock", url: "https://github.com/erikdoe/ocmock.git", .revision("afd2c6924e8a36cb872bc475248b978f743c6050"))
    ],
    targets: [
        .target(name: "OCMockWrapper", dependencies: [
            .product(name: "OCMock", package: "OCMock")
        ])
    ]
)

You’ll need a dummy source file in OCMockWrapper/Sources/OCMockWrapper/ and a header at OCMockWrapper/Sources/OCMockWrapper/include/OCMockWrapper.h. Its content is not important; I used #import <OCMock/OCMock.h>. Then drag the top-level OCMockWrapper folder into your project and add its product to your target.

We’ve been using it this way for a while and it works well. The only downside is that if you use OCMock from other packages of your own in addition to the wrapper, they have to agree on the commit hash, but that hasn’t been a problem for us to ensure.

michal-tomlein avatar Dec 29 '21 17:12 michal-tomlein