Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Xcode Preview 1

Slide 3

Slide 3 text

1 Xcode PreviewͰͷDIઓུͱͦͷ՝୊ 2 ண؟఺ͱղܾํ๏

Slide 4

Slide 4 text

1 Xcode PreviewͰͷDIઓུͱͦͷ՝୊ 2 ண؟఺ͱղܾํ๏

Slide 5

Slide 5 text

Qiita Viewer QiitaͷهࣄΛݕࡧͯ͠ɺ୺຤ʹอଘ͢ΔΞϓϦ https://github.com/mtj0928/QiitaViewer 4

Slide 6

Slide 6 text

5

Slide 7

Slide 7 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ 6

Slide 8

Slide 8 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ 6

Slide 9

Slide 9 text

struct ItemListView: View { @StateObject let viewModel = ItemListViewModel() var body: some View { // viewModelͷitemsΛ࢖ͬͯϦετΛදࣔ͢Δ } } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] func fetchItems() async throws { items = try await APIClient.share.getItems() } } 7

Slide 10

Slide 10 text

struct ItemListView: View { @StateObject let viewModel = ItemListViewModel() var body: some View { // viewModelͷitemsΛ࢖ͬͯϦετΛදࣔ͢Δ } } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] func fetchItems() async throws { items = try await APIClient.share.getItems() } } ViewModelΛ StateObjectͰ؅ཧ 7

Slide 11

Slide 11 text

struct ItemListView: View { @StateObject let viewModel = ItemListViewModel() var body: some View { // viewModelͷitemsΛ࢖ͬͯϦετΛදࣔ͢Δ } } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] func fetchItems() async throws { items = try await APIClient.share.getItems() } } ViewModelΛ StateObjectͰ؅ཧ APIܦ༝ͰitemsΛऔಘ 7

Slide 12

Slide 12 text

struct ItemListView_Previews: PreviewProvider { static var previews: some View { ItemListView() } } 8

Slide 13

Slide 13 text

Xcode PreviewΛ࢖͏্Ͱͷ໰୊఺ // ViewModelͷதͷؔ਺ func fetchItems() async throws { items = try await APIClient.share.getItems() } 9

Slide 14

Slide 14 text

Xcode PreviewΛ࢖͏্Ͱͷ໰୊఺ // ViewModelͷதͷؔ਺ func fetchItems() async throws { items = try await APIClient.share.getItems() } ຖճAPIͷݺͼग़͕͠૸ͬͯ͠·͏ 9

Slide 15

Slide 15 text

Xcode PreviewΛ࢖͏্Ͱͷ໰୊఺ // ViewModelͷதͷؔ਺ func fetchItems() async throws { items = try await APIClient.share.getItems() } ຖճAPIͷݺͼग़͕͠૸ͬͯ͠·͏ UIͷεςʔλεͷίϯτϩʔϧ͕Ͱ͖ͳ͍ APIͷݺͼग़͠ʹ੒ޭͨ࣌͠ͷUI APIͷݺͼग़͠ʹࣦഊͨ࣌͠ͷUI APIΛݺͼग़͍ͯ͠ΔؒͷUI 9

Slide 16

Slide 16 text

Dependency Injection

Slide 17

Slide 17 text

Initializer Injection

Slide 18

Slide 18 text

protocol APIClientProtocol { func getItems() async throws -> [Item] } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] let apiClient: APIClientProtocol init(apiClient: APIClientProtocol) { self.apiClient = apiClient } func fetchItems() async throws { items = try await apiClient.getItems() } } 12

Slide 19

Slide 19 text

protocol APIClientProtocol { func getItems() async throws -> [Item] } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] let apiClient: APIClientProtocol init(apiClient: APIClientProtocol) { self.apiClient = apiClient } func fetchItems() async throws { items = try await apiClient.getItems() } } APIClient༻ʹprotocolΛఆٛ 12

Slide 20

Slide 20 text

protocol APIClientProtocol { func getItems() async throws -> [Item] } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] let apiClient: APIClientProtocol init(apiClient: APIClientProtocol) { self.apiClient = apiClient } func fetchItems() async throws { items = try await apiClient.getItems() } } APIClient༻ʹprotocolΛఆٛ protocolΛinitͰࠩ͠ࠐΉ 12

Slide 21

Slide 21 text

protocol APIClientProtocol { func getItems() async throws -> [Item] } class ItemListViewModel: ObservableObject { @Published var items: [Item] = [] let apiClient: APIClientProtocol init(apiClient: APIClientProtocol) { self.apiClient = apiClient } func fetchItems() async throws { items = try await apiClient.getItems() } } APIClient༻ʹprotocolΛఆٛ protocolΛinitͰࠩ͠ࠐΉ γϯάϧτϯͷ୅ΘΓʹ DI͞ΕͨAPIClinetΛ࢖͏ 12

Slide 22

Slide 22 text

struct ItemListView: View { @StateObject let viewModel: ItemListViewModel var body: some View { // viewModelͷitemsΛ࢖ͬͯϦετΛදࣔ͢Δ } } 13

Slide 23

Slide 23 text

struct ItemListView: View { @StateObject let viewModel: ItemListViewModel var body: some View { // viewModelͷitemsΛ࢖ͬͯϦετΛදࣔ͢Δ } } ViewModelΛ֎͔Βࠩ͠ࠐΉ 13

Slide 24

Slide 24 text

private struct MockAPIClient: APIClientProtocol { func getItems() async throws -> [Item] { // ϞοΫ͍ͨ͠ॲཧΛ͜͜ʹೖΕΔ } } struct ItemListView_Previews: PreviewProvider { static var previews: some View { let apiClient = MockAPIClient() let viewModel = ItemListViewModel(apiClient: apiClient) ItemListView(viewModel: viewModel) } } 14

Slide 25

Slide 25 text

Initializer Injection Ұ൪҆શͳDIख๏ ίϯύΠϧ࣌ʹDI͞Ε͍ͯΔ͜ͱΛอূͰ͖Δ ґଘͷόέπϦϨʔ͕ඞཁ 15

Slide 26

Slide 26 text

Initializer Injection Ұ൪҆શͳDIख๏ ίϯύΠϧ࣌ʹDI͞Ε͍ͯΔ͜ͱΛอূͰ͖Δ ґଘͷόέπϦϨʔ͕ඞཁ 15

Slide 27

Slide 27 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ 16

Slide 28

Slide 28 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ APIClient͕ඞཁ 16

Slide 29

Slide 29 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ APIClient͕ඞཁ DB͕ඞཁ 16

Slide 30

Slide 30 text

App อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷݕࡧ هࣄͷৄࡉ APIClientͱDBΛ౉͢ APIClient͕ඞཁ DB͕ඞཁ 16

Slide 31

Slide 31 text

όέπϦϨʔͷ՝୊ ݕࡧը໘͸APIΛୟ͚ͩ͘ͳͷʹɺDBͷ৘ใ΋౉͢ඞཁ͕͋Δ ItemListView( viewModel: ItemListViewModel(apiClient: MockAPIClient()), db: MockDatabase() ) 17

Slide 32

Slide 32 text

όέπϦϨʔͷ՝୊ ݕࡧը໘͸APIΛୟ͚ͩ͘ͳͷʹɺDBͷ৘ใ΋౉͢ඞཁ͕͋Δ ItemListView( viewModel: ItemListViewModel(apiClient: MockAPIClient()), db: MockDatabase() ) ͜Εඞཁ...ʁ 17

Slide 33

Slide 33 text

όέπϦϨʔͷ՝୊ ݕࡧը໘͸APIΛୟ͚ͩ͘ͳͷʹɺDBͷ৘ใ΋౉͢ඞཁ͕͋Δ ItemListView( viewModel: ItemListViewModel(apiClient: MockAPIClient()), db: MockDatabase(), keychain: MockKeychain(), fileManager: MockFileManager(), userDefaults: MockUserDefaults(), authManager: MockAuthManager(), logger: MockLogger(), ... ) 17

Slide 34

Slide 34 text

όέπϦϨʔͷ՝୊ ݕࡧը໘͸APIΛୟ͚ͩ͘ͳͷʹɺDBͷ৘ใ΋౉͢ඞཁ͕͋Δ ItemListView( viewModel: ItemListViewModel(apiClient: MockAPIClient()), db: MockDatabase(), keychain: MockKeychain(), fileManager: MockFileManager(), userDefaults: MockUserDefaults(), authManager: MockAuthManager(), logger: MockLogger(), ... ) ը໘਺͕૿͑Ε͹૿͑Δ΄ͲXcode Previewʹ౉͢ґଘ͕૿͑Δ 17

Slide 35

Slide 35 text

όέπϦϨʔͷ՝୊ ը໘ͷ਺͕૿͑Δ΄Ͳඞཁͳґଘ͕૿͑ͯɺXcode PreviewΛ ؾܰʹࢼͤͳ͘ͳΔ 18

Slide 36

Slide 36 text

όέπϦϨʔͷ՝୊ ը໘ͷ਺͕૿͑Δ΄Ͳඞཁͳґଘ͕૿͑ͯɺXcode PreviewΛ ؾܰʹࢼͤͳ͘ͳΔ ର৅ͷView͕ͲͷґଘΛ࣮ࡍʹૢ࡞͢Δͷ͔ݺͼग़͠ଆ͸Θ͔Βͳ͍ DBΛ৮Δͷ͔ɺͦΕͱ΋APIΛୟ͘ͷ͔ Xcode Preview࣌ʹԿΛϞοΫ͢ΔͱͲ͏൓ө͞ΕΔͷ͔ͷ೺Ѳ͕೉͘͠ͳΔ 18

Slide 37

Slide 37 text

@Environment @EnvironmentObject

Slide 38

Slide 38 text

RootView() .environment(\.apiClient, APIClient()) .environment(\.database, Database()) struct ItemListView: View { @Environment(\.apiClient) var apiClient: APIClientProtocol } 20

Slide 39

Slide 39 text

@Environmentͷ՝୊ 1. ඞཁͳґଘ͕Θ͔Βͳ͍ struct ItemListView_Previews: PreviewProvider { static var previews: some View { ItemListView() .environment(\.apiClient, MockAPIClient()) } } 21

Slide 40

Slide 40 text

@Environmentͷ՝୊ 1. ඞཁͳґଘ͕Θ͔Βͳ͍ struct ItemListView_Previews: PreviewProvider { static var previews: some View { ItemListView() .environment(\.apiClient, MockAPIClient()) } } ͜ΕΛ๨Εͯ΋ίϯύΠϧΤϥʔʹͳΒͳ͍ 21

Slide 41

Slide 41 text

@Environmentͷ՝୊ 2. initͰΞΫηε͕Ͱ͖ͳ͍ struct ItemListView: View { @Environment(\.apiClient) var apiClient: APIClientProtocol? @StateObject var viewModel: ItemListViewModel init() { self.viewModel = ItemListViewModel(apiClient: apiClient) } var body: some View { ... } } 22

Slide 42

Slide 42 text

@Environmentͷ՝୊ 2. initͰΞΫηε͕Ͱ͖ͳ͍ struct ItemListView: View { @Environment(\.apiClient) var apiClient: APIClientProtocol? @StateObject var viewModel: ItemListViewModel init() { self.viewModel = ItemListViewModel(apiClient: apiClient) } var body: some View { ... } } initͰEnvironmentͷ஋ʹΞΫηεͰ͖ͣ ViewModel͕࡞Εͳ͍ 22

Slide 43

Slide 43 text

՝୊ͷཁ໿ Initializer Injection ը໘ͷ਺͕૿͑Δ΄Ͳ౉͢ґଘ͕૿͑ͯɺXcode PreviewΛࢼ͠ʹ͘͘ͳΔ Ͳͷґଘ͕Xcode Previewʹ࣮ࡍʹඞཁͳґଘ͔ᐆດʹͳΔ @Environment ԿΛDI͢Δ΂͖͔ɺίϯύΠϥ͸Θ͔Βͳ͍ initͰ͸ΞΫηεͰ͖ͳ͍ͷͰɺObservableObjectΛ࡞Δʹ͸޻෉͕ඞཁ 23

Slide 44

Slide 44 text

1 Xcode PreviewͰͷDIઓུͱͦͷ՝୊ 2 ண؟఺ͱղܾํ๏

Slide 45

Slide 45 text

Xcode Previewͷؔ৺ൣғ Xcode Preview࣌ͷؔ৺͸ର৅ͷը໘͚ͩͰ͋Γɺଞͷը໘ʹؔ৺͸ͳ͍ struct ItemListView: View { ... } struct ItemListView_Previews: PreviewProvider { static var previews: some View { ItemListView(viewModel: ...) } } 25

Slide 46

Slide 46 text

Xcode Previewͷؔ৺ൣғ Xcode Preview࣌ͷؔ৺͸ର৅ͷը໘͚ͩͰ͋Γɺଞͷը໘ʹؔ৺͸ͳ͍ struct ItemListView: View { ... } struct ItemListView_Previews: PreviewProvider { static var previews: some View { ItemListView(viewModel: ...) } } ItemListViewʹ͚ͩڵຯ͕͋Γ ભҠઌͷը໘ʹڵຯ͸ͳ͍ 25

Slide 47

Slide 47 text

App هࣄͷݕࡧ อଘࡁΈهࣄͷҰཡ ΞΧ΢ϯτઃఆ هࣄͷৄࡉ 26

Slide 48

Slide 48 text

App ؔ৺಺ هࣄͷݕࡧ ؔ৺಺ อଘࡁΈهࣄͷҰཡ ؔ৺಺ ΞΧ΢ϯτઃఆ ؔ৺಺ هࣄͷৄࡉ 26

Slide 49

Slide 49 text

App ؔ৺֎ ؔ৺಺ هࣄͷݕࡧ ؔ৺಺ อଘࡁΈهࣄͷҰཡ ؔ৺಺ ΞΧ΢ϯτઃఆ ؔ৺಺ هࣄͷৄࡉ ؔ৺֎ 26

Slide 50

Slide 50 text

App ؔ৺֎ ؔ৺಺ هࣄͷݕࡧ Initializer Injection ؔ৺಺ อଘࡁΈهࣄͷҰཡ ؔ৺಺ ΞΧ΢ϯτઃఆ ؔ৺಺ هࣄͷৄࡉ ؔ৺֎ 26

Slide 51

Slide 51 text

App ؔ৺֎ ؔ৺಺ هࣄͷݕࡧ Initializer Injection ؔ৺಺ อଘࡁΈهࣄͷҰཡ ؔ৺಺ ΞΧ΢ϯτઃఆ ؔ৺಺ هࣄͷৄࡉ ؔ৺֎ @Environment 26

Slide 52

Slide 52 text

Dependency Provider 27

Slide 53

Slide 53 text

DependencyProvider 1. DI͍ͨ͠ΦϒδΣΫτΛ·ͱΊͨstructΛ࡞Δ struct AppDependency { let apiClient: APIClientProtocol let database: DatabaseProtocol } 28

Slide 54

Slide 54 text

DependencyProvider 2. AppDependencyΛEnvironmentʹ౉͢ let dependency = AppDependency( apiClient: APIClient(), database: Database() ) AppRootView() .environment(\.dependency, dependency) 29

Slide 55

Slide 55 text

DependencyProvider 3. Environment͔ΒґଘΛऔΓग़͠ɺunwrap͢ΔViewΛ࡞Δ struct DependencyProvider: View { @Environment(\.dependency) var dependency: AppDependency? let childView: (AppDependency) -> ChildView var body: some View { if let dependency { childView(dependency) } else { #if DEBUG Text("Dependency is not set.") // ... .background(.red) #endif 30

Slide 56

Slide 56 text

DependencyProvider 3. Environment͔ΒґଘΛऔΓग़͠ɺunwrap͢ΔViewΛ࡞Δ struct DependencyProvider: View { @Environment(\.dependency) var dependency: AppDependency? let childView: (AppDependency) -> ChildView var body: some View { if let dependency { childView(dependency) } else { #if DEBUG Text("Dependency is not set.") // ... .background(.red) #endif Environment͔Β ґଘΛऔΓग़͢ 30

Slide 57

Slide 57 text

DependencyProvider 3. Environment͔ΒґଘΛऔΓग़͠ɺunwrap͢ΔViewΛ࡞Δ struct DependencyProvider: View { @Environment(\.dependency) var dependency: AppDependency? let childView: (AppDependency) -> ChildView var body: some View { if let dependency { childView(dependency) } else { #if DEBUG Text("Dependency is not set.") // ... .background(.red) #endif ChildViewΛ֎͔Βࠩ͠ࠐΉ 30

Slide 58

Slide 58 text

DependencyProvider 3. Environment͔ΒґଘΛऔΓग़͠ɺunwrap͢ΔViewΛ࡞Δ struct DependencyProvider: View { @Environment(\.dependency) var dependency: AppDependency? let childView: (AppDependency) -> ChildView var body: some View { if let dependency { childView(dependency) } else { #if DEBUG Text("Dependency is not set.") // ... .background(.red) #endif ґଘ͕஫ೖ͞Ε͍ͯΕ͹ ґଘͱڞʹChildViewΛग़͢ 30

Slide 59

Slide 59 text

DependencyProvider 3. Environment͔ΒґଘΛऔΓग़͠ɺunwrap͢ΔViewΛ࡞Δ struct DependencyProvider: View { @Environment(\.dependency) var dependency: AppDependency? let childView: (AppDependency) -> ChildView var body: some View { if let dependency { childView(dependency) } else { #if DEBUG Text("Dependency is not set.") // ... .background(.red) #endif } ґଘ͕஫ೖ͞Ε͍ͯͳ͔ͬͨΒ ͦͷ͜ͱΛදࣔ͢Δ 30

Slide 60

Slide 60 text

DependencyProviderͷ࢖͍ํ 1. ֤ViewͷinitͰ͸ͦͷView͕ඞཁͳґଘ͚ͩΛએݴ͢Δ struct ItemListView: View { init(viewModel: ItemListViewModel) { ... } } 31

Slide 61

Slide 61 text

DependencyProviderͷ࢖͍ํ 1. ֤ViewͷinitͰ͸ͦͷView͕ඞཁͳґଘ͚ͩΛએݴ͢Δ struct ItemListView: View { init(viewModel: ItemListViewModel) { ... } } struct ItemListView_Previews: PreviewProvider { static var previews: some View { let viewModel = ItemListViewModel(apiClient: MockAPIClient()) ItemListView(viewModel: viewModel) } } 31

Slide 62

Slide 62 text

DependencyProviderͷ࢖͍ํ 2. ଞͷViewΛදࣔ͢Δ࣌ɺDependency ProviderΛڬΜͰґଘΛղܾ͢Δ var body: some View { ... .navigationDestination(for: Item.self) { item in } } 32

Slide 63

Slide 63 text

DependencyProviderͷ࢖͍ํ 2. ଞͷViewΛදࣔ͢Δ࣌ɺDependency ProviderΛڬΜͰґଘΛղܾ͢Δ var body: some View { ... .navigationDestination(for: Item.self) { item in DependencyProvider { } } } ·ͣDependencyProviderΛݺͿ 32

Slide 64

Slide 64 text

DependencyProviderͷ࢖͍ํ 2. ଞͷViewΛදࣔ͢Δ࣌ɺDependency ProviderΛڬΜͰґଘΛղܾ͢Δ var body: some View { ... .navigationDestination(for: Item.self) { item in DependencyProvider { dependency in } } } ґଘ͕౉͞ΕΔ 32

Slide 65

Slide 65 text

DependencyProviderͷ࢖͍ํ 2. ଞͷViewΛදࣔ͢Δ࣌ɺDependency ProviderΛڬΜͰґଘΛղܾ͢Δ var body: some View { ... .navigationDestination(for: Item.self) { item in DependencyProvider { dependency in ItemDetailView( item, database: dependency.database ) } } } ౉͞ΕͨґଘΛ࢖ͬͯ Child ViewΛ࡞Δ 32

Slide 66

Slide 66 text

33

Slide 67

Slide 67 text

DependencyProviderͷԿ͕خ͍͔͠ 1. ͲͷView͔ΒͰ΋ґଘ͕औΓग़ͤΔ non-optionalͳ஋ͱͯ͠औΓग़ͤΔ struct FooView: View { var body: some View { NavigationLink("࣍ͷը໘΁") { DependencyProvider { dependency in NextView(database: dependency.database) } } } } 34

Slide 68

Slide 68 text

DependencyProviderͷԿ͕خ͍͔͠ 2. ֤View͸ඞཁͳґଘ͚ͩΛinitͰએݴͰ͖Δ ભҠઌͷը໘ͷͨΊͷґଘ͸ඞཁͳ͍ Xcode PreviewΛར༻͢ΔͨΊͷඞཁे෼ͳґଘΛίϯύΠϥ͕஌ΕΔ ݺͼग़͠ଆ͕ͲͷΑ͏ʹґଘղܾΛ͍ͯ͠Δͷ͔஌Δඞཁ͸ͳ͍ 35

Slide 69

Slide 69 text

DependencyProviderͷԿ͕خ͍͔͠ 3. EnvironmentͷઃఆΛ๨ΕΔ͜ͱ͕ͳ͍ AppDependencyͷઃఆ͸1ճͰྑ͍ Ծʹઃఆ͠๨Ε͍ͯͨΒࢸΔͱ͜ΖͰը໘͕ਅͬ੺ʹͳΔͷͰɺ͙͢ʹؾ෇͚Δ ґଘΛ௥Ճ͢Δ࣌͸ɺAppDependencyʹϓϩύςΟΛ௥Ճ͢Δ AppDependencyΛ࡞͍ͬͯΔՕॴͰઃఆ࿙Ε͕͋ͬͨΒίϯύΠϧΤϥʔʹͳΔ 36

Slide 70

Slide 70 text

DependencyProviderͷԿ͕خ͍͔͠ 4. DIͷํ๏͕View૚Ͱด͍ͯ͡Δ ϓϨθϯςʔγϣϯ૚΍ϏδωεϩδοΫ૚Ͱ͸γϯϓϧͳ Initializer InjectionΛҡ࣋Ͱ͖Δ ୯ମςετͰ͸DependencyProviderʹґଘ͢Δඞཁ͕ͳ͍ 37

Slide 71

Slide 71 text

Ͱ΋͜ͷํ๏ͬͯSwiftUI͚ͩͰ͢ΑͶʁ

Slide 72

Slide 72 text

iOS17͔Β͸UIKitͰ΋Ͱ͖·͢ UITraitCollectionͰSwiftUIͷEnvironmentͱಉ༷ͷ͜ͱ͕Մೳʹʂ ৄ͘͠͸WWDCͷηογϣϯಈըΛࢀর͍ͯͩ͘͠͞ https://developer.apple.com/videos/play/wwdc2023/10057/ 39

Slide 73

Slide 73 text

·ͱΊ Xcode PreviewΛຊ֨తʹ࢖͏ʹ͸DI͸ॏཁͳςʔϚ Initializer Injection΍Environment͸ͦΕͧΕ՝୊͕ଘࡏ ͦΕͧΕͷྑ͍ͱ͜ͲΓͳDependencyProviderΛఏҊ iOS17͔Β͸UIKitͰಉ༷ͷ͜ͱ͕Ͱ͖Δ͔΋...ʁ 40

Slide 74

Slide 74 text

·ͱΊ Xcode PreviewΛຊ֨తʹ࢖͏ʹ͸DI͸ॏཁͳςʔϚ Initializer Injection΍Environment͸ͦΕͧΕ՝୊͕ଘࡏ ͦΕͧΕͷྑ͍ͱ͜ͲΓͳDependencyProviderΛఏҊ iOS17͔Β͸UIKitͰಉ༷ͷ͜ͱ͕Ͱ͖Δ͔΋...ʁ Ξϯέʔτ/ϑΟʔυόοΫ଴͍ͬͯ·͢ʂ 40