Share
Embed
Transcript
21 slides
-
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‥ -
Which is better? func parseInt(string: String) -> Int? func parseInt(string:
String) throws -> Int func parseInt(string: String) throws -> Int? -
Which is better? func parseJSON(data: NSData) -> JSONObject? func parseJSON(data:
NSData) throws -> JSONObject func parseJSON(data: NSData) throws -> JSONObject? -
func parseJSON(data: NSData) throws -> JSONObject do { let json
= try parseJSON(data) // Something } catch { // Handle error } if let json = try? parseJSON(data) { // Something } -
enum JSONDecodeError: ErrorType { case MissingRequiredKey(String) case UnexpectedType(key: String, expected:
Any.Type, actual: Any.Type) } struct JSONObject { let raw: [String : AnyObject] func getValue<T>(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 } } -
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 } -
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 } -
Which is better? enum JSONDecodeError: ErrorType { case MissingRequiredKey(String) case
UnexpectedType(key: String, expected: Any.Type, actual: Any.Type) } -
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)'" } } } -
Do more better struct JSONObject { let raw: [NSString :
AnyObject] /** Get typed value for the key - parameters: - key: JSON key - returns: Typed value */ func getValue<T>(key: String) throws -> T { guard let value = raw[key] else { throw JSONDecodeError.MissingRequiredKey(key) } ... -
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<T>(key: String) throws -> T { guard let value = raw[key] else { throw JSONDecodeError.MissingRequiredKey(key) } ... -
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.) -
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 -
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