xcode 如何在框架内读取资源文件?

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

How to read resources files within a framework?

objective-cxcodemacos

提问by Lingfeng Xiong

I built a framework and a cocoa application in Mac OS X. The framework is dynamically linked to the application. In a class of the framework, I need to read a resource file within this framework's resources folder. The code below

我在 Mac OS X 中构建了一个框架和一个可可应用程序。该框架与应用程序动态链接。在框架的一个类中,我需要读取这个框架的资源文件夹中的资源文件。下面的代码

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *characterCodeTable = [resourcePath stringByAppendingPathComponent:@"pymb.txt"];

does not work since "resourcePath" is the path to application's resources folder, not the framework's.

不起作用,因为“resourcePath”是应用程序资源文件夹的路径,而不是框架的。

So how can I access the framework's resource folder in the code in this framework itself?

那么如何在这个框架本身的代码中访问该框架的资源文件夹呢?

BTW: Is there any best practice to organize miscellaneous files in a framework/application bundle?

顺便说一句:是否有任何最佳实践来组织框架/应用程序包中的杂项文件?

回答by mipadi

Instead of calling +[NSBundle mainBundle], call either +[NSBundle bundleWithIdentifier:]or +[NSBundle bundleForClass:]. The former takes an NSStringargument of the framework's indentifier; the latter takes a Classargument of a class provided by the framework. Then, you can call the usual NSBundlepaths as necessary.

不要调用+[NSBundle mainBundle],而是调用+[NSBundle bundleWithIdentifier:]+[NSBundle bundleForClass:]。前者接受NSString框架标识符的参数;后者采用Class框架提供的类的参数。然后,您可以NSBundle根据需要调用常用路径。

Full documentation can be found here.

可以在此处找到完整的文档。

回答by loretoparisi

There are several counter and side effects when using solutions like

使用解决方案时有几个反作用和副作用,例如

[NSBundle mainBundle]

or

或者

NSBundle *localBundle  = [NSBundle bundleForClass:[myObject class]]

when you app structure is like

当你的应用程序结构就像

MyContainerApp
  |------Frameworks/
        |-----------------MyFramework.framwork/
                                |-------------------Resources/
                                                           |-------------mydata.json

So, if you can create a bundle file and give it to container app (as a 3rd party framework developer) you can provide this API

因此,如果您可以创建一个包文件并将其提供给容器应用程序(作为 3rd 方框架开发人员),您可以提供此 API

+ (NSBundle *)frameworkBundle {
    static NSBundle* frameworkBundle = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
        NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"YourFrameworkBundle.bundle"];
        frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath];
    });
    return frameworkBundle;
}

BUT, a very super-easy, and let's say super-efficient solution is the old C header with hexdump

BUT,一个非常简单的,让我们说超级高效的解决方案是带有hexdump的旧 C 头文件

xxd -i mydata.json >> mydata.json.h

This hexdump will generate a header file with these definitions

这个 hexdump 将生成一个包含这些定义的头文件

unsigned char mydata_json[] = {
   // hex array
};

and

unsigned int mydata_json_len = 32227;

So in your framework or static library you can access to it just

所以在你的框架或静态库中你可以访问它

 unsigned char *rawBytes = mydata_json;
 NSUInteger dataLen = mydata_json_len;
 NSData *serializedData = [NSData dataWithBytesNoCopy:rawBytes length:dataLen freeWhenDone:NO];

then you maybe want to get it into text:

那么你可能想把它变成文本:

NSString* myString = [NSString stringWithUTF8String:[rawBytes bytes]];

And that's it. Happy coding!

就是这样。快乐编码!