Categories
english

Swift Package Manager: tricks for creating your own packages

I recently created my first Package distributed with SPM. Here are some problems that I had to solve.

Adding dependencies

I could not understand why I still had to include the StripeTerminal package to an app since I already had it declared as a dependency to my package:

let package = Package(

dependencies: [
.package(name: "StripeTerminal", url: "https://github.com/stripe/stripe-terminal-ios", from: "2.0.0"),
],

I’ve been explained that this is a two step process. First the dependency is declared (like above), then it is associated with the target:

    targets: [
        .target(
            name: "Astral",
            dependencies: [
                "StripeTerminal"
            ]),
    ]

Develop an example app along with your Package

Providing an example app that exerts the package is very common. A straightforward method is to create an Xcode project for the app inside an Example directory:

MyPackage
	Example
		Example.xcodeproj
	Sources
		…

Then, open Example.xcodeproj and add MyPackage using File > Add Packages…. Your package will then be listed as a dependency of the Example App.

Now you are faced with a problem: when developing the package, you would like to edit the code of both the example app and the package, but the package’s code is read-only.

There is however a trick: you can drag your Package in the Example App’s project again. This way, the package is both a local package and a “published” package. You can edit its code and push its code directly to the remote repository (on github).

Translation of storyboards

You will easily find documentation about translating resources. First, a default localization must be declared in the package’s manifest:

let package = Package(
 name: "Astral",
 defaultLocalization: "en",

You will have to create subfolders for translations manually, as the current version Xcode (13.2) does not provide an option to create localizations, as it does for targets:

MyPackage
	Sources
		Resources
			Base.lproj
				MyPackage.storyboard
			en.lproj
				Localizable.strings
				MyPackage.strings
			fr.lproj
				Localizable.strings
				MyPackage.strings

Here again, Xcode has a tool to extract strings from the Base storyboard to the localized .strings file, like these:

// MyPackage.strings

/* Class = "UITableViewController"; title = "Readers discovery"; ObjectID = "g2Y-ee-6gs"; */
"g2Y-ee-6gs.title" = "Readers discovery";

/* Class = "UILabel"; text = "Disconnect this Reader"; ObjectID = "jdX-zC-qRq"; */
"jdX-zC-qRq.text" = "Disconnect this Reader";

but this tool does not work for packages!

A solution is to create a brand new project, for instance of type “Framework” and drag MyPackage.storyboard to it. Then you will find the option to create its localizations, and the menu items Product > Export/Import Localization if needed.

I have sent a feedback to Apple, and hopefully the options will be added, but we have a workaround in the meantime.