内部有资源的 IOS 静态框架

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12180113/
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-08-30 19:55:51  来源:igfitidea点击:

IOS Static Framework with resources inside

iosframeworksuiimageviewxib

提问by Andrei Stanescu

I'm trying to create a framework that keeps some common code I use around in my projects. I found online tutorials and managed to create a framework but I still have one problem related to resources (xibs, images, etc).

我正在尝试创建一个框架,以保留我在项目中使用的一些通用代码。我找到了在线教程并设法创建了一个框架,但我仍然有一个与资源(xib、图像等)相关的问题。

Let's say I have a MainViewController.xibwhich has a UIImageViewusing a test.png. All these are in my framework package.

假设我有MainViewController.xib一个UIImageViewusing a test.png。所有这些都在我的框架包中。

When I use the framework in another project, I add it to the "Copy Bundle Resources" build phase. The problem is that the xib is only accessible using a path like dummy.framework/Resources/MainViewController.xiband the UIImageViewinside can't load test.png.

当我在另一个项目中使用该框架时,我将其添加到“复制捆绑资源”构建阶段。问题是只能使用类似路径访问 xibdummy.framework/Resources/MainViewController.xib并且UIImageView内部无法加载test.png.

It seems that the UIImageView will try to load the png from the root of the bundle, and not from the relative folder where the xib is also stored.

似乎 UIImageView 将尝试从包的根目录加载 png,而不是从也存储 xib 的相对文件夹中加载 png。

Has anybody managed to create a framework with code and resources and use it in another project?

有没有人设法用代码和资源创建一个框架并在另一个项目中使用它?

采纳答案by Ismael

Short answer: you can't.

简短的回答:你不能。

When you compile the app, the bundle is generated with the resources of the "main" project, ignoring the resources in linked frameworks. This includes images, xib's, plist's, etc. (anything that isn't a source file)

编译应用程序时,会使用“主”项目的资源生成包,忽略链接框架中的资源。这包括图像、xib、plist 等(任何不是源文件的内容)

What you need to do is add those resources to your main project so that they are available for use inside your application, not the happiest way around it but it'll work.

您需要做的是将这些资源添加到您的主项目中,以便它们可以在您的应用程序中使用,这不是最愉快的方式,但它会起作用。

回答by Ryan Poolos

I know this is an old thread, but to keep new people from making the same mistakes here is a note:

我知道这是一个旧线程,但为了防止新人犯同样的错误,这里有一个注释:

As of Xcode 6 and iOS8, Apple has a fully supported first party Dynamic Framework solution built in. For more information look here: https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14

从 Xcode 6 和 iOS8 开始,Apple 内置了完全受支持的第一方动态框架解决方案。有关更多信息,请查看此处:https: //developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/ xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14

But the short of it is, create a new project and choose the Cocoa Touch Framework template.

但简而言之,创建一个新项目并选择 Cocoa Touch Framework 模板。

回答by devinross

I created a framework target and to access images inside its asset catalog I did the following:

我创建了一个框架目标并访问其资产目录中的图像,我执行了以下操作:

UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];

回答by Rivera

I don't manually manage frameworks anymore but use and recommendCocoaPodsinstead.

我不再手动管理框架,而是使用并推荐CocoaPods



Original answer:

原答案:

  1. Use the fake framework@wattson12 mentioned. It will compile and save the resources as well.
  2. Inspired by this script, add this to your target to copy the resources to your app:

    SOURCE_PATH="${TARGET_BUILD_DIR}/MYFramework.framework/Resources/"
    TARGET_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MYFrameworkResources.bundle"
    mkdir -p $TARGET_PATH
    cp -R $SOURCE_PATH $TARGET_PATH
    
  1. 使用提到的假框架@wattson12。它也会编译和保存资源。
  2. 灵感来自这个脚本,将它添加到你的目标的资源复制到你的应用程序:

    SOURCE_PATH="${TARGET_BUILD_DIR}/MYFramework.framework/Resources/"
    TARGET_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MYFrameworkResources.bundle"
    mkdir -p $TARGET_PATH
    cp -R $SOURCE_PATH $TARGET_PATH
    

You could also just drag the framework to your Copy Resources step, but then you'll be adding unnecessary headers and compiled code as well.

您也可以将框架拖到 Copy Resources 步骤,但随后您还将添加不必要的头文件和编译代码。

Edit

编辑

To use these resources from IB, for instance a png file, replace:

要使用来自 IB 的这些资源,例如 png 文件,请替换:

MyImage

by:

经过:

MYFrameworkResources.bundle/MyImage.png

It will preview a broken image icon but will work when running.

它将预览损坏的图像图标,但在运行时会起作用。

Load a Nib from code:

从代码加载 Nib:

[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...

Finally you can add these methods in a NSBundle category to ease access to Nib resources that my be in your main bundle or in MYFrameworkResources.bundle:

最后,您可以将这些方法添加到 NSBundle 类别中,以便轻松访问位于主包或 MYFrameworkResources.bundle 中的 Nib 资源:

@implementation NSBundle (MyCategory)

+ (NSString *)pathForResource:(NSString *)name
                       ofType:(NSString *)extension
{
    // First try with the main bundle
    NSBundle * mainBundle = [NSBundle mainBundle];
    NSString * path = [mainBundle pathForResource:name
                                           ofType:extension];
    if (path)
    {
        return path;
    }

    // Otherwise try with other bundles
    NSBundle * bundle;
    for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
                                                          inDirectory:nil])
    {
        bundle = [NSBundle bundleWithPath:bundlePath];
        path = [bundle pathForResource:name
                                ofType:extension];
        if (path)
        {
            return path;
        }
    }

    NSLog(@"No path found for: %@ (.%@)", name, extension);
    return nil;
}

+ (NSArray *)loadNibNamed:(NSString *)name
                    owner:(id)owner
                  options:(NSDictionary *)options
{
    // First try with the main bundle
    NSBundle * mainBundle = [NSBundle mainBundle];
    if ([mainBundle pathForResource:name
                             ofType:@"nib"])
    {
        NSLog(@"Loaded Nib named: '%@' from mainBundle", name);
        return [mainBundle loadNibNamed:name
                                  owner:owner
                                options:options];
    }

    // Otherwise try with other bundles
    NSBundle * bundle;
    for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
                                                          inDirectory:nil])
    {
        bundle = [NSBundle bundleWithPath:bundlePath];
        if ([bundle pathForResource:name
                             ofType:@"nib"])
        {
            NSLog(@"Loaded Nib named: '%@' from bundle: '%@' ", name, bundle.bundleIdentifier);
            return [bundle loadNibNamed:name
                                  owner:owner
                                options:options];
        }
    }

    NSLog(@"Couldn't load Nib named: %@", name);
    return nil;
}

@end

It will first look into your application bundle and then in MYFrameworkResources.bundle, etc.

它将首先查看您的应用程序包,然后查看 MYFrameworkResources.bundle 等。

回答by Luca Torella

In order to load an image from a dynamic framework in Swift 3:

为了从Swift 3 中的动态框架加载图像:

UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)

UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)

回答by wattson12

Basic frameworks do not include most kinds of resources, to include resources use this "fake" framework library

基本框架不包括大多数类型的资源,要包括资源使用这个“假”框架库

You end up with a .embeddedframework folder which contains the actual framework, but also includes any resources which you add to the Copy Bundle Resources build phase. Ive used it to include xibs, core data models, images, and plists

您最终会得到一个包含实际框架的 .embeddedframework 文件夹,但也包含您添加到复制捆绑资源构建阶段的任何资源。我用它来包含 xibs、核心数据模型、图像和 plists

回答by leerie simpson

As of Xcode 7 we can now use Asset Catalogs. In my experiments I've found that u can reference files in the same workspace bit different projects removing the need to micro manage assets in build phases or worrying about targets.

从 Xcode 7 开始,我们现在可以使用资产目录。在我的实验中,我发现您可以在同一个工作区中引用不同项目中的文件,从而无需在构建阶段微管理资产或担心目标。