10.8K Views
October 04, 21
スライド概要
iOSDC2021 で発表した内容です
iOS エンジニアをやっています。
Combine Scheduler iOSDC Japan 2021
iOS & 2 Sansan @kalupas0930 2
Combine ViewModel + Combine combine-schedulers combine-schedulers 3
https://github.com/kalupas226/iOSDC2021SampleApp 4
Search 5
Model Response GitHubRepository.swift / Response body struct GitHubRepository: Decodable, Identifiable, Equatable { { let id: Int let fullName: String "items": [ { "id": 3081286, "full_name": "iOSDC" }, { "id": 3081287, "full_name": "iOSDC2021" }, // ... ] } extension GitHubRepository { private enum CodingKeys: String, CodingKey { case id case fullName = "full_name" } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) } id = try container.decode(Int.self, forKey: .id) fullName = try container.decode(String.self, forKey: .fullName) } } struct GitHubRepositoryList: Decodable { let items: [GitHubRepository] } 6
Model API GitHubAPIClient.swift // interface struct GitHubAPIClient { var searchRepository: (String) -> AnyPublisher<GitHubRepositoryList, Never> } // extension GitHubAPIClient { // static GitHubAPIClient `.live` // ex) GitHubListView(viewModel: GitHubViewModel(gitHubAPIClient: .live)) static let live = Self( searchRepository: { searchWord in URLSession.shared.dataTaskPublisher( for: URL(string: "https://api.github.com/search/repositories?q=\(searchWord)")! ) .map { $0.data } .decode(type: GitHubRepositoryList.self, decoder: JSONDecoder()) .replaceError(with: .init(items: [])) // .eraseToAnyPublisher() } ) } 7
ViewModel GitHubViewModel.swift 8
View GitHubListView.swift 9
SearchButton iOSDC2021SampleAppTests.swift 11
SearchButton iOSDC2021SampleAppTests.swift 12
publish values from the main thread GitHubViewModel.swift 14
DispatchQueue.main receive GitHubViewModel.swift 15
iOSDC2021SampleAppTests.swift 17
wait iOSDC2021SampleAppTests.swift 18
GitHubViewModel.swift 20
GitHubViewModel.swift 21
22
iOSDC2021SampleAppTests.swift 24
iOSDC2021SampleAppTests.swift 25
0.3s GitHubViewModel.swift 26
iOSDC2021SampleAppTests.swift 27
wait 28
0.3s 0.33s wait CI 0.33s 29
combine-schedulers 30
combine-schedulers Point-Free Combine Combine Scheduler protocol Scheduler AnyScheduler TestScheduler ImmediateScheduler Animated schedulers FailingScheduler UIScheduler Publishers.Timer 31
combine-schedulers Point-Free Combine Combine Scheduler protocol Scheduler AnyScheduler TestScheduler ImmediateScheduler Animated schedulers FailingScheduler UIScheduler Publishers.Timer 32
schedulers ViewModel combine-
ViewModel GitHubViewModel.swift 34
combine-schedulers Scheduler GitHubViewModel.swift 35
ViewModel GitHubViewModel.swift 36
combine-shcedulers Scheduler GitHubViewModel.swift 37
Preview ViewModel initialize GitHubListView.swift 38
GitHubListView.swift 39
combine-schedulers
iOSDC2021SampleAppTests.swift 42
iOSDC2021SampleAppTests.swift 43
iOSDC2021SampleAppTests.swift 44
TestScheduler iOSDC2021SampleAppTests.swift 45
TestScheduler iOSDC2021SampleAppTests.swift 46
iOSDC2021SampleAppTests.swift 47
iOSDC2021SampleAppTests.swift 48
49
combine-schedulers 0.3s 0.33s wait 0.33s 50
combine-schedulers 0.3s 0.33s wait 0.33s 51
combine-schedulers ask the speaker
, 53
operator Combine operator 54
protocol 55
Scheduler Scheduler option Scheduler 56
protocol 57
Scheduler Scheduler 58
protocol 59
3 function 60
Scheduler protocol Scheduler
Apple DispatchQueue ImmediateScheduler RunLoop OperationQueue 62
DispatchQueue 63
Scheduler combine-shcedulers
Test Scheduler Scheduler Test combine-schedulers protocol 2 associatedtype 2 property 3 function interval 65
Test Scheduler Scheduler Test combine-schedulers protocol 2 associatedtype 2 property 3 function interval 66
Scheduler Scheduler MyTestScheduler typealias 67
Generics associatedtype property Scheduler DispatchQueue ImmediateScheduler RunLoop OperationQueue Scheduler TestScheduler Generics 68
initializer MyTestScheduler.swift 69
1 function MyTestScheduler.swift 1 function 70
MyTestScheduler.swift 71
MyTestScheduler.swift -> schedule 72
MyTestScheduler MyTestScheduler.swift Combine 73
schedule advance iOSDC2021SampleAppTests.swift 74
MyTestScheduler MyTestScheduler.swift 75
DispatchQueue.myTest iOSDC2021SampleAppTests.swift 76
Publisher MyTestScheduler iOSDC2021SampleAppTests.swift 77
2 function MyTestScheduler.swift 2 function 78
MyTestScheduler.swift 79
date MyTestScheduler.swift 80
advance date MyTestScheduler.swift 81
2 function iOSDC2021SampleAppTests.swift 82
(5000s) iOSDC2021SampleAppTests.swift 83
84
3 function MyTestScheduler.swift 3 function interval 85
MyTestScheduler.swift 86
interval 87
MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 88
MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 89
MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 90
MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 91
0.5s 1s MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 92
1s MyTestScheduler.scheduled [] s.schedule(after: scheduler.now, interval: 1) [scheduleAction(for: now), now)] s.advance() [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 1), now + 1)] s.advance(.milliseconds(500)) [scheduleAction(for: now + 2), now + 2)] 93
iOSDC2021SampleAppTests.swift 94
iOSDC2021SampleAppTests.swift 95
interval MyTestScheduler.swift 96
MyTestScheduler.swift 97
interval iOSDC2021SampleAppTests.swift 98
interval iOSDC2021SampleAppTests.swift 99
iOSDC2021SampleAppTests.swift 100
MyTestScheduler.swift 101
MyTestScheduler.swift 102
iOSDC2021SampleAppTests.swift 103
interval iOSDC2021SampleAppTests.swift Date interval schedule function 104
MyTestScheduler.swift 105
1 2 function MyTestScheduler.swift 106
3 function MyTestScheduler.swift 107
iOSDC2021SampleAppTests.swift 108
interval iOSDC2021SampleAppTests.swift 109
interval iOSDC2021SampleAppTests.swift 110
AnyCancellable MyTestScheduler.swift 111
MyTestScheduler.swift 112
iOSDC2021SampleAppTests.swift 113
combine-schedulers
Combine operator , , , … wait wait combine-schedulers combine-schedulers Protocol Scheduler Test animation Generics 115
GitHub pointfreeco / combine-schedulers tcldr / Entwine Point-Free Combine Schedulers: Testing Time Combine Schedulers: Controlling Time Combine Schedulers: Erasing Time Apple Developer Documentation Scheduler 116
117