I'm building a Cocoa Touch Static Library. How should I decide whether to copy a header file as public, private, or project?
3 Answers
Public: The interface is finalized and meant to be used by your product’s clients. A public header is included in the product as readable source code without restriction.
Private: The interface isn’t intended for your clients or it’s in early stages of development. A private header is included in the product, but it’s marked “private”. Thus the symbols are visible to all clients, but clients should understand that they're not supposed to use them.
Project: The interface is for use only by implementation files in the current project. A project header is not included in the target, except in object code. The symbols are not visible to clients at all, only to you.
Source: Xcode Developer Library > Tools & Languages > IDEs > Project Editor Help > Setting the Visibility of a Header File

- 1
- 1

- 6,846
- 6
- 43
- 54
-
Randy - You should merge the Power's answer into yours to make it it a better single answer, imho. – Chris Markle Sep 05 '12 at 20:40
-
This is incorrect. Apple may have documented that - but they didn't implement it. "Public" headers WILL PREVENT YOU distributing your app (bug in Xcode) unless you de-couple your projects (no embedding of project files!) – Adam May 14 '13 at 16:18
-
2Does anyone know WHERE THE HECK are those options for header files in XCode 5?! – mindbomb Oct 30 '13 at 17:48
-
@mindbomb You can find them in the File Inspector under 'Target Membership'. – NoilPaw Nov 04 '13 at 14:17
Randy's answer is good and gives you all the relevant background. I wanted to add some info to help you based on how you expect your library will be used.
PROJECT: If you are distributing your project, and expect users to include your project as a sub-project in their own, you should ensure your headers are marked as 'project'. Not doing so will lead to issues like this: Xcode 4 Archive Version Unspecified
Note that this applies to every sub-project...including sub-projects of sub-projects, recursively.
PUBLIC: If you expect users of your library to only link against your object (and NOT have your original project), make sure your headers are marked as 'public' (only for headers they'll need to refer to).

- 1
- 1

- 686
- 7
- 12
-
1And the most important point here is to remember: Apple currently makes it impossible to simply "distribute a library" and let your users decide how to use it, because of the bug referenced above (bug in xcode: if a library has public headers, and is embedded, Xcode archiver breaks with no workaround) – Adam May 14 '13 at 16:16
-
4@Adam, if you're talking about a bug in Xcode, please include the release number. SO answers stick around a long time, and a bug now isn't going to be a bug after $SOME_RELEASE. – James Moore Jun 27 '13 at 17:31
-
@JamesMoore SO is designed to cope very well with answers that change over time - I don't see a problem here. Besides that ... when Apple starts issuing release notes for Xcode (I believe most Xcode changes are removed from the release notes before apple publishes them), and starts admitting to the known bugs, we'll have time to do these updates manually. Until then, it's way too much effort to constantly edit and re-edit and re-check the many SO posts that relate to the main bugs on Xcode. – Adam Jun 28 '13 at 11:21
-
1@JamesMoore ... version? All from 1 to 5.1 and counting. I have reported this and other 20 bugs like that during the last 12 months. A new version of Xcode (5) was released and as a bonus we still have all bugs. Some of my bugs were marked as duplicate and nothing was done. They decided to improve the interface instead. Today, my Xcode 5.1 crashed 12 times.... and counting. – Duck Oct 28 '13 at 17:58
-
@William Power If a public header includes a header file HeaderB.h, and HeaderB.h includes another header file HeaderC.h, what should be the visibility of HeaderB.h, HeaderC.h. According to me, all the headers which are visible in public header file, but won't be directly included in the project will be marked as Private and all the headers that are included in these Private headers can be marked as Project Header. I am linking the library instead of including it as a subproject. – Deep Arora Apr 30 '16 at 15:03
-
@DeepArora In general I'd recommend against importing anything except required Apple frameworks (Foundation, UIKit) in any .h files. If you need your header to refer to some other class, you can use @ class forward declarations. Your .m file should import what it needs. As an aside, it can be hard to track down unwanted/accidental imports, so it's worth being deliberate about from the start. ;) – William Power Apr 12 '17 at 02:03
Objective-C Headers: Public, Private, Project
[Objective-C static library manual]
[Target Membership]
public - API which is exposed for consumer
private - API which is exposed for consumer but it is risky to use it
project - API is not visible for consumer. A kind of encapsulation on module level
File structure
ClassA.h - public
ClassB.h - project
ClassC.h - private

Headers folder is set by:
Public Headers Folder Path(PUBLIC_HEADERS_FOLDER_PATH)
//default value is
$(CONTENTS_FOLDER_PATH)/Headers
PrivateHeaders folder is set by:
Private Headers Folder Path(PRIVATE_HEADERS_FOLDER_PATH)
//default value is
$(CONTENTS_FOLDER_PATH)/PrivateHeaders

1.To expose Objective-C code for Objective-C or Swift consumers you should use .modulemap
and public headers
//Swift
import SomeModule
//Objective-C
@import SomeModule;
[.modulemap] -> only public headers or error
2.To expose Objective-C code for Objective-C consumer with non-module usage
//Objective-C
//umbrella
#import <ObjCFramework/ObjCFramework.h>
//specific руфвук
#import <ObjCFramework/ClassA.h>
//#import <ObjCFramework/ClassB.h> //error
#import <ObjCFramework/ClassC.h>
when you import a project header you get
Showing All Messages
'ObjCFramework/ClassB.h' file not found

- 29,217
- 8
- 193
- 205