When I import my project from Github, I have two folders which appear in Xcode with a blue color, but all the other folders are yellow. What's going on?
Blue is used to represent a "Folder Reference".
A clear description of what these are and when to use them comes from http://struct.ca/2010/xcode-folder-references/
There are two types of folders in Xcode: groups and folder references.
You can use groups to organize files in your project without affecting
their structure on the actual file system. This is great for code,
because you’re only going to be working with your code in Xcode. On
the other hand, groups aren’t very good for resource files.
On any reasonably complicated project, you’ll usually be dealing with
dozens – if not hundreds – of asset files, and those assets will need
to be modified and manipulated from outside of Xcode, either by you or
a designer. Putting all of your resource files in one flat folder is a
recipe for disaster. This is where folder references come in. They
allow you to organize your files into folders on your file system and
keep that same folder structure in Xcode.
Related
In Xcode, what is the difference between a folder and a group? Are these interchangeable terms or is there a subtle difference?
Groups
With groups, Xcode stores in the project a reference to each individual file.
Folders
Folder references are simpler. You can spot a folder reference because it shows up in blue instead of yellow.
There are two types of folders in Xcode: groups and folder references.
You can use groups to organize files in your project without affecting
their structure on the actual file system. This is great for code,
because you’re only going to be working with your code in Xcode. On
the other hand, groups aren’t very good for resource files.
On any reasonably complicated project, you’ll usually be dealing with
dozens – if not hundreds – of asset files, and those assets will need
to be modified and manipulated from outside of Xcode, either by you or
a designer. Putting all of your resource files in one flat folder is a
recipe for disaster. This is where folder references come in. They
allow you to organize your files into folders on your file system and
keep that same folder structure in Xcode.
Reference
A folder in Xcode represents a folder in the file system.
A group in Xcode is a "fake" folder which does NOT represent a folder in the file system.
It is common to use a combination of groups and folders for a given Xcode project.
Xcode behavior (starting with v9) has changed and groups are now actual folders on-disk.
I found that Xcode 9.2 has two versions of group when you create a group. One is group the other is group without folder. The first one also creates folder in your file system, the second one doesn't.
I was following a tutorial and it had me drag a nested folder with a number of autogenerated Swift files with public classes and structs. I missed that I was supposed to click the "Create groups" and not "Create folder references". When I added the folders/paths using the incorrect 'folder ref', my other scripts did not see these public objects. When I did it the right way, added them using 'groups', then they were recognized in other scripts. I think this is in keeping with TheNitram's comment, that 'group' adds to the root ...
I have opened a project from Github, which has blue folders in its file structure.
As far as I understand this is a physical folder reference rather than just a means of grouping files together which might just lay around loosely on your hard drive.
So my question: When do you use those blue folders over the "normal" Group, what are its advantages and drawbacks and how do you create them in Xcode?
If you use blue folder references for your resources these folders will also be created inside your application bundle, while resource files in groups will simply be copied to your mainBundle's root directory.
When folder structure is managed outside of XCode (for example, a cross-platform project which has project files for different versions of XCode, Visual Studio and other IDEs, all using mostly the same directory tree), you normally want folder references. Otherwise one would have to recreate every project file every time folder structure changes.
Like many people, I would love to have Xcode use a folder structure that mirrors the folder-structure on disk. However, I cannot get the code in "folder references" (the cyan folders) to show up in my project targets under "Compile Sources." Is there any way to do this?
I have managed to even add a cyan folder to the "Compile Sources" build phase, but that does not result in the contents of that folder being added.
How can I use folder references for code?
The simple (and very unfortunate) answer is that Folder References under Xcode remain broken and buggy, they don't work. Tested 04-Mar-2017 in Xcode 8.2.1
Below is an example exploration so you do not have to waste your time replicating the Xcode failure.
(incidentally buggy Xcode crashed twice while I was producing this example)
Per the question, the overall desire is to use a folder reference in Xcode so Xcode picks up all the files in the folder and includes them in the project, and by proxy will update automatically based upon any Finder or Xcode changes of the folder. In this way 50 projects all leveraging the same set of common source code files do not have to be individually updated when those folders get changed. Below explores how this is broken in Xcode (tested in 8.2.1)
The example: ViewController.m includes NSError+Core.h so we want everything from the folder "NSError+Core" to be added to the project.
NSError+Core.h is in this centrally located development folder
Drag the source folder from the Finder into the Project under the "Support" group (nothing up my sleeves, simple drag)
Xcode dutifully offers to add the drag to the target, note the "Create folder references" is selected, not "Create group references". Note also it is clear that Xcode is offering and is told to add this folder and files to the targets.
Although everything looks like it should work, the compiler does not pick up the header file and a recompile yields the same results... can't find header. Ditching the DerivedData does not help either.
So doing a double check, we check the "Compile Sources" under the project and sure enough, the source file is not there either. Remember, Xcode 'added' it to the target...
So what if we drag it from the folder into the "Support" group...
It offers to add them to the project again?! Note that the settings are identical to the first time they were drug in by virtue of the parent folder drag instead of files...
And now the source file shows up in the "Compile Sources" list. Note the bizarre double listing of the files in the project.
(Xcode crashed shortly after snapping this screen shot)
And of course the compiler can now find the header file and the error clears on the import as it should have the first time we drug it in...
Did it just need a little help to "find" the file? If so, the "Create folder references" does exactly what?
So we try and tidy up and drag the files back from the parent "Supporting Files" group to their rightful folder. Without any confirmation, indication, notification, the files just vanish from the group and nothing happens in the NSError+Core folder.
Oh by the way, it really did delete them from the project too... The Compile Sources no longer has the NSError+Core.m reference.
SO to sum up, "Folder references" as implemented thus far do not seem to have any useful purpose... It would appear to be a 6+ year old dunsel on the USS Xcode.
Kevin - linked source folders, folder references, etc, are super useful for when you have a common code base shared across different IDEs, like I do for my games that I compile on Windows, Mac, iOS, Android, Linux, etc. I have 3 different IDEs all building the same shared codebase, so it's very helpful when one automatically picks up on a new file and adds it right into the project after I merely run svn update, and I svn commit from one IDE (say XCode) and my Eclipse in Windows project picks up the change. I have a different project for each because each IDE likes the project files in a certain configuration so it's easier for me to have multiple SVN directories (base-project, project-ios, project-android) that all share code in base-project than to have one mega project directory with the different IDE bits unhappily all shoved into subdirectories (which is what I tried the first time around).
Furthermore - it used to work fine in XCode 3. They seemed to not like that useful of a feature so it is no longer working in XCode 4 as I've just found out.
I just tried doing this to share code across multiple Xcode projects, and our team came to the conclusion that it's better to create an Xcode project that contains all of your shared classes, compiles them into a static/dynamic library, and then add that as a subproject to those that need the shared code. Then you can set up target dependencies and link your shared library. This will get you the "automatic updating" every time you add a new class to the shared library project.
This approach also works well with submodules or even cocoapods/carthage.
You can't. Why are you even trying? A folder reference's job is to embody a folder, without having entries for all the individual files in the folder. It's primary use is for copying an entire folder of resources verbatim into a project. If you want to compile the sources though, then those sources must be referenced in the Compile Sources build phase of the target, which requires having individual entries for each file.
Depending on what's in the folder, it might make more sense to have a Makefile or some other external build process that builds the content in the folder into a static library. This way you can invoke that build process from a Shell Script Phase, and then just link in the resulting static library. Alternatively if you're using this folder as a way to have a shared bit of code (e.g. an svn:externals or git submodule), you could give that folder its own Xcode project and then embed that project into any of your other projects which share this folder.
what is copy items into destination group's folder (if needed)
is this a good option? If I dont choose it will it just make a reference to my files?
Also if I have two images with the same name like /images/home.gif, /public/home.gif
but they are in different groups how does the compile know which image to use? is this even possible?
I'll have a crack at this :-)
1 & 2 - Used when adding files to a project. If selected, the file you are adding is copied into the projects directory from wherever it originally was. Note it is copied. If not selected, the project can still use it, it just has a reference to the original source file. Which means that if something happens to the original file, the project will not longer have a copy it can use. Personally for files such as images I copy them into the project so they stay with the project. For other things such as external apis, I don't because I don't want multiple copies everywhere.
3 - If you have two images with the same name you won't be able to copy them in without renaming one. XCode may do this for you, I've never tried. I'd suggest renaming one so you control it's name.
4 - Don't get confused by groups. They are logical groupings of files within XCode and do not refer to the underlying file system. Having said that you can actually assign a directory to a group so if you really wanted to you can match the two. I tend to do it a little. In my projects I generally have a src and test directory. I setup two groups and assign them to refer to these directories. Then when I create a new source code file I can create it in the src or test group and it will be created in the sub-directory instead of the project root directory. Often below src and test I will use other groups, but they do not map to any sub directories. The result is that the root directory of the project is free of source code files and the source code also has source and test code separated.
I am relatively new to Xcode and one thing that has bothered me is that when I add a resource it gets added to the top level directory of my project directory. So for example, at the moment, all of my images are at the top level directory and it makes things look messy. I rather would've liked, for example, to have an images/ folder and then sub-folders within that to store images for certain things, like tab-bar/ icons. Is this possible? Or is it convention to just keep everything in the top level directory?
Someone in the #iphonedev channel at freenode told me something about the build process rule or something, it just seemed too complicated I figured I shouldn't bother, and that most people just kept things at their root directory considering the complexity of the solution. Perhaps it isn't all that complicated though, I just felt it should be easier.
For example I would also like to have a sub-folder for my views, like views/ that stores all of my nib files; currently they are all in the top level directory. And the same goes for my property lists.
I would appreciate it if you could tell me what the convention is, I doubt it is to just store everything in the top level directory. And I'm referring to the actual file system, not simply creating 'virtual folders' in Xcode to organize things, because the top level directory of my project will still be a mess. And if it is possible to organize things better, I would appreciate any detailed help on how to accomplish it.
I think I have heard that in the final build, the entire file structure gets squashed to the root directory. I don't mind so much about that, I just want things to be organized while I am working on my project. I think this is where that 'build rule' thing comes in, but I'm not sure how or what to do.
Here's a little more explanation of Graham's suggestion:
Create an images directory
Create an images Group in Xcode
Right-click the group and Get Info
"Choose..." to set the group's directory to be your images directory
Now, anything you put in the images group will automatically go into the images directory. That's true if you drag/drop from within Xcode, from other other projects or from Finder, or if you Add New... by right-clicking on the images directory. (This assumes you leave the default setting of "relative to group" in the info pane.)
This will work for anything you put in that group (NIBs, etc).
For imageNamed:, you just give the base name.
My recommendation is to keep a small number of filesystem directories, and mostly organize with groups in Xcode. But I agree, a small number of filesystem directories are very helpful. I put all my source code in a Classes directory (just because Apple used that name; I would have picked "Sources" or something). I also have a Resources directory at the top level and generally create images and audio directories under that. But I don't generally create a lots of real directories beyond that. This keeps things a bit tidier, but makes it easier to grep and wildcard things with the shell.
Beyond shell tools, the big advantage of organizing by groups rather than directories is the impact on version control systems like subversion. When you suddenly realize that your "Views" group is way too big, you can reorganize it without taking the huge impact of moving files around.
The accepted answer didn't work for me in Xcode 4.3.2. Looks like they removed the "Get info" menu option. Instead I did this:
Created the directory on disk where I wanted it.
Went to the file menu
Right clicked on the group I wanted to add to
Selected "Add Files to PROJECTNAME"
Added the files from the directory I created in (1)
Life is hard for IDEs. They have to mediate between a filesystem world, where the compiler, with its source files live, and the UI world, where programmers work.
In the old times that formed the contemporary coding culture, everybody, compilers and people, used to live all togheter in the filesystem. So today we still have a tendency to think we want to control where sources and resources reside on the disk. That is good, because we may need to know exactly what compilers eat.
Anyway if you think your IDE just as a the frontend of a funny database system of source code and if you really have full confidence about its capabilities and features (which is seldom the case), you may get to the conclusion that if you just don't care about the filesystem you may have a better life, as a programmer (and as a human being).
You're right wondering, because Xcode is not very good nor friendly about filesystem code organization and people that is (correctly) picky on that will learn how to move files on their right folder on disk, and on their right Xcode group. That, if you use the "Create folder references for any added folders", have a 1:1 relation.
But you will see many people, and many project examples from Apple itsef, that use a simple flat filesystem tree with everything in the same folder.
My advice is that you at least group public headers and resources in different folders, something à la Java/Maven, but there is no universal convention.
It's actually really easy to get from where you are to where you want to be. Create the images/ folder and put all the images in it. Now in the project window in Xcode, the image files have gone red because they aren't in place any more. Get Info on them, and "Choose..." the new location.
Note that just because you've moved the file in the source file system (known as $SRCROOT), there's no change to the way the file is used in the product. If it got copied into Contents/Resources/ before you moved the file, that's where it gets copied to afterwards. No subfolder will be added at the destination.