Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Decodable - Pairs Taiwan

Muukii
June 15, 2017

Decodable - Pairs Taiwan

Muukii

June 15, 2017
Tweet

More Decks by Muukii

Other Decks in Programming

Transcript

  1. About Me ‣ muukii <Hiroshi Kimura> ‣ iOS Senior Engineer

    at eureka, Inc. ‣ Pairs Taiwan iOS ‣ GitHub : @muukii ‣ https://about.me/muukii ☕ ⌚
  2. Agenda ‣ WWDC17 ‣ Swift4 - Codable - Decodable -

    Customize & DecodingError ‣ Pairs Taiwan iOS Development ‣ muukii/StackScrollView
  3. Decodable • JSONDecoder [ { "name" : "muukii", "age" :

    18, "state" : { "isFavorite" : false }, "flags" : ["a", "b", "c"] }, … … ] struct User: Decodable { struct State: Decodable { let isFavorite: Bool } let name: String let age: Int let state: State let flags: [String] } let decoder = JSONDecoder() let users = try decoder.decode([User].self, from: data)
  4. ‣ Too many JSON libraries ‣ SwiftyJSON/SwiftyJSON ‣ muukii/JAYSON ‣

    and more. and more. Can We Replace JSON Libraries?
  5. Custom Decoding struct User: Decodable { private enum CodingKeys: String,

    CodingKey { case name = "username" case age case flags } let name: String let age: Int let flags: [String] init(from decoder: Decoder) throws { let c = try decoder.container(keyedBy: CodingKeys.self) name = try c.decode(String.self, forKey: .name) age = try c.decode(Int.self, forKey: .age) flags = try c.decode([String].self, forKey: .flags) } }
  6. do { let users = try decoder.decode([User].self, from: data) }

    catch let error as DecodingError { } catch { } Error Handling JSONDecoder throw DecodingError
  7. DecodingError let error: DecodingError switch error { case .keyNotFound(let key,

    let context): case .typeMismatch(let type, let context): case .valueNotFound(let type, let context): case .dataCorrupted(let context): }
  8. case .keyNotFound(let key, let context): print(key) // age print(context.debugDescription) //

    Key not found when expecting non-optional type A for coding key "age" print(context.codingPath.map { $0?.stringValue }) // [nil, Optional("age")] Root -> age .keyNotFound
  9. { "age" : 18, "state" : { "isFavorite" : false

    } } struct User: Decodable { struct State: Decodable { let isFavorite: String } let state: State } .typeMismatch
  10. case .typeMismatch(let type, let context): print(type) // String print(context.debugDescription) //

    Expected to decode String but found a number instead. print(context.codingPath.map { $0?.stringValue }) // [nil, Optional("state"), Optional("isFavorite")] .typeMismatch Root -> state -> isFavorite
  11. .valueNotFound { "age" : null, "name" : "muukii" } struct

    User: Decodable { let age: Int let name: String } User.age is required
  12. .valueNotFound case .valueNotFound(let type, let context): print(type) // Int print(context.debugDescription)

    // Found null value when expecting non-optional type UInt for coding key "age" print(context.codingPath.map { $0?.stringValue }) // [nil, Optional("age")] Root -> age
  13. Summary ‣ Decodable is useful ‣ Simple code for simple

    mappings ‣ Possible custom mapping ‣ DecodingError indicates useful information ‣ KeyPath on caused error ‣ "notFoundKey", "valueNotFound", "keyMismatch" , "dataCorrupted"
  14. Used techniques • No Interface Builder • TextureGroup/Texture (AsyncDisplayKit) •

    muukii/StackScrollView • Module (Request, Service, Component, App) • MVVM with RxSwift • Carthage & CocoaPods • and more…
  15. What is StackScrollView? • iOS Form UI Builder • Doesn't

    use UITableViewCell / UICollectionViewCell • UIView based Cell • Initialization is faster than UIStackView • No built-in UI-Components • No longer need to consider reusing Cells • Self-sizing with AutoLayout • Nothing is impossible
  16. Usage StackScrollView let view = StackScrollView() let cell_1 = LabelStackCell()

    view.append(views: [cell_1]) let cell_2 = LabelStackCell() view.append(views: [cell_2]) let cell_3 = LabelStackCell() view.append(views: [cell_3])
  17. Usage StackScrollView final class LabelStackCell: UIView { let label =

    UILabel() init() { super.init(frame: .zero) addSubview(label) label <- Edges(16) // nakiostudio/EasyPeasy } } Label UIView must have sufficient internal constraints
  18. Features class StackScrollView { func append(view: UIView) func remove(view: UIView,

    animated: Bool)
 func scroll(to view: UIView, animated: Bool) }
  19. Features protocol StackCellType : class { } extension StackCellType where

    Self : UIView { var stackScrollView: StackScrollView? { get } func scrollToSelf(animated: Bool) func updateLayout(animated: Bool) func remove() } Recalculate size of view extension LabelStackCell : StackCellType {}
  20. Summary ‣ Helpful APIs for Form UI ‣ No longer

    need to consider reusing Cells ‣ Nothing is impossible ‣ We can create custom UI for Our Products.