簡體   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