The name of a source group, and its location in the project structure group tree, can be completely independent of the name and location of the folder to which it refers.. TheInventorySe
Trang 1You use this ability of Info windows later in this chapter to reorganize some large projects and fi x the properties of targets
ORGANIZING SOURCES
This section presents several strategies for organizing source items and references in a project To illustrate how references can be confi gured, start with the very simple project pictured in Figure 5 - 8
This project is, ostensibly, an Objective - C project for inventory management It consists of four primary source
fi les: main.m , RootAppDelegate.m , InventoryServer.m , and WarehouseClient.m The three class fi les have matching header fi les, and there is a precompiled header fi le along with other Interface Builder documents and property lists in the Resources group
This section reorganizes this project four different ways, using different types and combinations of references All of these projects are available for download at http://www.wrox.com Open the Root, Root2, Root3, Root4, and RootRot projects as you work through this section These aren ’ t functional projects, and make no attempt to be They exist solely to demonstrate various source item reference strategies As you work through these different schemes, keep the following in mind:
Source items and groups are objects in the project Source fi les and folders are the physical
items in the fi lesystem
Every source item has a reference to its source fi le or folder
The name of a source group, and its location in the project structure group tree, can be completely independent of the name and location of the folder to which it refers The name
of all other types of source items is always the same as the fi le or folder to which it refers
The folder referred to by the topmost project structure group (also known as the project group) is always the project folder
Default References
In Chapter 3, you created, renamed, and deleted source groups You then moved groups around and moved source fi les into and out of groups If you used what you ’ ve learned in Chapter 3 to create the example project shown in Figure 5 - 8, you would end up with a project folder that looks like Figure 5 - 9
➤
➤
➤
➤
FIGURE 5-8
Trang 2In Chapter 3 you were probably unaware that every group you created had a folder reference The
InventoryServer.m fi le is relative to the folder referred to by the Services group, which is relative
to the folder referred to by the Classes group, which is relative to the folder referred to by the Root
project group You can see this by examining any source item ’ s reference
Now you know that all of these source items and groups use enclosing group references, which
mean they all indirectly refer to the project folder This is why all of the fi les are in the same folder
(see Figure 5 - 9)
Whenever you create a new group using the File ➪ New Group command, Xcode creates a group
with an empty path and an enclosing group reference The net effect is a kind of “ null ” folder
reference that always refers to the same folder as its parent group
Thus, the default organization of Xcode projects places all of the source fi les directly in the project
folder You are free to reorganize the hierarchy of your source groups and items to any depth you
want; the organization of the actual fi les will remain fl at For small - to medium - sized projects
that are self - contained and have no duplicate fi lenames, this is the easiest organization It is
uncomplicated and shouldn ’ t cause any surprises Better yet, you don ’ t have to worry about source
group folder references If your project falls into this category, feel free to skip ahead to the next
section now and come back here when your projects get more complex
However, if you want to control the physical organization of the fi les in your project, or your project
source fi les are already organized into multiple folders, read on
Sharing a Subfolder
Often, source fi les are already organized into a hierarchy of folders They may have been organized
this way in a former project, for source control, or by an obsessive programmer — we know who
you are The next few variations of the Root project present different techniques for grafting a
source group structure onto an existing folder structure
Figure 5 - 10 shows a reorganization of the source fi les by type All of the programming source fi les
in the Root2 project have been moved into a Source folder and the application bundle resource
fi les have been moved into a Resources folder
FIGURE 5-9
Trang 3The folder references for the Classes, Other Source, and Resources groups were changed from enclosing group to project relative The paths of the fi rst two groups were both set to Source The Resources group ’ s path was set to Resources
TIP TO REMEMBER
If you want to quickly browse the properties of several source items, open up the Inspector palette (Option+Command+I) The Inspector follows the current selection, so just click each source item to review its path and reference type
This is a variation of the default references you looked at in Root Instead of lumping everything together in the project folder, a few key folders are designated as gathering places for a broad collection of assets The Source folder contains all of the program source fi les In the project, the Classes, Services, Client, and Other Sources groups all refer to the same folder
This allows fi ne - grained organization within the project structure group, using a coarser folder structure
This is a good organization for a medium - sized project whose fi les are grouped by type, where you just want to keep the main project folder uncluttered, or there is some other logical reason for subdividing the fi les A good application of this approach would be for a project that produced multiple targets (that is, a client and a server) The project might have broad subfolders like Common , Client , and Server , whereas the project structure group would have more detailed groups, like Utilities, Network Services, Logging, Database, and so on
By establishing a few key high - level groups anchored to a specifi c subfolder, then using default subgroups, you keep much of the fl exibility of Xcode default source group arrangement, while imposing a modest amount of structure on the actual fi les
FIGURE 5-10
Trang 4Everything is Relative
Another approach is to mirror the structure of a complex hierarchy of folders in the project group
Rather than being disconnected from the folder structure in the fi lesystem, the project source groups
mimic them verbatim This is a good solution for large projects with an extensive folder hierarchy
The folder structure in Figure 5 - 11 isn ’ t that large or extensive, but the technique applies to a
hundred folders as easily as it applies to these six
FIGURE 5-11
In this scheme, each source group uses its path to point to a specifi c subfolder within its enclosing
group ’ s folder In earlier projects, all of the source groups using an enclosing group reference type
have had empty paths — referring to the same folder as their parent group These groups all have
paths that refer to a subfolder of the enclosing group and have the same name as the folder to
which they refer The end result is a source group structure that parallels the folder structure in the
fi lesystem
In Figure 5 - 12, the Source group refers to the Source folder within the folder of its enclosing group
Its enclosing group (Server) refers to the Server folder within its enclosing group, which is the
project folder
Trang 5A few of the source items in the Root3 project are listed in the following table to illustrate the relationships
ITEM REFERENCE T YPE PATH COMPLETE PATH
Client Enclosing - group Client … /Root3/Client Resources Enclosing - group Resources … /Root3/Client/Resources Source Enclosing - group Source … /Root3/Client/Source Server Enclosing - group Server … /Root3/Server Resources Enclosing - group Resources … /Root3/Server/Resources Source Enclosing - group Source … /Root3/Server/Source
Warehouse-Client.m
Enclosing - group WarehouseClient.m … /Root3/Client/Source/
WarehouseClient.m Root - Info.plist Enclosing - group Root - Info.plist … /Root3/Server/Resources/
Root - Info.plist main.m Enclosing - group main.m … /Root3/Server/Source/main.m
FIGURE 5-12
Trang 6As you develop the project, it ’ s pretty easy to maintain the relationship between the source groups
and the fi lesystem folder structure New and imported fi les are automatically added to the correct
folder If a folder is reorganized or renamed, making the same change to its source group keeps all
enclosing references valid
You might think that setting up all of these references would be tedious — especially for the
imagined project containing hundreds of source fi les Fear not Xcode ’ s import process, described
a little later in this chapter, will create any number of nested source groups — exactly like those
described here — with a single command
Outside the Box
Conveniently, all of the references so far have been to folders inside the folder of the enclosing group
or project, but this does not have to be the case Figure 5 - 13 shows the project group and the fi les in
project folder for Root4
FIGURE 5-13
You ’ ll notice that the project includes a Client group that contains two source fi les
( WarehouseClient.h and WarehouseClient.m ) that aren ’ t in the project folder, so where
do these fi les come from? The answer can be found in the Client group ’ s properties, as shown in
Figure 5 - 14
FIGURE 5-14
Trang 7The Client group uses a project relative reference Its POSIX path refers to a subfolder of Root4 ’ s sister project, Root3 The Root4 project has included fi les outside its project folder, just as if it owned them Some selected source item references are listed in the following table
ITEM REFERENCE T YPE PATH COMPLETE PATH
Root4 fi xed Project … /Root4 Client Project - relative /Root3/Client/
Source
… /Root3/Client/Source
WarehouseClient.h Enclosing - group WarehouseClient.h … /Root3/Client/Source/
WarehouseClient.h WarehouseClient.m Enclosing - group WarehouseClient.m … /Root3/Client/Source/
WarehouseClient.m Root4AppDelegate.h Enclosing - group Root4AppDelegate.h … /Root4/Root4AppDelegate.h
Although it ’ s easier to create a single project with multiple targets, as you see in Chapter 16, this isn ’ t always possible If you must create multiple projects that need to share common assets, relative paths that refer to sister project folders is one way to share a single source fi le
A popular use for this scheme is to set up “ libraries ” of source fi les (that is, a Utilities folder full
of commonly used C functions or classes) Any number of projects can include selected fi les from the shared Utilities folder, without duplicating source fi les, or incurring the added complexity of creating a formal framework or dynamic library
A more robust solution to sharing folders amongst multiple projects is to use source trees See Chapter 21 if you have this type of folder structure
This technique can also be used to create “ shell ” projects Suppose you have a large project written for Linux in an Eclipse project folder You can create an Xcode project that uses source group paths that refer to the folders inside the Eclipse workspace folder The Xcode project wouldn ’ t have to contain anything beyond the project document and any project - specifi c fi les
The disadvantage to this technique is that it creates a rather fragile project structure:
If the fi rst project ’ s folder were renamed, the references in the second project would break
If either project were moved without the other, the references would break
If the folder structure of the fi rst project were reorganized, the references in the second proj-ect would break
Ideally, project folders are self - contained and autonomous The only references they have to assets outside the project folder are to system frameworks that never change location When the ideal isn ’ t practical, you can use relative paths to include shared assets outside the project ’ s folder
➤
➤
➤
Trang 8Bad References
It ’ s just as important to know what kind of references you should not create I left this last
project open overnight, and some mischievous pixies snuck in and decided they would have a little
fun with it
At fi rst glance, the RootRot project looks pretty much like project Root3 All of the references are
valid, and the project builds and runs — at least on my computer Things can ’ t be all bad, can they?
The following table lists a few of the references in the project
ITEM REFERENCE T YPE PATH COMPLETE PATH
RootRot fi xed project … /RootRot
Client Absolute … /RootRot/Client … /RootRot/Client
Source Enclosing - group Database … /RootRot/Source/
Database WarehouseClient.h Enclosing - group /Source/
WarehouseClient.h
… /RootRot/Client/Source/
WarehouseClient.h main.m Project - relative Server/Source/main.m … /RootRot/Server/Source/
main.m Resources Project - relative /Root3/Server/Resources … /Root3/Server/Resources
Root - Info.plist Enclosing - group Root - Info.plist … /Root3/Server/Resources/
Root - Info.plist
Here ’ s some of what ’ s going on in the RootRot project:
The Client source group uses an absolute path If you copied this project to your system —
or moved it anywhere other than where the project was originally created — the project won ’ t build because Client won ’ t refer to a valid folder, and all items that refer to Client ’ s folder will be broken
The WarehouseClient.h item was moved from the Source group to the Resources group Xcode conveniently “ fi xed ” the path of the item so that it still refers to the
WarehouseClient.h fi le that ’ s in the sister directory to Resources If the location or name
of the Source folder ever changed, this reference would break
main.m uses a project relative path If the location or name of either the Server or Source folder changed, the reference would break On the other hand, this item could be moved anywhere in the project structure group and would still refer to the main.m fi le
The second Resources group has been changed to a project relative reference that refers
to the Resources folder in the Root3 project None of the references for its subitems (like
Root - Info.plist ) has been altered Because they all use enclosing folder references, they all now refer to items in Root3 ’ s, not RootRot ’ s, project folder This could create a great deal of confusion
➤
➤
➤
➤
Trang 9Although Xcode provides you very fl exible structures for organizing and referring to your project ’ s assets, you can see that this fl exibility can be abused If you checked out a project like RootRot to a new directory, you ’ d probably end up spending more time trying to fi gure out what ’ s wrong with the project than you would building it
Best Practices
Here are some simple tips for keeping your project group functional and tidy:
Use enclosing group references unless there ’ s a compelling reason to use some other refer-ence type
Avoid references to items outside your project folder
Use project relative references to point to top - level folders within the project folder that aren ’ t likely to move, or to top - level folders outside the project that contain assets shared with other projects
When referring to assets included in an SDK or the Xcode tool, use the appropriate SDK or Xcode reference type
Never use absolute references for anything except system frameworks or other reasonably static assets, like a shared repository of development resources on a fi le server
Learn to use source trees (see chapter 21)
If your asset is a product, or any part of a product, that ’ s produced by a target, always use
a product relative reference (or an enclosing folder reference that refers to a product relative reference)
CREATING NEW SOURCE FILES
In this section you learn how to add new fi les to a project You ’ ve already created source groups
This section describes how to create new fi les and add them to your project The next section shows you how to import existing fi les and folders into a project
Unless your project is trivial, you will soon want to create new source fi les The File ➪ New File command creates a new source fi le based on a fi le template of your choosing, and adds that fi le as
a source item to your project The item is added to the currently selected group, or the group that contains the currently selected item The fi rst step to creating a new source fi le is to choose the location in the project where you want it added Now choose File ➪ New File (Command+N) or Right/Control+click a source item and choose Add ➪ New File
Figure 5 - 15 shows the New File Assistant where you choose a fi le template Most templates are self - explanatory Source fi le templates produce skeletal fi les with some basic comments and appropriate #include or #import statements The C++ and Objective - C class fi le templates declare
an empty class with the same name as the fi le
➤
➤
➤
➤
➤
➤
➤
Trang 10Many templates have other options that can be selected before creating the fi le
For example, the Objective - C template has an option to choose the base class for the new class
The UIViewController class template will optionally produce a companion NIB document
containing the UIView for the new controller Choose your desired options and click the Next
button This presents the dialog box shown in Figure 5 - 16
FIGURE 5-15
FIGURE 5-16