What steps are involoved in loading a .Framework under MacOS X? - xcode

I am realtivly new to the concept of dynamic loading and shared libraries. While I fully understand how dlopen() could be used to reference symbols in a shared library I have yet to fullt grasp what MacOS does behind the scenes when I don't statically link against something. When adding a framework to Xcode I have the option to load it into my project or I can just provide some form of symlink to it(the actual implementation is obfuscated be the easy to use interface).
There after all I seem to need to do is import the header files that porvide and API to these frameworks and I can just invoke their symbols free of hassle. Can someone explain to me what I am actually doing, because it make no sense to me.

The sheet you're referring to has nothing to do with the actual linking of the framework. The copy vs. link choice refers to how you want to include the framework in your Xcode project, not your app binary.
For system frameworks there really isn't anything you need to do but import the headers.
For custom frameworks (your own or third-party) the framework must reside at the load path directory when your app launches. Typically the load path will point to your app bundle's Frameworks (sub)directory, so you must add a Copy Files build phase that copies the framework to your app bundle's Frameworks directory.
Remember to check out Apple's Framework Programming Guide, especially the section on frameworks embedded in your app bundle.

Related

Adding swift framework extracted from IPA

I'm trying to run an IOS app created by another dev that is using a cocoapod from a private repository I have no access to. I managed to extract the .framework bundle from the IPA and add it to the xcode project but it is not being recognized (I get "No such module").
Is it possible to do what I'm trying to achieve?
So far, what I've tried:
build it in release as I guess the framework in the IPA is in release
add the .framework as embedded binary
add the .framework as Linked Framework and Libraries
copy the .framework to ~/System/Library/Framework
update the Frameworks Search Path including $(SRCROOT), recursive, hardcoded paths, etc.
change the .framework location to "Relative to Build Products"
Thanks!
It wasn't that much easy to get the frameworks used in project from ipa file.
Whenver the application runs for first time, also when you archive your application, all the linked .frameworks will get converted to .dylib that is dynamic libraries.
What is static library - a unit of code linked at compile time, which does not change.
What is dynamic library - a unit of code and/or assets linked at runtime that may change.
Framework - A framework is a hierarchical directory that encapsulates a dynamic library, header files, and resources, such as storyboards, image files, and localized strings, into a single package. Apps using frameworks need to embed the framework in the app's bundle.
Dynamic Library
A dynamic lib file is just resides inside the framework folder.
Following is a description from apple documentation
Dynamic libraries outside
of a framework bundle, which typically have the file extension .dylib,
are not supported on iOS, watchOS, or tvOS, except for the system
Swift libraries provided by Xcode.
Ref: Documentation
So you cannot simply copy a .dylib to xcode bundle and just use it. There is some sort of security too.
Another approch
It is possible to decompile the source code from .ipa files. You will get idea from below links.
SO Question regarding decompiling of ipa file
Decompilation Possibility
It seems that when an app is archived for distribution, the Headers and Modules folders are removed from the .framework bundle.
The Header folder contains the .h headers for Objective-C and the Modules folder contains the .swiftmodule equivalent files for Swift.
Without these files you have no public API to consume for the framework binary, so unfortunately this renders the frameworks unusable without reverse engineering.

What are Embedded Binaries in Xcode?

I'm using Alamofire in a Swift project, and part of their manual installation instructions are to add Alamofire under Embedded Binaries in the General tab for my application target.
What are Embedded Binaries?
Embedded binaries are binary files that are copied to your application bundle when you build the project. Use embedded binaries when your application relies on third-party frameworks so people can use your application without needing those frameworks installed on their machine. Embedded binaries keep users from having to manually install third-party frameworks. Your application uses the framework you embedded.
In your Alamofire example your application relies on Alamofire. If you didn't embed the Alamofire framework, nobody would be able to use your application unless they installed Alamofire manually. By embedding Alamofire with your application everyone can run your application.
"Binary" means: compiled code — as opposed to "source code", which is what you are working with when you write code as text.
They could have given you source code and let you compile it, but they didn't; they are keeping the source code secret, so they've given it all to you after compilation, so that you can't read it.
"Embedded" means: to be included inside your app bundle, by copying them into it at build time.
So, they are handing you some compiled code (frameworks) and telling you how to include them inside your app bundle. These frameworks, unlike Cocoa's frameworks, do not already exist on the device, so if you don't include them inside the app, they won't be present and your app would be unable to call into them.
Contrast this to Cocoa's frameworks. They, too, are compiled code. But they do already exist on the device. Therefore they are not embedded inside your app; they are merely linked (and, if they appeared, would appear in the next group, Linked Frameworks and Libraries).
Embedding binaries copies the entire framework to the target.
A framework is a hierarchical directory that encapsulates a dynamic
library, header files, and resources, such as storyboards, image
files, and localized strings, into a single package. Apps using
frameworks need to embed the framework in the app's bundle.
So, when you embed a framework in your app, it increases the size of your app because it is copied to you app bundle. In most of the scenarios we will be using this sections when we are using third party framework.
When we add a framework to Embedded Binaries it automatically adds that framework to Linked Frameworks and Libraries also.
Refer to apple documentation for more details: https://developer.apple.com/library/archive/technotes/tn2435/_index.html

install app on mac with shared libraries outside bundle

I am working on a Qt app with some library dependencies, for which I will have to make an installer.
From everything I read, seems like the best way is to make a bundle app with all library dependencies, and the required Qt frameworks, inside myapp.app/Contents/Frameworks
There are other applications created in parallel... that will get to be deployed on mac as well. They will have the same library dependencies and will be built using the same Qt version.
In that case it makes sense for the libraries and Qt to be installed OUTSIDE the bundle... so both (all) apps have access without having multiple copies of the same libraries.
Does that seem reasonable - and do-able with mac osx concept of bundle islands ? And how would I create such an installer that places libraries outside the app bundle ?
The simplest method of deploying Qt for OS X is to use the macdeployqt command line tool, and you have identified correctly that the normal method is to place the frameworks inside the app bundle, but multiple apps will each have copies of the frameworks.
It is reasonable to suggest moving the Qt frameworks to a separate, external location and linking to that instead. However, you will need to manage the framework carefully, especially when it comes to providing updates and be aware that if the framework is removed or altered, all your applications will fail to load. This, however is the same for any framework dependent application.
The thing to consider is where to place the framework. Normally, external frameworks reside in /Library/Frameworks, but if we all start to use that for Qt, problems may occur when your app is installed and another developer installs their app's frameworks with a different version of the libraries.
Apple defines various 'key directories' for applications and initially, the most likely location would appear to be the "Application Support Directory", but the documentation states that this is for: -
any type of file that supports the app but is not required for the app to run
This location is often used for support files, such as templates for the user to select.
If your application is to be deployed via the Apple Store, I wouldn't be surprised if it is rejected if you use this location. However, you're not using the Apple Store, then you could deploy the frameworks here.
If the Apple Store is your method of deployment, then /Library/Frameworks is probably the only place acceptable for the Qt framework to reside, with the possibility of the problems I've mentioned above.
Alternatively, consider just how many applications you're developing and is it really an issue to bundle the frameworks multiple times against the advantages that it brings, such as allowing the user to cleanly remove the application and all of its dependencies, as well as reducing problems of the framework being altered or removed accidentally?
If you choose to move them externally, you can refer to the answer to this question, which comprehensively explains how to make installer packages, after having updated your binary dependencies on the frameworks with the install_name_tool, as outlined here.

What are the advantages/disadvantages of Cocoa frameworks, libraries, and bundles?

I have the following requirement.
I need to implement dll kind of thing on mac.I need to create a backend library which can be loaded dynamically.This backend library will contain the cocoa classes and c++ classes.
What is advantage/disadvantage of cocoa framework,I was googling so far,I was not able to figure out the best one.Please give me some suggestion.Is cocoa framework also loaded dynamically?
The main difference between a dynamic library and a framework is that a framework can contain resources (images, sound files, nibs, etcetera) and header files. When you use a dynamic library, these are separate.
Both a framework and a dynamic library are loaded at runtime. If your library will only be used on Mac OS X, I recommend creating a framework because it is easier to manage since everything is in one folder.
Bundles (the white LEGO bricks) are almost exclusively used as plug-ins. If you want to create a plug-in interface you should accept bundles and you should provide a framework the bundles can link against. Bundles are also loaded at runtime.
Here's a decent tutorial (PDF form) that goes a little more in depth explaining the differences between ordinary libraries and frameworks.

Including a framework without embedding it in the app bundle

I'm still not 100% sure with the framework linking process, but from what I've seen here before nobody has asked a similar question, perhaps because this could be a silly question, but I'll give it a go anyway.
In my current X-Code project, I'm using a custom framework, say example.framework. At the moment, as far as I'm aware of, in order for the program to function with the framework, I need to have it either in /Library/Frameworks, or I need to have it copied into the bundle resources in the build phase.
Would anybody know about adding a framework to a project in a way that it gets compiled into the executable, so I don't have to include the raw framework with the app? I'd rather not share the whole framework...
Thank you in advance! Any suggestions are also welcome!
A Mac OS X framework is basically a shared library, meaning it's a separate binary.
Basically, when your main executable is launched, the OS will load the framework/dylib into memory, and map the symbols, so your main executable can access them.
Note that a framework/dylib (bundled into the application or not), does not need to contain the header files, as those are only needed at compilation time.
With Xcode, you can actually decide whether or not to include the header files, when you are copying the framework to its installation directory (see your build phases).
If you don't copy header files, people won't be able to use your framework/dylib (unless they reverse-engineer it, of course).
If you still think a framework is not suitable for your needs, you may want to create a static library instead.
A static library is a separate object file (usually .a) that is «included» with your final binary, at link time.
This way, you only have a single binary file, containing the code from the library and from your project.

Resources