Swift — nowoczesny język programowania firmy Apple, zaprezentowany na WWDC 2014 jako następca Objective-C. Swift łączy bezpieczne typowanie, automatyczne zarządzanie pamięcią ARC (Automatic Reference Counting) i podejście zorientowane na protokoły. Swift Programming Language — główne źródło informacji o składni i standardowej bibliotece języka.
Najważniejsze
Swift — wieloparadygmatowy język programowania opracowany przez Apple dla iOS, macOS, watchOS, tvOS i visionOS. Kluczowe cele języka: bezpieczeństwo, szybkość i wyrazistość składni. Swift używa kompilatora LLVM i generuje zoptymalizowany kod maszynowy, porównywalny wydajnością z C++.
Od premiery w 2014 roku Swift przeszedł przez 6 głównych wersji. Swift 6 (2024) wprowadził pełny model data-race safety poprzez ścisłą kontrolę izolacji kodu współbieżnego. Według GitHub Octoverse 2025, Swift znajduje się w top-10 języków pod względem wzrostu społeczności, wyprzedzając Rust i Kotlin w tempie adopcji na platformach Apple.
Swift jest otwarty i wieloplatformowy — kod źródłowy jest opublikowany na GitHub (Swift Open Source). Oprócz platform Apple, Swift jest używany na Linux i Windows do programowania serwerowego (Vapor, Hummingbird), choć głównym obszarem zastosowania pozostaje tworzenie aplikacji mobilnych i desktopowych w ekosystemie Apple.
Główne powody przejścia: Swift eliminuje całe klasy błędów możliwych w Objective-C. Type safety zapobiega niezgodności typów na etapie kompilacji. Optionals eliminują nil-rozwiązania. ARC jest wbudowany od pierwszego dnia, w przeciwieństwie do MRC/ARC w Objective-C. Składnia Swifta jest krótsza i czytelniejsza — badania wskazują na redukcję objętości kodu o 30-40% w porównaniu z Objective-C przy rozwiązywaniu podobnych zadań.
Podstawowa składnia Swifta łączy znane konstrukcje podobne do C z elementami języków funkcyjnych. Zmienne deklaruje się przez var, stałe — przez let. Kompilator używa type inference, więc jawne podanie typu jest wymagane tylko w przypadku niejednoznaczności.
import Foundation
// Stałe i zmienne
let name = "Swift"
var version = 6.0
var count: Int = 42
// Funkcje z parametrami domyślnymi
func greet(person: String, greeting: String = "Hello") -> String {
return "\(greeting), \(person)!"
}
// Guard-let do wczesnego wyjścia
func parse(input: String?) -> Int {
guard let value = input, let number = Int(value) else {
return 0
}
return number
}Switch i pattern matching w Swifcie są potężniejsze niż w C i Kotlin. Switch obsługuje dopasowywanie z krotkami, zakresami, warunkami where i wiązaniem wartości. Kompilator sprawdza wyczerpujący zakres wszystkich case — brak default nie jest błędem, jeśli wszystkie możliwe wartości są pokryte.
let point = (x: 3, y: -1)
switch point {
case (0, 0):
print("Punkt początkowy")
case let (x, y) where x == y:
print("X równa się Y")
case let (x, y) where abs(y) > x:
print("Y jest większe od X modulo")
default:
print("Punkt (\("point.x), \(point.y))")
}Optionals — centralna koncepcja Swifta, rozwiązująca problem null-referencji na poziomie systemu typów. Optional<Wrapped> to enum z dwoma case: .none (nil) i .some(Wrapped). Kompilator zabrania używania Optional bez jawnej weryfikacji, co eliminuje całą klasę błędów wykonawczych.
var optionalString: String? = "Hello"
optionalString = nil // dozwolone
// Optional Binding — bezpieczne wyodrębnienie
if let text = optionalString {
print("Tekst: \("text)")
} else {
print("Brak wartości")
}
// Optional Chaining — bezpieczny dostęp do właściwości
let length = optionalString?.count ?? 0
// Operator nil-coalescing
let greeting = optionalString ?? "Default"Optional Chaining z operatorem ?. pozwala bezpiecznie wywoływać metody i uzyskiwać dostęp do właściwości wartości opcjonalnej. Jeśli łańcuch zostanie przerwany przez nil, wynikiem całego wyrażenia jest nil. Nil-coalescing (??) dostarcza wartość domyślną i jest szeroko stosowany w kodzie UI do wyświetlania tekstu zastępczego.
Protocols w Swifcie definiują kontrakt — zestaw właściwości i metod. W przeciwieństwie do interfejsów Javy, Swift protocols mogą mieć domyślne implementacje przez protocol extensions. To podstawa Protocol-Oriented Programming, zalecanego przez Apple podejścia zamiast dziedziczenia klas.
protocol NamedEntity {
var name: String { get }
func description() -> String
}
// Domyślna implementacja przez extension
extension NamedEntity {
func description() -> String {
return "Entity: \(name)"
}
}
// Konformizm przez extension
extension String: NamedEntity {
var name: String { return self }
}Protocol Extensions pozwalają dodawać metody do protokołu bez modyfikacji każdego typu go implementującego. Jest to szczególnie przydatne do dodawania wspólnych narzędzi: map, filter, reduce dla Sequence, czy Codable dla serializacji JSON. Apple zbudowało wiele frameworków (SwiftUI, Combine) na protokołach z rozszerzeniami.
Closures w Swifcie — anonimowe funkcje przechwytujące zmienne z zewnętrznego kontekstu. Składniowo closures są podobne do lambd w Kotlin, ale z bardziej elastyczną składnią: trailing closure, shorthand argument names ($0, $1) i autoclosures.
// Domknięcie z przechwytywaniem kontekstu
let numbers = [5, 3, 8, 1, 9]
// Trailing closure syntax
let sorted = numbers.sorted { $0 < $1 }
// Łańcuch funkcyjny
let result = numbers
.filter { $0 > 3 }
.map { $0 * 2 }
.reduce(0, +)
// Domknięcie jako parametr funkcji
func performAsync(completion: @escaping (Result<Data, Error>) -> Void) { }@escaping closures są używane, gdy domknięcie wykonuje się po powrocie z funkcji — typowo dla zapytań sieciowych i operacji asynchronicznych. @autoclosure automatycznie opakowuje wyrażenie w closure, co jest używane w assert i logice short-circuit.
Wybór między struct a class — jedna z pierwszych decyzji przy projektowaniu modelu w Swifcie. Apple zaleca używanie struct domyślnie (value-typ) i przejście do class (reference-typ) tylko w przypadku potrzeby dziedziczenia lub identyfikacji przez referencję.
| Cecha | Struct | Class |
|---|---|---|
| Sposób przekazywania | Przez wartość (kopia) | Przez referencję |
| Dziedziczenie | Nie jest wspierane | Jest wspierane |
| Zarządzanie ARC | Nie jest wymagane | ARC (licznik referencji) |
| Deinicjalizator deinit | Brak | Tak |
| Mutowalność | mutating func do zmiany właściwości | Każda metoda może zmieniać |
| Przechowywanie w kolekcjach | Kopiowane przy wstawianiu | Przechowywana referencja |
Value-typy (struct) są bezpieczniejsze w środowisku wielowątkowym — każdy wątek otrzymuje niezależną kopię. Reference-typy (class) są niezbędne do pracy z UIKit (UIView, UIViewController), gdzie wymagana jest tożsamość referencyjna i dziedziczenie od klas systemowych.
ARC (Automatic Reference Counting) — system zarządzania pamięcią Swifta dla reference-typów. Kompilator wstawia retain/release w czasie wykonania, śledząc liczbę silnych referencji do obiektu. Gdy licznik osiągnie zero, obiekt jest natychmiast zwalniany.
Głównym problemem ARC są retain cycles (cykliczne referencje). Gdy dwa obiekty trzymają silne referencje jeden do drugiego, pamięć nie jest zwalniana. Rozwiązaniem są słabe referencje weak (automatycznie stają się nil przy zwolnieniu) i referencje unowned (gwarantujące, że obiekt żyje).
class ProfileViewController: UIViewController {
var onLogout: (() -> Void)?
func setupHandler() {
// [weak self] zapobiega retain cycle
onLogout = { [weak self] in
guard let self else { return }
self.dismiss(animated: true)
}
}
}Aby zapobiec retain cycles w domknięciach, używaj [weak self] z guard let self = self else { return }. Ta zasada jest szczególnie ważna w UIKit, gdzie ViewController trzyma silne referencje do swoich właściwości, a domknięcia wewnątrz tych właściwości odnoszą się do ViewController.
Często zadawane pytania
Swift obsługuje Int, Double, Float, String, Bool, Array, Set, Dictionary i krotki (tuples). Typy liczbowe mają stały rozmiar: Int8, Int16, Int32, Int64 i bezznakowe UInt. Do pracy z datami używany jest Date z Foundation, dla danych — Data.
Optional — enum z dwoma case: .none (nil) i .some(Wrapped). Swift wymaga jawnego sprawdzenia Optional przez if let, guard let lub ??, co eliminuje NullPointerException. Opcjonalne łańcuchy (?.) pozwalają bezpiecznie uzyskiwać dostęp do właściwości zagnieżdżonych wartości opcjonalnych.
Struct — value-typ, kopiowany przy przypisaniu, nie obsługuje dziedziczenia, nie wymaga ARC. Class — reference-typ, przekazywany przez referencję, obsługuje dziedziczenie i deinicjalizatory. Apple zaleca struct jako domyślny typ.
ARC automatycznie zlicza silne referencje do obiektów klas. Gdy licznik spadnie do zera, pamięć jest zwalniana. Aby zapobiec cyklicznym referencjom, używaj weak (automatyczny nil) i unowned (gwarantowany czas życia). ARC nie ma zastosowania do struct i enum.
Protocol-Oriented Programming — podejście wykorzystujące protokoły z rozszerzeniami zamiast hierarchii klas. Protokoły mogą zawierać domyślne implementacje metod przez protocol extensions. Pozwala to na ponowne wykorzystanie kodu bez dziedziczenia, zachowując elastyczność i testowalność.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również