Difference between framework and static library in xcode4, and how to call them
Asked Answered
U

3

137

I am quite new to xcode and objective-c. I want to ask a very basic question.

I saw that when "linking binary to libraries" in project settings, there are differences about framework and libraries, imported from other projects in workspace.

First question, why is there a framework? And why is there a library? Cannot my library be a framework?

And then, from a .h file, how can I call classes from my imported static library?

I suppose there must be a prefix, but I couldn't find it. Neither nor "ProjName/Myclass.h" are working.

Please, be as specific as you can.

Thanks

Unclasp answered 5/6, 2011 at 20:49 Comment(0)
Y
142

The biggest advantage a framework has over static libraries is that they act as a neat way of packaging up the compiled library binary and any related headers. They can be dropped into your project (just like the SDK's built-in frameworks like Foundation and UIKit) and they should just work (most of the time).

Most frameworks contain dynamic libraries; frameworks created in Xcode using the Mac Framework template will create a dynamic library. The iPhone does not support dynamic frameworks which is why it has become common for reusable libraries of iOS code to be distributed as static libraries instead.

Static libraries are fine, but they require a bit of extra work on the part of the user. You need to link your project to the library and you need to copy the header files into your project or reference them somewhere by setting the appropriate header search paths in your build settings.

So: in summary, my opinion is that the best way of distributing your library is as a framework. To create a "static" framework for iOS, you can essentially take a normal framework and replace the binary with your compiled static library. This is how I distribute one of my libraries, Resty and is how I intend to distribute my libraries in the future.

You may want to look at the supplied Rakefile in that project (in case you aren't aware, Rake is Ruby's equivalent of Make). I have a handful of tasks for compiling my project (using xcodebuild) and packaging them as a static framework for iOS. You should find this useful.

Alternatively, you may wish to use these Xcode 4 templates for creating an iOS framework.

Update 9 Dec 2013: this is a popular answer so I thought I'd edit to say that my first choice for library distribution has changed. My first choice for any third party library as either a consumer or producer is CocoaPods. I distribute my libraries using CocoaPods and offer a precompiled static library with headers as a fallback option.

Yon answered 17/6, 2011 at 17:57 Comment(7)
So libraries can be either static and dynamic, and frameworks are simply a group of libraries, which can also be either dynamic or static, is that the correct understanding?Taco
It seems that Xcode framework target also allows you to copy headers, but not bundle resources. Can distributed static libraries also contain headers?Taco
Follow up question: does it matter if you had built a framework using either Debug or Distribution? Because otherwise Distribution has a smaller footprint.Clincher
@Luke Redpath: Still thinking CocoaPods is the best way to distribute a private SDK? Do you hide your .m source files? When distributing to clients, do you use a private CocoaPod repo and make it available for your clients? I'm thinking to change to Pods, but I'd like to hide the implementation and just expose some headers as the Static Library does.Sievert
@Sievert yes I do; in fact I just did some work for a client making their private SDK available using CocoaPods. The trick is to have a public repo with the compiled static library, headers and podspec pointing at this and a private repo with your source. Ideally you'd have some kind of CI/automation to check out your private repo, compile and update your public repo, keeping the two in sync. Use tags to tag actual versioned releases in the public repo (and probably in the private repo too so you know which source commit was used to create the public release).Yon
@LukeRedpath your solution with CI sounds pretty ideal ...do you know about some good article/blog with some tutorial how to set it up? Ideally with JenkinsPeccant
with swift we can't create static library the only would be creating a framework.so framework is basically collection of static and dynamic libraries but dynamic library we shouldn't use as dynamic linking is opposed to apple rules.so swift project is turned into framework it has to contain static library its quite contradicting.Dockage
C
19

basically, frameworks ARE libraries and provide a handy mechanism for working with them. If you look "inside" a framework, it's just a directory containing a static library and header files (in some folder structure with metadata).

If you want to create your own framework, you have to create a "static library" and pack it in a specific way. see this question

In general, framworks on platforms are used for reusable behaviour where you add your own code "into an existing framework". if you want to have some specific functionality, you may want to use a library (e.g. three20) and pack it into your app distributable

Cordiality answered 5/6, 2011 at 21:10 Comment(5)
Note that there is no requirement that a framework must contain a static library. In fact, on Mac OS X most frameworks do not contain static libraries — they contain dynamic libraries instead.Illbehaved
thanks it's clear, but how can I call a class in a static library from within a .m file ? Is it enough to call #import "MyClass.h", besides adding in "link binaries with libraries" ?Unclasp
@Bavarious you're right i should have written only "libraries" ^^; still, there is nearly any framework without libraries - in most cases, you link against a framework for compiling and the library is present on the target system. this again is this behaviour-vs.-functionality thingCordiality
@Unclasp yes, basically that is what you have to do. Just make sure the .h-files are somewhere in your path. If you have the XCode-project of the libaray, you can include the project and its target as a dependency so you get more debugging features and the .h-files in your pathCordiality
I am confused, I tought your answer was correct, but I saw it marked as "-1" ?!?!?! Second, the library is part of a workspace, and correctly linked from the main project. But I am still getting "class not found" at line '#import "MyClass.h"' when building the application. I know there is a trick for making it working.Unclasp
T
0

First question, why is there a framework? And why is there a library? Cannot my library be a framework?

As a developer you are able to create library or framework, as a result you can use both of them. Framework contains library inside plus resources

[Library, Framework...]

And then, from a .h file, how can I call classes from my imported static library?

You are able to use library, just be sure that you use correct Library Search paths and Header Search Paths to .modulemap and umbrella.h

[Objective-C consumer -> Objective-C static library]

Totten answered 24/9, 2022 at 7:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.