Building Modern Frameworks says every app has its own copy of a custom framework. Now that Xcode supports iOS frameworks, is it still true that frameworks are static libraries but just more convenient? If that's true, then why choose the static library template? Otherwise, should I convert all my required custom frameworks to static libraries once Swift supports static libraries?
Frameworks serve the same purpose as static and dynamic shared
libraries, that is, they provide a library of routines that can be
called by an application to perform a specific task. For example, the
Application Kit and Foundation frameworks provide the programmatic
interfaces for the Cocoa classes and methods. Frameworks offer the
following advantages over static-linked libraries and other types of
dynamic shared libraries:
Frameworks group related, but separate, resources together. This grouping makes it easier to install, uninstall, and locate those
resources.
Frameworks can include a wider variety of resource types than libraries. For example, a framework can include any relevant header
files and documentation.
Multiple versions of a framework can be included in the same bundle. This makes it possible to be backward compatible with older
programs.
Only one copy of a framework’s read-only resources reside physically in-memory at any given time, regardless of how many
processes are using those resources. This sharing of resources reduces
the memory footprint of the system and helps improve performance.
This excerpt taken from here.
Excerpt taken from here.
How are Frameworks and Library Different from each other?
Inversion of Control is a key part which makes a framework different from a library. When we call a method from a library we are in control, but with the framework the control is inverted, the framework calls our code. (E.g a GUI framework calls our code through the event handlers)
A library is essentially a set of functions (well defined operations) that we can call (organized into classes). Each does some work and then returns the control to the client
A framework embodies some abstract design with more behavior built in. In order to use it, we need to insert our behavior into various places in the framework either by subclassing or by plugging in our code. The framework code then calls our code at these points.
A framework can also be considered as a skeleton where the application defines the meat of the operation by filling out the skeleton. The skeleton still has code to link up the parts
The use of dynamic frameworks is exclusively for swift from iOS 8 and later, i.e (you can't submit a build with iOS 7 and a dynamic framework)
If you want support for iOS 7 and before you can use a static library and objc
A dynamic framework and a static library are different things, a framework is a bundle where you have a directory and can include resources, views, classes, and also libraries
A static library is only executable code
Also you use the code in a static library inside your own code, in the case of a framework he use the code and handle the way it runs and what do
This link could help you
http://www.knowstack.com/framework-vs-library-cocoa-ios/
Related
I have main application target. And I'm moving some code into frameworks to reduce compile time of the huge project.
Default framework type is Dynamic (BuildSettings -> Mach-O Type). I understand benefits of using Apple's dynamic frameworks as several apps will use the same framework and each application size will be lower (because the app size doesn't include this dynamic frameworks).
But if I'm using my own frameworks and only in my application, why should I choose dynamic frameworks.
It looks like the app size will be bigger with dynamic frameworks Source and application start time will be longer (because it needs to connect all these dynamic libraries, but with static they are already a part of app executable).
App store size probably will be bigger as well with dynamic frameworks as well.
Would be helpful if somebody can fill me in what benefits can we get using dynamic frameworks 🤝
Your assessment is mostly correct.
It is possible to not directly link against frameworks, but instead load them on demand with dlopen.
This can be used both for a plugin system where only one of many available libraries will be needed, or to defer the loading of particularly heavy frameworks, which would actually reduce the launch time of your app.
Further reasons I can think of for using dynamically linked frameworks are:
Licensing reasons.
If you're developing a closed-source library for other developers to use, then a static library normally has a lot more information still embedded than a dynamic library and with a static library you can easily conceal the fact that you're using it, both of which you might not want.
If you have symbol clashes (e.g. due to linking against a static library multiple times, as might be the case with the Rust standard library), then you can split the different codebases into frameworks in order to separate the namespaces.
I feel weird about difference between advantage of dynamic linking library in Window or Linux and iOS.
⬇️ sentences below are to prove why I feel weird.
I learned that library can divided into static library and dynamic library
Advantage of using dynamic library is allow other application to use same dynamic library ( in Window, .dll file) so that each of application memory usage can be reduce and it can be easiar to redistribute dynamic library rather than to redistribute application.
Actually I could have experienced "there is no XXX.dll file" in using some applications
And in Xcode, when to create new project, we can choice framework and static library in framework & library.
And after creating project, we can choice how to being what Mach-O Type is like "Executable, Dynamic Library, Static Library" etc..
So, I think that if I choice Mach-O type with Dynamic Library, the project will be compiled using dynamic linking library in linking way.
⬇️ I really wonder about.
But like in Window, Could iOS user downloads .so file in their iPhone in order to work normally app or update dynamic library?
Could others app launched in iPhone use same dynamic library ?
Because I could't experience about that.
If it(1,2) can't be, why to use dynamic library even we couldn't get actual advantage of using dynamic library like in Window or Linux ?
Your understanding of dynamic and static libraries is correct.
Static Linking
The compiled source code (object code, the .o files) and the compiled library code are combined into a single executable [1]
Dynamic Linking
The compiled source code (object code) and the library code are not combined together. The references to the dynamically linked library are resolved at runtime while the app launches or while running (the second part is not applicable in the case of iOS Apps) [1]
Q1
iOS borrows heavily from MacOS on how its applications work. Executables in both the OSes are Mach-O files. Now, on macOS dynamically linked libraries or dylibs are intended and designed to be updated without having to update the entire app. And by design, this is possible in iOS as well. What prevents this is Apple's guidelines restricting apps from downloading executable code from the internet. Any new update has to go through their review process. [2]
Q2
Yes, some dynamically linked libraries are shared across apps. However, they are created and updated by Apple through iOS updates. All Apple frameworks like UIKit, SceneKit, etc are examples of this. This is why these frameworks are weakly linked in Xcode with the option 'Do Not Embed'
Q3
Using your own dylibs are not completely pointless. If you ship extensions in your app, then dylibs are an excellent option to share code between the app and extensions without increasing the binary size. In this case, the executables share the same library. [3]
[1] https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html#//apple_ref/doc/uid/TP40001873-SW1
[2] https://developer.apple.com/app-store/review/guidelines/#app-completeness#2.5.2
[3] https://developer.apple.com/forums/thread/73802
[Vocabulary]
But like in Window, Could iOS user downloads .so file in their iPhone in order to work normally app or update dynamic library?
Dynamic library in iOS world is .dylib and they are updated along with OS updates. As an example Swift standard library[About] has a copy in every app before ABI OS stability[About]. But you cannot still download .dylib manually
Could others app launched in iPhone use same dynamic library ?
Of course. For example core libraries(runtime(Objective-C, Swift), Foundation)... distributed as dynamic libraries to share binaries through different applications and processes(IPC)
If it(1,2) can't be, why to use dynamic library even we couldn't get actual advantage of using dynamic library like in Window or Linux ?
You are able to create a dynamic framework with dynamic library inside(from iOS v8) which can be used for extensions(share some code inside different application)
In one of the answers for a question on iOS Framework vs. Static Library, yoAlex5 quoted,
A Library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.
A Framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework's code then calls your code at these points. The main control of the program is inverted, moved away from you to the framework. (Inversion of Control)
Could anyone please give any example for iOS with minimal code snippet where I can understand how Static Library cannot support inversion of control when a Framework can?
In the accepted answer to the question that you cited, the following is mentioned:
Hence on iOS, your only option is basically to use a static library or
static framework (the main difference being that a static framework is
distributed as a compiled .a file most often, whereas a static library
may simply be included as a subproject - you can see all of the code -
which is compiled first and its resulting .a file used as a dependency
by the project).
So the main difference on iOS actually is that normally a framework is used in compiled form, whereas a library is used as code. Therefore both support in principle inversion of control.
However, even if everything a framework can, could also be provided by a library, one should definitively restrict certain functionality to frameworks. Wiki says:
Frameworks have key distinguishing features that separate them from
normal libraries:
• inversion of control: In a framework, unlike in
libraries or in standard user applications, the overall program's flow
of control is not dictated by the caller, but by the framework.
• extensibility: A user can extend the framework – usually by
selective overriding – or programmers can add specialized user code to
provide specific functionality.
• non-modifiable framework code: The
framework code, in general, is not supposed to be modified, while
accepting user-implemented extensions. In other words, users can
extend the framework, but cannot modify its code.
I support a suite of related iOS apps, some of which make use of extensions (WatchKit and Today Widget). All of these apps and extensions make use of a shared private framework I've built up over time for handling certain workflows around authentication and common business logic. This framework is maintained as a private pod.
Recently, I've run into a problem where I'd like to add a method to the framework that's only really useful for the iOS apps (extensions don't need it) that uses certain APIs that are unavailable to extensions (such as [UIApplication sharedApplicaion]). I'd like to get the usual benefit of shared code, where this is implemented in only one place (the shared framework) for all my various apps to leverage. However, I can't find a way to conditionally include that method for just the apps and not the extensions without getting a compile-time error.
Normal recommendations around this problem usually suggest the use of a preprocessor macro to opt-out around the problematic code if desired, but that doesn't really work for a shared framework situation. Macros are applied at compile-time, so the shared framework is either going to include that method, or not, and there doesn't seem to be a runtime solution to optionally exclude it. If it's included, the extensions can't compile. If it's not included, my apps can't make use of the feature.
I also started investigating if there was some way that Cocoapods could automatically make two versions of the framework, one to be used by the apps, and one by the extensions, but this would seem to introduce problems around duplicate symbols, and generally doesn't seem supported.
Are there any other suggestions for how to handle this, apart from just extracting out the problematic functionality into a different framework? (I really would prefer to just share one)
Recently I started to modularize my applications much more aggresively than I used to, separating pieces of code into frameworks or libraries.
I like the concept of “private frameworks” in desktop Cocoa, ie. the frameworks included in the application bundle. From my small experience the frameworks are better suited for code reuse than simple libraries, as the frameworks can include their own headers with them. This makes adding a new framework to an existing project a whole lot easier.
The problem is that these “private” frameworks are not supported on iOS. You have to do with static libraries there, and the header management is a pain. Is there a good technical reason for Apple to not support frameworks on iOS?
(Just to make sure: Apple unfortunately uses the term “private framework” for two things. The first is “custom” frameworks that ship with an application, the second is undocumented and prohibited frameworks that people are not supposed to use on iOS. I’m asking about the former.)
PS. Did this change in iOS 8? There’s a “Cocoa Touch Framework” template in Xcode 6.
It appears that custom frameworks are now supported by Xcode 6:
iOS developers can now create dynamic frameworks. Frameworks are a
collection of code and resources to encapsulate functionality that is
valuable across multiple projects. Frameworks work perfectly with
extensions, sharing logic that can be used by both the main
application, and the bundled extensions.