In my previous post I looked at creating a CircleImage, basically creating a reusable SwiftUI control. Now let’s look at how we might start creating packages to allow us to share such library code.
Creating a Swift Package
From Xcode, select File | New | Swift Package. A very basic package is created (mine’s name MyLibrary) with a Sources/YouPackageName/YourPackageName.swift file containing the following code
struct MyLibrary { var text = "Hello, World!" }
We’ll stick with this simple bit of code but make the struct and the text var public. Also we’ll need to add a public init method or you’ll see an error such as this
initializer is inaccessible due to ‘internal’ protection level
So the new code looks like this
public struct MyLibrary { public var text = "Hello, World!" public init() { } }
Now use Command + B to build the package.
Local Package
To use the package locally, i.e. not having it deployed to a remote repos or the likes.
Within the application that you wish to use the package, simply (using Finder) select the package folder (i..e mine’s MyLibrary) and drag and drop this into your application under the top level project node in the Project Navigator.
Now we can use the code by simply importing it, for example
import MyLibrary
and now within your code
let text = MyLibrary().text
Making our package more useful
Let’s now move the code for our CircleImage into the package, we’ll leave the package name and therefore the component will be renamed, as MyLibrary
Here’s the code
import SwiftUI @available(iOS 13, *) public struct MyLibrary: View { var image: Image var borderColor: Color var shadowRadius: CGFloat public var body: some View { image .clipShape(Circle()) .overlay(Circle().stroke(borderColor, lineWidth: 4)) .shadow(radius: shadowRadius) } public init(image: Image, borderColor: Color = .white, shadowRadius: CGFloat = 10) { self.image = image self.borderColor = borderColor self.shadowRadius = shadowRadius } }
In the above we’ve removed the public keyword on the fields and instead relied on the init method to set up any defaults. We also need to mark the code with the @available attribute to state what versions of OSX or iOS is supported, for example Image is available in 13.0 of iOS.
Within the package file Package.swift we also add the platforms value, here’s a snippet of my code, showing where to expect the platforms value
... name: "MyLibrary", platforms: [ .macOS(.v10_15), .iOS(.v13), ], products: [ ...
and in our application we now simply use something like the following
MyLibrary(image: landmark.image) .offset(x: 0, y: -130) .padding(.bottom, -130)
We’ll look at using GitHub or the likes to host our package in a subsequent post, but this gives an idea on how to get something up and running.