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.
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.
We are developing an SDK in Objective-C and as part of our service to our SDk consumers we have a tool that checks to see if all the required frameworks exist in the develop project.
In order for us to do so we use NSBundle.allFrameworks that should return all of the frameworks and we search for the required framework in the returned result.
We are seeing a weird behaviour with that call that changes between OS versions.
For example when we call NSBundle.allFrameworks on iOS the returned list doesn't contain some of the frameworks such as
MobileCoreServices, CoreGraphics, UIKit, SystemConfiguration
If we run the same call on an iOS 11 device the only framework that is missing is SystemConfiguration.
Is anyone familiar with this behaviour?
We would really love to provide that functionality for our users
According to the docs, it returns:
An array of all of the application’s bundles that represent frameworks. Only frameworks with one or more Objective-C classes in them are included.
And the Discussion section mentions that:
The returned array includes frameworks that are linked into an application when the application is built and bundles for frameworks that have been dynamically created.
This means that frameworks with at least one Objective-C class, and that are bundled within the app/linked against the app, are shown.
e.g. If both the app and the bundled frameworks are not linking against a specific framework, it won't appear in the list.
This is a variant of the old "dyld: Library not loaded: #rpath/libswiftCore.dylib" problem. I'm pretty sure I know what the issue is, but I don't have any ideas on how to fix it.
I'll reference the project I'm working on, so I don't clutter the question with huge blocks of code.
The project generates a dylib that can be thrown into another project, and abstract a huge block of coding for developers (a communication layer of a client/server system).
I want the framework to be as simple as possible to to use; even if that means making it a big fat pig. I just want people to be able to toss it into their project (Swift or ObjC), and not have to worry about playing around with different variants for things like simulators and devices.
I use a variant of the old Wenderlich script to lipo the executables for x86 and ARM together.
Note the commented-out section. There be draggones.
Works great. In Swift.
Objective-C, not so great. That's because of the various Swift frameworks that need to be carried into the Objective-C program.
I switched on the embed frameworks setting, and the target dutifully gives me all my frameworks.
The problem is that each architecture has frameworks for ONLY that architecture. They aren't "fat" frameworks, so my hand-built "fat" framework really is kinda skinny, because it will only work on certain architectures.
My question is whether or not there's a way to ensure that the Swift frameworks I embed can be made "fat," or if I just have to give up, and package different variants of the framework for Objective-C programmers.
Any ideas?
I'm giving up on this sucker.
You cain't git thar f'm here.
This library will be Swift-only.
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/
The first thing I tried is to create a static library but later I found out that it's not supported yet. Apple Xcode Beta 4 Release Notes:
Xcode does not support building static libraries that include Swift
code. (17181019)
I was hoping that Apple will be able to add this in the next Beta release or the GA version but I read the following on their blog:
While your app’s runtime
compatibility is ensured, the Swift language itself will continue to
evolve, and the binary interface will also change. To be safe, all
components of your app should be built with the same version of Xcode
and the Swift compiler to ensure that they work together.
This means that frameworks need to be managed carefully. For instance,
if your project uses frameworks to share code with an embedded
extension, you will want to build the frameworks, app, and extensions
together. It would be dangerous to rely upon binary frameworks that
use Swift — especially from third parties. As Swift changes, those
frameworks will be incompatible with the rest of your app. When the
binary interface stabilizes in a year or two, the Swift runtime will
become part of the host OS and this limitation will no longer exist.
The news is really alarming for me a person who writes components for other developers to use and include in their apps. Is this means that I have to distribute the source code or wait for two years?. Is there any other way to distribute the library without exposing the code (company policy)?
Update:
Is Swift code obfuscation an option at this point ?
Swift is beta now, and even for 1.0 Apple has been pretty clear they're after a restricted feature set -- better to do a small number of things well than to try to do everything.
So for now, there's no way to distribute binary static libraries. Presumably that'll change sometime after Swift 1.0. For now, you can:
Distribute source
Ship a binary framework (instead of a library) if you're okay with the ABI being fragile
Use ObjC for library code
You can always combine approaches, too: e.g., implement the critical (secret) details of your library in ObjC, and ship Swift source that wraps it in a nice Swift API.
Obfuscating code written in a language that's very much subject to change sounds like a recipe for a maintenance nightmare.
I believe the whole approach is wrong. You cannot do something that is not (yet) doable by the technology you are trying to use.
Rationale: Swift is a new language, currently in Beta, and therefore changing. As I see it, this fact means not only that you are not able to ship static libraries, but that (real) developers will not be actually use third-party static libraries. What's the actual use of a library that may not work in the next release of the compiler? The issue gets bigger if you whant to use more than one library, because they might not be compatible! Therefore, even if you would be able to ship static libraries, they wouldn't be actually useful for production environment. So, what's the point?
Suggestion: write your static libraries in Objective-C (or C or whatever "non-beta"). Developers who need third-party libraries (e.g. yours) shouldn't expect them to be written in Swift until Swift is stable. You don't use experimental materials to build real bridges, right? You use well-tested, predictable ones.
From Xcode 9 beta 4, Xcode supports static library with Swift sources.