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

Swift | 喜びと感動を

Swift | 喜びと感動を

Developers IO 2016 in Fukuoka での資料です

Avatar for Takaaki Tanaka

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