ERROR HANDLING IN COCOA AGENDA Objective-Cs NSError Swifts - - PowerPoint PPT Presentation

error handling in cocoa agenda
SMART_READER_LITE
LIVE PREVIEW

ERROR HANDLING IN COCOA AGENDA Objective-Cs NSError Swifts - - PowerPoint PPT Presentation

ERROR HANDLING IN COCOA AGENDA Objective-Cs NSError Swifts try/catch/throws Swifts Result<S,F> type Exceptions & Assertions OBJECTIVE-C ERROR HANDLING NSERROR IN OBJECTIVE-C NSError *error = nil; NSString *string =


slide-1
SLIDE 1
slide-2
SLIDE 2

ERROR HANDLING IN COCOA

slide-3
SLIDE 3

AGENDA

Objective-C’s NSError Swift’s try/catch/throws Swift’s Result<S,F> type Exceptions & Assertions

slide-4
SLIDE 4

OBJECTIVE-C ERROR HANDLING

slide-5
SLIDE 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); }

slide-6
SLIDE 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

slide-7
SLIDE 7

NSERROR IN OBJECTIVE-C…
 …IN THE SAD REAL WORLD

NSString *string = [NSString stringWithContentsOfFile:@"test.txt" encoding:NSUTF8StringEncoding error:nil];

slide-8
SLIDE 8

SWIFT ERROR HANDLING

slide-9
SLIDE 9

SWIFT ERROR HANDLING

Swift 2 uses throws instead of NSError Objective-C methods are bridged to Swift accordingly:

slide-10
SLIDE 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

slide-11
SLIDE 11

DO/CATCH IN SWIFT

do { let content = try String(contentsOfFile: “test.txt", encoding: NSUTF8StringEncoding) } catch let error as NSError { print(error) }

slide-12
SLIDE 12

DECLARING ERROR TYPES

How do you know which types of errors to catch? Header documentation! Unfortunately throws has no type information

slide-13
SLIDE 13

DECLARING ERROR TYPES

/**

  • Returns: the content of the file
  • Throws: `NSError` if file could not be read

*/ func readFile() throws -> String { //... }

slide-14
SLIDE 14

DEFINING SWIFT ERROR TYPES

enum FileReadError: ErrorType { case InvalidFilePath case InvalidEncoding case IncorrectFileFormat(actualFileFormat: String) }

slide-15
SLIDE 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 }

slide-16
SLIDE 16

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!") }

slide-17
SLIDE 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 }

slide-18
SLIDE 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

slide-19
SLIDE 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!" ) } }

slide-20
SLIDE 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)) }

slide-21
SLIDE 21

ASSERTIONS AND EXCEPTIONS

slide-22
SLIDE 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

slide-23
SLIDE 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

slide-24
SLIDE 24

ASSERTIONS

slide-25
SLIDE 25

SUMMARY

slide-26
SLIDE 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

slide-27
SLIDE 27

ADDITIONAL RESOURCES

slide-28
SLIDE 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