Date post: | 14-Apr-2017 |
Category: |
Software |
Upload: | make-school |
View: | 659 times |
Download: | 0 times |
ERROR HANDLING IN COCOA
AGENDA
Objective-C’s NSError
Swift’s try/catch/throws
Swift’s Result<S,F> type
Exceptions & Assertions
OBJECTIVE-C ERROR HANDLING
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); }
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
NSERROR IN OBJECTIVE-C… …IN THE SAD REAL WORLD
NSString *string = [NSString stringWithContentsOfFile:@"test.txt" encoding:NSUTF8StringEncoding error:nil];
SWIFT ERROR HANDLING
SWIFT ERROR HANDLING
Swift 2 uses throws instead of NSError
Objective-C methods are bridged to Swift accordingly:
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
DO/CATCH IN SWIFT
do { let content = try String(contentsOfFile: “test.txt", encoding: NSUTF8StringEncoding) } catch let error as NSError { print(error) }
DECLARING ERROR TYPES
How do you know which types of errors to catch?
Header documentation!
Unfortunately throws has no type information
DECLARING ERROR TYPES/** - Returns: the content of the file - Throws: `NSError` if file could not be read*/func readFile() throws -> String { //...}
DEFINING SWIFT ERROR TYPES
enum FileReadError: ErrorType { case InvalidFilePath case InvalidEncoding case IncorrectFileFormat(actualFileFormat: String)}
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}
HANDLING SWIFT ERROR TYPES
do { try readFile("test.txt") } catch FileReadError.InvalidFilePath { print("Invalid filepath") } catch FileReadError.InvalidEncoding { print("Invalid encoding") } catch let FileReadError.IncorrectFileFormat(actualFileFormat) { print("Unexpected file format: \(actualFileFormat)") } catch { print("Unhandled Error!") }
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 }
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
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!" ) } }
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)) }
ASSERTIONS AND EXCEPTIONS
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
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
ASSERTIONS
SUMMARY
SUMMARYSwift 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
ADDITIONAL RESOURCES
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