xcode 从 CocoaPods 资源包加载图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23835052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:57:05  来源:igfitidea点击:

Load image from CocoaPods resource bundle

iosiphoneobjective-cxcodecocoapods

提问by David Potter

I am creating a private library that includes resources that are referenced by components in the library. The library is shared with apps using CocoaPods. In the .podspec for the library, I've included a line like this:

我正在创建一个私有库,其中包含库中组件引用的资源。该库与使用 CocoaPods 的应用程序共享。在库的 .podspec 中,我包含了这样的一行:

s.resource_bundles = {'IXMapKitResources' => ['IXMapKit/Resources/*']}

One of the resources in the bundle is an asset catalog with multiple image sets, one of which is called 'IXMKAnnotationIcons-Normal-Accident'. The following code returns a nil:

捆绑包中的资源之一是具有多个图像集的资产目录,其中之一称为“IXMKAnnotationIcons-Normal-Accident”。以下代码返回 nil:

UIImage * image = [UIImage imageNamed: @"IXMKAnnotationIcons-Normal-Accident"];

I found an article on mokacoding.comdescribing how to load fonts from a pod, but this didn't work for me:

在 mokacoding.com 上找到了一篇描述如何从 pod 加载字体的文章,但这对我不起作用:

- (UIImage *) ixmk_imageNamed: (NSString *) name
{
    NSString * IXMKResourceBundleName = @"IXMapKitResources.bundle";
    NSString * resourceName = [NSString stringWithFormat: @"%@/%@", IXMKResourceBundleName, name];

    NSString * imageTypeString = [self ixmk_stringForImageType: imageType];
    NSURL * url = [[NSBundle mainBundle] URLForResource: resourceName withExtension: imageTypeString];

    NSData * imageData = [NSData dataWithContentsOfURL: url];
    if (imageData != nil)
    {
        CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef) imageData);
        CGImageRef imageRef = [self ixmk_imageFromDataProvider: provider imageType: imageType];

        UIImage * image = [UIImage imageWithCGImage: imageRef];

        CFRelease(imageRef);
        CFRelease(provider);

        return image;
    }
    else
    {
        return nil;
    }
}

The CocoaPods webpage describing the resources keywordhas the following warning:

描述资源关键字CocoaPods 网页有以下警告:

We strongly recommendlibrary developers to adopt resource bundles as there can be name collisions using the resources attribute. Moreover resources specified with this attribute are copied directly to the client target and therefore they are not optimized by Xcode.

我们强烈建议库开发人员采用资源包,因为使用资源属性可能会发生名称冲突。此外,使用此属性指定的资源会直接复制到客户端目标,因此它们不会被 Xcode 优化。

I'm at a loss of what to do here.

我不知道在这里做什么。

回答by David Potter

This turns out to be a problem with asset catalogs, not CocoaPods or bundles. Moving the images out of the asset catalog solved the problem. It looks like Apple doesn't support asset catalogs in secondary resource bundles. Pity.

结果证明这是资产目录的问题,而不是 CocoaPods 或捆绑包。将图像移出资产目录解决了这个问题。看起来 Apple 不支持辅助资源包中的资产目录。遗憾。

回答by onmyway133

For example Paramount

例如派拉蒙

podspec

podspec

s.resource_bundle = {
    'Paramount' => ['Sources/Paramount.bundle/*.png']
}

swift

swift

public extension UIImage {
  static func make(name: String) -> UIImage? {
    let bundle = NSBundle(forClass: Paramount.Toolbar.self)
    return UIImage(named: "Paramount.bundle/\(name)", inBundle: bundle, compatibleWithTraitCollection: nil)
  }
}

Here Paramount.Toolbar.selfcan be any class in that framework

这里Paramount.Toolbar.self可以是该框架中的任何类

回答by plusmancn

The obvious solution that wasn't listed anywhere is using the Cocoapods generated bundle (which the folder actually doesn't exist) as a NSBundle:

未在任何地方列出的明显解决方案是使用 Cocoapods 生成的包(该文件夹实际上不存在)作为 NSBundle:

have a try: http://blog.flaviocaetano.com/post/cocoapods-and-resource_bundles/

试试看:http: //blog.flaviocaetano.com/post/cocoapods-and-resource_bundles/

it worked for me!!

它对我有用!!

回答by Naloiko Eugene

As for me, I had to add the "s.resources" into the .podspec. Before this was missing.

至于我,我必须将“s.resources”添加到 .podspec 中。在这之前失踪了。

Only the s.resource_bundles were set this way: 'BPPicker/Assets/.', changed it to 'BPPicker/Assets/*' as well.

只有 s.resource_bundles 是这样设置的: 'BPPicker/Assets/ ',也将其更改为 'BPPicker/Assets/*'。

#
# Be sure to run `pod lib lint BPPicker.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#

Pod::Spec.new do |s|
  s.name             = 'BPPicker'
  s.version          = '0.1.11'
  s.summary          = 'This is the imito Body Part Picker.'

# This description is used to generate tags and improve search results.
#   * Think: What does it do? Why did you write it? What is the focus?
#   * Try to keep it short, snappy and to the point.
#   * Write the description between the DESC delimiters below.
#   * Finally, don't worry about the indent, CocoaPods strips it!

  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC

  s.homepage         = 'https://bitbucket.org/imito/bppicker'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'Ievgen Naloiko' => '[email protected]' }
  s.source           = { :git => 'https://[email protected]/imito/bppicker.git', :tag => s.version.to_s }
  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

  s.ios.deployment_target = '9.0'

  s.source_files = 'BPPicker/Classes/**/*'

  s.resource_bundles = {
    'BPPicker' => ['BPPicker/Assets/*']
  }
    s.resources = "BPPicker/**/*.{png,json}"

    s.frameworks = 'UIKit'
    s.dependency 'ObjectMapper'
end

回答by Durul Dalkanat

This answer works with Swift3and Swift4.

这个答案适用于Swift3Swift4

Create a function under the pod directory into the file.

在pod目录下创建一个函数放入文件中。

func loadImageBundle(named imageName:String) -> UIImage? {
    let podBundle = Bundle(for: self.classForCoder)
    if let bundleURL = podBundle.url(forResource: "Update with directory name", withExtension: "bundle")
    {
        let imageBundel = Bundle(url:bundleURL )
        let image = UIImage(named: imageName, in: imageBundel, compatibleWith: nil)
        return image
    }
    return nil
}

Usage

用法

imageView.image = loadImageBundle(named: "imagefile")

回答by nferocious76

In your pod file: images are in .xcassets so it can be easily organized with 1x, 2x, 3x

在您的 pod 文件中: images are in .xcassets so it can be easily organized with 1x, 2x, 3x

s.resources = 'PodName/Assets/**'

Usage: Swift

用法: Swift

let bundle = Bundle(for: ClassThatWillUseTheImage.self)
let image = UIImage(named: "close", in: bundle, with: .none)

Usage: Objective-C

用法: Objective-C

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
UIImage *image = [UIImage imageNamed:@"close" inBundle:bundle withConfiguration:nil];

Tested in Version 11.4 (11E146) iOS 13.0+

在版本 11.4 (11E146) iOS 13.0+ 中测试

Using #imageLiteral(resourceName: "close")does not work however, it shows the image being read but will throw and error.

#imageLiteral(resourceName: "close")但是,使用不起作用,它显示正在读取的图像但会引发错误。

回答by Hai Feng Kao

I made a pod that can locate the resource bundles in pods. I hope it will end the "CocoaPods resource bundle" problem once and for all.

我做了一个 pod,可以定位 pod 中的资源包。我希望它能一劳永逸地结束“CocoaPods 资源包”问题。

https://github.com/haifengkao/PodAsset

https://github.com/haifengkao/PodAsset