Loading from Mainbundle

Loading from mainBundle

This returns the bundle that contains the TestClass class:

NSBundle(forClass: TestClass.self)

While this returns the main bundle of the application:

NSBundle.mainBundle()

If you execute this code from your application code, it will always return your main bundle. But if that class is contained in a different library or framework, it will return the bundle that contains it.

For example, all Swift libraries in CocoaPods are integrated using dynamic frameworks, and they are deployed in a different bundle inside the main bundle. So all the frameworks must use the embedded bundle to access their resources.

I'd recommend using the first approach (NSBundle(forClass:) method) to improve code portability. And it's required when creating dynamic frameworks.

iOS mainBundle not loading resources

I don't know exactly what is the issue here. But it is the most common problem. In two situations such issue occurs. 1. file path is wrong. 2.File is not included in bundle.

After checking above file path shown by you I don't think it is the issue of file path. But you can check your file is included in target or not. Just right click on your file and select get info. Where check in target your current target is selected or not.

UIImage load wrong image in main bundle

Thank you for everyone's answer. I sorry about I had mislead all of us to bundle.

I found the cause of the problem. The Error Image isn't came from sub bundle, which came from Assets.car. The cause of the problem should be blame to Image.assert in physical directory actually. CocoaPods will copy all match "*.assets" to Assets.car.

I had made same question at Apple Developer forum, and found the key tip of the problem.

The issue of Cocoapods which relative to the problem Pods copy resource script overrides default xcasset bahaviour.

Pod_resources.sh script would copy every *.xcassets in Pod_Root if your Pod Repo had add any folder which name match *.xcassets.

Key Code of Pod_resources.sh:

if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
...
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
while read line; do
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
XCASSET_FILES+=("$line")
fi
...
fi

Condition XCASSET_FILES will be fulfill if your Pod had add any xcassets file.

Swift 3 Load xib. NSBundle.mainBundle().loadNibNamed return Bool

First of all the method has not been changed in Swift 3.

loadNibNamed(_:owner:topLevelObjects:) has been introduced in macOS 10.8 and was present in all versions of Swift. However loadNibNamed(nibName:owner:options:) has been dropped in Swift 3.

The signature of the method is

func loadNibNamed(_ nibName: String, 
owner: Any?,
topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray>?) -> Bool

so you have to create an pointer to get the array of the views on return.

var topLevelObjects = NSArray()
if Bundle.main.loadNibNamed("CardView", owner: self, topLevelObjects: &topLevelObjects) {
let views = (topLevelObjects as Array).filter { $0 is NSView }
return views[0] as! NSView
}

Edit: I updated the answer to filter the NSView instance reliably.


In Swift 4 the syntax slightly changed and using first(where is more efficient:

var topLevelObjects : NSArray?
if Bundle.main.loadNibNamed(assistantNib, owner: self, topLevelObjects: &topLevelObjects) {
return topLevelObjects!.first(where: { $0 is NSView }) as? NSView
}

Loading a bundle from Objective C class

I know we have the main bundle for the app but why is it creating a bundle for an objective c class called TestClass?

The second bundle is usually a framework. Since the code is from a tutorial, likely the author wants to explain, what bundles are and how you access them.

Having a class you do not need to do that, because the runtime environment searches for the right bundle of a class. But if you want to load other resources (videos, images, sounds, and so on), you have to do it you own. To get the right bundle, you can ask a class residing there for its bundle.

Using NSBundle to load my resources

[NSBundle bundleWithPath:[NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] bundlePath], pathToYourBundleWithinTheDotAppDirectory];

Let me know how you get on.

Best way of loading images from application bundle

If you want to try loading the images without caching, you can use:

[[UIImage alloc] initWithContentsOfFile:@"image.png"]; 

This could be slightly faster loading the image for the first time, since it doesn't have to cache it first. If you only need to use these images once, it probably makes sense to try it this way. The other benefit of doing it this way is that you won't have an image cache using up memory for longer than necessary.



Related Topics



Leave a reply



Submit