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 无论如何。
这是我的做法。
首先,这里介绍了如何创建 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.")
}
我遇到了同样的问题。
场景:
- 我们的框架将被消耗iOS/OSX
- Framework 中有很多 PNG
- 我们想要在 iOSApp && MacOs 中使用 png
- 让我们假设框架项目和目标是 "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 使用:
- 将资产目录添加到您的框架项目(例如,“Media.xcassets”)。
- 添加资源,例如颜色集。假设您将颜色命名为“Thunder”。
- 在您的框架中创建一个名为“Color+Extensions.swift”(或您喜欢的任何名称)的文件。
- 在此文件中执行:
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)
我创建了一个 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 无论如何。
这是我的做法。
首先,这里介绍了如何创建 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.")
}
我遇到了同样的问题。 场景:
- 我们的框架将被消耗iOS/OSX
- Framework 中有很多 PNG
- 我们想要在 iOSApp && MacOs 中使用 png
- 让我们假设框架项目和目标是 "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 使用:
- 将资产目录添加到您的框架项目(例如,“Media.xcassets”)。
- 添加资源,例如颜色集。假设您将颜色命名为“Thunder”。
- 在您的框架中创建一个名为“Color+Extensions.swift”(或您喜欢的任何名称)的文件。
- 在此文件中执行:
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)