ottijp blog

SPM (Swift Package Manager) でアルファベット読み仮名変換ライブラリを作る

2020-12-22swiftSPM

これはInfocom Advent Calendar 2020 22日目の記事です.

SPM (Swift Package Manager) でライブラリを作ってみました.

お題は,アルファベット・数字・記号の文字列を読み仮名に変換するライブラリです. たまに見る,自動で発行されたパスワードに振ってあるような読み仮名を生成する用途です.

swift (エス・ダブリュー・アイ・エフ・ティー)

作ったライブラリはこちらに置いてあります.

ottijp/YomiGana

Swiftパッケージの作り方

Xcodeを使って,次のような手順でSwiftパッケージを作成しました.

  1. Swift Packageの新規作成

    • File メニューから New > Swift Package…
  2. パッケージのコードとテストを作成

    • Sources ディレクトリと Tests ディレクトリ
  3. README.md の記述
  4. ライセンス表記ファイルの追加
  5. GitHubにアップロード
  6. リリースタグを付ける

ちなみに,生成されるのはSPMの仕様に則ったもので,XCodeプロジェクトではないので,自分で必要なファイルを作って Package.swift に構成を記述すれば,Xcodeを使わなくても作成することはできます. (Xcodeで作った場合, .swiftpm というXcodeの管理ディレクトリも併せて作成されます.)

Swiftパッケージの構成

Swiftパッケージには package, product, target などの概念があるので,ここで簡単に説明します.

  • Swiftパッケージの単位はパッケージで,Package.swift で構成が定義される
  • パッケージには複数のターゲットが含まれる(テストターゲットも含まれる)(Package.swift の targets

    • ターゲットのソースコードは Sources/<Target> に置かれる
    • テストターゲットのソースコードは Tests/<Target> に置かれる
  • 複数のターゲットをまとめて,ライブラリや実行可能モジュールとして公開する(Package.swift の products
  • パッケージが他のパッケージに依存する場合は Package.swift の dependencies に記述する

今回は,1つのターゲット(YomiGana)をライブラリとして公開するので,次のような定義にしました.(Xcodeで新規作成した状態から変更していません.)

Package.swift
// swift-tools-version:5.3

import PackageDescription

let package = Package(
  name: "YomiGana",
  products: [
    .library(name: "YomiGana", targets: ["YomiGana"]),
  ],
  dependencies: [],
  targets: [
    .target( name: "YomiGana", dependencies: []),
    .testTarget( name: "YomiGanaTests", dependencies: ["YomiGana"]),
  ]
)

Xcode上では次のように見えています.

package structure

作ったライブラリのソース

public な部分は以下の通りです.

YomiGana.swift
public extension String {
  /// 文字ごとの読み仮名に変換する
  /// - Parameters:
  ///   - charset: 印字・表示される文字形状を特定する文字セット
  ///   - separator: 読み仮名文字列を区切るセパレータ
  /// - Returns: セパレータで区切られた,文字ごとの読み仮名文字列
  func toYomiGana(charset: YomiGanaCharset = .ascii, separator: String = "・") -> String {
    // 読み仮名ディクショナリ
    let dict: [Character:String]
    switch charset {
    case .ascii:
      dict = kanaDict
    case .jisx0201:
      // JIS X 0201は字体の異なる文字が含まれるため,差分を合成する
      dict = kanaDict.merging(kanaDictJisDiff, uniquingKeysWith: { (_, new) in new })
    }

    return self.map({ c in dict[c] ?? String(c) }).joined(separator: separator)
  }
}

/// 文字セット
public enum YomiGanaCharset {
  /// ASCII
  case ascii
  /// JIS X 0201
  case jisx0201
}

全体はリポジトリのソースをご覧ください.

YomiGana/YomiGana.swift at main · ottijp/YomiGana

ライブラリの使い方

作ったパッケージを取り込んでライブラリを使うには,次のようにします.

まず,Xcodeの File メニューから Swift Packages > Add Package Dependency… を選択し,Swiftパッケージを追加します. (リポジトリのURLは https://github.com/ottijp/YomiGana を指定.)

すると,このような感じでパッケージが追加されます.

package added

その後,パッケージをインポートして利用します.

main.swift
import YomiGana
print("Hello, World!".toYomiGana())
// エイチ(大文字)・イー・エル・エル・オー・コンマ・空白・ダブリュー(大文字)・オー・アール・エル・ディー・感嘆符

開発時の動作検証

リリースする前に,ローカルで他のプロジェクトに組み込んで使ってみたい場合は,ライブラリ参照元のプロジェクトに次のように取り込むことで動作検証できます.

※ 作ったライブラリをXcodeの別ウィンドウで開いているとうまくいかなかったので,この操作の前に閉じておきましょう.

まず,パッケージのディレクトリを,Finderからドラッグし,Xcodeにドロップします.

package dropped

次に, ライブラリを利用するターゲットの参照ライブラリ(↑の画像右側)の + ボタンを押して,ライブラリを選択します.

choose library

これで,通常のインストール時と同様に,パッケージをインポートして利用できるようになります.

Swiftパッケージ作成時の注意事項

今回作ったライブラリには該当部分はありませんでしたが,Swiftパッケージにおいて,クラスのデフォルトイニシャライザはinternalなので,パッケージ外からアクセスできないようです. 公開するものはpublicで明示的に宣言が必要なので注意してください.

cf: 【iOS】オープンソースSwiftライブラリのつくり方 - Qiita

refs

SPM

文字


ottijp
Satoshi SAKAO (@ottijp)

都内でアプリケーションエンジニアをしています

...