繁体   English   中英

Swift Package 资源 colors 在 CI 测试用例中返回为零。 但是在本地测试用例中返回正常

[英]Swift Package resource colors coming back as nil in CI test cases. But return fine during local test cases

奇怪的是,这只发生在 CI (GitHub Actions) 上运行时。

这是我的资产目录:

在此处输入图像描述

这是我对 UIColor 的扩展,用于访问这些 colors:

// MARK: - UIKit

public extension UIColor {
    // MARK: Design System Colors

    static let primaryColor = UIColor(named: "PrimaryColor", in: .module, compatibleWith: nil)!
    static let primaryVariant = UIColor(named: "PrimaryVariant", in: .module, compatibleWith: nil)!
    static let onPrimary = UIColor(named: "OnPrimary", in: .module, compatibleWith: nil)!
    static let onPrimaryMedium = UIColor(named: "OnPrimaryMedium", in: .module, compatibleWith: nil)!
    static let onPrimaryDisabled = UIColor(named: "OnPrimaryDisabled", in: .module, compatibleWith: nil)!

    static let surface = UIColor(named: "Surface", in: .module, compatibleWith: nil)!
    static let onSurface = UIColor(named: "OnSurface", in: .module, compatibleWith: nil)!
    static let onSurfaceMedium = UIColor(named: "OnSurfaceMedium", in: .module, compatibleWith: nil)!
    static let onSurfaceDisabled = UIColor(named: "OnSurfaceDisabled", in: .module, compatibleWith: nil)!

    static let background = UIColor(named: "Background", in: .module, compatibleWith: nil)!
    static let onBackground = UIColor(named: "OnBackground", in: .module, compatibleWith: nil)!

    static let accent = UIColor(named: "Accent", in: .module, compatibleWith: nil)!
    static let divider = UIColor(named: "Divider", in: .module, compatibleWith: nil)!

    // MARK: Status Colors

    static let statusSuccess = UIColor(named: "StatusSuccess", in: .module, compatibleWith: nil)!
    static let statusWarning = UIColor(named: "StatusWarning", in: .module, compatibleWith: nil)!
    static let statusError = UIColor(named: "StatusError", in: .module, compatibleWith: nil)!

    // MARK: Map Colors

    static let pinPlace = UIColor(named: "PinPlace", in: .module, compatibleWith: nil)!
    static let pinRoute = UIColor(named: "PinRoute", in: .module, compatibleWith: nil)!
    static let polyline = UIColor(named: "Polyline", in: .module, compatibleWith: nil)!
    static let polylineRoute = UIColor(named: "PolylineRoute", in: .module, compatibleWith: nil)!
}

我有一个测试用例,它只运行所有这些 colors 并检查它们是否可以从模块包中加载(以便强制解包它们是安全的):

@testable import MyProject
import SwiftUI
import UIKit
import XCTest

/// Test to ensure that the colors can be loaded from the module bundle without crashing.
class MyProjectColorTest: XCTestCase {
    func testLoadUIColorFromBundle() {
        for color in UIColor.myProjectUIColors {
            XCTAssertNotNil(color)
        }
    }
}

fileprivate extension UIColor {
    static var myProjectUIColors: [UIColor] = [
        UIColor.primaryColor,
        UIColor.primaryVariant, //It fails when it tries to access this color.
        UIColor.onPrimary,
        UIColor.onPrimaryMedium,
        UIColor.onPrimaryDisabled,
        UIColor.surface,
        UIColor.onSurface,
        UIColor.onSurfaceMedium,
        UIColor.onSurfaceDisabled,
        UIColor.background,
        UIColor.onBackground,
        UIColor.accent,
        UIColor.divider,
        UIColor.statusSuccess,
        UIColor.statusWarning,
        UIColor.statusError,
        UIColor.pinPlace,
        UIColor.pinRoute,
        UIColor.polyline,
        UIColor.polylineRoute,
    ]
}

最后:

这是我的 package 清单:

// 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: "MyProject",
    defaultLocalization: "en",
    platforms: [
        .iOS(.v13),
        .watchOS(.v6),
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "MyProject",
            targets: ["MyProject"]
        ),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "MyProject",
            dependencies: [],
            exclude: [
                "MyProjectDemo/*",
            ],
            // I've also tried omitting this and letting SPM handle it automatically.
            resources: [
                .process("*.xcassets"),
            ]
        ),
        .testTarget(
            name: "MyProjectTests",
            dependencies: ["MyProject"]
        ),
    ]
)

另外,这是我的 GitHub 操作脚本:

name: Build

on:
  push:
    branches: [ master ]
    paths:
       - '.github/workflows/swiftlint.yml'
       - '.swiftlint.yml'
       - '**/*.swift'
  pull_request:
    branches: [ master, develop ]
    paths:
       - '.github/workflows/swiftlint.yml'
       - '.swiftlint.yml'
       - '**/*.swift'

jobs:
  Build:
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
      - name: List available Xcode versions
        run: ls /Applications | grep Xcode
      - name: Select Xcode
        run: sudo xcode-select -switch /Applications/Xcode_12.2.app
      - name: Show Build Destinations
        run: xcodebuild -showdestinations -scheme MyProject
      - name: Build
        run: xcodebuild test -scheme MyProject -destination 'platform=iOS Simulator,OS=14.2,name=iPhone 12'
  Lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
      - name: Lint
        uses: norio-nomura/action-swiftlint@3.2.0

有一个解决方法。 在这里成立-> https://developer.apple.com/forums/thread/664295

import Foundation

class CurrentBundleFinder {}

extension Foundation.Bundle {
        
    static var myModule: Bundle = {
        /* The name of your local package, prepended by "LocalPackages_" */
        let bundleName = "UI_UI"
        let candidates = [
            /* Bundle should be present here when the package is linked into an App. */
            Bundle.main.resourceURL,
            /* Bundle should be present here when the package is linked into a framework. */
            Bundle(for: CurrentBundleFinder.self).resourceURL,
            /* For command-line tools. */
            Bundle.main.bundleURL,
            /* Bundle should be present here when running previews from a different package (this is the path to "…/Debug-iphonesimulator/"). */
            Bundle(for: CurrentBundleFinder.self).resourceURL?.deletingLastPathComponent().deletingLastPathComponent(),
        ]
        for candidate in candidates {
            let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
            if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                return bundle
            }
        }
        fatalError("unable to find bundle named \(bundleName)")
    }()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM