Getting Started
Here, you’ll find information about the how to use the Swift programming language.
If you’re new to Swift, check out A Swift Tour in The Swift Programming Language, for a quick introduction to the most important concepts and features of the language.
Installing Swift
The first step to using Swift is to download and install the compiler and other required components. Go to the Download page and follow the instructions for your target platform.
In order to follow along with the examples below,
make sure to add Swift to your $PATH
.
On macOS
The default location for the downloadable toolchain on macOS is
/Library/Developer/Toolchains
.
You can make the latest installed toolchain available for use from the terminal with the following command:
$ export TOOLCHAINS=swift
To select any other installed toolchain, use its identifier in the TOOLCHAINS
variable. The identifier can be found in toolchain’s Info.plist
file.
$ /usr/libexec/PlistBuddy -c "Print CFBundleIdentifier:" /Library/Developer/Toolchains/swift-4.0-RELEASE.xctoolchain/Info.plist
org.swift.4020170919
$ export TOOLCHAINS=org.swift.4020170919
On Linux
- Install required dependencies:
Ubuntu 18.04 | Ubuntu 20.04 | Ubuntu 22.04 | CentOS 7 | Amazon Linux 2 |
---|---|---|---|---|
|
|
|
|
|
If you installed the Swift toolchain on Linux to a directory other than the system root, you will need to run the following command, using the actual path of your Swift installation:
$ export PATH=/path/to/Swift/usr/bin:"${PATH}"
On Windows
Dependencies
Swift has the following general dependencies:
-
Git (used by Swift Package Manager)
-
Python1 (used by the debugger - lldb)
Windows has the following additional platform specific dependencies:
-
Windows SDK (provides the Windows headers and import libraries)
-
Visual Studio (provides the Visual C++ SDK/Build Tools for additional headers)
Enabling Developer Mode
In order to develop applications, particularly with the Swift Package Manager, you will need to enable developer mode. Please see Microsoft’s documentation for instructions for enabling developer mode.
Installation Instructions
Install using the Windows Package Manager
The Windows Package Manager can be found in the App Store or be installed directly.
Install using Scoop
# Optional: Needed to run a remote script the first time
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# Command for installing scoop
Invoke-RestMethod -Url 'get.scoop.sh' | Invoke-Expression
-
Install required dependencies:
The platform dependencies cannot be installed through the currently supported package managers as the install rules do not install the components necessary. They will be installed through Visual Studio installer.
With Winget (Windows Package Manager):
winget install Git.Git winget install Python.Python.3.10 curl -sOL https://aka.ms/vs/16/release/vs_community.exe start /w vs_community.exe --passive --wait --norestart --nocache ^ --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community" ^ --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ^ --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 del /q vs_community.exe
With Scoop:
# Scoop already comes pre-installed with Git, so no need to re-install it. scoop bucket add versions scoop install python310 curl -sOL https://aka.ms/vs/16/release/vs_community.exe start /w vs_community.exe --passive --wait --norestart --nocache ^ --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community" ^ --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ^ --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 del /q vs_community.exe
Start up a new Command Prompt/Powershell Prompt and install the Python library six.
pip install six
-
Install Swift:
Swift can be installed through the official installer directly, or using the Windows Package Manager as well. Notice that Windows Package Manager release may be behind the official release.
- Using the official installer:
- Download the latest package release.
- Run the package installer.
- Using the Windows Package Manager:
winget install Swift.Toolchain
- Using Scoop:
scoop install swift
- Using the official installer:
A Swift toolchain will be installed at %SystemDrive%\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain
. A compatible Swift SDK will be installed at %SystemDrive%\Library\Developer\Platforms\Windows.platform\Developer\SDKs\Windows.sdk
.
Traditional Installation
NOTE: The traditional installation process is required for Swift older than 5.4.2.
Swift has been tested with Visual Studio 2019. You will need to install Visual Studio with the following components. The installer for Swift is available in the Download section. The toolchain on Windows is installed to %SystemDrive%\Library\Developer\Toolchains
.
The following Visual Studio components are required:
Component | Visual Studio ID |
---|---|
MSVC v142 - VS 2019 C++ x64/x86 build tools (Latest) | Microsoft.VisualStudio.Component.VC.Tools.x86.x64 |
Windows 10 SDK (10.0.17763.0)2 | Microsoft.VisualStudio.Component.Windows10SDK.17763 |
The following additional Visual Studio components are recommended:
Component | Visual Studio ID |
---|---|
Git for Windows | Microsoft.VisualStudio.Component.Git |
Python 3 64-bit (3.7.8) | Component.CPython.x64 |
The following additional Visual Studio component is suggested:
Component | Visual Studio ID |
---|---|
C++ CMake tools for Windows | Microsoft.VisualStudio.Component.VC.CMake.Project |
Support Files
NOTE: This is only required for versions older than 5.4.2
You must use the x64 Native Tools for VS2019 Command Prompt
to run the following steps. The x64 Native Tools for VS2019 Command Prompt
runs the DevEnv
script from Visual Studio that sets up the necessary environment variables to find the system headers.
In order to make the Windows SDK accessible to Swift, it is necessary to deploy a few files into the Windows SDK. The following will modify your Visual Studio Installation, and as such will require to be run from an (elevated) “Administrator” x86 Native Tools for VS2019 Command Prompt
.
copy /Y %SDKROOT%\usr\share\ucrt.modulemap "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap"
copy /Y %SDKROOT%\usr\share\visualc.modulemap "%VCToolsInstallDir%\include\module.modulemap"
copy /Y %SDKROOT%\usr\share\visualc.apinotes "%VCToolsInstallDir%\include\visualc.apinotes"
copy /Y %SDKROOT%\usr\share\winsdk.modulemap "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap"
Because it is installing the files into the Visual Studio image, the files will need to be copied each time Visual Studio is updated.
Repairing after Visual Studio Updates
If Visual Studio is updated, you may have to repair the installation. See Microsoft’s instructions for repairing installed programs.
Swift Version
You can verify that you are running the expected version of Swift
by entering the swift
command and passing the --version
flag:
$ swift --version
Apple Swift version 2.2-dev (LLVM ..., Clang ..., Swift ...)
The -dev
suffix on the version number
is used to indicate that it’s a development build,
not a released version.
Using the REPL
If you run swift repl
without any other arguments,
you’ll launch the REPL, an interactive shell
that will read, evaluate, and print the results
of any Swift code you enter.
$ swift repl
Welcome to Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50).
Type :help for assistance.
1>
Interacting with the REPL is a great way to experiment with Swift.
For example, if you enter the expression 1 + 2
,
the result of the expression, 3
, is printed on the next line:
1> 1 + 2
$R0: Int = 3
You can assign values to constants and variables,
and use them in subsequent lines.
For instance, the String
value Hello, world!
can be assigned to the constant greeting
,
and then passed as an argument to the print(_:)
function:
2> let greeting = "Hello!"
greeting: String = "Hello!"
3> print(greeting)
Hello!
If you enter an invalid expression, the REPL will print an error showing where the problem occurred:
let answer = "forty"-"two"
error: binary operator '-' cannot be applied to two 'String' operands
let answer = "forty"-"two"
~~~~~~~^~~~~~
You can use the up-arrow and down-arrow keys (↑
and ↓
)
to cycle through previous lines entered into the REPL.
This allows you to make a slight change to a previous expression
without retyping the entire line,
and is especially convenient for fixing errors like the one in the previous example:
let answer = "forty-two"
answer: String = "forty-two"
Another useful feature of the REPL
is that it can automatically suggest functions and methods
that can be used in a particular context.
For example, if you enter re
after a dot operator on a String
value
and then hit the tab key (⇥
),
the REPL will give a list of available completions
like remove(at:)
and replaceSubrange(bounds:with:)
:
5> "Hi!".re⇥
Available completions:
remove(at: Index) -> Character
removeAll() -> Void
removeAll(keepingCapacity: Bool) -> Void
removeSubrange(bounds: ClosedRange<Index>) -> Void
removeSubrange(bounds: Range<Index>) -> Void
replaceSubrange(bounds: ClosedRange<Index>, with: C) -> Void
replaceSubrange(bounds: ClosedRange<Index>, with: String) -> Void
replaceSubrange(bounds: Range<Index>, with: C) -> Void
replaceSubrange(bounds: Range<Index>, with: String) -> Void
reserveCapacity(n: Int) -> Void
If you start a block of code,
such as when iterating over an array with a for-in
loop,
the REPL will automatically indent the next line,
and change the prompt character from >
to .
to indicate that code entered on that line
will only be evaluated when the entire code block is evaluated.
6> let numbers = [1,2,3]
numbers: [Int] = 3 values {
[0] = 1
[1] = 2
[2] = 3
}
7> for n in numbers.reversed() {
8. print(n)
9. }
3
2
1
All of the functionality of Swift is available to you from the REPL, from writing control flow statements to declaring and instantiating structures and classes.
You can also import any available system modules,
such as Darwin
on macOS and Glibc
on Linux:
On macOS
1> import Darwin
2> arc4random_uniform(10)
$R0: UInt32 = 4
On Linux
1> import Glibc
2> random() % 10
$R0: Int32 = 4
On Windows
The REPL depends on Python bindings. You must ensure that Python 3.7 is available
in the path. The following command adds Python 3.7 from Visual Studio to %PATH%
so that it can be used:
path %ProgramFiles(x86)%\Microsoft Visual Studio\Shared\Python37_64;%PATH%
Because the Windows installation separates out the SDK from the toolchain, a few extra parameters must be passed to the REPL. This allows you to use multiple different SDKs with the same toolchain.
set SWIFTFLAGS=-sdk %SDKROOT% -I %SDKROOT%/usr/lib/swift -L %SDKROOT%/usr/lib/swift/windows
swift repl -target x86_64-unknown-windows-msvc %SWIFTFLAGS%
Using the Package Manager
Swift package manager provides a convention-based system for building libraries and executables, and sharing code across different packages.
These examples assume you have made swift
available in your path;
see Installing for more information.
Once available, you can invoke the package manager tools: swift package
, swift run
, swift build
and swift test
.
$ swift package --help
OVERVIEW: Perform operations on Swift packages
...
Creating a Package
To create a new Swift package, first create and enter a directory named Hello
:
$ mkdir Hello
$ cd Hello
Every package must have a manifest file called Package.swift
in its root directory.
You can create a minimal package named Hello
using:
$ swift package init
By default the init command will create a library package directory structure:
├── Package.swift
├── README.md
├── Sources
│ └── Hello
│ └── Hello.swift
└── Tests
├── HelloTests
│ └── HelloTests.swift
└── LinuxMain.swift
You can use swift build
to build a package. This will download, resolve and compile dependencies mentioned
in the manifest file Package.swift
.
$ swift build
Compile Swift Module 'Hello' (1 sources)
To run the tests for a package, use: swift test
$ swift test
Compile Swift Module 'HelloTests' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/HelloPackageTests.xctest/Contents/MacOS/HelloPackageTests
Test Suite 'All tests' started at 2016-08-29 08:00:31.453
Test Suite 'HelloPackageTests.xctest' started at 2016-08-29 08:00:31.454
Test Suite 'HelloTests' started at 2016-08-29 08:00:31.454
Test Case '-[HelloTests.HelloTests testExample]' started.
Test Case '-[HelloTests.HelloTests testExample]' passed (0.001 seconds).
Test Suite 'HelloTests' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'HelloPackageTests.xctest' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'All tests' passed at 2016-08-29 08:00:31.455.
Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds
Building an Executable
A target is considered as an executable if it contains a file named main.swift
.
The package manager will compile that file into a binary executable.
In this example,
the package will produce an executable named Hello
that outputs “Hello, world!”.
First create and enter a directory called Hello
:
$ mkdir Hello
$ cd Hello
Now run the swift package’s init command with executable type:
$ swift package init --type executable
Use the swift run
command to build and run the executable:
$ swift run Hello
Compile Swift Module 'Hello' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/Hello
Hello, world!
Note: Since there is only one executable in this package, we can omit the
executable name from the swift run
command.
You can also compile the package by running the swift build
command and then run
the binary from .build directory:
$ swift build
Compile Swift Module 'Hello' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/Hello
$ .build/x86_64-apple-macosx10.10/debug/Hello
Hello, world!
As a next step, let’s define a new sayHello(name:)
function
in a new source file, and have the executable call that
instead of calling print(_:)
directly.
Working with Multiple Source Files
Create a new file in the Sources/Hello
directory called Greeter.swift
,
and enter the following code:
func sayHello(name: String) {
print("Hello, \(name)!")
}
The sayHello(name:)
function takes a single String
argument
and prints our “Hello” greeting before, substituting the word “World”
with the function argument.
Now, open main.swift
again, and replace the existing contents with the following code:
if CommandLine.arguments.count != 2 {
print("Usage: hello NAME")
} else {
let name = CommandLine.arguments[1]
sayHello(name: name)
}
Rather than using a hardcoded name as before,
main.swift
now reads from the command line arguments.
And instead of invoking print(_:)
directly,
main.swift
now calls the sayHello(name:)
method.
Because the method is part of the Hello
module,
no import
statement is necessary.
Run swift run
and try out the new version of Hello
:
$ swift run Hello `whoami`
To learn about the Swift Package Manager, including how to build modules, import dependencies, and map system libraries, see the Swift Package Manager section of the website.
To learn more about Package Plugins, see Getting Started with Plugins.
Using the LLDB Debugger
You can use the LLDB debugger to run Swift programs step-by-step, set breakpoints, and inspect and modify program state.
As an example,
consider the following Swift code,
which defines a factorial(n:)
function,
and prints the result of calling that function:
func factorial(n: Int) -> Int {
if n <= 1 { return n }
return n * factorial(n: n - 1)
}
let number = 4
print("\(number)! is equal to \(factorial(n: number))")
Create a file named Factorial.swift
with the code above,
and run the swiftc
command,
passing the filename as a command line argument,
along with the -g
option to generate debug information.
This will create an executable named Factorial
in the current directory.
$ swiftc -g Factorial.swift
$ ls
Factorial.dSYM
Factorial.swift
Factorial*
Instead of running the Factorial
program directly,
run it through the LLDB debugger
by passing it as a command line argument to the lldb
command.
$ lldb Factorial
(lldb) target create "Factorial"
Current executable set to 'Factorial' (x86_64).
This will start an interactive console that allows you to run LLDB commands.
For more information about LLDB commands, see the LLDB Tutorial.
Set a breakpoint on line 2 of the factorial(n:)
function
with the breakpoint set
(b
) command,
to have the process break each time the function is executed.
(lldb) b 2
Breakpoint 1: where = Factorial`Factorial.factorial (Swift.Int) -> Swift.Int + 12 at Factorial.swift:2, address = 0x0000000100000e7c
Run the process with the run
(r
) command.
The process will stop at the call site of the factorial(n:)
function.
(lldb) r
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14dfdf, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
1 func factorial(n: Int) -> Int {
-> 2 if n <= 1 { return n }
3 return n * factorial(n: n - 1)
4 }
5
6 let number = 4
7 print("\(number)! is equal to \(factorial(n: number))")
Use the print
(p
) command
to inspect the value of the n
parameter.
(lldb) p n
(Int) $R0 = 4
The print
command can evaluate Swift expressions as well.
(lldb) p n * n
(Int) $R1 = 16
Use the backtrace
(bt
) command
to show the frames leading to factorial(n:)
being called.
(lldb) bt
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=4) -> Swift.Int + 12 at Factorial.swift:2
frame #1: 0x0000000100000daf Factorial`main + 287 at Factorial.swift:7
frame #2: 0x00007fff890be5ad libdyld.dylib`start + 1
frame #3: 0x00007fff890be5ad libdyld.dylib`start + 1
Use the continue
(c
) command
to resume the process until the breakpoint is hit again.
(lldb) c
Process 40246 resuming
Process 40246 stopped
* thread #1: tid = 0x14e393, 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000e7c Factorial`Factorial.factorial (n=3) -> Swift.Int + 12 at Factorial.swift:2
1 func factorial(n: Int) -> Int {
-> 2 if n <= 1 { return n }
3 return n * factorial(n: n - 1)
4 }
5
6 let number = 4
7 print("\(number)! is equal to \(factorial(n: number))")
Use the print
(p
) command again
to inspect the value of the n
parameter
for the second call to factorial(n:)
.
(lldb) p n
(Int) $R2 = 3
Use the breakpoint disable
(br di
) command
to disable all breakpoints
and the continue
(c
) command
to have the process run until it exits.
(lldb) br di
All breakpoints disabled. (1 breakpoints)
(lldb) c
Process 40246 resuming
4! is equal to 24
Process 40246 exited with status = 0 (0x00000000)
Now that you’ve been introduced to the Swift REPL, build system, and debugger, here are a few suggestions for what to do next:
- Check out the Package Manager project page for a deep dive into the Swift build system and package manager.
- Read Contributing to Swift to learn about the different ways you can participate in the Swift community.
- Go to developer.apple.com/swift for additional Swift resources, including videos, sample code, and playgrounds.