Why does Xcode autocompletion suggest .m files when importing? - ios

Just wondering -
When you start to type #import "
Xcode suggests .m files and .h files. I just had a few hours of frustration after mistakenly importing .m file.
Is that a bad design? Can you import .m files?

You can import any files. #import is just a preprocessor directive that basically says "include contents of the file I tell you into the current file". There are some include guards as well, but the import does just that - it imports the file you tell it to.
Importing the header with .h file is probably more of a convenience/convention (please don't beat me for this, I'm just guessing) unless there's some C/C++ standard that says otherwise.

Related

Mixing Swift and Objective-C : "ProjectName-Swift.h" file not found

I'm working on an iOS project that contains Swift and Objective-C Classes.
To instantiate an object described in Objective-C, I've understand that I needed to have a Bridging-Header file that contains all the imports of the headers I will have to use on my Swift classes. And it works great on my project.
I made all classes I needed, I subclassed Objective-C classes in Swift, everything is OK.
My problem is when it comes to do the opposite: instantiate a swift object in an Objective-C file. So I read that I need to have those options:
Define Modules as Yes
add the line #import "<#YourProjectName#>-Swift.h" on the *.m file I'm working on.
And that is what I did:
I changed all the values on the Build Settings that needed to be changed. I added the import line, I even tried to create the header file, but I still have the "<#YourProjectName#>-Swift.h" file not found error.
Of course, I replaced the YourProjectName by the actual module name, the one I found under Product Module Name in Packaging section on Build Settings. Also, there is no spaces in the Project Name.
Did I forgot a step?
Make sure you are importing the -Swift.h file from a .m Objective-C file and not a .h header file. The docs only talk about importing from .m:
... import the Xcode-generated header file for your Swift code into any Objective-C .m file you want to use your Swift code from.
The -Swift.h file is generated during the build and I've found that importing it from a .h file always fails, even when I know the file exists. Since it's generated by the build, I'm guessing it's cleaned out when the compiler is sifting through the headers and regenerated once the .swift files are compiled.

No warning in Xcode on header file including itself

I included in my iOS project a widely used UIImage category to handle PDF, and got some compilation errors. This raised several questions.
Q1: Why would Xcode (or actually the LLVM compiler) not give any warning on a header file that is including itself ? I don't know if this has a special meaning in C or Objective-C that would prevent it from being seen as a typo ? In my example, I believe that a mistake was made and Foundation.h was probably the intended include:
In the category file NSString+MD5.h I found:
#import "NSString+MD5.h"
#interface NSString(MD5)
- (NSString *)MD5;
#end
The corresponding .m does not include the .h. (Link is "Here")
Q2: I got the compilation error because I started from an Apple project that doesn't NOT include the Foundation framework (AVCam 3.1 for iOS) ! So NSString was undefined. I'm a bit puzzled by this but linking with the foundation framework in xcode is like including all its headers ? I would expect again some warning at least ?
Thanks for any explanation on this probably very basic C topic.
First of all, in Objective-C, we #import, which is different from #include. While #include will attempt to include any file you list, #import will never double import any file. I imagine that this explains why there's no problem with a .h file trying to #import itself. It's not correct for the file to import itself, but because it's an #import, it won't actually cause any issues.
As for the .m file not importing it's .h, in this case, it doesn't actually have to. It's a good idea, out of habit, to always import the .h file, and any files generated by Xcode will do this automatically, however it's not always necessary. It's only necessary when the .h file has declared something that the .m has to know about. For example, a #property that you intend to use. You've declared it in the .h so it'd have public access, but if you intend to use it in the .m, the .m has to know the #property has been defined. Additionally, if you've #imported some files in the .h that the .m needs and you don't want to import them again in the .m, you'd need to import the .h (although it's generally going to be better to just import them in the .m.
Here, the .h simply defines the exists of a method that returns an NSString * and is called md5 and takes no arguments. This means that anything importing this .h file can call this method and Xcode won't complain about the md5 method not existing. The corresponding .m file implements a method that coincidentally matches the one the .h defined. If you deleted the .m file, your program would almost certainly still compile just fine... but you'd hit an unrecognized selector exception when you go to the point that md5 was being called--despite Xcode not complaining about it. With the .m in the project, this exception isn't hit. The program figures out at run time which method to execute.
And finally, as for not including Foundation.h, every iOS project created by Xcode has #import Foundation.h and #import UIKit.h in the precompiled header file. Any other file in your project with these imports is just redundantly importing the file, as it's already been imported by the .pch, but because of the magic of #import (vs #include) it's not actually double imported.
If you're working with an iOS project that doesn't have these imports in your .pch, your best bet is to just stick them in the .pch.
If you're opposed to this for some reason, the best way to fix this md5 file is with this simple line:
#import Foundation.NSString;

Importing classes from prefix.pch

I am facing an issue, Currently i am using xcode 5.0, when i am importing clasess from prefix.pch then it dose not give suggestions on appdelegate.h file. But it gives suggestion on other view controller's. I have googled about it and find if we define macros in prefix.pch then this problem occurred. Still after removing the macros it did not give suggestion on appdelegate.
Suggestios means if i try to write
#property(strong,nonatomic) UINavigationController *navControler;
After writing #property(strong,nonatomic) UINav xcode did not give suggestion. But if I remove all the import statement and macros from prefix.pch file then xcode give suggestions on appdelegate.
From my point of view, rather than finding a workaround, I want to put some light on the actual problem.
So when you want to add something in .pch (pre compiled headers), it means you want to use the content of files before your program is actually being compiled & build. In simple words the headers included in pch acts as a stub code, a base code or may be a code that is meant for using as it is intact.
So if you have already included appDelegate.h file in .pch & writing some code in appDelegate.h file, then the compiler is trying to use 'appDelegate.h` from .pch as a pre-compiled information. And may be it is resulting in a indefinite sate of Xcode background processing, which is not allowing to show the drop down helps in the file which is already pre-compiled.
To me it looks like app delegate.h in .pch is not the right place. Where ever you want in your program, you can very well include appDelegate.h file. However it is also a signal of bad Class Design approaches.
Also, if you want to add #define statement & other macros in .pch then it is not the right approach. The right approach is :
Make a simple .h file, say constants.h
Add all your #defines & macros here in constants.h file.
Add the #import "constants.h" in your .pch file.
That should solve your problem.
Hope that helps.

Why does the default xcode class header import Foundation/Foundation.h?

Default file:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#end
My understanding is pre-compiled headers are included in every file. Why doesn't this import just go into the pre-compiled headers?
There is no guarantee that every project have a .pch file that import Foundation.h so Xcode need to generate it to make sure new files always compile.
Also some people think it is good style to include header even it is already included in .pch file. Because you know exactly what headers are needed by this file. It also allow people to disable prefix header if needed.
My Xcode 5 doesn't appear to be including it in every class (it is included in the .pch file). I agree with you that this makes more sense than including it everywhere. The answer to your question is probably "an oversight on Apple's part" :)

xcode .pch, exclude from one single file

.pch
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "thing.h"
#endif
I have a pretty large project I'm trying to debug and I have a suspicion the problem is in thing.h
From what I understand the .pch file is included in EVERY .m and .h in the project.
Is it possible to have it not included in just one or two files? For debugging I would like to not include thing.h in just one test file, but removing it from the .pch causes a cascading nightmare across the project.
This is a really old question but I just ran into this issue. I was able to solve the problem by wrapping the pch file with a ifndef SOME_NAME. Then in the project settings on each specific file I wanted it to not be included I added a compiler flag of -DSOME_NAME=1. Hope that helps someone in the future.

Resources