Do-Catch — konstrukce jazyka Swift pro zpracování chyb, která zachycuje výjimky vyhozené pomocí throw a provádí odpovídající blok kódu. Na rozdíl od tradičního try-catch v jiných jazycích, Swift vyžaduje explicitní označení funkcí, které mohou vyhodit chybu, modifikátorem throws. Podle Swift.org, 2026 je Do-Catch hlavním mechanismem zpracování chyb v Swift, který zajišťuje bezpečnost na úrovni typů.
Hlavní body
Do-Catch — je konstrukce v Swift sestávající z bloku do, uvnitř kterého se provádí kód schopný vyhodit chybu, a jednoho nebo více bloků catch, které tuto chybu zpracovávají. Blok do obsahuje volání throwing-funkcí označené try a catch bloky porovnávají chybu podle typu.
Swift implementuje model strukturovaného zpracování chyb, odlišný od výjimek v Objective-C. Zde chyba není exception s rozbalováním zásobníku, ale hodnota odpovídající protokolu Error. Vyhození chyby pomocí throw předává řízení nejbližšímu catch bloku bez režie rozbalování zásobníku.
Klíčová vlastnost Swift — explicitnost zpracování. Překladač neumožňuje volat throwing-funkci bez try, do-catch nebo alternativního mechanismu (try?, try!). To eliminuje situace, kdy chyba zůstává nepovšimnuta.
Základem zpracování chyb v Swift je protokol Error. Jakýkoli typ odpovídající tomuto protokolu může být vyhozen pomocí throw. Obvykle se chyby definují jako enum s potvrzením Error.
Error — prázdný protokol (marker). Nevyžaduje implementaci metod, pouze potvrzení shody. Překladač Swift používá Error pro statickou kontrolu: funkce s throws může vyhodit pouze hodnotu odpovídající Error.
Funkce označená throws musí být volána s try. Pokud uvnitř takové funkce dojde k throw, řízení je předáno volajícímu do-catch. Pokud chyba není zpracována nikde v řetězci volání, je propagována na vyšší úroveň.
enum FileError: Error {
case notFound
case permissionDenied
case corrupted(String)
}
func readFile(path: String) throws -> String {
guard FileManager.default.fileExists(atPath: path) else {
throw FileError.notFound
}
return try String(contentsOfFile: path)
}
rethrows — modifikátor pro funkce, které přijímají throwing-closure jako parametr. Pokud předané closure nevyhazuje chybu, lze rethrows funkci volat bez try. To umožňuje psát generické funkce vyššího řádu kompatibilní s throwing a non-throwing closures.
Swift podporuje několikanásobné catch bloky s porovnáním podle typu chyby. To připomíná when v Kotlin nebo switch podle typu: první vyhovující catch se provede, ostatní se přeskočí.
Každý catch blok může obsahovat vzor porovnání s konkrétním typem chyby. Swift kontroluje bloky v pořadí, takže specifičtější typy by měly být před obecnějšími. Pokud žádný vzor nevyhovuje, provede se catch blok bez vzoru.
Typová bezpečnost Do-Catch umožňuje zpracovávat každou chybu zvlášť nebo kombinovat více typů v jednom bloku pomocí čárky v pattern-matching. To odstraňuje rozsáhlé řetězce if-else typické pro Objective-C, kde analýza chyby probíhala pomocí návratového kódu nebo NSError s kontrolou domain a code.
Swift také podporuje catch where — porovnání s dodatečnou podmínkou. Lze například filtrovat chyby podle konkrétního kódu nebo textu: catch URLError where error.code == .notConnectedToInternet. To snižuje počet catch bloků při zachování přesnosti zpracování.
Pro ladění throwing funkcí Swift poskytuje rozdíl mezi chybami a výjimkami. Chyba Swift — je návratová hodnota, která nevyžaduje rozbalování zásobníku. Výjimky Objective-C (@try/@catch) pracují na úrovni runtime a používají se pouze pro fatální selhání. Do-Catch zpracovává právě chyby, ne výjimky, což jej činí předvídatelným a výkonným.
Při vývoji knihoven a SDK je důležité pamatovat, že throwing funkce jsou součástí veřejné smlouvy. Typ chyby není specifikován v signatuře, proto dokumentujte, jaké chyby může funkce vyhodit, v komentáři nebo pomocí enum podobného Result. To pomáhá uživatelům API psát správné catch bloky bez nahlížení do implementace.
V kontextu asynchronního programování Do-Catch s async/await řeší problém callback hell. Dříve v Swift vyžadovalo zpracování chyb v asynchronním kódu vnořené closures s kontrolou Error? v completion handler. S async/await a Do-Catch vypadá asynchronní throwing kód jako synchronní, což zjednodušuje čtení a údržbu složitých řetězců požadavků se zpracováním chyb v každém kroku.
do {
let content = try readFile(path: "/data/config.json")
process(content)
} catch FileError.notFound {
createDefaultConfig()
} catch FileError.permissionDenied {
requestAccess()
} catch FileError.corrupted(let detail) {
logCorruption(detail)
} catch {
print("Neznámá chyba: \(error)")
}
Swift nabízí tři varianty volání throwing funkcí: try, try? a try!. Každá varianta řeší konkrétní úkol a má svá omezení.
try se používá uvnitř do-bloku a chyba je zpracována v catch. Toto je základní způsob volání throwing funkcí. Překladač vyžaduje, aby try bylo v kontextu, kde může být chyba zachycena.
try? převádí výsledek throwing funkce na Optional. Pokud funkce vyhodí chybu, try? vrátí nil, jinak — Optional s úspěšnou hodnotou. Užitečné pro volání, kde lze chybu ignorovat, ale je potřeba indikátor úspěchu.
try! potlačuje zpracování chyb. Pokud throwing funkce vyhodí chybu, aplikace skončí s runtime chybou. Používejte try! pouze když jste si absolutně jisti, že chyba je nemožná — například při načítání vestavěného zdroje.
// try? — ignorujeme chybu, dostáváme nil při selhání
if let data = try? Data(contentsOf: url) {
processData(data)
}
// try! — pouze pokud je chyba zaručeně nemožná
let bundled = try! String(contentsOfFile: "Assets/default.txt")
// try — standardní varianta v do-catch
do {
let result = try performNetworkRequest()
updateUI(result)
} catch {
showError(error)
}
Do-Catch se aktivně používá ve vývoji iOS pro práci se systémovými API. Podívejme se na typické scénáře: práce se souborovým systémem, Core Data a síťové požadavky.
Mnoho metod FileManager je throwing. Do-Catch umožňuje správně zpracovat chybějící soubor, obsazený zdroj nebo nedostatečná oprávnění.
Parsování JSON přes JSONDecoder — throwing operace. Do-Catch zachycuje chyby dekódování a síťová selhání odděleně a poskytuje uživateli přesný text chyby.
struct User: Codable {
let id: Int
let name: String
}
func fetchUser(id: Int) async throws -> User {
let url = URL(string: "https://api.example.com/users/\(id)")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
// Volání se zpracováním
do {
let user = try await fetchUser(id: 42)
showUser(user)
} catch let error as URLError {
showNetworkAlert(error)
} catch let error as DecodingError {
showParseError(error)
} catch {
showGenericError(error)
}
Vývojáři, zejména ti přecházející z jiných jazyků, často dělají charakteristické chyby při používání Do-Catch. Podívejme se na nejčastější.
Často kladené otázky
V Swift je chyba hodnota odpovídající protokolu Error, nikoli exception s rozbalováním zásobníku. Throwing funkce musí být explicitně označeny throws a překladač vyžaduje try při volání — to eliminuje neošetřené chyby ve fázi kompilace.
Ano, async funkce mohou být také throws a do-catch pro ně funguje. Volání async throwing funkce vyžaduje try await uvnitř do-bloku. Toto je standardní způsob zpracování chyb v asynchronním kódu Swift.
Existují alternativy: try? převádí chybu na nil, try! způsobuje crash při chybě a rethrows umožňuje propagovat chybu z closure. Do-catch zůstává hlavním způsobem explicitního zpracování.
Swift netypizuje vyhazované chyby — jakákoli throwing funkce může vyhodit jakýkoli typ odpovídající Error. Rozdělte zpracování pomocí porovnání v catch na konkrétní typy chyb.
Ano, to je nejlepší praxe. Definujte AppError jako enum s potvrzením Error a převádějte systémové chyby na doménové. To sjednocuje zpracování a izoluje vrstvu aplikace od systémových detailů.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také