What does "import <XYZ/XYZ.h>" mean - objective-c

I am new to objective-c and started iphone application development. I have noticed the import statement like import <UIKit/UIKit.h> etc... I wanted to know what does it mean. Why not simply import <UIKit> or import <UIKit.h>? In fact if I do that, it gives a no-such-file-error"!
So does it mean that we should name our files like that? So that when we import the header, it looks like MyApplication/MyApplication.h? Or is it just for the libraries? Even if it is, then why is that so?
This syntax looks weird to me, so I am just asking out of curiosity. But may be I am supposed to use them somewhere that I am not doing. I guess knowing is the best solution :)

UIKit/UIKit.h is a path. UIKit is some package and UIKit.h is the header that you are actually importing.
This is common for large frameworks and libraries in Objective-C, C, and C++.

This is just a convention for frameworks - the parent directory has the same name as the header file. You don't need to do this for headers which are not part of frameworks.

Related

iOS Framework With Swift and Objective-C Where the Objective-C Uses Swift C

I have a framework building where it combines both Objective-C and Swift. My issue is that some of the Objective-C code within the framework needs to use some of the Swift classes in the framework. In order to do this, I do:
#import "FrameworkName-Swift.h"
in my Objective-C code in the framework. And here the first problem arises. The -Swift.h header is not located by Xcode this way. Digging around in the Derived Data, it turns out the -Swift.h file is located in the Framework/Headers folder, which in of itself seems odd. Should the -Swift.h file really be an exposed header for the framework? The -Swift.h file is an intermediary .h file, right?
To work around this issue of not locating the -Swift.h, I tried:
#import <FrameworkName/FrameworkName-Swift.h>
BUT, while now locating the -Swift.h file, this causes a severe and compilation-fatal rash of cyclic dependencies in Xcode, with messages like:
Cyclic dependency in module 'FrameworkName'
Could not build module 'UIKit'
Here's what those look like in-situ:
Thoughts?
I have an incomplete answer to this, which is more of a partial explanation and a workaround that works for me. Here's what I think is causing the issue.
While Apple let's you call Swift code that is in the framework, from your Objective-C in the framework, if the same Objective-C class also needs to be used from Swift you run into an include/import cycle. Here's the situation I have.
Call my Objective-C class Objc with files Objc.m and Objc.h
Now, since Objc has to use Swift code it needs an import something like this:
#import <FrameworkName/FrameworkName-Swift.h>
which in my case goes in the Objc.m file.
And since the Swift code needs to use the Objc class, you need the following in the Framework umbrella .h file (the umbrella .h file is named FrameworkName.h):
#import <FrameworkName/Objc.h>
Now, if you take a look at the FrameworkName-Swift.h file that is generated by Xcode (Xcode 7.0.1 in my case), you find that it has an import of #import <FrameworkName/FrameworkName.h>, which forms a cycle back to Objc.m.
My workaround for this was no more than a situation specific hack. It turns out that in my case Objc.m didn't critically need the Swift code. It just made the code look nicer and better engineered. So, with a comment and a couple of extra lines of (Objective-C) code in Objc.m, I worked around my issue.
Very insidiously, Xcode 7 (at least) is really resistant to getting out of this issue once you are in it. That is, when you get this cyclic dependency error, it can be very difficult to have Xcode stop telling you you have it, even if you have taken the cyclic dependency out of the code. I tried many things including removing all of the Derived Data files/folders, quitting Xcode, and restarting my Mac, and found nothing that worked consistently to have Xcode stop believing it had a cyclic dependency even though I'd fixed the issue.
This resulted in the more difficult fix. I had to effectively rebuild my Framework from scratch, every step along the way building and saving to my version control system so I'd be darn sure I could recover if Xcode started being convinced I had one of these cyclic dependencies. Makes me have even less faith in Xcode. :(.
Second fix: A workaround (10/9/15)
I've found a fix that works in some other cases:
1) Clean/remove your Xcode Derived Data, including the ModuleCache
2) Build a known working copy of your Xcode project (in my case, I had a revision before I started adding the framework)
3) Now, go back to your Xcode project with the framework included and attempt a build. For me, this now works.
This is strictly a work-around, and resolves a cyclic dependency issue that appears in somewhat different framework conditions for me than I described in the present question. I'm talking to Apple engineer right now about this issue, so will see if I can get a better fix. I'd rather not have to apply this workaround.
"Final Solution": Namespace pollution (10/22/15)
I have figured out what was going on!! It was a case of include file name space pollution. I had an Objective-C class named "Assert" (note the upper case "A"), with files Assert.h and Assert.m. I have been using this Objective-C class (part of my internal debugging) for quite a while. At least a year if not more, to no apparent problem with Xcode. Now, when I started using it in conjunction with a Cocoa Touch Framework of my own construction, a problem came up. It turns out that if I cleaned the Derived Data first, that the /usr/include/assert.h file was being picked up, and not my own Assert.h
Really odd.
And, if the Derived Data was not cleaned and I'd built a non-framework version of my project first (for the specific platform, e.g., for my iPhone if I was building for that), then my own Assert.h would get picked up.
My fix was pretty simple-- took about 10 minutes. I changed the name of my file/class to SMAssert with files SMAssert.h/.m. And then changed the references to the file in the various places that imported it. Voila!

Organizing modules in a D project

I come from Java backgrounds and the problem of packaging is as follows then:
I can have many files under the same package, say com.parobay.io. I can then distribute this as a library, and the users will use it like this:
import com.parobay.io.Input;
import com.parobay.io.Output;
or
import com.parobay.io.*; // to import everything
So I can have a single "module (com.parobay.io) and classes defined in multiple files.
So how to I achieve the same in D? Do I have to create a directory com\parobay\io and there place two files called Input.d and Output.d or is there a smarter way?
In Java the rules are very strict, so it's hard to get it wrong. In D there are many possibilities. So are there any conventions, like one class per file, or file name equal to the name of class?
You can choose to do it basically the same as Java, though remember these items:
import foo.* doesn't work in D, but you CAN make a file called package.d in the directory which manually lists public import foo.Input; public import foo.Output; etc. which allows you to import the whole package.
ALWAYS put a module com.parobay.io.Input; or whatever line at the top of any file that is imported. Don't expect it to just work based on directory structure and filename. The directory structure actually isn't strictly necessary, it is just a convention to easily find the file. The module line at the top with the name is the authoritative thing the compiler checks.
D modules often have all lowercase names, but you can use uppercase ones if you like. I think it is nice to use a lowercase name like the class name, so you might call the module io.input and the class Input. The reason for this convention is sometimes filename case gets lost when transferring from system to system. But developers are pretty aware of case so in practice either way should work.
One class per file will work fine or you can put two tightly coupled classes together in the same file (they'll have access to each other's private members if they are in the same file).
See this page for more info: http://dlang.org/module especially search for the heading "Package Module"
Don't use two separate files for your Input and Output classes. Instead, put both classes in a single file, parobay/io.d (corresponding to the module parobay.io).
It's definitely not the convention to limit yourself to just one class per file. D modules are for grouping together code of related functionality. When someone does import parobay.io;, they expect to get all of parobay.io - classes, utility functions and whatever else is relevant. It's similar to Java's import com.parobay.io.*;.
If someone really wants to import specific parts of your module, they can use selective imports:
import parobay.io: Input; // Just the Input class of the parobay.io module.
import parobay.io: Output; // Just the Output class.
import parobay.io: Input, Output; // Just the Input and Output classes.
There are a few additional things to note about this.
Package and module names are conventionally all-lowercase.
It makes everyone's lives easier if the path to the file matches up exactly with its full module name. For example, module foo.bar.baz should be in the file foo/bar/baz.d.
In my experience, it's rare for a D module to be named after a domain name. You can prefix your module names with com or org or net if you really want to, but it's not expected like it is in Java.
Adam D. Ruppe's answer has some great points about explicit module declarations and class member visibility. It's also well worth reading the module and style pages on the official D website.
D community has three widely accepted alternatives.
Write a module named all.d which includes all modules from your package. (Literally '*' --> 'all'). After that you simply do import com.paroboy.io.all;
I see more and more that D developers use _ for this. So they write a module called _.d for this purpose. Similarly to #1, you do import com.paroboy.io._;
Relatively new addition to the D programming language is the package.d module, which can be used to import the package. More about this at the following DIP: http://wiki.dlang.org/DIP37 . If I remember well, DMD supports it since v2.064 . (Documentation: http://dlang.org/module#PackageModule)
I myself use the #1 approach because it is obvious what is going on. While #2 and #3 may be confusing to people reading D source file, especially the third one. A valid question someone may ask: "What the heck am I importing, package?? But import is only for modules!??"
Allthough nothing stops you from having separate module per-class, I would not recommend it. D is truly modular language, so take advantage of that. Group all your types in a single D module. That is my advice, and that is the "D way".
NOTE:
There is a (big) semantic difference between Java "module" and a D module, as you have probably already noticed. I am primarily a Java programmer, so I know how confusing this may be to Java programmers who are playing with D. Java classes in the same package quite often take advantage of the package-level access. However, classes within the same module behave like "friends" in C++.
Speaking about Java modules, they were supposed to come with Java 8 (true modules!), but were posponed and will hopefully be included in Java 9.
UPDATE: We reached conclusion, after a chat on FreeNode (IRC) with some members of the D-Programming-Language, that it is indeed safe now to use the package attribute. It behaves as the specification says.

How do I import only one part of a module in TypeScript?

Let's say I have a translations module, and I only want to import the French translation file. I want to do something like this:
import french = module("./translations").french;
similar to how you can do with a require in CommonJS.
Is it possible to do something like that in TypeScript, or will I have to import the entire module and just do something like this?
import translations = module("./translations");
var french = translations.french;
This is actually something that is fairly reasonable to do in some circumstances. Unfortunately, this is not supported by TypeScript at the moment; the grammar for import declarations doesn't allow for dotting off of it (see spec section 9.2.2). This is something we could look at improving in the future. I recommend filing an issue on the Codeplex site.
If you only need part of your module, it sounds like your module design might be wrong - i.e. you should have a module that represents what you need and move the stuff you don't need into another module.
For example, have a module per language.

When should I import a header to Prefix.pch?

I've heard importing a header to Prefix.pch can improve performance as it will load the header once, instead of on each instance. So when is a header imported enough times in a project to warrant being included in the Prefix.pch? A dozen times? Several times? Just twice?
I typically add a header to Prefix.pch if it is being #imported into more than 3 classes. I don't think there's a rule of thumb - it depends on your own standards for what you consider clutter, elegance, how globally the code is used etc. For example, most of my projects have a Utilities.h and Utilities.m where I declare helper functions used in many places. I always add Utilities.h to my .pch.
I tend to avoid the temptation of chucking too much stuff in the .pch. In particular, it obfuscates the dependencies in your code. Suppose you want to see where your code is using AFNetworking lib (for example): You search for the #import statements, and then see that the .pch file imports it, which tells you... nothing.
If when using a module/lib you usually import a number of related header files you can create a new header file that just imports the glob of related headers and then import that instead.

Objective - C Static Library and it's public headers - what is the right way?

I'm building a static library that will be used in multiple iOS apps.
In parallel i'm working on one of those apps using my library.
During development I get at least once a day an annoying error about header files from the library not being found (in my app project).
I learned that when building a static library, headers can be either Public, Private or Project
I'm guessing that every header that I want to expose in my library should be Public.
My question is, what is the best way to manage these public headers? should I create one main public header file with #import to all my public headers?
Can Xcode generate such file for me?
Another major question is what is the recommended value for Public Header Folder Path setting?
My major goal is that future projects that will use this library, will be able to do so with as less configurations as possible (Adding linker flags, changing User Header Search Path etc.)
Thank you very much.
About public/private/project headers, here is a previous answer just in case
=> https://stackoverflow.com/a/8016333/1075192
Most of the time, C/C++/Obj-C libraries and frameworks have one main header including all the other ones. Cocoa frameworks follow this path for example.
To declare a CAAnimation with QuartzCore framework for example you could do this:
#import "QuartzCore/CAAnimation.h"
or
#import "QuartzCore/Quartzcore.h"
"QuartzCore.h" is actually only composed of a header guard and includes of all the other headers of the library.
In my opinion, It's actually better to use the first one as it doesn't include all the declarations you don't need. But most of the time we choose the lazy solution of including everything at once.
I have no idea if you can generate this directly with xCode, anyway it's easy enough to do it by yourself as it's just a bunch of includes or imports.
The public header folder path is generally "MyLibraryOrFramework/Headers" (just look inside any Cocoa's framework for example).
And last, if you want something really reusable and seamless, I suggest you use frameworks instead of static library (which is nearly similar).
Look at this fine answer to understand why it fits perfectly what you need:
=> https://stackoverflow.com/a/6389802/1075192
VoilĂ , hope this answer helped a bit.