Javier Sagredo
Javier Sagredo

Reputation: 73

Unable to create a Swift Package Manager library

The documentation about SPM is quite poor and most of the articles about it were published when SPM began.

I have implemented an algorithm (Hungarian algorithm) in Swift and was looking forward to publish it as a library in Github. I have had to use the SPM for the first time in this project to resolve another dependency and once it has started to work, it was perfect.

Now, I am not being able to use my library from another project. I have decided to start with a new fresh git repo cause I couldn't get the previous to work.

The library is named Hume and it has inside a Hume.swift file which defines a Hume class.

The steps I have gone through are these:

  1. Created directory for the library
  2. swift package init --type library
  3. Populated the files with the code
  4. Pushed to a GitHub repo + tagged the version
  5. Created directory for the executable which is going to use the library
  6. swift package init --type executable
  7. Add the dependency in Package.swift
  8. swift build

At this point, swift clones the repo of the library and compiles it without problems (as main.swift contains just a Hello world).

  1. swift package generate-xcodeproj

An when I open the project and try to import my library, it seems the module name is recognized but when I try to declare an object, it says I can't declare a variable of a type that is a module.

This is the Package.swift file in the library:

// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Hume",
    products: [
        .library(
            name: "Hume",
            targets: ["Hume"]),
    ],
    dependencies: [
        .package(url: "https://github.com/aleph7/Upsurge.git", from: "0.10.2"),
    ],
    targets: [
        .target(
            name: "Hume",
            dependencies: ["Upsurge"]),
        .testTarget(
            name: "HumeTests",
            dependencies: ["Hume"]),
    ]
)

The Library has only one file with this style:

import Upsurge

class Hume {
    // Attributes
    ....

    init(matriz:[[Double]]){
        ....
    }

    public func resuelve() -> (Double, [(Int, Int)]){
        ....
    }
}

This is the Package.swift in the dummy executable:

// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "aa",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    .package(url: "https://github.com/Jasagredo/Hume.git", from: "0.1.1"),
    ],
    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: "aa",
            dependencies: ["Hume"]),
    ]
)

The output when building:

 ~/Desktop/aa  swift build
Fetching https://github.com/Jasagredo/Hume.git
Fetching https://github.com/aleph7/Upsurge.git
Cloning https://github.com/Jasagredo/Hume.git
Resolving https://github.com/Jasagredo/Hume.git at 0.1.1
Cloning https://github.com/aleph7/Upsurge.git
Resolving https://github.com/aleph7/Upsurge.git at 0.10.2
Compile Swift Module 'Upsurge' (30 sources)
Compile Swift Module 'Hume' (1 sources)
Compile Swift Module 'aa' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/aa
 ~/Desktop/aa 

But when I edit main.swift in the dummy executable, I find this error:

import Hume

var a = Hume(matriz: [[1,1],[1,1]]) //Cannot call value of non-function type 'module<Hume>'

Also, Xcode doesn't auto-suggest me the class Hume. I just don't know what I'm doing wrong.

Any help is appreciated.

Upvotes: 1

Views: 851

Answers (1)

Javier Sagredo
Javier Sagredo

Reputation: 73

I have finally managed to get things to work. The problem was the class (and it's init method) weren't declared as public. The rest of the configuration is correct.

Upvotes: 4

Related Questions