5. NSERROR IN OBJECTIVE-C
NSError *error = nil;
NSString *string = [NSString stringWithContentsOfFile:@"test.txt"
encoding:NSUTF8StringEncoding error:&error];
if (!string) {
NSLog(@"File could not be read!");
}
if (error) {
NSLog(@"%@", error.localizedDescription);
}
6. NSERROR IN OBJECTIVE-C
Return value is most relevant for checking
whether an operation was successful or not [1]
Methods can return errors, but still successfully
return a value
[1] Apple Error Handling Documentation
7. NSERROR IN OBJECTIVE-C…
…IN THE SAD REAL WORLD
NSString *string = [NSString stringWithContentsOfFile:@"test.txt"
encoding:NSUTF8StringEncoding error:nil];
9. SWIFT ERROR HANDLING
Swift 2 uses throws instead of NSError
Objective-C methods are bridged to Swift
accordingly:
10. CALLING THROWING
FUNCTIONS
You need to choose one of these 3 approaches:
handle the error with a do/catch block
Use forced-try: try!
propagate the error further up the call stack by
declaring calling function as throws
11. DO/CATCH IN SWIFT
do {
let content = try String(contentsOfFile: “test.txt", encoding:
NSUTF8StringEncoding)
} catch let error as NSError {
print(error)
}
12. DECLARING ERROR TYPES
How do you know which types of errors to catch?
Header documentation!
Unfortunately throws has no type information
13. DECLARING ERROR TYPES
/**
- Returns: the content of the file
- Throws: `NSError` if file could not be read
*/
func readFile() throws -> String {
//...
}
14. DEFINING SWIFT ERROR
TYPES
enum FileReadError: ErrorType {
case InvalidFilePath
case InvalidEncoding
case IncorrectFileFormat(actualFileFormat: String)
}
15. THROWING SWIFT ERROR
TYPES
/**
- Returns: The content of the file
- Throws: `FileReadError.InvalidFilePath` if file could not be read;
`FileReadError.InvalidEncoding` if file encoding does not match expected encoding;
`FileReadError.IncorrectFileFormat` if file format does not match specified one
*/
func readFile(path: String) throws -> NSData {
// ...
throw FileReadError.InvalidFilePath
}
17. LIMITATIONS OF SWIFT
ERROR HANDLING
Errors don’t have type information
Error handling doesn’t work for asynchronous code
let request = NSURLRequest(URL: NSURL(string: "https://www.google.com")!)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request) { (data, response, error) -> Void in
// error handling happens in callback
}
18. RESULT TYPE
Result type can represent value or error depending on
result of operation. Popular Open Source
implementation: [2]
Can be used for synchronous and asynchronous code
func search(searchString: String) -> Result<Predictions, SearchError>
[2] https://github.com/antitypical/Result
19. CONSUMING RESULT TYPE
func handleSearchResult(result: Result<Predictions, Reason>) -> Void {
switch result {
case let .Success(predictions):
self.locations = predictions.predictions
case .Failure(_):
self.errorHandler.displayErrorMessage(
"The search returned an error, sorry!"
)
}
}
20. PRODUCING RESULT TYPE
func fetchAllTrips(callback: Result<[JSONTrip], Reason> -> Void) {
// in case of success
var trips: [JSONTrip] = [/*...*/]
callback(.Success(trips))
// in case of error
var reason: Reason = .NoData
callback(.Failure(reason))
}
22. EXCEPTIONS
Objective-C provides exceptions, Swift does not
Objective-C exceptions should not be caught, they are
not intended for error handling [1]
Exceptions are used to crash the app to make you
aware of a programming error
[1] Apple Error Handling Documentation
23. ASSERTIONS
Are used to state and verify assumptions
Typically only used at debug time
Objective-C: NSAssert…
Swift: assert, assertionFailure,
fatalError,… [3]
[3] Swift asserts the missing manual
26. SUMMARY
Swift 2 uses ErrorType and throws for error
handling
Swift 2 error handling has limitations (no type info,
not suitable for async code) - Result type is a
good alternative
Exceptions and assertions are used for
unrecoverable errors
28. ADDITIONAL RESOURCES
WWDC 106: What’s new in Swift
Javi Soto: Swift Sync and Async Error
Handling
Benjamin Encz: Swift Error Handling and
Objective-C Interop in Depth