Previously, my Xcode would place the .h header file alongside the .m implementation file.
For example:
/SomeProject
/Metrics
MetricManager.h
MetricManager.m
/Utils
DeviceUtils.h
DeviceUtils.m
Recently, my Xcode began grouping all headers into a /PrivateHeaders folder like so:
/SomeProject
/PrivateHeaders
DeviceUtils.h
MetricManager.h
/Metrics
MetricManager.m
/Utils
DeviceUtils.m
What are the implications of doing it one way vs. the other?
Is there some setting in Xcode I can toggle to go back to the old way?
Related
I have a Swift project and have add a cocoapod, which is written in Objective-C. It has header and implementation files. From what I understand, to use/import these files into my Swift files, I need to add a bridging file.
I found this site describing how to do this manually, since the Objective-C files are already part of my project (from the cocoapod).
http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/
1.) Navigate to your project build settings and find the “Swift Compiler – Code Generation” section. You may find it faster to type in “Swift Compiler” into the search box to narrow down the results.
2.) Next to “Objective-C Bridging Header” you will need to add the name/path of your header file. If your file resides in your project’s root folder simply put the name of the header file there.
I don't have a Objective-C Bridging Header in that section and it doesn't appear you can add new entries there.
I'm using Xcode 7.3.1. Anyone have some idea how this should be done?
Are you sure you looked at the correct Build Settings section, search with the keyword Swift compiler - General in the search field as describe below and then you can find it.
You need to create the header file first. It is a regular Objective-C header file and should be named <Your app or framework name>-Bridging-Header.h. For any Objective-C headers you want Swift to know about add an import statement to the newly created header file. Then follow your previous steps.
There is also a hidden header that gets created for you called <Your app or framework name>-Swift.h. If you need to access any Swift classes from an Objective-C file import this header.
I added some Obj-C code (the excellent Expressions) to my Swift project using Xcode's Add files... but it did not ask me if I wanted to make a bridging header. So I made one myself in the Obj-C code's group, edited it to #import the single header I needed, and made sure that file was referenced in the Swift Compiler in Build Settings. I then looked through the Obj-C code and made sure the .m files were in the target - they were, and they're listed in Compile Sources.
The header in question contains this:
#interface NSNumber (Expression)
+ (NSNumber *)numberByParsingExpression:(NSString *)expression;
+ (NSNumber *)numberByParsingExpression:(NSString *)expression withVariables:(NSDictionary *)varDictionary;
#end
Now I am trying to call this code using the same basic syntax as this post:
let result = NSNumber.numberByParsingExpression(f.1)
along with several variations on the theme. But it won't compile, "Type 'NSNumber' has no member 'numberByParsingExpression'".
Did I miss a step here?
According to https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
You can create a bridging header yourself by choosing File > New >
File > (iOS, watchOS, tvOS, or OS X) > Source > Header File.
You’ll need to edit the bridging header file to expose your
Objective-C code to your Swift code.
In your Objective-C bridging header file, import every Objective-C
header you want to expose to Swift. For example:
In Build Settings, in Swift Compiler - Code Generation, make sure the
Objective-C Bridging Header build setting under has a path to the
bridging header file. The path should be relative to your project,
similar to the way your Info.plist path is specified in Build
Settings. In most cases, you should not need to modify this setting.
Any public Objective-C headers listed in this bridging header file
will be visible to Swift. The Objective-C functionality will be
available in any Swift file within that target automatically, without
any import statements. Use your custom Objective-C code with the same
Swift syntax you use with system classes.
If you already did this correctly, and it still isn't working, try deleting the projects derived data, and clean building your project.
Ok, this turns out to be an Xcode peccadillo.
When you create the header file within the group, it actually places it physically in the source folder. So in my case the header was created in /project/subproject/.h although it appeared within Xcode to be part of the base folder, /project/.h.
So in fact there were two headers, one in the right place with nothing in it, and another in the wrong place that was the one that was being edited within Xcode. So you have to look at the file inspector to make sure it placed the bridging header in the right place!
Consider my setup looks like this:
XCode 4 iphone/ipad project
ObjC .m file that includes a new header file, this header is reported as "file not found"
ObjC .m file is located in root folder of the project
new header file is also located in root folder of the project
new header file was created within Xcode 4 as "C header file" (!!)
I tried using #import and #include statements with both "" and <> lookup syntax.
The project already consists of a bunch of other objC headers/classes and they work nicely. I suspect that creating the file as a C-style header is the issue.
I did explicitly NOT try to add a USER_PATH or anything like that, since it's all happening in the root project folder.
Any ideas? I'm really surprised how complicated such simple things can get!
! Additional comment: (EDIT)
I now verified that I can create any type of header (menu "new file"->"C/C++"->"header") and it will never be found by objective-C code. Even a new clean project behaves the same! What kind of feature is this?
Weirdness.
I talked to a bunch of fellow Xcode sufferers and they confirmed I HAVE to set the extra path variable. Their explanation was a bit odd though: in objectiveC the lookup (import) simply scans the whole subfolder structure, whereas an 'include' does not. From my point of view this would only be a valid argument if the header file in question was located in a subfolder! But mine is in the exact same location as the '.m' file!
In one of my projects I have a class that has just some standard code that I use in most off the apps and I thought it would be useful to use this class in some other projects. Is there a way to put the .h and .m file in a central location to use in any of my projects? I could make changes to the class and would not have to worry about having to correct the files in multiple places.
For XCode 4.2 you could use a workspace, which can be comprised of multiple projects. Let's say you want to build a static lib. You can have a dedicated project for a lib, and include this project in multiple workspaces. You will need to properly setup project dependencies, so changes in your lib would be automatically picked up next time you build a product.
I found it was easier to save my .h & .m file in a folder called MyClasses, then drag both files in to the project I want to add them to. Xcode gives you the option to copy the files in to my project or leave them where they are. I left them in my MyClasses folder. I can now edited this class and all my changes show up in all the apps I have this class in.
Yes you can leave the files at a central location and add only refrences of the class to your project by dragging onto xcode into your project. Just do not copy files when xcode asks for it. Like we do for some third party libraries for ex. core-plot,facebook, Three20 etc.
In reference to this related question on stackoverflow:
If you create a constants file, how do you "link" to it in your target, so you don't have to
#import "Constants.h"
in every file you use constants?
You really should be using #import "Constants.h" every place you want to use the constants within it; Objective-C is a C-based language.
Furthermore, you aren't "linking" to it either when you put an #import directive in your code or if you put one in your prefix file. In both cases, the contents of the file are included in the text stream fed to the compiler by the preprocessor.
Finally, you shouldn't generally add random things to your prefix file. (Panagiotis Korros referred to this as "your pre-compiled header file," but that's slightly incorrect; your prefix file is used to generate the pre-compiled header file.) If you keep your build settings consistent across projects, and use the same name for your prefix files across projects, Xcode will actually cache and re-use the precompiled versions for you very aggressively. This is defeated by putting project-specific contents in them.
You can put the import line in your pre-compiled header file.
That is the .pch file named after you application name.
When I use the constant in more file inside my application, normally I use the .pch file (find it under "Supporting Files" folder).
Into my .pch file I insert the constant, for example:
static const int NAME_CONSTANT = 200;
and use NAME_CONSTANT into all file inside my project without import never file because the .pch is pre-compiled header file.