7

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

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

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

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

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

4

2 回答 2

14

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

完整的文档可以在这里找到。

于 2013-07-06T18:32:34.050 回答
5

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

[NSBundle mainBundle]

或者

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

当你的应用结构就像

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

因此,如果您可以创建一个捆绑文件并将其提供给容器应用程序(作为第 3 方框架开发人员),您可以提供此 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;
}

但是,一个非常简单的,可以说超级高效的解决方案是带有hexdump的旧 C 标头

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

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

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

unsigned int mydata_json_len = 32227;

因此,在您的框架或静态库中,您可以访问它

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

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

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

就是这样。快乐编码!

于 2014-11-03T23:45:14.047 回答