Slide 1

Slide 1 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. USFBTUSBJO5BOBLB3ZPHB ͦͷ4XJGUίʔυɺ 
 ͜͏ॻ͖׵͑ͯΈͳ͍͔ 1PMJTIJOHZPVS4XJGUDPEFXJUINF 1 DeNA × STORES × ϥΫϚ iOS Meetup!! #dena_stores_rakuma

Slide 2

Slide 2 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. "CPVUNF USFBTUSBJO5BOBLB3ZPHB 2 4XJGU J04 XBUDI04 $PSF/'$ 044 
 ɹɹJU`TNZNPUIFSUPOHVF 
 ɹɹ࠷ۙ#MVFTLZΛ͸͡Ί·ͨ͠ ɹɹɹɹɹɹɹɹɹɹ!USFBTUSBJOɹɹIUUQTUSFUKQ 
 
 %F/"$P -UE 
 ɹɹJ04"QQ%FWFMPQFSʢ"QSJM$VSSFOUʣ

Slide 3

Slide 3 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. BoolΛ൓స͢Δʹ͸toggle()Λ࢖͏ flag = !flagΑΓΘ͔Γ΍͍͢ w !Ͱ൓సͰ͖Δ͚Ͳʜʜ 3 var flag = true flag = !flag print(flag) // false

Slide 4

Slide 4 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. BoolΛ൓స͢Δʹ͸toggle()Λ࢖͏ flag = !flagΑΓΘ͔Γ΍͍͢ 4 struct Hoge { var fuga1 = Fuga(); var fuga2 = Fuga() struct Fuga { var piyo1 = Piyo(); var piyo2 = Piyo() struct Piyo { var flag = true } } } var hoge = Hoge() hoge.fuga1.piyo2.flag = !hoge.fuga2.piyo1.flag // fuga1ɾ2ɺpiyo2ɾ1 ͕ٯʂ

Slide 5

Slide 5 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. BoolΛ൓స͢Δʹ͸toggle()Λ࢖͏ flag = !flagΑΓΘ͔Γ΍͍͢ w toggle()ͰಡΈ΍͘͢ɺهड़ϛεͷ৺഑΋ݮΔ 5 flag.toggle() hoge.fuga1.piyo2.flag.toggle()

Slide 6

Slide 6 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. isMultiple(of:)Λ࢖͏ x % 2 == 0͸࢖Θͳ͍ w ӳޠͷจষͷΑ͏ʹಡΊͯɺՄಡੑ͕޲্ 6 let x = 4 print(x % 2 == 0) // true - `%` ԋࢉࢠΛ༻͍Δྫ print(x & 1 == 0) // true - `&` ԋࢉࢠΛ༻͍Δྫ print(x.isMultiple(of: 2)) // true - ӳޠͷจষͷΑ͏ʹಡΊΔ print(x.isMultiple(of: 3)) // false

Slide 7

Slide 7 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯͷendIndexΛ࢖͏ countͬΆ͍͚ΕͲ w ʮ࠷ޙͷΠϯσοΫεʯΛࣔ͢ w count͸0 O ɺendIndex͸0 7 let list = ["DeNA", "STORES", "Rakuten Rakuma”] print(list.count) // 3 print(list.endIndex) // 3

Slide 8

Slide 8 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯ͕ۭ͔Ͳ͏͔͸isEmptyͰಘΔ count == 0͸࢖Θͳ͍ w ಡΈ΍͍͢ w count͸0 O ɺisEmpty͸0 8 let list1 = ["DeNA", "STORES", "Rakuten Rakuma"] print(list1.count == 0) // false print(list1.isEmpty) // false var list2 = list1 list2.removeAll() print(list2.count == 0) // true print(list2.isEmpty) // true

Slide 9

Slide 9 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯͷΠϯσοΫε͸indexed()ͰಘΔ enumerated()΍zip(_:_:)Ͱ͸ͳ͘ w enumerated()͸ཁૉͱҰॹʹʮ0͔Β࢝·Δ࿈൪ʯΛฦ͢ 9 let prefectures = ["Hokkaido", "Aomori", "Iwate", "Miyagi", "Akita", "Yamagata", “Fukushima"] for (offset, prefecture) in prefectures.enumerated() { print(offset, prefecture, prefectures[offset]) /* 0 Hokkaido Hokkaido 1 Aomori Aomori 2 Iwate Iwate 3 Miyagi Miyagi 4 Akita Akita 5 Yamagata Yamagata 6 Fukushima Fukushima */ }

Slide 10

Slide 10 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯͷΠϯσοΫε͸indexed()ͰಘΔ enumerated()΍zip(_:_:)Ͱ͸ͳ͘ w ʮ0͔Β࢝·Δ࿈൪ʯͱʮίϨΫγϣϯͷΠϯσοΫεʯ͸Ұக͠ͳ͍͔΋ 10 let tohoku = prefectures.dropFirst() for (offset, prefecture) in tohoku.enumerated() { print(offset, prefecture, prefectures[offset]) /* 0 Aomori Hokkaido 1 Iwate Aomori 2 Miyagi Iwate 3 Akita Miyagi 4 Yamagata Akita 5 Fukushima Yamagata */ } print(tohoku[0]) // 💥 Fatal error: Index out of bounds

Slide 11

Slide 11 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯͷΠϯσοΫε͸indexed()ͰಘΔ enumerated()΍zip(_:_:)Ͱ͸ͳ͘ w ඪ४తͳ୅ସҊzip(_:_:)͸enumerated()ΑΓύϑΥʔϚϯε͕ѱ͍ 11 for (index, prefecture) in zip(tohoku.indices, tohoku) { print(index, prefecture, prefectures[index]) /* 1 Aomori Aomori 2 Iwate Iwate 3 Miyagi Miyagi 4 Akita Akita 5 Yamagata Yamagata 6 Fukushima Fukushima */ }

Slide 12

Slide 12 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ίϨΫγϣϯͷΠϯσοΫε͸indexed()ͰಘΔ enumerated()΍zip(_:_:)Ͱ͸ͳ͘ w 4XJGU"MHPSJUINTͷindexed()͸zip(_:_:)ΑΓ 
 ύϑΥʔϚϯε͕ྑ͍ 12 import Algorithms for (index, prefecture) in tohoku.indexed() { print(index, prefecture, prefectures[index]) /* 1 Aomori Aomori 2 Iwate Iwate 3 Miyagi Miyagi 4 Akita Akita 5 Yamagata Yamagata 6 Fukushima Fukushima */ }

Slide 13

Slide 13 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ೋॏͷϧʔϓ͸product(_:_:)Λ࢖͏ for-inΛճॻ͘ඞཁ͕ͳ͘ͳΔ 13 let years = [2021, 2022, 2023] let months = ["January", "February", "March", /* ... */] for year in years { for month in months { print(year, month) /* 2021 January 2021 February 2021 March ... 2022 January 2022 February 2022 March ... */ } }

Slide 14

Slide 14 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ೋॏͷϧʔϓ͸product(_:_:)Λ࢖͏ for-inΛճॻ͘ඞཁ͕ͳ͘ͳΔ w 4XJGU"MHPSJUINTͷproduct(_:_:)ͰωετΛݮΒͤΔ w Ұํ͕ۭͷ৔߹ɺແବͳϧʔϓॲཧ͕ൃੜ͠ͳ͍ 14 import Algorithms for (year, month) in product(years, months) { print(year, month) }

Slide 15

Slide 15 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. for-inͱforEach(_:)ͷ࢖͍෼͚Λߟ͑ͯΈΔ forEach(_:)ࣗମ͸for-inͰ࣮૷͞Ε͍ͯΔ͚Ͳ 15 func printWithLowercased(_ value: String) { print(value.lowercased()) } let list = ["DeNA", "STORES", "Rakuten Rakuma"] for name in list { printWithLowercased(name) } // ಉ͡ग़ྗ list.forEach { name in printWithLowercased(name) } // ಉ͡ग़ྗ

Slide 16

Slide 16 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. for-inͱforEach(_:)ͷ࢖͍෼͚Λߟ͑ͯΈΔ forEach(_:)ࣗମ͸for-inͰ࣮૷͞Ε͍ͯΔ͚Ͳ 16 for-inϧʔϓ forEach(_:) ϧʔϓΛ్தͰ΍ΊΔ breakΛ࢖͏ Ͱ͖ͳ͍ ॲཧͷ్தͰ࣍ͷཁૉʹҠΔ continueΛ࢖͏ returnΛ࢖͏ SFUVSOจΛ࢖͏ͱ ϧʔϓ͕͋Δείʔϓ͔Βग़Δ ࣍ͷཁૉͷॲཧʹҠΔ ཁૉ໊ͷলུ Ͱ͖ͳ͍ Ͱ͖Δʢ$0ʣ ؔ਺ͳͲΛ௚઀౉͢ Ͱ͖ͳ͍ Ͱ͖ΔʢforEach(someFunc())ʣ ඇಉظʢBTZODBXBJUʣॲཧ Ͱ͖Δ Ͱ͖ͳ͍

Slide 17

Slide 17 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ໊લۭؒʢ/BNFTQBDFTʣʹ͸enumΛ࢖͏ class΍structͰ͸ͳ͘ w struct΍classΛ࢖͏ͱɺ 
 internalͰ࢖͑ΔΠχγϟϥΠβ͕σϑΥϧτͰ༻ҙ͞Εͯ͠·͏ 17 enum BreakfastMenu { static let rice = "͝൧" static let bread = "ύϯ" // ... } print(BreakfastMenu.rice) // ͝൧

Slide 18

Slide 18 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ϥϯμϜͳ஋ɾཁૉ͕΄͍͠ arc4random()΍arc4random_uniform(_:)͸࢖Θͳ͍ w 4XJGU͔Β࢖͑ΔΑ͏ʹͳͬͨ 
 random()ɾrandom(in:)ɾrandomElement()Λ࢖͏ 18 let flag = Bool.random() let num = Int.random(in: 0..<10) let area = [1: "Shibuya", 2: "Shinjuku"].randomElement() let player = ["uhooi", "treastrain"].randomElement()

Slide 19

Slide 19 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. Optional.map(_:)Λ࢖͏ nilͷͱ͖͸nilͷ··ɺnilͰͳ͍ͱ͖͚ͩॲཧΛߦ͏ w nilͷͱ͖͸ʜͷ෼ذΛࣗ෼Ͱॻ͔ͳͯ͘ࡁΉ 19 struct Talk { let title: String } let selectedTalkTitle: String? = nil let selectedTalk: Talk? = selectedTalkTitle.map { Talk(title: $0) } print(selectedTalk) // nil

Slide 20

Slide 20 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ʮOptionalͳvarʯΛʮඇ0QUJPOBMͳletʯʹ ʮHFU͢Δͱ͖·Ͱʹ͸ඞͣTFU͞Ε͍ͯΔʯϓϩύςΟͰ 20 enum Area { case osaka, hiroshima } let area: Area = // ... var okonomiyaki: String? switch area { case .osaka: okonomiyaki = "ؔ੢෩" case .hiroshima: okonomiyaki = "޿ౡ෩" } print(okonomiyaki)

Slide 21

Slide 21 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ʮOptionalͳvarʯΛʮඇ0QUJPOBMͳletʯʹ ʮHFU͢Δͱ͖·Ͱʹ͸ඞͣTFU͞Ε͍ͯΔʯϓϩύςΟͰ 21 enum Area { case osaka, hiroshima } let area: Area = // ... let okonomiyaki: String switch area { case .osaka: okonomiyaki = "ؔ੢෩" case .hiroshima: okonomiyaki = "޿ౡ෩" } print(okonomiyaki)

Slide 22

Slide 22 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ͋ͱ͔ΒTFU͞ΕΔϓϩύςΟΛOptionalʹ͠ͳ͍ ඞͣTFU͞ΕΔͳΒpreconditionFailure(_:file:line:)ΛԾஔ͖͢Δ 22 import UIKit final class ViewController: UIViewController { // ͜ͷ collectionView ͸ viewDidLoad() ͷޙʹ࡞Δ͜ͱʹ͍ͯ͠ΔʢͱԾఆʣ private var collectionView: UICollectionView? override func viewDidLoad() { super.viewDidLoad() // collectionView Λ࡞Δ collectionView = UICollectionView(frame: .null) // ... // collectionView Λ࢖͏ view.addSubview(collectionView!) } }

Slide 23

Slide 23 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ͋ͱ͔ΒTFU͞ΕΔϓϩύςΟΛOptionalʹ͠ͳ͍ ඞͣTFU͞ΕΔͳΒpreconditionFailure(_:file:line:)ΛԾஔ͖͢Δ 23 import UIKit final class ViewController: UIViewController { // ͜ͷ collectionView ͸ viewDidLoad() ͷޙʹ࡞Δ͜ͱʹ͍ͯ͠ΔʢͱԾఆʣ private lazy var collectionView: UICollectionView = { preconditionFailure("collectionView has not been set") }() override func viewDidLoad() { super.viewDidLoad() // collectionView Λ࡞Δ collectionView = UICollectionView(frame: .null) // ... // collectionView Λ࢖͏ view.addSubview(collectionView) } }

Slide 24

Slide 24 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ֦ுʢ&YUFOTJPOTʣ͸ϓϩτίϧʢ1SPUPDPMTʣ͝ͱʹ࡞Δ ͦͷϓϩτίϧ΁ͷ४ڌͷͨΊͷ࣮૷͸ͦͷதͰͷΈߦ͏ 24 import Foundation struct Book { let name: String let uuid: UUID } extension Book: Identifiable, Hashable { var id: UUID { uuid } } extension Book { func hash(into hasher: inout Hasher) { hasher.combine(id) } }

Slide 25

Slide 25 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ֦ுʢ&YUFOTJPOTʣ͸ϓϩτίϧʢ1SPUPDPMTʣ͝ͱʹ࡞Δ ͦͷϓϩτίϧ΁ͷ४ڌͷͨΊͷ࣮૷͸ͦͷதͰͷΈߦ͏ 25 import Foundation struct Book { let name: String let uuid: UUID } extension Book: Identifiable { var id: UUID { uuid } } extension Book: Hashable { func hash(into hasher: inout Hasher) { hasher.combine(id) } }

Slide 26

Slide 26 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ֦ுʢ&YUFOTJPOTʣ͸ϓϩτίϧʢ1SPUPDPMTʣ͝ͱʹ࡞Δ ͦͷϓϩτίϧ΁ͷ४ڌͷͨΊͷ࣮૷͸ͦͷதͰͷΈߦ͏ w 4XJGU6*ͷྫ 26 import SwiftUI struct ContentView: View { let greeting = "Hello, happy world!" var body: some View { // ϓϩτίϧ View ଆͷఆٛͰ @MainActor ʹͳ͍ͬͯΔ Text(greeting) } }

Slide 27

Slide 27 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ֦ுʢ&YUFOTJPOTʣ͸ϓϩτίϧʢ1SPUPDPMTʣ͝ͱʹ࡞Δ ͦͷϓϩτίϧ΁ͷ४ڌͷͨΊͷ࣮૷͸ͦͷதͰͷΈߦ͏ w 4XJGU6*ͷྫ 27 import SwiftUI struct ContentView: View { let greeting = "Hello, happy world!" } extension ContentView { var body: some View { // 😫 ҉໧తʹ @MainActor Ͱ͸ͳ͘ͳΓɺ // ϓϩτίϧ View ଆͷఆٛͱ͸ҟͳͬͯ͠·͏ Text(greeting) } }

Slide 28

Slide 28 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ֦ுʢ&YUFOTJPOTʣ͸ϓϩτίϧʢ1SPUPDPMTʣ͝ͱʹ࡞Δ ͦͷϓϩτίϧ΁ͷ४ڌͷͨΊͷ࣮૷͸ͦͷதͰͷΈߦ͏ w 4XJGU6*ͷྫ 28 import SwiftUI struct ContentView { let greeting = "Hello, happy world!" } extension ContentView: View { var body: some View { // ✅ ϓϩτίϧ View ଆͷఆٛΑΓ // ҉໧తʹ @MainActor ʹͳΔ Text(greeting) } }

Slide 29

Slide 29 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ͦͷ΄͔఻͔͑ͨͬͨ͜ͱ ͕࣌ؒ଍Γͳ͔ͬͨʜʜ w switchจͰͪΌΜͱ໢ཏͯ͠ɺ 
 ݟམͱ͠Λແͨ͘͠Γޙͷมߋʹڧͨ͘͠Γ͢Δ w Resultͱεϩʔؔ਺ʢ5ISPXJOH'VODUJPOTʣͷ૬ޓม׵ w %FMFHBUFɾΫϩʔδϟΛBTZODͳؔ਺ʹ͢Δ w NotificationCenterΛ4XJGU$PODVSSFODZ͔Β࢖͏ w $PNCJOFɾ3Y4XJGUΛ4XJGU$PODVSSFODZ͔Β࢖͏ 29

Slide 30

Slide 30 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ͞ΒʹεςοϓΞοϓ 6*,JUʢJ04ͳͲʣͰʮͬͪ͜ͷํ͕͍͍Αʯ 30

Slide 31

Slide 31 text

Copyright © 2023 treastrain / Tanaka RyogaɹAll rights reserved. ɹɹɹɹɹεϥΠυɾൃද಺༰͸IUUQTUSFUKQͰެ։͍ͯ͠·͢ɹ⏩ ͦͷ4XJGUίʔυɺ 
 ͜͏ॻ͖׵͑ͯΈͳ͍͔ 1PMJTIJOHZPVS4XJGUDPEFXJUINF 31 DeNA × STORES × ϥΫϚ iOS Meetup!! #dena_stores_rakuma