iOS: 如何在框架中添加资产文件夹以及如何在代码中访问它们?

iOS: How to add Assets folder inside a Framework and how to access them in code?

我创建了一个 iOS 应用程序并向其添加了一个框架。生成的框架没有像生成 Single View App 这样的资产文件夹。所以我在framework文件夹里面做了一个Assets文件夹拖放到xcode,选择目标作为我的framework

我尝试使用该资产,但该资产未显示。可以告诉我如何正确地做到这一点吗?是否可以在框架内创建资产文件夹?

我是 iOS 的新手,因此非常感谢任何指导。提前致谢。

像往常一样通过新文件...>资源资产目录添加到框架目标,但要从此类资产中获取资源它需要明确指定包,如下例所示...

假设ImageProvider在框架目标中,代码可以是

public class ImageProvider {
    // convenient for specific image
    public static func picture() -> UIImage {
        return UIImage(named: "picture", in: Bundle(for: self), with: nil) ?? UIImage()
    }

    // for any image located in bundle where this class has built
    public static func image(named: String) -> UIImage? {
        return UIImage(named: named, in: Bundle(for: self), with: nil)
    }
}

当然你可以这样命名 class 无论如何。

backup

这是我的做法。

首先,这里介绍了如何创建 Bundle 来保存图像等资产。

首先,新建一个目标: 导航至主 Xcode 菜单,文件 => 新建 => 目标。然后选择 "macOS tab" 来自 "Framework & Library" select "Bundle".

为其命名并点击完成。您应该会在项目文件夹中看到该包。

其次,Bundle构建设置中的配置更改: 转到您的捆绑目标上的构建设置并将 Base SDK 更改为 iOS.

第三,添加图片: 直接将图像添加到 Bundle,无需添加资产文件夹。只需拖放即可。

第四,构建包: 选择您的捆绑包作为目的地并选择通用 iOS 设备并点击 Command + B

Fifth,.bundle 将出现在项目文件夹下的产品文件夹中。右键单击它并在 Finder 中查看它,然后将其拖放到主项目文件夹中。

最后,这是我如何访问您的捆绑包中的资产。

// Empty UIImage array to store the images in it.
var images = [UIImage]()

let fileManager = FileManager.default
let bundleURL = Bundle.main.bundleURL
let assetURL = bundleURL.appendingPathComponent("MyBundle.bundle") // Bundle URL
do {
  let contents = try fileManager.contentsOfDirectory(at: assetURL,
 includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey],
 options: .skipsHiddenFiles)
  for item in contents { // item is the URL of everything in MyBundle imgs or otherwise.

      let image = UIImage(contentsOfFile: item.path) // Initializing an image
      images.append(image!) // Adding the image to the icons array
  }
}
catch let error as NSError {
  print(error)
}

您的包中将包含 .plist 文件,因此,我建议您通过一个简单的条件来处理此问题,以检查文件名是否为 Info.plist 不要从中创建图像。

以下是我以非常琐碎的方式处理它的方法。

    let fileManager = FileManager.default
    let bundleURL = Bundle.main.bundleURL
    let assetURL = bundleURL.appendingPathComponent("Glyphs.bundle")
    do {
      let contents = try fileManager.contentsOfDirectory(at: assetURL, includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey], options: .skipsHiddenFiles)
      for item in contents {
        let imageName = item.lastPathComponent
        if imageName != "Info.plist" {
          let image = UIImage(contentsOfFile: item.path)
          icons.append(image!)
        }
      }
    }
    catch {
      //print(error)
      showAlert(withTitle: "Error", message: "Can't get the icons.")
    }

我遇到了同样的问题。 场景:

  1. 我们的框架将被消耗iOS/OSX
  2. Framework 中有很多 PNG
  3. 我们想要在 iOSApp && MacOs 中使用 png
  4. 让我们假设框架项目和目标是 "MyCustomFramework.framework"(通常的黄色图标..)已经在我们的应用程序中

-

func filePathInFrameworkBundle(name: String)->String{

    let myBundlePath  = Bundle.main.bundlePath

    #if  os(iOS)

    let inMyFW = myBundlePath +
        "/Frameworks" +
    "/MyCustomFramework.framework"

    #elseif os(OSX)
    let inMyFW = myBundlePath +
        "/Contents/Frameworks" +
        "/MyCustomFramework.framework" + "/Versions/A/Resources"

    #else
    #endif

    let pathInBundle = inMyFW+"/"+name
    return pathInBundle
}

现在您可以在通常的图像加载调用中使用此路径。

对于 SwiftUI 使用:

  1. 将资产目录添加到您的框架项目(例如,“Media.xcassets”)。
  2. 添加资源,例如颜色集。假设您将颜色命名为“Thunder”。
  3. 在您的框架中创建一个名为“Color+Extensions.swift”(或您喜欢的任何名称)的文件。
  4. 在此文件中执行:
    import SwiftUI

    private class LocalColor {
      // only to provide a Bundle reference
    }

    public extension Color {
        static var thunder: Color {
            Color("Thunder", bundle: Bundle(for: LocalColor.self))
        }
    }

我想这也适用于其他资产类型。

在使用您的框架的项目中,为您的框架添加 import 后,您应该可以正常使用颜色:

    Rectangle().foregroundColor(.thunder)