Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在iOS的cocoapod库中使用图像资源目录_Ios_Objective C_Iphone_Xcode_Cocoapods - Fatal编程技术网

如何在iOS的cocoapod库中使用图像资源目录

如何在iOS的cocoapod库中使用图像资源目录,ios,objective-c,iphone,xcode,cocoapods,Ios,Objective C,Iphone,Xcode,Cocoapods,我有一个cocoapod库,其中包含两种格式的资产: 故事板 XCode资产目录.xcassets(带图像) 我的podspec文件包含资源包的定义: s.resource_bundle = {'SparkSetup' => ['Resources/**/*.{xcassets,storyboard}']} 在pod项目中,我有一个单独的目标,通过使用这些文件+该捆绑包的plist文件来创建一个资源捆绑包 问题是,当我在应用程序项目中使用pod时,我可以看到pod目标中有情节提要/x

我有一个cocoapod库,其中包含两种格式的资产:

  • 故事板
  • XCode资产目录.xcassets(带图像)
我的
podspec
文件包含资源包的定义:

s.resource_bundle = {'SparkSetup' => ['Resources/**/*.{xcassets,storyboard}']}
在pod项目中,我有一个单独的目标,通过使用这些文件+该捆绑包的plist文件来创建一个资源捆绑包

问题是,当我在应用程序项目中使用pod时,我可以看到pod目标中有情节提要/xcassets文件,我可以轻松访问和运行情节提要,但在运行时找不到情节提要(指向.xcassets文件)中引用的图像(但在IB中正确显示)

我得到的错误是:

Could not load the "spinner" image referenced from a nib in the bundle with identifier "(null)"
我确实在products目录中看到了一个bundle文件。 要在我使用的故事板中实例化VCs,请执行以下操作:

+(NSBundle *)getResourcesBundle
{
    NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"SparkSetup" withExtension:@"bundle"]];
    return bundle;
}


+(UIStoryboard *)getSetupStoryboard
{
    UIStoryboard *setupStoryboard = [UIStoryboard storyboardWithName:@"setup" bundle:[SparkSetupMainController getResourcesBundle]];
    return setupStoryboard;
}
这对于查找情节提要似乎很有效,但对于查找同一捆绑包中的.xcsets中的图像却不起作用

我做错了什么?我如何从这个故事板/代码中引用图像,并能够将这个UI pod集成到任何应用程序中


谢谢

嗯,pods不支持图像资产目录-只需在podspec中包含包含图像文件的资源包,如下所示:

s.subspec 'Resources' do |resources|
    resources.resource_bundle = {'MyBundle' => ['Resources/**/*.{png}']}

end
并从pod安全访问图像,如下所示:

+(NSBundle *)getResourcesBundle
{
    NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"MyBundle" withExtension:@"bundle"]];
    return bundle;
}


+(UIImage *)loadImageFromResourceBundle:(NSString *)imageName
{
    NSBundle *bundle = [MyClass getResourcesBundle];
    NSString *imageFileName = [NSString stringWithFormat:@"%@.png",imageName];
    UIImage *image = [UIImage imageNamed:imageFileName inBundle:bundle compatibleWithTraitCollection:nil];
    return image;
}

这解决了在cocoapod中处理图像/资源的所有问题。

好吧,图像资产目录不受Pod的支持-只需在podspec中包含包含图像文件的资源包,如下所示:

s.subspec 'Resources' do |resources|
    resources.resource_bundle = {'MyBundle' => ['Resources/**/*.{png}']}

end
并从pod安全访问图像,如下所示:

+(NSBundle *)getResourcesBundle
{
    NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"MyBundle" withExtension:@"bundle"]];
    return bundle;
}


+(UIImage *)loadImageFromResourceBundle:(NSString *)imageName
{
    NSBundle *bundle = [MyClass getResourcesBundle];
    NSString *imageFileName = [NSString stringWithFormat:@"%@.png",imageName];
    UIImage *image = [UIImage imageNamed:imageFileName inBundle:bundle compatibleWithTraitCollection:nil];
    return image;
}

这解决了在cocoapod中处理图像/资源的所有问题。

如果您使用swift

class func loadImage(name: String) -> UIImage? {
    let podBundle = NSBundle(forClass: MyClass.self)
    if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
        let bundle = NSBundle(URL: url)
        return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
    }
    return nil
}

如果您使用的是swift

class func loadImage(name: String) -> UIImage? {
    let podBundle = NSBundle(forClass: MyClass.self)
    if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
        let bundle = NSBundle(URL: url)
        return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
    }
    return nil
}

至少从Cocoapods的1.0.1版开始,支持图像资产目录

在我的Swift 4.2代码中,我使用了:

public static var GoogleIcon: UIImage {
    let bundle = Bundle(for: self)
    log.msg("bundle: \(bundle)")
    return UIImage(named: "GoogleIcon", in: bundle, compatibleWith: nil)!
}
在我的pod规范中,我使用了:

s.resources = "SMCoreLib/Assets/*.xcassets"
当我使用模拟器构建时,.car文件确实会显示在框架中:

cd /Users/<snip>/SMCoreLib.framework 
ls
Assets.car  Info.plist  SMCoreLib
cd/Users//SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib

至少从Cocoapods的1.0.1版开始,支持图像资产目录

在我的Swift 4.2代码中,我使用了:

public static var GoogleIcon: UIImage {
    let bundle = Bundle(for: self)
    log.msg("bundle: \(bundle)")
    return UIImage(named: "GoogleIcon", in: bundle, compatibleWith: nil)!
}
在我的pod规范中,我使用了:

s.resources = "SMCoreLib/Assets/*.xcassets"
当我使用模拟器构建时,.car文件确实会显示在框架中:

cd /Users/<snip>/SMCoreLib.framework 
ls
Assets.car  Info.plist  SMCoreLib
cd/Users//SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib

Swift 3版

private func getImageFromBundle(name: String) -> UIImage {
   let podBundle = Bundle(for: YourClass.self)
   if let url = podBundle.url(forResource: "YourClass", withExtension: "bundle") {
      let bundle = Bundle(url: url)
      return UIImage(named: name, in: bundle, compatibleWith: nil)!
   }
   return UIImage()
}

Swift 3版本

private func getImageFromBundle(name: String) -> UIImage {
   let podBundle = Bundle(for: YourClass.self)
   if let url = podBundle.url(forResource: "YourClass", withExtension: "bundle") {
      let bundle = Bundle(url: url)
      return UIImage(named: name, in: bundle, compatibleWith: nil)!
   }
   return UIImage()
}

只有这对我有效(Swift 3和Swift 4)

然后按如下方式使用:

ImagesHelper.myImage
与的答案一样,不要忘记更新podspec文件,如:

s.resource_bundles = {
  'YourClass' => ['YourPodName/*/Assets.xcassets']
}

只有这对我有效(Swift 3和Swift 4)

然后按如下方式使用:

ImagesHelper.myImage
与的答案一样,不要忘记更新podspec文件,如:

s.resource_bundles = {
  'YourClass' => ['YourPodName/*/Assets.xcassets']
}

你喜欢这样吗

s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'

你喜欢这样吗

s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'

您可以使用POD的包id访问POD中的图像


您可以使用POD的包id访问POD中的图像


在pod规范的资源中添加
.xcasets
文件,并使用以下UIImage init:

extension UIImage {
    convenience init?(podAssetName: String) {
        let podBundle = Bundle(for: ConfettiView.self)

    /// A given class within your Pod framework
    guard let url = podBundle.url(forResource: "CryptoContribute",
                                  withExtension: "bundle") else {
        return nil

    }

    self.init(named: podAssetName,
              in: Bundle(url: url),
              compatibleWith: nil)
    }
 }

在pod规范的资源中添加
.xcasets
文件,并使用以下UIImage init:

extension UIImage {
    convenience init?(podAssetName: String) {
        let podBundle = Bundle(for: ConfettiView.self)

    /// A given class within your Pod framework
    guard let url = podBundle.url(forResource: "CryptoContribute",
                                  withExtension: "bundle") else {
        return nil

    }

    self.init(named: podAssetName,
              in: Bundle(url: url),
              compatibleWith: nil)
    }
 }

我自己用椰子豆来解决这个问题。我没有使用UIImage,而是添加了一个捆绑方法。该方法尝试定位给定名称的内部捆绑包,但返回到原始捆绑包。这允许代码在使用pod的应用程序代码以及pod代码本身中工作

extension Bundle {

    /**
     Locate an inner Bundle generated from CocoaPod packaging.

     - parameter name: the name of the inner resource bundle. This should match the "s.resource_bundle" key or
       one of the "s.resoruce_bundles" keys from the podspec file that defines the CocoPod.
     - returns: the resource Bundle or `self` if resource bundle was not found
    */
    func podResource(name: String) -> Bundle {
        guard let bundleUrl = self.url(forResource: name, withExtension: "bundle") else { return self }
        return Bundle(url: bundleUrl) ?? self
    }
}
然后在
viewdiload
方法中,或者在任何你有图像设置代码的地方,放置类似这样的东西,其中“ClassFromPod”指的是CocoaPod中的Swift类,“ResourceName”是pod中内部包的名称(你应该能够在“Pods/Projects”中使用Xcode项目导航器查看包)--嵌入式捆绑包具有乐高图标和“捆绑包”后缀。)


如您所见,UIImage API保持不变,只是所使用的捆绑包不同,这取决于它在运行时找到的内容。

我自己的CocoaPods解决方案。我没有使用UIImage,而是添加了一个捆绑方法。该方法尝试定位给定名称的内部捆绑包,但返回到原始捆绑包。这允许代码在使用pod的应用程序代码以及pod代码本身中工作

extension Bundle {

    /**
     Locate an inner Bundle generated from CocoaPod packaging.

     - parameter name: the name of the inner resource bundle. This should match the "s.resource_bundle" key or
       one of the "s.resoruce_bundles" keys from the podspec file that defines the CocoPod.
     - returns: the resource Bundle or `self` if resource bundle was not found
    */
    func podResource(name: String) -> Bundle {
        guard let bundleUrl = self.url(forResource: name, withExtension: "bundle") else { return self }
        return Bundle(url: bundleUrl) ?? self
    }
}
然后在
viewdiload
方法中,或者在任何你有图像设置代码的地方,放置类似这样的东西,其中“ClassFromPod”指的是CocoaPod中的Swift类,“ResourceName”是pod中内部包的名称(你应该能够在“Pods/Projects”中使用Xcode项目导航器查看包)--嵌入式捆绑包具有乐高图标和“捆绑包”后缀。)


如您所见,UIImage API保持不变,只是所使用的捆绑包不同,这取决于它在运行时找到的内容。

我仍然无法让它工作,因为上面没有任何解决方案。 我的Pod中有一个Assets.xcsets文件

在我的Pod类中,我想访问资产中的图像

具体如下:

s.resource_bundles = {
     'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
 func getImage(named name: String) -> UIImage {
    // Use a random singleton class in your project.
    // Emphasis on class, structs won't work.
    let bundle = Bundle(for: [random class].self)

    if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
        return image
    }

    return .init()
}
使用此帮助程序:

public struct ImagesHelper {
    private static var podsBundle: Bundle {
        let bundle = Bundle(for: SWDownloadPlayButton.self)
        return Bundle(url: bundle.url(forResource: "SWDownloadPlayButton",
                                      withExtension: "bundle")!)!
    }

    private static func imageFor(name imageName: String) -> UIImage {
        return UIImage.init(named: imageName, in: podsBundle, compatibleWith: nil)!
    }

    public static var download_icon: UIImage {
        return imageFor(name: "download_icon")
    }
}
但是无论我在我的Pod类中做什么(不是在示例项目中)…就像这样

s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
 var centerImage: UIImage = ImagesHelper.download_icon.withRenderingMode(.alwaysTemplate) {
        didSet {
            updateImage()
        }
    }

我的centerImage仍然为零

如果没有上述解决方案,我仍然无法使其正常工作。 我的Pod中有一个Assets.xcsets文件

在我的Pod类中,我想访问资产中的图像

具体如下:

s.resource_bundles = {
     'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
 func getImage(named name: String) -> UIImage {
    // Use a random singleton class in your project.
    // Emphasis on class, structs won't work.
    let bundle = Bundle(for: [random class].self)

    if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
        return image
    }

    return .init()
}
使用此帮助程序:

public struct ImagesHelper {
    private static var podsBundle: Bundle {
        let bundle = Bundle(for: SWDownloadPlayButton.self)
        return Bundle(url: bundle.url(forResource: "SWDownloadPlayButton",
                                      withExtension: "bundle")!)!
    }

    private static func imageFor(name imageName: String) -> UIImage {
        return UIImage.init(named: imageName, in: podsBundle, compatibleWith: nil)!
    }

    public static var download_icon: UIImage {
        return imageFor(name: "download_icon")
    }
}
但是无论我在我的Pod类中做什么(不是在示例项目中)…就像这样

s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
 var centerImage: UIImage = ImagesHelper.download_icon.withRenderingMode(.alwaysTemplate) {
        didSet {
            updateImage()
        }
    }

如果您使用SwiftUI,使用
图像,我在centerImage上仍然得到一个零。init(\uu name:String,bundle:bundle?)
初始值设定项不起作用,您必须这样初始化它:

s.resource_bundles = {
     'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
 func getImage(named name: String) -> UIImage {
    // Use a random singleton class in your project.
    // Emphasis on class, structs won't work.
    let bundle = Bundle(for: [random class].self)

    if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
        return image
    }

    return .init()
}
如果您使用的是Swif