Always Try, Try?, And Try!, Never give up

Always Try, Try?, And Try!, Never give up

Beside Swift being powerful, expressive language with a flexible, elegant syntax. There is one of the features I appreciate most is native support for error handling with try ke...

Alok Choudhary
Austin, TX
4 min read

How-to-Get-Started-With-Unit-Testing-Through-Xcode-in-Swift1

Beside Swift being powerful, expressive language with a flexible, elegant syntax. There is one of the features I appreciate most is native support for error handling with try keyword.

It is easy to ignore errors in Objective-C. You have to do a bit of extra work to enable error handling.

[swift]

NSError *error = nil;// Initialize Data With Contents of URL

NSData *data = [[NSData alloc] initWithContentsOfURL:URL options:0 error:&error];

if (error) {

// Error Handling …

}

[/swift]

This means that it is easy to ignore errors in Objective-C.

[swift]

// Initialize Data With Contents of URL

NSData *data = [[NSData alloc] initWithContentsOfURL:URL options:0 error:nil];

[/swift]

Swift is much stricter with error handling. This is a good thing. The syntax, for example, is much more expressive. The try keyword is used to indicate that a method can throw an error. To catch and handle an error, the throwing method call needs to be wrapped in a do-catch statement.

[swift]

do { // Initialize Data With Contents of URL let data = try NSData(contentsOfURL: URL, options: [])

} catch { // Error Handling … }

[/swift]

Any errors that are thrown in the do clause are caught and handled in the catch clause. That is the gist of error handling in Swift.

try, try? and try!

Many developers are confused by the different flavors of this keyword. Swift defines three variations.

  • `try`
  • `try?`
  • `try!`

You already know how to use the try keyword. But how does it differ from other two variations?

try?

The question mark of the try? keyword gives us a subtle hint. If we use the try? keyword and an error are thrown, the error is handled by turning it into an optional value. This means that there is no need to wrap the throwing method call in a do-catch statement.

If the operation fails, the method returns an optional without a value. If the operation succeeds, the optional contains a value.

The try? construct works very well in combination with optional binding as shown in the example below. Note that we invoke the init(contentsOfURL:options:) initializer without wrapping it in a do-catch statement. An optional is returned and, if successful, its value bound to the data constant.

[swift]

if let data = try? NSData(contentsOfURL: URL, options: []) {

print(“Data Loaded”)

} else {

print(“Unable to Load Data”)

}[/swift]

The try? keyword also works great with guard statements.

[swift]

func loadContentsOfFileAtURL(URL: NSURL) -> String? { guard let data = try? NSData(contentsOfURL: URL, options: []) else { return nil }

return String(data: data, encoding: NSUTF8StringEncoding) }

[/swift]

try!

More dangerous is the use of try!. In Swift, an exclamation mark always serves as a warning sign. To disable an error propagation use try with and exclamation mark.

This means that, if an error does get thrown, your application crashes as the result of a runtime error. As a general rule, use try or try?, and avoid or minimize the use of try!.

But when can you or should you use try!? It is perfectly fine to ignore try! altogether. If you are absolutely certain that a throwing operation will not throw an error at runtime, then it is safe to use try!.

The use of try! is similar to the use of implicitly unwrapped optional. If you are absolutely certain that an optional contains a value, you can safely use an exclamation mark to force unwrap the value of the optional. But consider the exclamation mark as a warning that you are performing an operation that may cause your application to crash.

Question Marks and Exclamation Marks

In Swift, the uses of the question mark and the exclamation mark are intuitive and carefully chosen. A question mark indicates that you are uncertain about something. An optional, for example, may contain a value.

The exclamation mark is a warning sign. You are performing a potentially dangerous operation. You are forcing something by taking a shortcut.

Even though it usually requires a few more lines of code, it is recommended to use try and try? instead of try!. And the same applies to unwrapping optionals. That said, there certainly are use cases that justify the use of try! and forced unwrapped optionals.

 

Further reading: 

https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html

Link copied to clipboard!

Made with ❤️ in Austin.

Copyright © 2026