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

Swift | 喜びと感動を

Swift | 喜びと感動を

Developers IO 2016 in Fukuoka での資料です

Takaaki Tanaka

October 08, 2016
Tweet

More Decks by Takaaki Tanaka

Other Decks in Technology

Transcript

  1. 

  2. 

  3. Ϋϥεϝιουͱ4XJGU w ೥຤ʹ৽نҊ݅޲͚ʹ౤ೖ w 4XJGU7FSTJPO w ͦͷޙ4XJGU7FSTJPO΁ w ೥݄ʹ4XJGUରԠ w

    ೥຤͔Β͸৽نҊ݅͸ɺ͢΂ͯ4XJGU΁ w J04ΤϯδχΞ͸໿໊ w ֤ϓϩδΣΫτͰΞαΠϯ͞ΕΔͷ͸d໊  ⡥$MBTTNFUIPE *OD
  4. 4XJGUͷओͳಛ௃ w MFU WBS w ܕਪ࿦ w $MBTT 4USVDU w

    0QUJPOBM w &OVN w (FOFSJDT w $MPTVSF w 1SPUPDPM w 1SPUPDPM&YUFOTJPO w NBQqBUNBQ  ⡥$MBTTNFUIPE *OD
  5. ม਺ w MFU w JNNVUBCMFͳ஋Λѻ͏ w ࠶୅ೖ͸ෆՄೳ w ෆม஋Ͱ͋Δ͜ͱΛอূ͢Δ w

    WBS w NVUBCMFͳ஋Λѻ͏ w ࠶୅ೖ͸Մೳ w 7FSTJPOҎ߱͸NFUIPEͷҾ਺ʹࢦఆͰ͖ͳ͘ͳͬͨ  ⡥$MBTTNFUIPE *OD
  6. ม਺  ⡥$MBTTNFUIPE *OD class Area { var code: String

    = "0010" } let area: Area = Area() area.code = "0012"
  7. ܕਪ࿦  ⡥$MBTTNFUIPE *OD let num3 = 1 + 1.0

    // Double let num4: CGFloat = 1.5 let num5 = num4 + 1.2 // CGFloat
  8. Ϋϥε w $MBTT w ࢀরܕ w ୅ೖ͞Εͨ৔߹͸ΞυϨε͕ࢀর͞ΕΔ  ⡥$MBTTNFUIPE *OD

    w 4USVDU w ஋ܕ w ୅ೖ͞Εͨ৔߹͸ίϐʔ͞ΕΔ w 0CKFDUJWF$ʹ͸ແ͍ͷͰ0CKFDWJUF$͔ΒݺͿ৔߹͸ /40CKFDUΛܧঝͨ͠Ϋϥεʹ͢Δඞཁ͕͋Δ
  9. Ϋϥε  ⡥$MBTTNFUIPE *OD class Area { var name: String

    = "" } let area1 = Area() area1.name = "AAAA" let area2 = area1 area2.name = "BBBB" let area3 = area1 area3.name = "CCCC" area1.name // CCCC area2.name // CCCC area3.name // CCCC
  10. Ϋϥε  ⡥$MBTTNFUIPE *OD struct Area { var name: String

    mutating func set(name: String) { self.name = name } } let area1 = Area(name: "AAAA") var area2 = area1 area2.set(name: "BBBB") var area3 = area1 area3.set(name: "CCCC") area1.name // AAAA area2.name // BBBB area3.name // CCCC
  11. &OVN  ⡥$MBTTNFUIPE *OD enum PeachBoySlave: Int { case Dog

    case Monkey case Bird } print(PeachBoySlave.Bird.rawValue) // 2 w 3BX7BMVF *OU
  12. &OVN  ⡥$MBTTNFUIPE *OD enum PeachBoySlave: String { case Dog

    = "Dog" case Monkey = "Monkey" case Bird = "Bird" } print(PeachBoySlave.Bird.rawValue) // Bird w 3BX7BMVF 4USJOH
  13. &OVN  ⡥$MBTTNFUIPE *OD enum PeachBoySlave: String { case Dog

    case Monkey case Bird enum Actor { case Grandpa case Grandma } } w ωετͯ͠ఆٛ͢Δ͜ͱ΋Ͱ͖Δ
  14. &OVN  ⡥$MBTTNFUIPE *OD enum PeachBoyEnemy { case Oni case

    Boss func encount() { print("Enemy") } } w ಠࣗϝιουͷఆٛ
  15. &OVN  ⡥$MBTTNFUIPE *OD w ܭࢉܕϓϩύςΟͷఆٛ enum PeachBoyEnemy { case

    Oni case Boss … var count: Int { switch self { case Oni: return 10 case Boss: return 1 } } }
  16. 0QUJPOBM  ⡥$MBTTNFUIPE *OD public enum Optional<Wrapped> : ExpressibleByNilLiteral w

    0QUJPOBM͸&OVNͰఆٛ͞Ε͍ͯΔ let value: Optional<Int> = 10
  17. 0QUJPOBM w HVBSEઅΛ༻͍ͯܖ໿ϓϩάϥϛϯάΛߦ͏  ⡥$MBTTNFUIPE *OD guard let unwrapValue =

    value else { return } unwrapValue // 10 let value: Int? = 10 guard let unwrapValue = value, unwrapValue < 10 else { return }
  18. (FOFSJDT w ॊೈʹ࠶ར༻Մೳͳܕ΍ؔ਺Λఆٛ͢Δ  ⡥$MBTTNFUIPE *OD class List<Element> { private

    var elements = [Element]() func append(element: Element) { elements.append(element) } } let intList = List<Int>() intList.append(element: 1) // [1] intList.append(element: 2) // [1, 2] let stringList = List<String>() stringList.append(element: "AAAA") // ["AAAA"] stringList.append(element: "BBBB") // ["AAAA", "BBBB"]
  19. (FOFSJDT w &OVNʹ΋(FOFSJDTΛఆٛ͢Δ͜ͱ͕Ͱ͖Δ w 3FTVMUܕ͕ྑ͍ྫ  ⡥$MBTTNFUIPE *OD public enum

    Result<Value, Error: ErrorType> { case Success(Value) case Failure(Error) } func result(with code: Int?) -> Result<Int, NSError> { guard let unwrapedCode = code else { let error = NSError( domain: "MyApp", code: 0, userInfo: nil)) return .Failure(error) ɹɹ } return .Success(unwrapedCode) }
  20. (FOFSJDT  ⡥$MBTTNFUIPE *OD Alamofire.request( Router.ItemSearch(parameters)) .responseJSON { response in

    switch response.result { case .Success(let value) : let json = JSON(value) items = results.keys.map { Item(json: results[$0]!) } case .Failure(let error) : print("error: \(error)") } }
  21. $MPTVSF w ίʔϧόοΫॲཧͷఆٛ  ⡥$MBTTNFUIPE *OD class Object { var

    handler: ((String) -> Void)? init(handler: ((String) -> Void)?) { self.handler = handler } func didReceive(message: String) { handler?(message) } }
  22. $MPTVSF w ίʔϧόοΫॲཧͷఆٛ  ⡥$MBTTNFUIPE *OD let obj = Object

    { message in print(message) // Hello World!! } … obj.didReceive(message: "Hello World!!")
  23. $MPTVSF w UZQFBMJBTͰએݴ͢Δ͜ͱͰϝϯςφϯεੑΛ޲্  ⡥$MBTTNFUIPE *OD class Object { typealias

    ReceiveHandler = ((String) -> Void) var handler: ReceiveHandler? init(handler: ReceiveHandler?) { self.handler = handler } func didReceive(message: String) { handler?(message) } }
  24. $MPTVSF w TFMGͷࢀরʹ஫ҙ w TFMG͕OJMʹͳΔՄೳੑ͕͋Δ৔߹͸XFBLΛࢦఆ͢Δ w ΞϯϥοϓॲཧΛهࡌ͢Δඞཁ͕͋Δ
  ⡥$MBTTNFUIPE *OD

    let obj = Object { [weak self] message in self?.receiveMessage = message } let obj = Object { [weak self] message in guard let weakSelf = self else { return } weakSelf.receiveMessage = message }
  25. 1SPUPDPM w 1SPUPDPM w Ϋϥεʹରͯ͠ػೳΛ௥Ճ͍ͯ͘͠ w ৼΔ෣͍Λఆٛ͢Δ w ΤϯίʔυͰ͖ΔσίʔυͰ͖ΔදࣔͰ͖ΔʜFUD 

    ⡥$MBTTNFUIPE *OD IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED 1SPUPDPM0SJFOUFE1SPHSBNNJOHJO4XJGU
  26. 1SPUPDPM  ⡥$MBTTNFUIPE *OD protocol Showable { func show() }

    protocol Decodable { func decode() } class Object: Showable, Decodable { func show() { print("Show") } func decode() { print("decode") } }
  27. 1SPUPDPM w BTTPDJBUFEUZQFͰ1SPUPDPMͰ࢖͏ܕͷ
 ϓϨʔεϗϧμʔΛએݴ͢Δ͜ͱͰ൚༻ੑΛ࣋ͨͤΔ  ⡥$MBTTNFUIPE *OD protocol Response {

    associatedtype ResponseType func receive(response: ResponseType) } class Object: Response { typealias ResponseType = [String : Any] func receive(response: ResponseType) { print(response) } }
  28. &YUFOTJPO w &YUFOTJPO  ⡥$MBTTNFUIPE *OD class Object { }

    extension Object { func receive() { print("receive") } }
  29. 1SPUPDPM&YUFOTJPO w ܕ੍໿ w ܕ੍໿Λ͚ͭΔ͜ͱͰద༻ൣғΛݶఆ͢Δ  ⡥$MBTTNFUIPE *OD protocol Encodable

    { func encode() } extension Encodable where Self: Object1 { func encode() { print("encode1") } } extension Encodable where Self: Object2 { func encode() { print("encode2") } }
  30. NBQqBUNBQ w 4FRVFODF  ⡥$MBTTNFUIPE *OD enum PokemonType: String {

    case Grass = "Grass" case Water = "Water" case Fire = "Fire" case Electric = "Electric" } let type1 = PokemonType(rawValue: "Grass") // PokemonType.Grass let type2 = PokemonType(rawValue: "Evil") // nil
  31. NBQqBUNBQ w 4FRVFODF w NBQͷద༻  ⡥$MBTTNFUIPE *OD let types

    = ["Grass", "Water", "Fire", "Electric"] let pokemonTypes = types.map { PokemonType(rawValue: $0) } [Optional(PokemonType.Grass), Optional(PokemonType.Water), Optional(PokemonType.Fire), Optional(PokemonType.Electric)]
  32. NBQqBUNBQ w 4FRVFODF w NBQͷద༻  ⡥$MBTTNFUIPE *OD let types

    = ["Grass", "Water", "Fire", "Ice"] let pokemonTypes = types.map { PokemonType(rawValue: $0) } [Optional(PokemonType.Grass), Optional(PokemonType.Water), Optional(PokemonType.Fire), nil]
  33. NBQqBUNBQ w 4FRVFODF w qBUNBQͷద༻  ⡥$MBTTNFUIPE *OD let types

    = ["Grass", "Water", "Fire", "Electric"] let pokemonTypes = types.flatMap { PokemonType(rawValue: $0) } [PokemonType.Grass, PokemonType.Water, PokemonType.Fire, PokemonType.Electric]
  34. NBQqBUNBQ w 4FRVFODF w qBUNBQͷద༻  ⡥$MBTTNFUIPE *OD let types

    = ["Grass", "Water", "Fire", "Ice"] let pokemonTypes = types.flatMap { PokemonType(rawValue: $0) } [PokemonType.Grass, PokemonType.Water, PokemonType.Fire]
  35. NBQqBUNBQ w $PMMFDUJPO w NBQͷద༻  ⡥$MBTTNFUIPE *OD let types1

    = ["Electric", "Electric", "Fire"] let types2 = ["Water", "Ice"] let types3 = ["Fire", "Grass", "Rock", "Grass"] let types = [types1, types2, types3].map { $0 } [["Electric", "Electric", "Fire"], ["Water", "Ice"], ["Fire", "Grass", "Rock", "Grass"]]
  36. NBQqBUNBQ w $PMMFDUJPO w qBUNBQͷద༻  ⡥$MBTTNFUIPE *OD let types1

    = ["Electric", "Electric", "Fire"] let types2 = ["Water", "Ice"] let types3 = ["Fire", "Grass", "Rock", "Grass"] let types = [types1, types2, types3].flatMap { $0 } ["Electric", "Electric", "Fire", "Water", "Ice", "Fire", "Grass", "Rock", "Grass"]
  37. NBQqBUNBQ w $PMMFDUJPO w qBUNBQͷద༻  ⡥$MBTTNFUIPE *OD let types1

    = ["Electric", "Electric", "Fire"] let types2 = ["Water", "Ice"] let types3 = ["Fire", "Grass", "Rock", "Grass"] let types = [types1, types2, types3].flatMap { $0 }. flatMap { PokemonType(rawValue: $0) } [PokemonType.Electric, PokemonType.Electric, PokemonType.Fire, PokemonType.Water, PokemonType.Fire, PokemonType.Grass, PokemonType.Grass]
  38. NBQqBUNBQ w 0QUJPOBM w NBQͷద༻  ⡥$MBTTNFUIPE *OD let value:

    String? = "Fire" let value1 = value.map { PokemonType(rawValue: $0) } Optional(Optional(PokemonType.Fire))
  39. NBQqBUNBQ w 0QUJPOBM w qBUNBQͷద༻  ⡥$MBTTNFUIPE *OD let value:

    String? = "Fire" let value1 = value.flatMap { PokemonType(rawValue: $0) } Optional(PokemonType.Fire)
  40. NBQqBUNBQ w 0QUJPOBM w 0QUJPOBM΁ͷΞΫηεΛߦ͏  ⡥$MBTTNFUIPE *OD let type

    = PokemonType(rawValue: "Water") let changedType = type.map { type -> PokemonType in switch type { case .Water: return PokemonType.Electric default: return type } }
  41. NBQqBUNBQ w 0QUJPOBM w 0QUJPOBMಉ࢜ͷܭࢉ  ⡥$MBTTNFUIPE *OD let value1:

    Int? = 10 let value2: Int? = 20 let value = value1.flatMap { v1 in value2.map { v2 in v1 + v2 } } Optional(30)
  42. NBQqBUNBQ w 0QUJPOBM w 0QUJPOBMಉ࢜ͷܭࢉ  ⡥$MBTTNFUIPE *OD let value1:

    Int? = 10 let value2: Int? = 20 let value3: Int? = 30 let value = value1.flatMap { v1 in value2.flatMap { v2 in value3.map { v3 in v1 + v2 + v3 } } } Optional(60)
  43. NBQqBUNBQ w 0QUJPOBM w 0QUJPOBMಉ࢜ͷܭࢉ  ⡥$MBTTNFUIPE *OD let value1:

    Int? = 10 let value2: Int? = 20 let value3: Int? = 30 let value4: Int? = 40 let value = value1.flatMap { v1 in value2.flatMap { v2 in value3.flatMap { v3 in value4.map { v4 in v1 + v2 + v3 + v4 } } } } Optional(100)
  44. NBQqBUNBQ  ⡥$MBTTNFUIPE *OD let a: Int? = 10 let

    b: Int? = 20 let c: Int? = 30 let value = curry(+) <^> a <*> b <*> c w 0QUJPOBM w "QQMJDBUJWF4UZMF
  45. ը૾औಘ w "MBNPpSF*NBHF w ඇಉظ௨৴ը૾औಘϥΠϒϥϦ  ⡥$MBTTNFUIPE *OD imageView.af_setImageWithURL(url) {

    response in switch response.result { case .Success: imageEmptyView.hidden = true default: () } }
  46. ඇಉظॲཧ w #SJHIU'VUVSFT w ඇಉظॲཧϑϨʔϜϫʔΫ w 'VUVSF1SPNJTFύλʔϯΛ4XJGUͰ΋ద༻͢Δ  ⡥$MBTTNFUIPE *OD

    IUUQTHJUIVCDPN5IPNWJT#SJHIU'VUVSFT <4XJGU>ඇಉظॲཧϑϨʔϜϫʔΫ #SJHIU'VUVSFTdಋೖฤd
  47. ඇಉظॲཧ w #SJHIU'VUVSFT  ⡥$MBTTNFUIPE *OD public func read<MO: NSManagedObject>(keyForId:

    String, valueForId: AnyObject) -> Future<MO, NSError> { let promise = Promise<MO, NSError>() dispatch_async(persistenceQueue) { [unowned self] in let context = NSManagedObjectContext.defaultContext() let previousRecord = MO.MR_findFirstByAttribute( keyForId, withValue: valueForId, inContext: context) dispatch_async(self.callbackQueue) { if let record = previousRecord { promise.success(record) } else { promise.failure(PersistenceServiceNotFoundError) } } } return promise.future }
  48. ඇಉظॲཧ w #SJHIU'VUVSFT  ⡥$MBTTNFUIPE *OD presenter.read<User>( keyForId: "name", valueForId:

    "Tanaka").onSuccess { [weak self] user in self?.update(user: user) }.onFailure { [weak self] error in self?.showFailedAlertWithError(error) } }
  49. 7FSTJPOରԠ w ഁյతͳมߋ w /4QSFpY͔Βͷ୤٫ w શ෦ϦϓϨΠε͞Ε͍ͯΔΘ͚Ͱ͸ͳ͍ʜ w "1*%FTJHOͷมߋ w

    ϝιουͷҾ਺ͷϥϕϧͷࢦఆ͕มߋ w Yܥͱͷޓ׵ੑ͸ແ͍ w 9DPEFͰ͕௥Ճ͞Ε͕ͨɺ
 ࣍ͷόʔδϣϯͰ͸%FQMJDBUFEʹͳΔ
  ⡥$MBTTNFUIPE *OD