266

Why isn't ProjectName-Prefix.pch created automatically in Xcode 6 ?

Is the precompile header no longer needed ?

Where should I write the code that was in ProjectName-Prefix.pch before ?

neowinston
  • 6,762
  • 9
  • 49
  • 80
Wei
  • 3,492
  • 4
  • 16
  • 18

8 Answers8

426

Without the question if it is proper or not, you can add PCH file manually:

  1. Add new PCH file to the project: New file > Other > PCH file.

  2. At the Target's Build Settings option, set the value of Prefix Header to your PCH file name, with the project name as prefix (i.e. for project named TestProject and PCH file named MyPrefixHeaderFile, add the value TestProject/MyPrefixHeaderFile.pch to the plist).

    TIP: You can use things like $(SRCROOT) or $(PROJECT_DIR) to get to the path of where you put the .pch in the project.

  3. At the Target's Build Settings option, set the value of Precompile Prefix Header to YES.

Community
  • 1
  • 1
Yedidya Reiss
  • 5,307
  • 2
  • 15
  • 19
  • 32
    Despite my opinions on PCH files, +1. It is still useful for people to know how to use the tools. – Rob Napier Jul 20 '14 at 02:28
  • 20
    @Yedidya, I just wanted to say a quick thanks for taking the time to communicate the answer to the question despite whatever judgements you have about it. I appreciate when people take the time to cordially answer questions rather than just berate the person about how ill advised the question is. – campo Oct 14 '14 at 16:57
  • 3
    Thanks. I find it useful when incorporating some of my Objective-C into a Swift project, so I don't have to go back and add a bunch of include files to each of those .m files. – Chris Prince Dec 26 '14 at 04:53
  • Very handy when transitioning from ObjC to Swift - I have a heap of libraries written in ObjC and the last thing I want to do is edit all of them to include the right system headers. – Echelon Jan 15 '15 at 11:53
  • 1
    This didn't work for me cause I used the target's build settings. However, when I followed this instructinos modifying the Project Build Settings instead everything worked. – Pauls Feb 12 '15 at 11:44
  • This is the real answer. – GoldenJoe Jun 16 '15 at 02:05
  • @GoldenJoe no, it's not. This "answer" is useful but does not answer the OP's question: **WHY** isn't ProjectName-Prefix.pch created automatically in Xcode 6?? – Alejandro Iván Jun 26 '15 at 15:05
  • Prakash's answer is even better! – Fattie Aug 13 '15 at 02:39
137

I suspect because of modules, which remove the need for the #import <Cocoa/Cocoa.h>.

As to where to put code that you would put in a prefix header, there is no code you should put in a prefix header. Put your imports into the files that need them. Put your definitions into their own files. Put your macros...nowhere. Stop writing macros unless there is no other way (such as when you need __FILE__). If you do need macros, put them in a header and include it.

The prefix header was necessary for things that are huge and used by nearly everything in the whole system (like Foundation.h). If you have something that huge and ubiquitous, you should rethink your architecture. Prefix headers make code reuse hard, and introduce subtle build problems if any of the files listed can change. Avoid them until you have a serious build time problem that you can demonstrate is dramatically improved with a prefix header.

In that case you can create one and pass it into clang, but it's incredibly rare that it's a good idea.


EDIT: To your specific question about a HUD you use in all your view controllers, yes, you should absolutely import it into every view controller that actually uses it. This makes the dependencies clear. When you reuse your view controller in a new project (which is common if you build your controllers well), you will immediately know what it requires. This is especially important for categories, which can make code very hard to reuse if they're implicit.

The PCH file isn't there to get rid of listing dependencies. You should still import UIKit.h or Foundation.h as needed, as the Xcode templates do. The reason for the PCH is to improve build times when dealing with really massive headers (like in UIKit).

Rob Napier
  • 250,948
  • 34
  • 393
  • 528
  • I agree to make the `.pch` file clean, but I'm confused in some situation, e.g. I use `SVProgressHUD`, almost all `ViewController` need to call it, so should I import `SVProgressHUD.h` in every `ViewController` ? or create a `BaseViewController` and import `SVProgressHUD.h` ? `Category`s have the same situation. Could you give me any suggestion? – Wei Jun 13 '14 at 08:16
  • 102
    @Rob your answer is subjective rant. I do not agree it should be accepted as an answer for this question. How would you implement something like this https://github.com/seancook/TWReverseAuthExample/blob/635d02f76b2ccf7f8574429a624cb41a5ece552e/Source/Other/TWiOSReverseAuthExample-Prefix.pch#L24 without pch ? Import the log into each and every file? This creates a whole pile of unnecessary bloat in your code. – Maxim Veksler Jul 18 '14 at 12:42
  • 26
    Each file that actually uses that macro, yes (in my experience this is usually less than every file in the system). This is a very good example of my point. Importing it implicitly masks the fact that you have a dependency on this logging macro. When you try to copy `TWAPIManager.m`, for example, to a another project, you'll get errors that `TWALog()` is not defined, with no hint about where to find it. I've encountered exactly that problem on several large projects trying to share code. Creating `TWAPILog.h` and importing it solves this with trivial dev cost. – Rob Napier Jul 18 '14 at 15:33
  • @RobNapier In the case of importing `UIKit`, though, what if you wanted to create a class that implements the `UITableViewDelegate` protocol? Would you `@import UIKit` for just that class, or would this be a necessary case for a PCH? Your answer, "as needed", isn't really clear. – sethfri Jul 20 '14 at 01:24
  • If you need UIKit functionality in a class, it import UIKit. If you don't, it should import Foundation. If you need AppKit functionality, you would import Cocoa. That keeps the code more reusable (I share a lot of code between iOS and OS X and recommend people not box themselves out of that for no purpose). You would still include UIKit in the PCH (when modules are not available), but only to improve build times. – Rob Napier Jul 20 '14 at 02:27
  • 5
    I use ReactiveCocoa in almost every class, it would be insane for me not to use a pch file... – Stefano Mondino Sep 30 '14 at 09:46
  • I'm with Rob on this, importing where needed is the cleanest clearest path to managing dependencies. If you *really* need to manage things simpler, you probably want to look at your own Framework (still need to import that puppy where it is used) or even a module... – uchuugaka Oct 18 '14 at 16:44
  • 2
    Not only modules, but swift support is probably a big piece. – uchuugaka Oct 18 '14 at 16:45
  • @Rob How would you do Crash Reporting, like New Relic's without adding it to PCH? They really need to be in everything so you can see where the bug came from. – Samin Nov 05 '14 at 19:10
  • I don't see how crash reporting is related. Importing a header file just declares functions and classes for you. It doesn't actually cause anything to run. Do you make specific `NewRelic` calls in every single file? That would seem very strange. Looking at their docs, I only see one call required to their library (which is what I would expect). Have you tried without putting them in pch? – Rob Napier Nov 06 '14 at 02:09
  • How about categories? Imho, its stupid to have to import a dozen files or so in each view controller for example, if you happen to have a lot of categories. – Andrei Nov 11 '14 at 11:20
  • 12
    The key is that PCH is a *pre-compiled header*. Pre-compilation is for build performance, not automatic availability. Pre-compilation introduces several ways to mess up your build, and should be reserved for huge things that *never* change between non-clean builds (like Foundation). – Rob Napier Nov 11 '14 at 14:19
  • Rob .. bizarre that you don't use Macros, buddy ! Programming without a preprocessor is like, uh, well it's no good. – Fattie Aug 13 '15 at 02:26
  • Everything else Rob says here is correct of course. – Fattie Aug 13 '15 at 02:39
  • 1
    What about macros to remove NSLog for a release configuration? – shim Jan 22 '16 at 15:52
  • 2
    @shim I always use my own logging macro that can be removed or reconfigured in different configs. Put that macro in a header; import the header where you use it. Even if I believed in using pch for that kind of macro, I would never write a macro to redefine NSLog itself. Rewriting standard functions is very confusing. – Rob Napier Jan 22 '16 at 16:17
  • @Rob, I wanted to ask what should be done if there is let say a constants file, which I know will be used through out the project ? Is there an alternative to using prefix or using prefix for such a small file is ok ? – Abdul91 Sep 30 '16 at 09:48
  • @Abdul91 generally constants should be kept together with the things they configure (in the same file, or in a closely related file imported by the configured object's header) and imported by those things they use them. In general, there shouldn't be a "system constants" file filled with unrelated constants. This is very harmful to code reuse. Most constants like "MySpecialColor" should be categories (on UIColor in this case). And styles and layouts should be passed as objects or active configurators that group related things when possible rather than relying on global standalone constants. – Rob Napier Sep 30 '16 at 10:17
  • @Rob, hmmm aight thanks, I think i got the gist of it. – Abdul91 Sep 30 '16 at 10:23
  • Sure, Rob. like logging. DLog is certainly something that should go in a .pch, unless you offer an alternative. You state that modules make a pch irrelevant, but you don't say why. The convenience we want the .pch for is simply so that we DO NOT HAVE TO import another header everywhere for something we want to be available everywhere. – Alex Zavatone Dec 13 '16 at 23:46
129

You need to create own PCH file
Add New file -> Other-> PCH file

Then add the path of this PCH file to your build setting->prefix header->path

($(SRCROOT)/filename.pch)

enter image description here

Inder Kumar Rathore
  • 37,431
  • 14
  • 121
  • 176
Prakash Raj
  • 1,935
  • 1
  • 14
  • 13
51

I'll show you with a pic!

  1. Add a new File Add a new File

  2. Go to Project/Build Setting/APPl LLVM 6.0-Language Add a new File

Alex McMillan
  • 13,847
  • 6
  • 47
  • 76
Slemon
  • 781
  • 7
  • 12
24

To add .pch file-

1) Add new .pch file to your project->New file->other->PCH file

2) Goto your project's build setting.

3) Search "prefix header". You can find that under Apple LLVM.

4) Paste this in the field $(SRCROOT)/yourPrefixHeaderFileName.pch

5) Clean and build the project. That's it!!!

enter image description here

Subham93
  • 625
  • 8
  • 14
12

If you decide to add a .pch file manually and you want to use Objective-C just like before xCode 6 you will also have to import UIKit and Foundation frameworks in the .pch file. Otherwise you will have to import these frameworks manually in each header file. You can add the following code anyway as it tests for the language used:

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif
mgm
  • 1,238
  • 13
  • 16
  • 2
    Everything which involves ObjC code must be wrapped inside the above #ifdef _ _OBJC_ _, otherwise you will get errors from C sources (in case you have such sources) that you will never understand – ishahak Oct 20 '15 at 03:59
7

For add new PCH file follow bellow steps :

(1) Add New fiew - Select iOS - Other and PCH File

(2) add path of this PCH file to your Project - BuildSetting - Apple LLVM 6.0 Language

Add Set Prefix Header Path YourApplicationName(root-path)/filename.pch

Nilesh Patel
  • 6,060
  • 1
  • 23
  • 40
Hitesh Vaghela
  • 1,625
  • 1
  • 11
  • 11
7

Use :

$(PROJECT_DIR)/Project name/PrefixHeader.pch

Arash Zeinoddini
  • 801
  • 13
  • 19