Swift Package Manager (SwiftPM) を使ってみよう ~作成編~


Xcode11からiOSアプリ開発にも使えるようになり、先日リリースされたXcode12ではかなり使いやすくなったSwiftPackageManager(以下、SwiftPM)について、プロジェクトへの導入方法とSwiftPMへ自作ライブリを作成方法のうち、この記事は自作ライブラリ作成方法になります。

↓導入方法はこちら
* Swift Package Manager (SwiftPM) を使ってみよう ~導入編~

ライブラリ作成方法 

導入環境

  • Xcode12

SwiftPM起動

[ Xcode起動 ] → [ File ] → [ New ] → [ Swift Packages ]

[ プロジェクト名 ] → [ Cleate ]

作成された画面
今回はあくまで自作ライブラリの登録までなので、

  • Package.swift
  • MyLibrary.swift

しか、触れません。(本当だったら、テストも書いた方がいいです。)

Package.swiftに、読み込みたい対象のファイルや外部ライブラリのURLを記載します。
今回は、外部ライブラリでNukeを読み込み、UIImageをExtensionして、UIImage側でNukeのLoadを行ったものを作ります。

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

import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms:[.iOS(.v11)],   // 使用するプラットフォーム(今回はiOS11以上)
    products: [
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary"]),
    ],
    dependencies: [
        .package(url: "https://github.com/kean/Nuke.git", from: "9.1.2")    // 読み込みたい外部ライブラリ


    ],
    targets: [
depends on.
        .target(
            name: "MyLibrary",
            dependencies: [
                .product(name: "Nuke", package: "Nuke")    // 読み込んだライブラリを使用する
            ]),
        .testTarget(
            name: "MyLibraryTests",
            dependencies: ["MyLibrary"]),
    ]
)

これで、ライブラリの使用するまでは完了。

MyLibrary.swift
import UIKit
import Nuke

public enum ProcessorsOption {
    case resize
    case resizeRound(radius: CGFloat)
    case resizeCircle
}

public typealias AspectMode = ImageProcessors.Resize.ContentMode

public extension UIImageView {

    func loadUrl(imageUrl: String?,
                 processorOption: ProcessorsOption = ProcessorsOption.resize,
                 aspectMode: AspectMode = .aspectFill,
                 crop: Bool = false,
                 placeHolder: UIImage? = nil,
                 failureImage: UIImage? = nil,
                 contentMode: UIView.ContentMode? = nil) {
        guard let url: String = imageUrl,
            let loadUrl: URL = URL(string: url) else {
            self.image = failureImage
            return
        }

        let resizeProcessor = ImageProcessors.Resize(size: self.bounds.size,
                                                     contentMode: aspectMode, crop: crop)
        let processors: [ImageProcessing]

        switch processorOption {
        case .resize:
            processors = [resizeProcessor]
        case .resizeRound(let radius):
            processors = [resizeProcessor, ImageProcessors.RoundedCorners(radius: radius)]
        case .resizeCircle:
            processors = [resizeProcessor, ImageProcessors.Circle()]
        }

        let request = ImageRequest(
            url: loadUrl,
            processors: processors
        )
        var contentModes: ImageLoadingOptions.ContentModes?

        if let mode = contentMode {
            contentModes = ImageLoadingOptions.ContentModes.init(success: mode,
                                                                 failure: mode, placeholder: mode)
        }
        let loadingOptions = ImageLoadingOptions(placeholder: placeHolder,
                                                 failureImage: failureImage, contentModes: contentModes)

        Nuke.loadImage(with: request, options: loadingOptions, into: self)
    }
}

ライブラリに内容は割愛させてもらいます。
(Nukeの画像ロードとリサイズを行ってくれるものをExtensionにしてみました。)

このままでは、No such module 'UIKit'が出ており、ビルドできません。

[ Tests ] → [ MyLibraryTests ] → [ MyLibraryTests.swift ]の中身を変更

ビルドを「MyMac」から「Any Any iOS Device」へ変更

ビルドが成功すれば完成です。

最後に作成したものをGitコマンドやソースツリーを使い、CommitしてTagを付与し、githubにPushすれば完了です。
↑こちらについては、

を、参照してください。
*Tagは[1.0.0]のようにしないとエラーになります。

全体配布を考えられるなら、ライセンスをつけることをお勧めします。
githubでライセンスをつける方法は

を参照ください。

ちなみに、今回作成したものをgithubに公開しています。
よかったらStarでもつけて使ってみてください。

github

↓導入方法はこちらになります。

参考

協力

自作ライブラリをSwiftPMに登録する方法で、外部ライブラリを導入する方法だけが参考だけでは分からず、「アプリ道場サロン」の方々にも協力していただきました。
ありがとうございました。