preface

Swift Package Manager is a product of Apple’s efforts to compensate for the lack of official component library management tools in current iOS development. Compared to other component-management controls, its definition files are easier to understand and Magic to use. Simply place the source code in the appropriate folder and Xcode automatically generates the project files and the configuration required to compile the target product. At the same time, SPM is compatible with Cocoapods to provide complementary features.

  • Project Address:
    • Github.com/apple/swift…
  • Related documents:
    • Developer.apple.com/documentati…

This article will focus on the current state of the component manager, common usage, and some thoughts for the future.

The status quo

Use of open source components

Looking at the SPM access provisioning of current open source components, it’s not hard to see that almost all of the frameworks still being maintained support integration in this way. Large to Microsoft APM SDK, small to the interface UI components, all have good compatibility support. Here are some components that may be used in future development. Resources from github.com/ivanvorobei… The detection rule is whether the package. swift file exists in the warehouse home directory.

According to statistics, about 56% of frameworks have been adapted to SPM access, and frameworks such as MarkdownUI have started to adapt only to SPM.

Some advantages

  • Simplified definition process: Put the file into the agreed directory can be packaged with one click.
  • Simplified SPM versioning: Xcode automatically finds compatible solutions based on the first line of the definition file.
  • Simplified hands-on process: No installation tools and no command line installation of components are required.
  • Good continuous integration: XcodeBuild works seamlessly and automatically after a project is configured.
  • Good compatibility: Can be used with most existing component management solutions.
  • Good debugging ability: fast and accurate breakpoint.

Some disadvantages

  • Documentation is hard to find.
  • Using a remote repository is very demanding on the network.

Method of use

Create components

Components can be created by selecting Swift Package in Xcode or by writing Swift Package init on the command line. The command line creation uses the current directory name as the package name.

Creating library package: Desktop
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/Desktop/Desktop.swift
Creating Tests/
Creating Tests/DesktopTests/
Creating Tests/DesktopTests/DesktopTests.swift
Copy the code

Define the components

The basic definition looks something like this. Don’t worry. Let’s take it line by line.

/ / swift – tools – version: 5.5

Do not ignore this line. If the tool chain version does not match, SDK version, or the latest SYSTEM API version occurs during packaging and compilation, check the possible problems in this line first.

// swift-tools-version:5.5

import PackageDescription

let package = Package(
  name: "MyLibrary",
  products: [
    .library(name: "MyLibrary", targets: ["MyLibrary"]),
  ],
  dependencies: [ ],
  targets: [
    .target(name: "MyLibrary", dependencies: []),
    .testTarget(name: "MyLibraryTests", dependencies: ["MyLibrary"]),
  ]
)
Copy the code

Basic definition

The definition of Swift Package is a little convoluted, but a little explanation makes it clear.

Targets

Targets is defined as A target can define A module or A test suite. In translation, a target corresponds to a clang Module or a test target. Only one language is allowed within a target, such as Swift or Objective-C/C/CPP. The name here is visible only to the current package and can be added to any dependencies. The Target supports binary targets, which can be either XCFramwork or.a. so.

Products

Look at products again, Products define the executables and libraries a package produces, and make them visible to other packages. A product can contain multiple targets, which are compiled into artifacts to be provided to the project. If other projects rely on the current Swift Package, the name here can be filled into the dependency requirements of other packages, and generally cannot be used internally. Finally, let’s look at the types of product. In general, the common.library types include.static (the default) and.dynamic. The.executable option is also available for compiling test binary and macOS command-line tools.

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

.executable(name: "appdecrypt", targets: ["appdecrypt"])
Copy the code

Resource file

The Swift Package needs to specify the purpose of each file. The code files are automatically recognized and compiled for packaging, and the resource files need to be specified and specified. Swift Package generates a Module extension for each Package for direct invocation. Converting the package. swift project file to xcproj using the command line does not generate the template definition file. The following definition generates a.module property within the Bundle class that is specifically used to access resources in the Particles folder.

.target( name: "MorphingLabel", exclude: ["Info.plist", "tvOS-Info.plist"], resources: [.process("Particles")] //Copy the code

The directory structure

For Swift Package, it is recommended to use the native directory structure rather than the custom Path.

The Swift Package export header file has a specified location and is automatically exported by creating an include in the current Source Path.

Swift Package requires a declaration for each resource file/folder, and the adaptation of wildcards is buggy.

Symbolic links can be used to link object files when specific file directory organization is required.

In general, a Target corresponds to a name in Swift Package, and the project root directory /Sources/name will be used as the current Target’s work search path.

. ├ ─ ─ Package. The swift # definition file ├ ─ ─ the README. Md # negligible ├ ─ ─ Sources # all files in this folder needs to be defined Or complains │ └ ─ ─ demo # target the default directory of the demo │ ├ ─ ─ │ ├─ ├─ └ └. Swift # target project source code │ ├─ └─ └ ├ ─ ├ ─ export.h # ├ ─ export.h # resources files in Sources/target name can be defined in package. swift. # need to add resources to target: [. Process ("Particles")]Copy the code

Other instructions

XCFramework

With respect to the compiled artifacts, the base Swift Package can generate static libraries, dynamic libraries, and then be manually packaged into the XCFramework. The PACKAGING workflow for SPM is very XCFramework friendly, as shown in the script below.

xcodebuild -create-xcframework \
        -framework "$BUILD_FOLDER/iOS.xcarchive/Products/Library/Frameworks/MorphingLabel.framework" \
        -framework "$BUILD_FOLDER/tvOS.xcarchive/Products/Library/Frameworks/MorphingLabel.framework" \
        -framework "$BUILD_FOLDER/Simulator.xcarchive/Products/Library/Frameworks/MorphingLabel.framework" \
        -framework "$BUILD_FOLDER/tvOSSimulator.xcarchive/Products/Library/Frameworks/MorphingLabel.framework" \
        -output Build/LTMorphingLabel.xcframework
Copy the code

Github.com/lexrus/LTMo…

product -> .library(name: "MorphinglabelXCFramework", targets: ["LTMorphingLabel"]) // need to manually package, here only provide the name for other project calls, dependencies will use binaryTarget ->. BinaryTarget (name: "LTMorphingLabel", url: "Https://github.com/lexrus/LTMorphingLabel/releases/download/0.9.3/LTMorphingLabel.xcframework.zip", checksum: "28a0ed8b7df12c763d45b7dde2aa41fd843984b79e6fbd3750f2fc1a6c247a13" )Copy the code

There are lazy tools that generate and compile XCFrameowrk for package. swift, but because they rely on the build method that converts projects into XCPROj, swift packages with resource files are not available.

github.com/akkyie/XPM

Some practical

I currently have an open source private project that uses SPM. You can pull down the repository to take a look. Xcode is not stable in resolving dependencies, so the project’s solution is to pull all code locally and use local resolution integration by modifying dependencies. The local integration approach is very stable and maximizes your ability to modify source code. Swift is evolving so fast that url direct integration with remote repositories is not currently recommended.

Github.com/SailyTeam/S…

After you create the XCWorkspace locally, you can add product from package. swift directly to the build flow of your project. Again, I appreciate the versatility of the Swift Package, where some libraries are written in pure Objective-C and can be seamlessly integrated with one click.

Other benefits of native integration include, of course, zero compile warnings, so you can break any problems directly into the Swift Package code. Cocoapod often doesn’t work. For compilation warnings, prepare for eye candy!

Here you can focus on several mixed-compiled library definitions and the Fluent Icon library definition file. As described above, include files are automatically exported to Swift for use.

Q&A

Q: I imported Swift Package into the project, but I couldn’t import it

A: Please command + Shift + K clean up the project and recompile. Swift Package has module cache.

Q: I failed to export my include to a header file in a higher directory

A: Please clean up the project and recompile, sometimes you need to restart Xcode.

Q: I specified the minimum requirement iOS 13 when compiling, why Swift Package cannot call API?

A: Please check whether package. swift has A specified version in platform. If so, please upgrade the swift-tools-version definition line.

Q: My resource file still has warnings after adding process

A: Please use folder names or specify the name of each file. Wildcards don’t work well.

Q: I didn’t find the fields you mentioned when DEFINING package. swift

A: Upgrade swift-tools-version in the first line.

Q: Online drawing of Swift Package cannot be completed

A: please consider removing the ~ / Library/Caches/org. Swift. Swiftpm /, and change the better network. If this still fails delete the package. resolved file

Add comments if you have any questions.

Afterword.

I like Swift Package very much. Local integration is convenient and fast, and it also gives me great power to implement upstream warehouse which is almost impossible for me to implement. In combination with Swift Access Control, such as the accessible internal attribute in module, the crash caused by UI accidental call when writing App background is largely solved. Swift does not have class-private access control keywords. Debugging can be punched directly into the code and is fast. If you can provide a.patch extension file for Package, combined with an optimized remote repository, it will most likely replace bloated Cocoapod. Pod modifiers the XCConfig of the compile target, while the Swift Package is very invasive by providing integration between library and workspace. Finally, the multi-platform compilation capability of Swift Package is also very good. UIKit can be adapted to iOS/iPadOS/tvOS/watchOS after one compilation. The compilation and configuration of CI can be resolved automatically only by calling XcodeBuild. I probably won’t touch Cocoapods again for personal projects.

Due to the worldwide scarcity of Swift Package document resources, once problems occur, it is difficult to search and solve by ourselves, and many codes of existing open source projects need to be referred to, resulting in scattered knowledge points. If you have any ideas, please consider dropping us a comment or writing a comment.

Join us

Bytes to beat the APM China currently committed to improve the performance of the whole system products within the whole group and stability performance, covering technology stack iOS/Android/Flutter/Web/Hybrid/PC/game/small programs, work content including but not limited to, online monitoring, online operations, the depth of optimization, offline prevent deterioration and so on. Long-term expectations for the industry output more constructive problem finding and in-depth optimization means. At the same time, keep close attention to the industry’s cutting-edge technologies, such as Swift Async /await, SwiftUI, Swift Package Manager, etc.

Welcome you to join us, in order to “faster, more stable, more economical, more quality” the ultimate goal hand in hand forward. We have recruitment requirements in Both Beijing and Shenzhen. Please send your resume to [email protected]. Email title: Name – Years of work – APM Medium – Technology stack direction (e.g. IOS /Android/Web/ backend).