[英]How to retrieve a file/resource in a iOS framework bundle from a main program?
I use methods about creating a universal binary framework for iOS development to distribute a library.我使用有关为 iOS 开发创建通用二进制框架的方法来分发库。 I would also like to add files in the framework, and load them in the main program (an SSL certificate actually).
我还想在框架中添加文件,并将它们加载到主程序中(实际上是一个 SSL 证书)。 This is related to this StackOverflow question , the main difference is that I want to include something else than a XIB.
这与这个 StackOverflow 问题有关,主要区别在于我想包含 XIB 以外的其他内容。
If we read the thread related to the linked post, it seems it is not possible.如果我们阅读与链接帖子相关的主题,似乎是不可能的。 However, the following blog article was mentioned;
但是,提到了以下博客文章; we can read:
我们可以阅读:
"Static frameworks are not a full replacement for standard frameworks -- standard methods for accessing the framework resources, such as
+[NSBundle bundleForClass:]
will not return the expected bundle. The bundle path is determined by querying dyld for the library path corresponding to the symbol address -- In the case of static linking, this will return the path to the binary into which the static library was linked. Additionally,NSBundle/CFBundle
will examine the previous stack from for the return address, and use that return address to determine the calling code's dyld binary path. Given these restrictions, some work-arounds are possible, such as using-[NSBundle privateFrameworkPath]
to locate the path to the embedded framework."“静态框架不能完全替代标准框架——访问框架资源的标准方法,例如
+[NSBundle bundleForClass:]
不会返回预期的包。包路径是通过查询 dyld 对应的库路径来确定的符号地址——在 static 链接的情况下,这将返回 static 库链接到的二进制文件的路径。此外,NSBundle/CFBundle
将检查先前的堆栈以获取返回地址,并使用该返回地址来确定调用代码的 dyld 二进制路径。鉴于这些限制,一些解决方法是可能的,例如使用-[NSBundle privateFrameworkPath]
来定位嵌入式框架的路径。”
I am a beginner in iOS development, and I struggle in using such a mechanism.我是 iOS 开发的初学者,我在使用这种机制方面很挣扎。 Using the
privateFrameworksPath
returns a path indeed, but I do not know what to do next to locate the file I want to load.使用
privateFrameworksPath
确实会返回一个路径,但我不知道下一步该怎么做才能找到我要加载的文件。
It is something like that:是这样的:
NSBundle * bundle = [NSBundle bundleForClass:[self class]];
NSString * path = [bundle privateFrameworksPath]; // Works, return something like .../Frameworks
NSString * file = [path stringByAppendingPathComponent:@"MyFramework.framework/Versions/A/my-cert.der"];
NSData * trustedCertData = [NSData dataWithContentsOfFile:file]; // Returns nil
Any ideas?有任何想法吗?
The following code worked for me in a similar case 以下代码在类似情况下适用于我
NSBundle * bundle = [NSBundle bundleForClass:[self class]];
NSString * file = [bundle pathForResource:@"my-cert" ofType:@"der"];;
NSData * trustedCertData = [NSData dataWithContentsOfFile:[file stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
The NSBundle bundleForClass:
method returns a bundle for the framework of the current class. NSBundle bundleForClass:
方法返回当前类框架的包。 So if you call this method from within MyFramework you won't need to append the path with MyFramework.framework
again, but you would have caught that debugging if that was your problem. 因此,如果您在MyFramework中调用此方法,则无需再次使用
MyFramework.framework
附加路径,但如果这是您的问题,您可能已经捕获了调试。
Also the dash in my-cert.der
may need to be replaced with the % equivelent. 此外,
my-cert.der
的破折号可能需要替换为%equivelent。 hence the stringByReplacingPercentEscapesUsingEncoding:
call. 因此
stringByReplacingPercentEscapesUsingEncoding:
调用。
Access to Framework bundle访问框架包
The key point is to pass any metatype
[About] of class which belongs to framework关键点是传递属于框架的
metatype
的任何元类型[About]
Objective-C Objective-C
NSBundle *someBundle = [NSBundle bundleForClass:[SomeFrameworkClass class]];
Swift Swift
//via public framework's class
let frameworkBundle = Bundle(for: SomeFrameworkClass.self)
//or via Bundle Identifier(PRODUCT_BUNDLE_IDENTIFIER)
let frameworkBundle = Bundle(identifier: "com.someid")
//or if it is called from the framework
let frameworkBundle = Bundle(for: type(of: self))
let frameworkBundle = Bundle(for: Self.self)
//working with bundle as usual
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.