Understanding bundles frameworks and libraries - cocoa-touch

I'm developing ios B2B app and I have several questions regarding app modularization.
Firstly i need to understand main difference between bundles and frameworks. When to use bundles and when frameworks.
Another question is. Is it possible for bundle to contain a .framework inside in it and vice versa.
Is it possible to create a plugins for ios app and load them dynamically, if yes then what it should be? bundle framework or library?
Is it possible for library to contain a resource files ?
Is it possible to create a resource bundle and dynamic library and then load them dynamically at runtime.

Is it possible to create a plugins for ios app and load them
dynamically, if yes then what it should be? bundle framework or
library?
No
Is it possible for library to contain a resource files ?
No
Is it possible to create a resource bundle and dynamic library and
then load them dynamically at runtime.
No
A Bundle is a type of Directory, a folder. A Framework is a bundle. So is an Application and so is a Plugin.
A Static Library is a single file code archive you can compile into your app at build time
A Dynamic Library is a single file code archive you can load at Runtime
A Framework is a Dynamic library in a Bundle with other things
A Plugin is a Dynamic library in a Bundle with other things
The Xcode build option 'Bundle' means 'Place the compiled Dynamic Library in a Bundle' - this is what you do when you want to create a Plugin.
Static libraries are the only option for modularising your code on iOS.
On the desktop..
Typically a Framework is for sharing code and resources between multiple apps. You want your app to behave as though the code was actually compiled into it. You want loading to happen transparently and you don't want to do anything special to use the methods, functions, etc. contained in it.
A Plugin (a Bundle containing compiled code and resources) is for optional, dynamically loaded code, e.g. a software extension that you can choose to load or not. You want to carefully architect your app so that it isn't dependent on the Plugin but acquires new behaviour if you manually locate and load it at Runtime.
A Framework and a Plugin are very similar, but a Framework has a strict file layout to facilitate locating and loading code and resources. With a plugin, these jobs are your responsibility so you can structure the Bundle contents however you want.
Because loading code is so easy in Cocoa on OSX (but not iOS) Frameworks can contain Plugins which contain Frameworks which contain more Frameworks, etc.
On iOS some people put Static Libraries in Bundles with resources and call them Frameworks. This has none of the benefits and all of the drawbacks of a real framework.

Related

iOS: staic framework and dynamic framework?

Recently, I decide to make a framework for login module. I add the image resources to the framework, but I could not get it by code. I change the build the setting. mach-o type static library into dynamic library. I can get the image.
It is easier to make a moudle with dynamic framework than static framework.
but I google and find the dynamic framework made by developer is different with the Apple's dynamic framework. the app contain custom dynamic framework can not upload to Appstore ? Is it true?
who can answer my question? Thank you so much!!!
Dynamic frameworks are extremely common in AppStore apps. What you're probably seeing in posts is that you cannot manually load frameworks at runtime on iOS (i.e. there's no access to dlopen). They all have to be loaded at link time. You also cannot ship "shared" frameworks, where multiple apps share a single copy (like Apple's system frameworks). Each app must contain all of its custom frameworks.
But you can certainly ship dynamic frameworks in your bundle.

Xcode: How to have shared code (i.e. framework) between main project and plugin bundle

In my project I had two targets, 1) The main application which loads 2) a bundle of plugins. I have started to have objects which need to be available in both targets, so naively tried to compile them separately in each target (producing warnings about having different implementations: Class X is implemented in both Y and Z. One of the two will be used. Which one is undefined.)
To solve this I decided to create a framework, so I added a framework, but I don't know how to make it so that a) both the main app and bundle access the framework (via the compiled framework, and not just through the headers in the project), and so the framework is compiled when I run the project.
If you know how to do this, thanks!
Here are the steps I followed:
Create a new framework in the project , copy all the shared code over.
In the main header of the framework, include the headers of all the shared code.
Build the framework to test it builds (e.g. select the scheme of the framework and click play)
Go to the Build Phases of both the Application and the Plugin Bundle and add the framework to ‘target dependencies’ and ‘Link binary with libraries’
To include the frameworks stuff in code in the app and bundle, just use the main header, and use <> rather than “" e.g if your framework was called Foo use #import
When it comes to deploying, there might have to be some fiddling with where the framework gets installed, currently it gets put alongside the app itself, rather than inside, but I will probably fix that later :)

Shared library update

I have my application splited into 4 main parts:
main application (acting like a glue for other parts - load plugins, has linked core and ui libraries)
core (shared library with classes etc., it will be even something like sdk, basically contains all except things related to Ui)
ui (shared library, that contains ui resources, types etc.)
other plugins (shared libraries, loaded by main application, which will use Plugin manager from core
The main reason for this is that i want to have possibility to replace all parts of application just by downloading plugins for my application (through plugin manager window in that application).
Let's say i want to redesign look of my app. In that case i should just release new version of ui shared library/plugin.
I am not sure if it will work, if that ui shared library is linked to my app by linker when application is compiled (core and ui are linked by linker, other shared libraries/plugins are loaded by plugin manager when app is starting).
Question:There will be probably saved some metadata about those libraries in final executable, for instance size?? So i probably can't just replace ui shared library, without need to compile and link my app again?
Generally speaking, you can replace a shared library with an other version of the shared library in distribution (without recompilation of the executable, etc.) in case the original library and the replaced library do have same ABI

Building a distributable static library that uses cocoapods

I'm building a static library to be distributed to other iOS developers and having some trouble configuring the linker to allow the static library to be used in another app. I have used this guide to create a MyStaticLibrary.framework bundle containing the lib itself, and other assets such as images. This builds successfully and uses cocoapods to source the required dependencies (AFNetworking, etc.). So far, so good.
But when I import MyStaticLibrary.framework into a new Xcode project to test build an app with the library, I get tons of linker errors (Undefined symbols for architecture i386, _OBJC_CLASS_$_CLASSNAME) indicating that I'm doing something very wrong here.
So my question is, how can I build MyStaticLibrary.framework with the dependencies sourced from cocoapods, such that I can provide a 3rd party with just my framework file and allow them access to all functions specified in the public headers?
Any libraries you include using CocoaPods will not be compiled into your framework by default - they're meant to be external dependencies that are not part of your actual product. However, according to their FAQ, they support a mode where you can download pods and not have them linked to your project. From their FAQ:
Note that CocoaPods itself does not require the use of a workspace. If
you prefer to use sub-projects, you can do so by running pod install
--no-integrate, which will leave integration into your project up to you as you see fit.
To include external dependencies in your compiled binary:
For code: Instead of using cocoapods, check out the repositories you want to include and copy the source files into your project -- this will ensure they are compiled with the rest of your code
For static libraries (i.e. .a files), in your framework's Link Binary With Libraries build phase, make sure to include all the ones you would like to compile. You should also make sure the associated header files are included in Copy Headers build phase, with the appropriate visibility.
Note When bundling third party libraries in this way, you run the risk of conflicting with the projects that are integrating your framework. For example, let's say you are using a lib called SOSomeView, and you choose to compile that in with your framework. Now, if the app you are integrating with also includes SOSomeView, you will get a compile-time error that the class is declared twice. To fix this issue, you should re-namespace any external dependencies you want to hardcode into your framework (i.e. rename the class to XXSOSomeView).
I don't know how to solve that problem if you are compiling static libraries in with your framework.

Plug-in architecture, access to code in application?

For a project I am doing, I want the Mac application to accept plug-ins. I like the whole idea of just adding Bundles to the application to extend it's functionality.
Only I came across a small question, where I can't find the answer to:
I need to include a JSON parser in my application, for some functionality. Is it possible for a plug-in Bundle to also use that same parser? Or does every plug-in that uses a JSON parser, need to include the parser themselves?
What is the best way to do this for separate Bundles?
On OS X there are two types of loadable things, a dylib and a plugin. (These two terms have specialized technical meaning in the context of mach-o, the binary format OS X uses.)
A loaded dylib can't refer to the libraries in the executable, while a loaded plugin can. As a side effect, a dylib can be loaded to any executable, but a plugin can only be loaded into the executable you specify when you make the plugin.
So you want to make a plugin. There is a template in the XCode to do that. Don't forget to specify the target executable in the linker flag, which can be set somewhere in the inspector.
For more, read Code Loading Programming Topics.