I use methods about creating a universal binary framework for iOS development to distribute a library. I would also like to add files in the framework, and load them in the main program (an SSL certificate actually). This is related to this StackOverflow question, the main difference is that I want to include something else than a 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."
I am a beginner in iOS development, and I struggle in using such a mechanism. Using the privateFrameworksPath
returns a path indeed, but I do not know what to do next to locate the file I want to load.
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?
It's called contentsOfFile , and here it is in action: if let filepath = Bundle. main. path(forResource: "example", ofType: "txt") { do { let contents = try String(contentsOfFile: filepath) print(contents) } catch { // contents could not be loaded } } else { // example.
A framework is a bundle (a structured directory) that contains a dynamic shared library along with associated resources, such as nib files, image files, and header files. When you develop an application, your project links to one or more frameworks.
One is to right click your "src" folder in Xcode, and select "New File..", the other is to go to the menu and select File > New > File... In the dialog that pops up, navigate to OS X > Source and then select C++ file.
Access to Framework bundle
The key point is to pass any metatype
[About] of class which belongs to framework
//Objective-C
NSBundle *someBundle = [NSBundle bundleForClass:[SomeFrameworkClass class]];
//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
[Vocabulary]
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. 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.
Also the dash in my-cert.der
may need to be replaced with the % equivelent. hence the stringByReplacingPercentEscapesUsingEncoding:
call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With