R.swift: Support for Cocoapods resource_bundles

Created on 13 Dec 2016  Â·  8Comments  Â·  Source: mac-cain13/R.swift

I use R.swift in a dynamic framework which organizes all the images for the main project and other frameworks. After the dynamic framework building successfully, but the image I access in main project is nil.
This is the code: let image = R.image.driver_task_calender()
After check, I found thelet hostingBundle = Bundle(identifier: "com.**.**") ?? Bundle.main is wrong.

I think this is the correct hosting bundle :

var hostingBundle: Bundle {
        let podBundle = Bundle(for: TheClassName.self)
        if let bundleURL = podBundle.url(forResource: "TheBundleName", withExtension: "bundle") {
            if let bundle = Bundle(url: bundleURL) {
                return bundle
            }
        }
        return podBundle
    }

Expect to get help.

enhancement

Most helpful comment

I've encountered the same issue as @wangguangfeng in the project I've been working on, and since no _official_ solution exists (yet) I've decided to fix it using some _bash magic_.

In short, the solution I am using involves modifying the R.generated.swift file (right after it gets generated) and replacing the hostingBundle value with the correct bundle for my Pod library.

First I've defined a class that represents my Pod resource bundle:

class ResourceBundle: Bundle {
    static var bundleURL: URL {
        let url = Bundle(for: ResourceBundle.self).bundleURL
        return bundleURL.appendingPathComponent("TheBundleName.bundle")
    }

    static var sharedBundle: ResourceBundle? {
        return ResourceBundle(url: bundleURL)
    }
}

Then I modified the custom Run Script build phase that executed the rswift command:

# run the 'rswift' command to generate the constants file
"$PODS_ROOT/R.swift/rswift" "$SRCROOT"

CODE_TO_REPLACE="Bundle(for: R.Class.self)"
CODE_REPLACEMENT="ResourceBundle.sharedBundle as! Bundle"

# replace the bundle creation in the generated code
sed -i '' -e "s/$CODE_TO_REPLACE/$CODE_REPLACEMENT/g" "$SRCROOT/R.generated.swift"

With this simple _fix_ we can fully benefit from the generated constants file in our Pod libraries!

All 8 comments

I organized the framework by cocoapods, in the dynamic framework place a spec file. In the spec file:
s.resource_bundles = { 'JFoundation' => ['JFoundation/Resources/**/*.{storyboard,xib,xcassets,json,imageset,png}'] }

Thanks for using R.swift and reporting this issue.

I've fixed this issue in the latest release of R.swift, version 3.2.0. If you upgrade to that version your problem should be solved! Please let me know if you still have troubles using R.swift from a framework after upgrading. :)

please do not close the issue. After upgrading there are something wrong, I think you should upgrade the R.swift and add some script, like adding --accessLevel public to the call to R.swift to use R.swift in a library. To distinguish the different situation between using in main project and dynamic framework.

the correct hosting bundle :

var hostingBundle: Bundle {
        let podBundle = Bundle(for: TheClassName.self)
        if let bundleURL = podBundle.url(forResource: "TheBundleName", withExtension: "bundle") {
            if let bundle = Bundle(url: bundleURL) {
                return bundle
            }
        }
        return podBundle
    }

your hostingBundle generated by R.swift :
fileprivate static let hostingBundle = Bundle(for: R.Class.self)

Ah alright, so basically you're asking for support for Cocoapods resource_bundles feature.

This is basically pulling your library apart and moving things over to another bundle, I can take a look if this is something we can support. Not sure when I have time for it, if anyone has any idea how R.swift should detect that resources are moved to another bundle you're very welcome to share it!

I've encountered the same issue as @wangguangfeng in the project I've been working on, and since no _official_ solution exists (yet) I've decided to fix it using some _bash magic_.

In short, the solution I am using involves modifying the R.generated.swift file (right after it gets generated) and replacing the hostingBundle value with the correct bundle for my Pod library.

First I've defined a class that represents my Pod resource bundle:

class ResourceBundle: Bundle {
    static var bundleURL: URL {
        let url = Bundle(for: ResourceBundle.self).bundleURL
        return bundleURL.appendingPathComponent("TheBundleName.bundle")
    }

    static var sharedBundle: ResourceBundle? {
        return ResourceBundle(url: bundleURL)
    }
}

Then I modified the custom Run Script build phase that executed the rswift command:

# run the 'rswift' command to generate the constants file
"$PODS_ROOT/R.swift/rswift" "$SRCROOT"

CODE_TO_REPLACE="Bundle(for: R.Class.self)"
CODE_REPLACEMENT="ResourceBundle.sharedBundle as! Bundle"

# replace the bundle creation in the generated code
sed -i '' -e "s/$CODE_TO_REPLACE/$CODE_REPLACEMENT/g" "$SRCROOT/R.generated.swift"

With this simple _fix_ we can fully benefit from the generated constants file in our Pod libraries!

@mac-cain13 hi, what about this feature? To set custom bundle as argument for example?

Hello @mac-cain13, first of all thanks for making R.swift, it's a great library! Not sure if it's the right place for that but like @EvsenevDev I would also be interested in this feature. In the meantime thanks to @wojciechczerski for the workaround :)

We'll discuss support for bundles further in #186

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jalone87 picture jalone87  Â·  6Comments

Przemyslaw-Wosko picture Przemyslaw-Wosko  Â·  4Comments

mac-cain13 picture mac-cain13  Â·  4Comments

theamorn picture theamorn  Â·  4Comments

vladimirvrabelml picture vladimirvrabelml  Â·  7Comments