3. Errors: Objective-C vs Swift
NSFileManager (Objective-C)
// just want to delete an image ...
NSError *error = nil;
// passing a NSError by reference and returns a boolean ???
if (![[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) {
}
FileManager (Swift)
func removeItem(atPath:filePath) throws Error
4. enum ScoreError: Error {
case negativeScore(message:String)
case unreachableScore(message:String)
}
func updateTeamScore(score:Int) throws {
guard score >= 0 else {
throw ScoreError.negativeScore(message: “Score cannot be negative”)
}
guard isReachableScore(score:score) else {
throw ScoreError.unreachableScore(message: “Score is unreachable”)
}
}
Throwing Errors
5. Catching Errors
// let’s try to update the score for a team
do {
try updateTeamScore(score: -1)
} catch ScoreError.negativeScore {
print("How can a score go negative?")
} catch ScoreError.unreachableScore {
print("How could a team achieve this score?")
} catch _ {
}
6. // similar to optionally unwrapping
guard let jsonString = try? decode(rawString) else { return nil }
let data = JSON(jsonString)
// similar to forced unwrapping
let photo = try! loadImage(atPath:"./Resources/score.png”)
try? and try!
7. func updateTeamScore(score:Integer) throws
defer {
animateScore()
}
guard score >= 0 else {
throw ScoreError.negativeScore(message: “Score cannot be a negative number”)
}
guard isReachableScore(score) else {
throw ScoreError.unreachableScore(message: “Score is unreachable”)
}
this.team.currentScore = score
// animateScore is always called at
// the end of the function's scope
}
defer
8. func testErrorHandling() {
do {
try updateTeamScore(score: -1)
XCTFail("Should never get here")
} catch let e as ScoreError {
XCTAssertEqual(e, ScoreError.negativeScore(message: "Score cannot be a negative
number"))
} catch {
XCTFail("Wrong error")
}
}
Unit Testing
Different ways in which errors were handled with Objective-C
References to errors. Delegates.
Up to the client to understand what all these errors were all about. A lot of times, lazy developers would simply pass NULL.
Making error a lot more explicit.
More difficult to ignore it - the compiler will complain.
What’s this new `throws` keyword all about?
Exception handling as control flow???? Errors in Swift don’t result in the call stack being unwound which is computationally expensive. Performance characteristics of a throw statement are similar to a regular return.
Consider the following example about updating a score for a team
NSParameterAssert
guarding against the if let pyramid of doom
functions which throw should return optionals if anything at all
Client code
Error hierarchy
First meeting with try