How can I load an image from Assets.car (compiled version of xcassets) within an NSBundle?

前端 未结 1 1948
旧时难觅i
旧时难觅i 2021-02-01 10:20

In a nutshell :

How can I load images from a compiled Assets.car within an NSBundle?

Full Version:

1条回答
  •  清歌不尽
    2021-02-01 10:51

    I was in the same situation as you, and I ended up going with the "hack" you mentioned, but it is automated during pod install so it's a lot more maintainable.

    In my podspec I have

    # Pre-build resource bundle so it can be copied later
      s.pre_install do |pod, target_definition|
        Dir.chdir(pod.root) do
          command = "xcodebuild -project MyProject.xcodeproj -target MyProjectBundle CONFIGURATION_BUILD_DIR=Resources 2>&1 > /dev/null"
          unless system(command)
            raise ::Pod::Informative, "Failed to generate MyProject resources bundle"
          end
        end
      end
    

    Then later on in the podspec:

      s.resource = 'Resources/MyProjectBundle.bundle'
    

    The trick here is to build the bundle before pod install so that the .bundle is available, and can then just be linked as if you had it in the source all along. That way I can easily added new resources/images/xibs in the bundle target, and they will be compiled and linked. Works like a charm.

    The I have a category on NSBundle+MyResources that allows easy access to the bundle resources:

    + (NSBundle *)myProjectResources
    {
        static dispatch_once_t onceToken;
        static NSBundle *bundle = nil;
        dispatch_once(&onceToken, ^{
            // This bundle name must be the same as the product name for the resources bundle target
            NSURL *url = [[NSBundle bundleForClass:[SomeClassInMyProject class]] URLForResource:@"MyProject" withExtension:@"bundle"];
            if (!url) {
                url = [[NSBundle mainBundle] URLForResource:@"MyProject" withExtension:@"bundle"];
            }
            bundle = [NSBundle bundleWithURL:url];
        });
        return bundle;
    }
    

    So if you want to load e.g. a core data model:

    NSURL *modelURL = [[NSBundle myProjectResources] URLForResource:@"MyModel" withExtension:@"momd"];
    

    I've made some convenience methods to access images as well:

    + (UIImage *)bundleImageNamed:(NSString *)name
    {
        UIImage *imageFromMainBundle = [UIImage imageNamed:name];
        if (imageFromMainBundle) {
            return imageFromMainBundle;
        }
    
        NSString *imageName = [NSString stringWithFormat:@"MyProject.bundle/%@", name];
        UIImage *imageFromBundle = [UIImage imageNamed:imageName];
        if (!imageFromBundle) {
            NSLog(@"Image not found: %@", name);
        }
        return imageFromBundle;
    }
    

    Haven't yet had this fail on me.

    0 讨论(0)
提交回复
热议问题