Xcode
Prefix.pch
iOS development
Swift
Objective-C

What is Prefix.pch file in Xcode?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you have worked on an older Objective-C project in Xcode, you have likely encountered a file called Prefix.pch. The .pch extension stands for "precompiled header." This file lets you declare imports and macros that are automatically available in every source file of your project without writing explicit #import statements in each one. While modern Swift projects have largely moved past this pattern, understanding Prefix.pch is still important for maintaining legacy codebases and for knowing how Xcode's build system optimizes compilation.

What the Prefix.pch File Does

The Prefix.pch file is a header that Xcode compiles once and then implicitly includes at the top of every source file in your project. This has two main benefits.

First, it eliminates repetitive imports. If every .m file in your project needs UIKit or Foundation, you can put those imports in the Prefix.pch file once instead of repeating them in hundreds of files.

Second, it speeds up builds. Because the contents of this file are compiled into a binary format ahead of time (hence "precompiled"), the compiler does not need to re-parse those headers for every source file. On large Objective-C projects with many shared headers, this can reduce build times noticeably.

Typical Prefix.pch Contents

Here is what a standard Prefix.pch file looks like in an iOS Objective-C project.

objc
1#ifdef __OBJC__
2    #import <UIKit/UIKit.h>
3    #import <Foundation/Foundation.h>
4    #import "AppConstants.h"
5    #define APP_VERSION @"2.1.0"
6    #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
7#endif

The #ifdef __OBJC__ guard ensures that these Objective-C imports are only processed when compiling Objective-C files. If your project contains any C or C++ files, they would fail on #import syntax without this guard.

How Xcode Uses the Prefix Header

Xcode's build settings include a field called "Prefix Header" (the build setting key is GCC_PREFIX_HEADER). When this is set to a file path (for example, MyApp/Prefix.pch), the compiler automatically prepends that file's contents to every compilation unit.

There is also a companion setting called "Precompile Prefix Header" (GCC_PRECOMPILE_PREFIX_HEADER). When set to YES, Xcode compiles the prefix header into a binary .pch.gch file once, then reuses that binary for every source file. This is what gives the build speed improvement.

You can check these settings in Xcode by navigating to your target's Build Settings and searching for "prefix."

Adding a Prefix.pch to a New Project

Starting with Xcode 6, Apple stopped generating a Prefix.pch file for new projects by default. If you need one, you can create it manually.

  1. Create a new file in your project. Choose "Header File" and name it PrefixHeader.pch.
  2. Add your common imports and macros to the file.
  3. Open your target's Build Settings.
  4. Search for "Prefix Header" and set the value to the path relative to your project root, such as MyApp/PrefixHeader.pch.
  5. Set "Precompile Prefix Header" to YES.
objc
1// PrefixHeader.pch
2#ifndef PrefixHeader_pch
3#define PrefixHeader_pch
4
5#ifdef __OBJC__
6    #import <Foundation/Foundation.h>
7    #import <UIKit/UIKit.h>
8#endif
9
10#endif

After a clean build, every source file in the target will have access to the imports defined in this file.

Why Swift Projects Do Not Use Prefix.pch

Swift replaced the precompiled header pattern with modules. When you write import UIKit in a Swift file, the compiler loads a precompiled module binary rather than parsing raw header text. This achieves the same build performance benefit without needing a global prefix file.

Swift's module system also provides better encapsulation. Each file explicitly declares what it imports, making dependencies clear. With Prefix.pch, all imports are implicit, so it can be hard to tell which frameworks a particular file actually depends on.

For mixed Objective-C and Swift projects, the Prefix.pch only applies to the Objective-C source files. Swift files are unaffected by it.

Common Pitfalls

  1. Putting too much in the Prefix.pch. It is tempting to add every header your project uses, but this increases the precompiled header size and creates hidden dependencies. When you eventually remove or refactor a framework, many files break because they relied on the implicit import. Keep the file lean, limited to truly universal imports like Foundation and UIKit.
  2. Forgetting the OBJC guard. Without the #ifdef __OBJC__ wrapper, C and C++ files in your project will fail to compile because they do not understand #import. Always wrap Objective-C-specific imports in this guard.
  3. Not cleaning after changes. When you modify the Prefix.pch file, the precompiled binary can become stale. Run Product > Clean Build Folder (Shift+Cmd+K) after editing the prefix header to avoid confusing build errors.
  4. Assuming it works in Swift. The Prefix.pch file has no effect on Swift source files. If you are working in a mixed-language project, do not rely on it for Swift code. Use bridging headers and module imports instead.
  5. Ignoring per-target scope. The prefix header setting is per-target in Xcode. If your project has multiple targets (app, tests, extensions), each target needs its own prefix header configuration or none at all.

Summary

The Prefix.pch file in Xcode is a precompiled header that provides global imports and macros across all Objective-C source files in a target. It reduces redundant imports and speeds up compilation by precompiling shared headers into a binary format. Apple removed it from new project templates starting with Xcode 6, and Swift's module system makes it unnecessary for pure Swift projects. For legacy Objective-C codebases, keep the file minimal, use the __OBJC__ guard, and clean your build folder after modifications.


Course illustration
Course illustration

All Rights Reserved.