Xcode projects and SwiftUI views
What an Xcode project is made of, and how a SwiftUI screen is composed from views and modifiers.
Inside an Xcode project
An Xcode project records targets, build settings and file references. Since Xcode 16 the file that stores that metadata is the folder-based .xcodeproj, which merges far better in version control than the old monolithic project file did.
| Item | Purpose |
|---|---|
| Target | A product to build: the app, a widget, a test bundle |
| Build settings | Compiler flags, deployment target, bundle identifier, signing |
Info.plist | Declared capabilities, usage descriptions, launch configuration |
Assets.xcassets | App icon, accent colour, images with light and dark variants |
| Swift Package Manager | Dependency manager; packages are resolved into the project |
| Scheme | Which target runs and with what arguments and environment |
- The deployment target is the oldest iOS version that can run the build. API availability annotations let you use newer APIs conditionally.
- The bundle identifier is permanent for a given app record in App Store Connect — choose it before your first upload.
- Signing needs a team and a provisioning profile; automatic signing will create and refresh them for you in most cases.
Views and modifiers
In SwiftUI a view is a value that describes part of the screen. The body of a view returns other views, and modifiers wrap a view to change its layout, styling or behaviour.
import SwiftUI
struct Task: Identifiable {
let id = UUID()
var title: String
var isDone: Bool
}
struct TaskRow: View {
var task: Task
var body: some View {
HStack(spacing: 12) {
Image(systemName: task.isDone ? "checkmark.circle.fill" : "circle")
.foregroundStyle(task.isDone ? .green : .secondary)
Text(task.title)
.strikethrough(task.isDone)
Spacer()
}
.padding(.vertical, 4)
}
}
#Preview {
List {
TaskRow(task: Task(title: "Write the summary", isDone: false))
TaskRow(task: Task(title: "Ship the build", isDone: true))
}
}- Container views come first:
VStack,HStack,ZStack,List,ScrollView,Grid. - Modifier order matters:
.padding().background(.blue)paints a padded area, while.background(.blue).padding()paints a tight box with space around it. #Previewrenders a canvas of the view without running the app — build screens in small previewable pieces.
💡
SwiftUI recomputes
body often, so keep it cheap and free of side effects. Never start a network request or mutate state directly in body; use .task or .onAppear for that.FAQ
What is the difference between a view and a view modifier?
A view describes content; a modifier returns a new view with changed behaviour, layout or appearance. Modifiers are just views wrapped around your content, which is why their order matters.
Why does my preview fail to build?
Commonly because the preview executes real code that expects a network or a database. Inject preview data into the view instead, and keep live services behind a protocol you can stub.
Related
State and navigation Persistence and the App Store
Last refreshed 2026-09-18.