🐥

Swift PackageのUnit Testでリソースファイルを使う

2021/10/01に公開

Swift Packageでリソースファイルを使う

自作Swift Packageで、リソースファイル(画像・JSONファイル等)を取り扱う際に調べたことです。
バージョンはswift 5.3以上です。

https://developer.apple.com/documentation/swift_packages/bundling_resources_with_a_swift_package

大きく分けて

  • Xcode > Files > Add files to [package name] で追加する方法。ファイルが自動で移動されます。
  • Package.swift.targetの中で、resourcesで指定します。

Resource

resourcesResourceの配列として定義されます。対象ファイルを***.bundleにコピーします。

https://developer.apple.com/documentation/swift_packages/resource

以下の2つが使えます。

  • .process(_ path: String): ファイル・ディレクトリをコピーします。ディレクトリであれば、中身をトップレベルに展開します
  • .copy(_ path: String): ファイル・ディレクトリをコピーします。ディレクトリはそのままの構造でコピーします。

アクセス方法はBundle.moduleを使います。

let settingsURL = Bundle.module.url(forResource: "settings", withExtension: "plist")

もし、.copyを使っていた場合は、ディレクトリ情報も含めてパスを取得する必要があります。

Unit Testのみに使うリソースの場合

自作Swift PackageのUnit Testで、テストのためだけにJSONファイルを使いたい場合がありました。
その場合、Xcodeによる自動認識はできず、Package.swiftで直接指定する必要がありました。

調査していく中で、この記事を参考にしました。
https://newbedev.com/use-resources-in-unit-tests-with-swift-package-manager

// swift-tools-version:5.3
import PackageDescription

  targets: [
    .target(
      name: "Example",
      dependencies: [],
      resources: [
        .process("Resources"),
      ]),
    .testTarget(
      name: "ExampleTests",
      dependencies: [Example],
      resources: [
        // Copy Tests/ExampleTests/Resources directories as-is. 
        // Use to retain directory structure.
        // Will be at top level in bundle.
        .copy("Resources"),
      ]),

テストターゲット配下のTests/ExampleTestsの下にResourcesを置き、.copy("Resources")を指定します。
ただこの方法では、Xcode12~13ではエラーが起きました。

bundle format unrecognized, invalid, or unsuitable

ディレクトリ名にResourceはNG

こちらの記事を確認すると、どうやらResourcesの名前がよくないようなので、filesに変えたら上手くいきました。

Discussion