xcstrings-tool icon indicating copy to clipboard operation
xcstrings-tool copied to clipboard

Local Package Previews Bundle issue: Fatal Error in resource_bundle_accessor.swift

Open LucasVanDongen opened this issue 6 months ago • 6 comments

Set Up

I have a Local Swift Package I use for separating my features and have a more quick iteration over features using local Previews that load fast and reliable because I don't need to build the whole project, nor include heavy 3rd party dependencies for my UI target.

Problem

One big issue is that Previews ran within a package rather than the main app have issues accessing values from a bundle like icons, fonts and translations. I used SwiftGen for everything, that works with some hacking using a custom bundle .myPackage (see below), but it doesn't support xcassets yet. XCStrings Tool does, and works really well, but I cannot control the bundle.

Attempted Solution

For SwiftGen I can, and with the help of a custom bundle .myPackage it works everywhere. I don't see a way to do this in XCStrings Tool. I cloned the repo and tried to hard code .myPackage but I wasn't able to make it work inside my local package, perhaps because the binary version of the plug-in just works better in that scenario? So I'm not sure if that direction of solution would actually work for me.

Bundle.swift and Crash Log

Bundle.swift:

//
//  Bundle.swift
//  
//
//  Created by Lucas van Dongen on 23/07/2024.
//

import Foundation

extension Bundle {
    private class BundleFinder {}
}

extension Bundle {
    static let myPackageBundleName = "HardwareIntegrationUI_HardwareIntegrationUI"

    public static let myPackage: Bundle = {
        let bundleNameIOS = myPackageBundleName
        let candidates = [
            // Bundle should be here when the package is linked into an App.
            Bundle.main.resourceURL,
            // Bundle should be here when the package is linked into a framework.
            Bundle(for: BundleFinder.self).resourceURL,
            // For command-line tools.
            Bundle.main.bundleURL,
            // Bundle should be here when running previews from a different package
            // (this is the path to "…/Debug-iphonesimulator/").
            Bundle(for: BundleFinder.self)
                .resourceURL?
                .deletingLastPathComponent()
                .deletingLastPathComponent()
                .deletingLastPathComponent(),
            Bundle(for: BundleFinder.self)
                .resourceURL?
                .deletingLastPathComponent()
                .deletingLastPathComponent(),
        ]

        for candidate in candidates {
            let bundlePathiOS = candidate?.appendingPathComponent(bundleNameIOS + ".bundle")
            if let bundle = bundlePathiOS.flatMap(Bundle.init(url:)) {
                return bundle
            }
        }
        fatalError("Can't find myPackage custom bundle.")
    }()
}

The pruned error report:

== PREVIEW UPDATE ERROR:

    CrashReportError: Fatal Error in resource_bundle_accessor.swift
    
    XCPreviewAgent crashed due to fatalError in resource_bundle_accessor.swift at line 44.
    
    unable to find bundle named HardwareIntegration_HardwareIntegrationUI
    
    Frames: [
        Frame {
            imageIndex: 9
            imageOffset: 189728
            symbol: _assertionFailure(_:_:file:line:flags:)
            symbolLocation: 244
        }
        Frame {
            imageIndex: 2
            imageOffset: 3753152
            symbol: closure #1 in variable initialization expression of static NSBundle.module
            symbolLocation: 3372
            sourceFile: resource_bundle_accessor.swift
            sourceLine: 44
        }
        Frame {
            imageIndex: 2
            imageOffset: 3749764
            symbol: one-time initialization function for module
            symbolLocation: 12
            sourceFile: resource_bundle_accessor.swift
            sourceLine: 9
        }
        Frame {
            imageIndex: 10
            imageOffset: 15848
            symbol: _dispatch_client_callout
            symbolLocation: 16
        }
        Frame {
            imageIndex: 10
            imageOffset: 21980
            symbol: _dispatch_once_callout
            symbolLocation: 28
        }
        Frame {
            imageIndex: 2
            imageOffset: 3753608
            symbol: NSBundle.module.unsafeMutableAddressor
            symbolLocation: 80
            sourceFile: resource_bundle_accessor.swift
            sourceLine: 9
        }
        Frame {
            imageIndex: 2
            imageOffset: 3809132
            symbol: static String.Localizable.BundleDescription.current.getter
            symbolLocation: 144
            sourceFile: Localizable.swift
            sourceLine: 63
        }

LucasVanDongen avatar Jul 27 '24 11:07 LucasVanDongen