Xcode: What is a target and scheme in plain language?
Asked Answered
R

6

290

Yeah the title says it :-) What do they mean in plain English language? I really don't understand the explanation on Apple's website and I need to rename my target and I'm afraid that nothing works after that..

Richela answered 17/12, 2013 at 14:59 Comment(2)
Docs: developer.apple.com/library/content/featuredarticles/…Jolenejolenta
worth reading blog.just2us.com/2009/07/…Cataclysm
P
397

I've added in Workspace and Project too!

  • Workspace - Contains one or more projects. These projects usually relate to one another
  • Project - Contains code and resources, etc. (You'll be used to these!)
  • Target - Each project has one or more targets.
    • Each target defines a list of build settings for that project
    • Each target also defines a list of classes, resources, custom scripts etc to include/ use when building.
    • Targets are usually used for different distributions of the same project.
      • For example, my project has two targets, a "normal" build and an "office" build that has extra testing features and may contain several background music tracks and a button to change the track (as it currently does).
      • You'll be used to adding classes and resources to your default target as you add them.
      • You can pick and choose which classes / resources are added to which target.
        • In my example, I have a "DebugHandler" class that is added to my office build
      • If you add tests, this also adds a new target.
  • Scheme - A scheme defines what happens when you press "Build", "Test", "Profile", etc.
    • Usually, each target has at least one scheme
    • You can autocreate schemes for your targets by going to Scheme > Manage Schemes and pressing "Autocreate Schemes Now"
Polly answered 17/12, 2013 at 15:20 Comment(7)
Let's try if I understood correctly...I'm programming an app and make two targets. One which I'll upload to the app store and one in which I develop already the next version of the same app. And in schemes I make for example one scheme in both targets to run and one scheme for debug? But why do I need different schemes for that? I didn't understand the advantage of that of BJ Homer..Richela
FWIW, I don't use different schemes for release and debug unless I'm adding extra debug features like I describe in my answer.Polly
what do you mean that your office build has a music button in the bottom. Does your actual app have extra code that is only activated in the office build or is the music ran on your mac. Sorry I'm confusedPermian
This kind of defines what things make up each concept, but not the purpose of each item. To me thats what the OP was asking about.Schopenhauer
does xcodebuild build --workspace has any connection with Scheme 's Build?Blanket
@Permian Let me share a different example. Suppose you were a company that managed the codebase of both Uber and Lyft (two very big car riding companies). The code base has a lot similarities. Both would have passengers/drivers/maps/itineraries, etc. You wouldn't want to write those objects for each code base. Instead in your project, you would have an Uber target and a Lyft target. And then for each target you can have a different plist, app icon, etc. Some classes can be only for the Uber target, or only Lyft target. But for the most case, they would be for the same target. (1/2)Jaco
Additionally you could have a precompiler flag/variable that is different per scheme and access that in Xcode and compile code of a single file differently (2/2)Jaco
B
87

A target is an end product created by running "build" in Xcode. It might be an app, or a framework, or static library, or a unit test bundle. Whatever it is, it generally corresponds to a single item in the "built products" folder.

A scheme represents a collection of targets that you work with together. It defines which targets are used when you choose various actions in Xcode (Run, Test, Profile, etc.) Often, you will have just one scheme, which uses the main app target for the Run, Archive, and Profile actions, and a unit test target for the Test action. If you were building two related apps, you might have two schemes that used the same unit test bundle but different app targets.

The main benefit of schemes (introduced in Xcode 4) is that they allow you to switch between running your app and your unit tests without needing to toggle the selected target.

Bogle answered 17/12, 2013 at 15:17 Comment(1)
Your answer is almost correct. The way Apple describes these are slightly different. See my answer below. A target is not the end product. Based on Apple 'A target contains the instructions to build one thing like an app or a framework.'. A scheme doesn't necessarily represent a collection of targets. It just defines how to do a certain action.Jaco
V
74

I am a visual person, hence to explain the concept I will be using a diagram.

When you have multiple targets they can be one-to-one matched with Xcode's Run,Test,Profile actions, this concept defines a scheme

enter image description here

A target is a version of your Project,i.e targets differ slightly in classes & resources to use during built time. A project can have multiple built time setting for separate distribution requirements.

Vogel answered 17/5, 2015 at 21:10 Comment(4)
This diagram seems wrong. A scheme should be tied to a particular target, I am not seeing where within a scheme you can have multiple targets.Eisenstein
@Eisenstein No, carelesslyChoosy is correct. In the scheme editor, click the 'build' item at left. In the right hand area, click '+' and you can add more targets to this scheme. Tick the boxes as desired. These targets' executables are then available in the other actions (Run, Profile, etc) in the executable drop-down.Utta
This is good but it is missing the build configuration part of schemes. I think of scheme as a collection of how actions (Run, Test, Profile) match to a combination of targets and build configurations (debug, release, qa, prod, etc).Religiosity
@Eisenstein This answer is a bit confusing. It's highly unlikely that you would use a target that can be used for both run & test action of a scheme. However it is very likely that you have multiple targets under the same test action of a single scheme. Meaning it's generally best to have different tests targets. i.e. one for unit-tests, another for performance tests, another for UI tests. By doing that you can have Multiple targets under the test action of a single scheme Or have each test target ran by a unique test action of a scheme. For more in the semi answer belowJaco
G
23

Xcode structure

Workspace  
  -> Project 
    -> Target 
     -> Dependency 
      -> Scheme 
        -> Action
        -> Build Configuration  
          -> Build Configuration File(.xcconfig) 

Workspace (.xcworkspace) - is a container of multiple projects. It was created as a next step of cross-project references[About]

  • Workspace contains all schemes from included projects
  • Workspace handles all implicit dependencies[About]

Observations:

  • It is safe to work with different projects inside the same workspace and do not catch
//if you try to open two projects on two Xcode instances
Couldn't load Project.xcodeproj because it is already opened from another project or workspace
  • Cocoapods[About] working with workspace where creates Pods project

Project (.xcodeproj) - It is a container for targets and scheme. It defines code files, resources...

Also Projects manages Build Configuration(changed by scheme) and Build Configuration File[About]

You can convert existing Project into Workspace

File -> Save As Workspace...

[Workspace vs Project]

Target - PBXNativeTarget section. Defines a specific set of build settings that generate:

  • Application target
  • Library and framework targets
  • Test
  • Aggregate[About]. E.g. it is used to create a Universal framework or Umbrella framework

Scheme

Contains action(run, test, profile, analyze, archive) + configuration(additional arguments, [Build Configuration], diagnostic)

Scheme can be shared which helps you in CI, Carthage[Example]... and located:

<project_path>/<project_name>.xcodeproj/xcshareddata/xcschemes

Dependency - Targets can have dependencies. Dependency is a source link against. These dependencies can be linked statically or dynamically[About] There are two types of them:

  • Explicit Dependency[About] - Source code of the dependency that is located in the same project or nested project
  • Implicit Dependency[About] - Source/closed code of the dependency that is located in the project that is a part of the same workspace.

[Vocabulary]

Glade answered 6/12, 2019 at 15:17 Comment(0)
J
15

tldr; Targets contain instructions to build a module/framework/library or an App/end Product e.g. instructions to build a watchOS app and an iOS App. Schemes know how to respond to certain actions e.g. a build action or test action or archive action.

Make sure you See WWDC16 video — Introduction to Xcode [45:13]. If you wanted to gain deeper knowledge then watch the entirety of the video. The video is simple to follow yet very foundational. My answer is mostly off of that.


Scheme

A scheme is how you specify what you want to run and it also contains information about how you want to run it.

For example, I could have a project with an iOS app and a Watch app, and in that case, I would have one scheme to run my iOS app and one scheme to run my Watch app

Run will run my app in the debugger.

Test will run my tests.

Profile will run my app in instruments so I can measure its performance.

Analyze will run Xcode's static analyzer and help catch problems I might otherwise have missed.

And finally, the Archive action will build my app for release and put it in the archive that I can then use to distribute to my testers or to the App Store or to save for future crash log de-symbolication, or symbolication.

Project

A project is a document that you use to organize your code an resources in Xcode.

You have references to source code files and resource files on disc, targets which actually build those files into products like your app, Build settings which configure how your targets build their products, and schemes which configure how you perform actions, such as Run, with your targets.

Now, to access your project settings, you select your project in the navigator, you select the popover at the top of the editor, and select your project there.

Target

You have references to source code files and resource files on disc, targets which actually build those files into products like your app, Build settings which configure how your targets build their products, and schemes which configure how you perform actions, such as Run [test, build], with your targets. A target contains the instructions to build one thing like an app or a framework.

The thing that your target produces is called its product. The set of steps that your target takes to build its product are called build phases.

Build Settings

And lastly, a target has Build settings to configure how it builds its product [how the code is compiled, the optimizations used and how things are linked and certain flags that get passed on to the linker and compiler. For more see here]

Now, one thing to note is that both projects and targets have Build settings, and targets inherit the value set at the project level but can override them with a target-specific value.

A target's build phases do things like cause dependencies to build first, compile the source files in that target, and link the target against libraries and frameworks.

To summarize:

Targets

Helps put a set of files together to build/run a product/module/package

  • An app you ship to app store.
  • A framework or library that is a dependency of an app.

Like a single app can have an iOS target along with a watchOS target. Or just a single iOS Target. Or a single iOS target along with a test target, etc.

If you go to your target's Build Phase >> Compile Sources you'll see every file that's being built for that target. Example:

enter image description here

To explicitly quote Apple docs:

A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product. Projects can contain one or more targets, each of which produces one product.

The instructions for building a product take the form of build settings and build phases, which you can examine and edit in the Xcode project editor. A target inherits the project build settings, but you can override any of the project settings by specifying different settings at the target level. There can be only one active target at a time; the Xcode scheme specifies the active target.

A target and the product it creates can be related to another target. If a target requires the output of another target in order to build, the first target is said to depend upon the second. If both targets are in the same workspace, Xcode can discover the dependency, in which case it builds the products in the required order. Such a relationship is referred to as an implicit dependency. You can also specify explicit target dependencies in your build settings, and you can specify that two targets that Xcode might expect to have an implicit dependency are actually not dependent. For example, you might build both a library and an application that links against that library in the same workspace. Xcode can discover this relationship and automatically build the library first. However, if you actually want to link against a version of the library other than the one built in the workspace, you can create an explicit dependency in your build settings, which overrides this implicit dependency.

Schemes

A given target can be put through different actions.

  • build
  • run
  • test
  • profile
  • archive

You can have a scheme that has all the diagnostics enabled (which makes debugging slow) vs. a scheme that doesn't have any. Or a scheme that runs certain performance related tests vs. a scheme that runs both unit-tests and performance tests. You can edit a scheme so that it performs such actions as:

  • Building multiple targets

  • Executing scripts before or after any action

  • Sending emails before or after any action

  • Running with memory management diagnostics

  • Producing either a debug or release build for any action.

For more on that see Customizing the build schemes for a project


To put it all together:

Once you hit run, Xcode will look at the selected scheme. It will find its associated target(s). Use the Build Phases of that target and its Build Settings (any Project Settings that isn't overridden by the target settings will get included) to build a product into the selected destination (the destination can be an iPhone simulator or a physical iPhone or watchOS, etc). enter image description here

AGAIN WATCH THE WWDC VIDEO!

Jaco answered 4/3, 2021 at 13:46 Comment(3)
could you please fix the video URL? unfortunately it seems redirected now :(Pernell
@Alexa289 sadly I wasn't able to find the video on youtube or on apple.com. However I uploaded the pdf from their presentations: docdro.id/kNi6PJ4 It's still worth taking a lookJaco
Here you go: wwdctogether.com/wwdc2016/413Isolationism
E
3

My take:

Target -- a lower abstraction -- various kinds of builds. Each target has its own Build Settings (so if you split into several targets, take care of that huge sheet individually for each target). Targets have a convenient way of including/excluding files, so you can configure the build effectively on a per-file basis.

Scheme -- a higher abstraction -- guides a target through various ways of deployment (Run, Test, Archive). Has modest ways of configuring the build through Environment Parameters, but employs the Build Settings from the target. Creating / editing / deleting schemes is cheaper and easier than targets.

You can have several schemes guiding one target in several different ways.

Eighth answered 3/12, 2020 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.