Slide 1

Slide 1 text

Swift 2
 Error Handling in Practice

Slide 2

Slide 2 text

cockscomb

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Recent work • Rewrite Hatena Blog for iOS with Swift • Hatena Summer Internship 2015 “iOS App Course” • Sample code: hatena/swift-Sample-GitHubSearch • Textbook: Available soon • Secret projects‥

Slide 5

Slide 5 text

I moved our codes 
 into Swift 2 the past week

Slide 6

Slide 6 text

Swift 2
 Error Handling in Practice

Slide 7

Slide 7 text

Which is better? func parseInt(string: String) -> Int? func parseInt(string: String) throws -> Int func parseInt(string: String) throws -> Int?

Slide 8

Slide 8 text

Which is better? func parseInt(string: String) -> Int?

Slide 9

Slide 9 text

Which is better? func parseJSON(data: NSData) -> JSONObject? func parseJSON(data: NSData) throws -> JSONObject func parseJSON(data: NSData) throws -> JSONObject?

Slide 10

Slide 10 text

Which is better? func parseJSON(data: NSData) throws -> JSONObject

Slide 11

Slide 11 text

func parseJSON(data: NSData) throws -> JSONObject do { let json = try parseJSON(data) // Something } catch { // Handle error } if let json = try? parseJSON(data) { // Something }

Slide 12

Slide 12 text

enum JSONDecodeError: ErrorType { case MissingRequiredKey(String) case UnexpectedType(key: String, expected: Any.Type, actual: Any.Type) } struct JSONObject { let raw: [String : AnyObject] func getValue(key: String) throws -> T { guard let value = raw[key] else { throw JSONDecodeError.MissingRequiredKey(key) } guard let typedValue = value as? T else { throw JSONDecodeError.UnexpectedType( key: key, expected: T.self, actual: value.dynamicType) } return typedValue } }

Slide 13

Slide 13 text

do { let json = try parseJSON(data) let userName: String = try json.getValue("user_name") // Something } catch { // Handle error } if let json = try? parseJSON(data), let userName: String = try? json.getValue("user_name") { // Something }

Slide 14

Slide 14 text

Which is better? enum JSONDecodeError: ErrorType { case MissingRequiredKey(String) case UnexpectedType(key: String, expected: Any.Type, actual: Any.Type) } enum JSONDecodeError: ErrorType { case MissingRequiredKey case UnexpectedType }

Slide 15

Slide 15 text

Which is better? enum JSONDecodeError: ErrorType { case MissingRequiredKey(String) case UnexpectedType(key: String, expected: Any.Type, actual: Any.Type) }

Slide 16

Slide 16 text

Do more better enum JSONDecodeError: ErrorType, CustomDebugStringConvertible { case MissingRequiredKey(String) case UnexpectedType(key: String, expected: Any.Type, actual: Any.Type) var debugDescription: String { switch self { case .MissingRequiredKey(let key): return "Required key '\(key)' missing" case let .UnexpectedType(key: key, expected: expected, actual: actual): return "Unexpected type '\(actual)' was supplied for '\(key): \(expected)'" } } }

Slide 17

Slide 17 text

Do more better struct JSONObject { let raw: [NSString : AnyObject] /** Get typed value for the key - parameters: - key: JSON key - returns: Typed value */ func getValue(key: String) throws -> T { guard let value = raw[key] else { throw JSONDecodeError.MissingRequiredKey(key) } ...

Slide 18

Slide 18 text

Do more better struct JSONObject { let raw: [NSString : AnyObject] /** Get typed value for the key - parameters: - key: JSON key - returns: Typed value - throws: JSONDecodeError */ func getValue(key: String) throws -> T { guard let value = raw[key] else { throw JSONDecodeError.MissingRequiredKey(key) } ...

Slide 19

Slide 19 text

as NSError enum MyError: ErrorType { case SuperError } let error = MyError.SuperError as NSError print(error.localizedDescription) // The operation couldn’t be completed.
 (Module.MyError error 0.)

Slide 20

Slide 20 text

enum MyError: ErrorType { case SuperError static func description(code: Int) -> String? { switch code { case 0: return "Super error occurred" default: return nil } } } NSError.setUserInfoValueProviderForDomain("Module.MyError") { (error, userInfoKey) -> AnyObject? in switch userInfoKey { case NSLocalizedDescriptionKey: return MyError.description(error.code) default: break } return nil } let error = MyError.SuperError as NSError print(error.localizedDescription) // Super error occurred

Slide 21

Slide 21 text

Error handling in practice • Functions can return Optional type or throw error • ErrorType should provide informations in detail • Documentation comment with possible error kind • Treating ErrorType as NSError have some problems