2012-08-29 95 views
15

我想创建一个框架,保持我在项目中使用的一些常见代码。 我发现在线教程,并设法创建一个框架,但我仍然有一个问题与资源(xibs,图像等)有关。IOS静态框架与内部资源

比方说,我有一个MainViewController.xib它有一个UIImageView使用test.png。所有这些都在我的框架包中。

当我在另一个项目中使用框架时,我将它添加到“Copy Bundle Resources”构建阶段。问题在于,xib只能使用类似dummy.framework/Resources/MainViewController.xibUIImageView之类的路径访问,因此无法加载test.png

看来,UIImageView将尝试从bundle的根目录加载png,而不是从其中存储xib的相对文件夹加载png。

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

+1

嗨安德烈,你能告诉我你怎么加的.bundle文件到框架目录...我我无法做到这一点。我的shell脚本中可能有一些错误。 – Apple

回答

0

简答:你不行。

当您编译应用程序时,将使用“main”项目的资源生成包,忽略链接框架中的资源。这包括图像,xib的,plist的等(任何非源文件)

你需要做的是将这些资源添加到您的主项目,以便它们可用于您的应用程序内,而不是最快乐的方式,但它会工作。

+0

好吧,资源被复制,但在一个子文件夹中。 –

+2

这是最接近真实事实的答案。但是,您可以强制xcode从框架中复制资源,但它们将被放置在主包中的子文件夹中。这使得他们在屁股上加载他们很痛苦。 –

+0

你现在可以做到这一点 – doozMen

1

基本框架不包括大多数类型的资源,包括资源利用this "fake" framework library

您与其中包含实际的框架.embeddedframework文件夹结束了,但还包括要添加到复制包资源的任何资源建立阶段。我用它来包含xibs,核心数据模型,图像和plists

+0

是的,但是如果你(在框架中)有一个xib,它使用了也在框架中的资源(比如说一个图像)。你能否在测试应用程序中加载xib? –

+0

我没有在我面前的项目,但我敢肯定,这将是确定的,给它一个镜头... – wattson12

+0

我已经得出结论,我想要达到的是不是真的可能。由于Interface Builder无法显示子文件夹中的图像(它们在运行时工作),但以捆绑形式提供任何资源实际上并不可行。最好的方法是简单地添加一个zip文件和静态库,用户可以在其项目中使用该文件夹。 –

4

我不再手动管理框架,而是使用和recommendCocoaPods来代替。


原来的答复:

  1. 使用fake framework @提到wattson12。它也会编译和保存资源。
  2. 通过this script的启发,将它添加到你的目标的资源复制到你的应用程序:

    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 
    

你也可以只拖动框架将复制的资源一步,但随后你会添加不必要的标题和编译代码。

编辑

要使用从IB这些资源,例如png文件,替换:

MyImage 

由:

MYFrameworkResources.bundle/MyImage.png 

它将预览残缺的图像图标,但将在运行时起作用。

负荷码笔尖:

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

最后,你可以在一个NSBundle类添加这些方法来缓解访问笔尖资源,我在你的主束或MYFrameworkResources.bundle:

@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 

它会先看看你的应用程序包,然后在MYFrameworkResources.bundle等

+0

谢谢,但界面生成器仍然不会正确地检测资源 –

+0

你有问题的图像? (预先考虑路径是否足够)或与Nibs?您还可以检查您的构建目录,以查看资源在应用程序中的复制位置。 – Rivera

12

我知道这是一个古老的线程,但为了保持新peopl从使这里同样的错误e是一张纸条:

由于Xcode的6 iOS8上,苹果已经完全支持第一方动态框架解决方案建成欲了解更多信息请看这里:https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14

但短期的它是,创建一个新项目并选择Cocoa Touch Framework模板。

+0

一切都很好,但你是否真的设法将图像资源包含在Xcode 6中创建的动态框架中。我自己尝试了所有的东西,但无法使它工作!似乎是来自Apple的非常少的文档。 – simonthumper

+9

是的。它非常简单,但可能并不明显。简单地在正常的框架中包含你的图像,但为了加载它们,你需要引用你的框架。所以'[NSBundle bundleWithIdentifier:@“com。<#company#>。<#framework#>”];' –

+0

你不需要在创建一个包或任何东西时玩弄。 Xcode的框架为你处理。但是你必须从这个默认包中加载它们。我发现使用框架类别的快捷方式创建一个NSBundle类别非常有用。 –

7

我创建了一个框架,目标和访问图像的资产目录内,我做了以下内容:

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

非常感谢您,我浪费了大量时间试图为其寻找解决方案。而这一个工作:) – Ismail

-1

由于Xcode的7,我们现在可以使用资产目录。在我的实验中,我发现你可以在同一个工作区中引用不同的项目文件,而不需要在构建阶段微观管理资源,或者担心目标。

+0

这个答案是无关的问题 – doozMen

0

为了在从动态的框架加载图像斯威夫特3

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