Is There a Prefix Header (Or Something with This Functionality) in Swift

Is there a Prefix Header (or something with this functionality) in Swift?

No. But you don't need it — there's no cost to import UIKit beyond the time it takes you to type twelve characters. (Or use an Xcode New File template that has them there already.)

That's the TLDR. For the whole story, read on...


In (Obj)C, the old way to make API available for use in a source code file was textual inclusion. The preprocessor would see your #import <Foundation/Foundation.h> directive and copy all the text from that header file (and from any other headers it includes, and the headers they include, and so on) into your source file before passing it off to the compiler. As you might expect, recompiling thousands of lines of system header declarations for each file in a project wasn't so performant.

So, we got precompiled headers some years ago—you'd put your common #imports in one place, and the compilation step for those parts would be done once, with a result that the compiler backend could reuse for each file in your project. But that had its problems, too: there's a maintenance burden to keeping your PCH happy, and it doesn't let you restrict the namespace used in each source file (i.e. if you want one .m file in your project to see only the symbols it needs to use, and not all the other stuff used elsewhere in your project).

And on top of that, textual inclusion has an underlying fragility problem. If you #define something above your #import lines, and that define changes a symbol used in the imported headers, those headers will have compile errors (or fail in more subtle ways, like defining the wrong API). There are conventions to keep that from happening, but conventions aren't enforced — you're always a typo / new team member / bad merge away from everything falling apart.

Anyway, textual inclusion wasn't so great, even with precompiled headers, so in Xcode 5 Apple introduced Modules. (Actually, not just Apple. They're in the LLVM/Clang compiler suite, so they're open source.) Modules are based on semantic import, not textual inclusion — that is, a module tells the compiler at an abstract level what API symbols it makes available to your source code, rather than pasting in the text of those symbols' definitions — so they're not fragile, and they're individually precompiled on the back end so building your project stays fast.

Modules are the default for ObjC projects now. (Notice that if you create a new ObjC project, it doesn't include a precompiled header anymore. You can turn modules off, so if you have an old project you might still be using textual inclusion and precompiled headers.) You can find out more about ObjC modules in Session 404 from WWDC 2013.


Why all this business about ObjC? We're talking Swift, right? Well, Swift is based on a lot of the same infrastructure.

Swift uses modules from the start, so it's always based on semantic import. That means there's no build-time performance hit and no fragility. All that Swift import does is tell the compiler what symbols you need (and the linker where to find them when producing your binary executable).

So the only cost to putting the same imports at the top of every file is the typing. And that's a necessary cost — in Swift, the source file is a semantic unit, and there's real meaning to deciding what goes into it. For example, the behaviors of many of the Swift standard library types change if you import Foundation, to enable bridging with Cocoa collection and value types — if there's a part of your app that wants to work strictly with Swift collection and value types, you might not want to import Foundation (or Cocoa or UIKit or something else that includes it).


Update: Furthermore, what you choose import in a Swift file has real meaning.

For example, how the compiler optimizes generics and static/dynamic dispatch depends on what declarations are visible in a given file, so if you import more than you need to, you may generate slower code. So generally, it's best to import only what you need.

Explicit imports also help with clarity and readability. If imports were project-wide, then when you copy-paste code out of one project and into another you'd see lots of errors in the new location... and it'd be a lot less clear what imports you need to resolve them.


"But I hate putting the same several imports at the top of every file all the time," you say. Let's think about that a little.

  • Do you really need several? Most modules transitively import their dependencies. You don't need to import Foundation if you're already importing Cocoa (OS X) or UIKit (iOS/tvOS/watchOS). And if you're writing a SpriteKit or SceneKit game, for example, you automatically get UIKit/Cocoa (for whichever platform) and Foundation for free.

  • Do you really need the same in every file? Sure, you're in a UIKit project so you're using UIKit almost everywhere. But that's just one import, twelve characters at the top. Maybe your project is also using Contacts or Photos or CoreBluetooth or HealthKit... but it probably doesn't need to use all of those in every single type you define. (If it does, your code probably suffers from poor separation of concerns.)

  • Are you really managing import statements all the time? I don't know about your projects, but in most large projects I've worked on, I'd say at least 90% of the development activity involves editing existing source files, not creating new ones... after starting up work on a project or major feature, very seldom are we (re)defining the set of source files or their dependencies. And there are shortcuts that can help with (among other things) setting up imports, like Xcode file templates.

What is an alternative to pch in swift?

You cannot define "Macros" in swift, so there is no ".pch" file for swift.

Also, Swift doesn't have separate "Header (.h) and Implementation (.m)", so there is no need of predefined headers which are needed to compile.

For more information refer to this question, Why .pch file not available in swift?

Class Import Problem:

In Swift, you don't need to write "import" statement for your project classes everywhere. You can access the project classes just by creating their objects.

Pods:

If you are using pods then it's necessary to import frameworks in
every class where you are using.

Third Party Swift Frameworks:

For external Frameworks/Modules, you can create a bridging header file
and replace the below line with your framework/module name:

@import ModuleName;

Reference: Implicitly import specific Swift module

Iphone write code in prefix.pch

Pre-compiled header files were brought to serve one purpose: to make compiling faster. It is compiled and stored in cache, and automatically included in every source file during the compilation time. Its like each source file does,

#import "Prefix.h"

This can be handy for project-wide #defines. (FYI, #defines are a code smell)

Xcode quotes: Precompiling the prefix header will be most effective if the contents of the prefix header or any file it includes change rarely. If the contents of the prefix header or any file it includes change frequently, there may be a negative impact to overall build time.

More clear explanation is here

Please keep this in mind when you #import s source file header in .pch. I would suggest you to explore other ways to write your code rather than choosing .pch file.

You can use Prefix.h for #import of constants and utility source files. Also for convenience in debugging like this:

#ifndef DEBUG
#define NSLog(x,...)
#endif

I see that you want to declare constant strings to use project-wide. Create a new header file "Constants.h"(or "Global.h", as you like it) and write all your global constants(usually macros & typedef enum's) here. However, to declare constant strings using extern you would need implementation file too.

In "Constants.h",

extern NSString *const app_ID;

And in "Constants.m",

NSString *const app_ID=@"dfgdf";

Hope that helps.

What is Prefix.pch file in Xcode?

Precompiled header.

What is it?

A Prefix.pch is a precompiled header. Precompiled headers were invented to make compiling faster. Rather than parsing the same header files over and over, these files get parsed once, ahead of time.

Xcode

In Xcode, you add imports of the header files you want in a “prefix header,” and enabling Precompile Prefix Header so they get precompiled. But the idea behind a prefix header is different from precompiling.

A prefix header is implicitly included at the start of every source file. It’s like each source file adds

#import "Prefix.pch"

at the top of the file, before anything else.

Removing it.

You can remove the precompiled header. This question has been already answered in thread I'm linking below. It contains all the information you need as well as useful comments.

Is it OK to remove Prefix.pch file from the Xcode project?

Prefix.pch: how to not use it for certain files?

I'd suggested not to use @import. Use instead old fashion #import.
If you have difficulties with that, then use @import's only exactly where you need them, like in Swift.

There is also one possible solution.
Put yours import in #ifdef __OBJC__ #ifndef __cplusplus #endif #endif block.
Example

#ifdef __OBJC__
#ifndef __cplusplus
@import ...
#endif
#endif

PrefixHeader.pch file can't find headers

Select your project (named "Project" for example) and click on "ProjectTests" (in TARGETS section).
Then, go to Build Phases > Link Binary With Libraries and add Parse.framework

Why .pch file not available in swift?

Even in Obj-C, using Macros for constants and expressions is something you shouldn't do. Taking examples from your comments:

#define NAVIGATIONBAR_COLOR @"5B79B1"

It would be better as a category method on UIColor, for example

+ (UIColor *) navigationBarColor {
return [UIColor colorWith...];
}

The isPad macro should be either a plain function

BOOL isIPad() {
return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);
}

or again a category method, e.g. on UIDevice

[UIDevice isIPad]

defined as

+ (BOOL)isIPad {
return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);
}

The precompiled headers were never meant to share macros to all of your code. They were made to include framework headers there to speed up the compilation process. With the introduction of modules last year and now with the possibility to create custom modules, you don't need precompiled headers any more.

In Swift the situation is the same - there are no headers and no macros so there is also no precompiled header. Use extensions, global constants or singletons instead.



Related Topics



Leave a reply



Submit