27

In Xcode 9, when you create a group it creates a linked folder in the file system, too. So you don't need to create folder for each group manually. A good explanation about the group and folder related changes in Xcode 9, see this.

I have a custom Xcode project template which generates a project and adds loads of Swift boilerplate source files in custom folders. My problem is that I can only create group folders like this: enter image description here, which represents a Group not associated with a file system directory. It's not good because if you later rename a folder in Xcode, it will have no effect on the corresponding file system directory.

My goal is to write an Xcode project template that adds my custom boilerplate swift files in real reference folders like this: enter image description here.

You can download my simplified template from here, place it under: ~/Library/Developer/Xcode/Templates

Then Xcode > File > New > Project, and select Custom-Template.

TemplateInfo.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Kind</key>
    <string>Xcode.Xcode3.ProjectTemplateUnitKind</string>
    <key>Concrete</key>
    <true/>
    <key>Identifier</key>
    <string>custom-swift.xcodeTemplate</string>
    <key>Description</key>
    <string>Swift starter project for iOS projects</string>
    <key>Ancestors</key>
    <array>
        <string>com.apple.dt.unit.cocoaTouchFramework</string>
    </array>
    <key>Nodes</key>
    <array>
        <string>Classes/Interfaces/CustomInterface.swift</string>
    </array>
    <key>Definitions</key>
    <dict>
        <key>Classes/Interfaces/CustomInterface.swift</key>
        <dict>
            <key>Group</key>
            <array>
                <string>Classes</string>
                <string>Interfaces</string>
            </array>
            <key>Path</key>
            <string>Classes/Interfaces/CustomInterface.swift</string>
        </dict>
    </dict>
</dict>
</plist>

It creates a project like this:

enter image description here

What I'd like to achieve:

enter image description here

Any help is much appreciated! :)

Update 1:

I found a small workaround.. Create your own complex folder hierarchy with the template script then simply delete the root folder - in my case "Classes". Then open the Trash and drag it back to Xcode, select "Copy items if needed" and select "Create groups". It will build the folder structure with real reference folders.

balazs630
  • 3,421
  • 29
  • 46
  • Doesn't this help? https://stackoverflow.com/questions/5575294/how-to-add-folder-reference-in-xcode-4-project-template or https://stackoverflow.com/questions/41484822/creating-groups-using-a-custom-template-xcode-8 – Tarun Lalwani May 23 '18 at 17:32
  • Thanks for the links but I can create groups and folders like that, I've already have that in my code. My question is Xcode 9 specific, please check it again. – balazs630 May 23 '18 at 20:33
  • Add a node for `Classes` and a definition, that will add a folder to the instanciated project. Folder will be represented by blue folder, not like group with folder in yellow. – Jean-Baptiste Yunès May 23 '18 at 21:34
  • 1
    I see... But blue folders map to real folders in the deployed bundle of the app, which I don't want for code. The real use case for blue folders is assets for example. You should use folder references only, if some kind of assets should be dynamically inserted into the project. For normal project files like classes it is good practice to use groups. – balazs630 May 24 '18 at 00:31
  • 3
    I'm looking for a solution too, that's very important to support Xcode 9 group/folder linked – Rico Crescenzio May 28 '18 at 11:47
  • 1
    Updated the original question with a temp workaround. – balazs630 Oct 05 '18 at 09:11

2 Answers2

1

Here is what you need to do. In the node section specify the group before naming the file.

<key>Nodes</key>
<array>
<string>MyGroup/File.swift:comments</string>
<array>

Next in the definitions provide the group name in the key like so:

<key>Definitions</key>
<dict>
<key>MyGroup/File.swift</key>
<dict>
<key>Path</key>
<string>File.swift</string>
<key>Group</key>
<string>MyGroup</string>
</dict>

Hopefully this will help.

8azan
  • 148
  • 1
  • 10
0

For That purpose one can use Components as used in imessages template

Example of component is

<key>Components</key>
    <array>
        <dict>
            <key>Identifier</key>
            <string>com.apple.dt.unit.messagesextensioncomponentios</string>
            <key>Name</key>
            <string>___PACKAGENAME___ MessagesExtension</string>
            <key>ProductBuildPhaseInjections</key>
            <array>
                <dict>
                    <key>TargetIdentifier</key>
                    <string>com.apple.dt.messagesOnlyApp</string>
                </dict>
            </array>
        </dict>
    </array>
Rizwan Mehboob
  • 1,333
  • 17
  • 19
  • Nice finding but components are always created outside of the main application folder as I know. Note that my group hierarchy is inside the 'Example' folder. I'm sure there is something to do with the 'Name' key because when you change a group into a group with linked folder, in the project.pbxproj xml file this 'Name' key appears for the changed group. – balazs630 May 30 '18 at 09:54