xcode 从CocoaPods资源包加载镜像

5q4ezhmt  于 2023-04-07  发布在  其他
关注(0)|答案(8)|浏览(464)

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

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

bundle中的一个资源是一个包含多个图像集的资产目录,其中一个称为'IXMKAnnotationIcons-Normal-Accident'。以下代码返回nil:

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

我发现了一个article on 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;
    }
}

描述resources关键字的CocoaPods网页有以下警告:
我们强烈建议库开发者采用资源包,因为使用resources属性可能会有名称冲突。而且使用该属性指定的资源会直接复制到客户端目标,因此不会被Xcode优化。
我不知道该怎么办。

n8ghc7c1

n8ghc7c11#

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

pkwftd7m

pkwftd7m2#

例如Paramount
podspec

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

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)
  }
}

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

ego6inou

ego6inou3#

没有列出的明显的解决方案是使用Cocoapods生成的bundle(文件夹实际上不存在)作为NSBbundle:
试试看:http://blog.flaviocaetano.com/post/cocoapods-and-resource_bundles/
它为我工作!!

t5fffqht

t5fffqht4#

至于我,我不得不将“s.resources”添加到. podspec中。在此之前,它丢失了。
只有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' => 'naloiko@gmail.com' }
  s.source           = { :git => 'https://ievgen_naloiko@bitbucket.org/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
yks3o0rb

yks3o0rb5#

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

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

用法:Swift

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

用法:Objective-C

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

在版本11.4(11E146)iOS 13.0+中测试
使用#imageLiteral(resourceName: "close")不起作用,它显示正在读取的图像,但会抛出错误。

a0x5cqrl

a0x5cqrl6#

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

pbgvytdp

pbgvytdp7#

此答案适用于Swift3Swift4
在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
}

用途

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

8nuwlpux8#

这里有几个不同的问题:
在iOS 8.0之前,只有将资产目录编译到应用的主捆绑包中,才能读取资产目录中的图像。iOS 8引入了init(named:in:compatibleWith:)来解决这一问题。
然而,即使在2023年使用iOS 8的方法,特别是无法从资产目录中加载图像和颜色的问题似乎仍然能够发生,尽管它不是100%可重现的。
发生这种情况的方式是Pod作者(可以理解)用与他们的Pod相同的名称命名他们的资源包之一。
如果应用程序开发人员在他们的Podfile中使用了use_frameworks!指令,CocoaPods会创建一个名为(BarKit.framework *)的框架,并在其中创建一个名为BarKit.bundle的包,其中包含Assets.car文件(您可以使用carDump之类的工具来验证资产确实存在于此文件中)。
关键的是,框架和bundle的产品名(在相应的Info.plist文件中)都设置为org.cocoapods.BarKit。这似乎会混淆资产“反编译器”,尽管bundle中的其他所有内容都将继续工作。
查看此修复是否有帮助的一种方法是手动将资源包的包ID重命名为与其配套框架不同的名称。

  • 对不起,但这里的“Foo”对于一个家庭网站来说可能有点不雅。

相关问题