Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a .xcassets file to an Xcode framework project

Tags:

xcode

cocoa

I've got a framework project that uses a number of images. As it stands I just drag these images into the project so that they sit alongside my source files:

enter image description here

When I embed this project into a separate app project, I can access these resources as expected.

Ideally, I'd now like to organize my framework images with a .xcassets file. Unlike app projects, the framework project template doesn't provide one of these by default, so I've added one manually using the File > New menu. Unfortunately when I rebuild the framework and re-embed it, I can no longer access the images. Is what I'm trying to do possible?

like image 288
Paul Patterson Avatar asked Oct 21 '15 14:10

Paul Patterson


2 Answers

If you want to access assets in a subproject (framework etc.) you need to make sure that you are collecting them from their own bundle since they are not part of the Main Bundle.

You can do that simply with this Swift 4 code:

let bundle = Bundle(for: type(of: self))
let image = UIImage(named: "imageName", in: bundle, compatibleWith: nil)
like image 111
Foti Dim Avatar answered Sep 23 '22 00:09

Foti Dim


From what I can make out, the answer to my question is yes, sort of...

To make use of the NSImage(named: ...) API one of two things needs to be true: either the image should exist within the app's main bundle, or (to paraphrase the docs):

[there should be] an [NSImage] object whose name was set explicitly using the setName: method and currently resides in the image cache.

In the case where the image resides in an embedded framework, the first isn't true since the framework is a separate bundle, and there's no way of adding to the main bundle at runtime. This leaves the second approach.

Whenever your code is going to use NSImage(named: ...) make sure you've already loaded the image using some other way, then set its name:

let bundle = NSBundle(forClass: MyFrameworkClass.self)
let image = bundle.imageForResource(name) // image in the framework .xcassets
image.setName(name)

I don't know how much use this is, and you should definitely be aware of the notes in the docs about how the image cache operates, but it is at least one way of storing images in a .xcassets folder in one bundle, then accessing them from another.

like image 38
Paul Patterson Avatar answered Sep 24 '22 00:09

Paul Patterson