├── .gitignore
├── README.md
├── final
├── GitHubSearch
│ ├── APIError.swift
│ ├── LoadingState.swift
│ ├── Resources
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ └── Preview Content
│ │ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── GitHubSearchApp.swift
│ └── Repository
│ │ ├── RepositoryModel.swift
│ │ ├── RepoSearchView.swift
│ │ ├── RepoSearchClient.swift
│ │ └── RepoSearch.swift
├── GitHubSearch-final.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── project.pbxproj
└── GitHubSearchTests
│ └── RepositoryTests.swift
├── starter
├── GitHubSearch
│ ├── APIError.swift
│ ├── Resources
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ └── Preview Content
│ │ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── GitHubSearchApp.swift
│ └── Repository
│ │ ├── RepoSearch.swift
│ │ ├── RepositoryModel.swift
│ │ ├── RepoSearchView.swift
│ │ └── RepoSearchClient.swift
├── GitHubSearch.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── project.pbxproj
└── GitHubSearchTests
│ └── RepositoryTests.swift
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata/
2 | .build/
3 | .DS_Store
4 |
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LetsGitHubSearch
2 |
3 | 발표자료
4 | https://www.slideshare.net/ssuser3d03b2/swiftui-tca-github-search
5 |
--------------------------------------------------------------------------------
/final/GitHubSearch/APIError.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | enum APIError: Error {
4 | case invalidURL
5 | }
6 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/APIError.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | enum APIError: Error {
4 | case invalidURL
5 | }
6 |
--------------------------------------------------------------------------------
/final/GitHubSearch/LoadingState.swift:
--------------------------------------------------------------------------------
1 | enum LoadingState {
2 | case initial
3 | case loading
4 | case loaded
5 | case failed
6 | }
7 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Resources/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Resources/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/GitHubSearchApp.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | @main
4 | struct GitHubSearchApp: App {
5 | var body: some Scene {
6 | WindowGroup {
7 | RepoSearchView()
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/starter/GitHubSearch.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/final/GitHubSearch-final.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/starter/GitHubSearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/final/GitHubSearch-final.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/final/GitHubSearch/GitHubSearchApp.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | import ComposableArchitecture
4 |
5 | @main
6 | struct GitHubSearchApp: App {
7 | var body: some Scene {
8 | WindowGroup {
9 | RepoSearchView(
10 | store: Store(
11 | initialState: RepoSearch.State(),
12 | reducer: RepoSearch()._printChanges()
13 | )
14 | )
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/starter/GitHubSearchTests/RepositoryTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import ComposableArchitecture
4 |
5 | @testable import GitHubSearch
6 |
7 | @MainActor
8 | final class RepositoryTests: XCTestCase {
9 | func test_user_get_repoSearchResults_when_search() async {
10 | // Arrange
11 | // TestStore를 생성합니다.
12 |
13 | // Act & Assert
14 | // 1. "Swift"를 입력했을 때, state.keyword가 "Swift"인지 테스트합니다.
15 | // 2. 검색을 했을 때, 예상하는 검색 결과가 나오는지를 테스트합니다.
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Repository/RepoSearch.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | import ComposableArchitecture
4 |
5 | struct RepoSearch: ReducerProtocol {
6 | struct State: Equatable {
7 | // TODO: 지금 앱은 어떤 상태들로 정의되는가?
8 | // keyword와 searchResults 상태 추가하기
9 | }
10 |
11 | enum Action: Equatable {
12 | // TODO: 상태들을 변화시키는 사용자의 액션은 무엇인가?
13 | // keywordChanged, search 액션 추가하기
14 | }
15 |
16 | func reduce(into state: inout State, action: Action) -> EffectTask {
17 | // TODO: 각각의 Action이 발생했을 때 상태는 어떻게 변화해야 하는가?
18 | // switch action {
19 | // case let .keywordChanged(keyword):
20 | // case .search:
21 | // }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Repository/RepositoryModel.swift:
--------------------------------------------------------------------------------
1 | struct RepositoryModel: Decodable, Equatable, Sendable {
2 | var items: [Result]
3 |
4 | struct Result: Decodable, Equatable, Sendable {
5 | var name: String
6 |
7 | enum CodingKeys: String, CodingKey {
8 | case name = "full_name"
9 | }
10 | }
11 | }
12 |
13 | // MARK: - Mock data
14 |
15 | extension RepositoryModel {
16 | static let mock = Self(
17 | items: [
18 | RepositoryModel.Result(name: "Swift"),
19 | RepositoryModel.Result(name: "SwiftyJSON"),
20 | RepositoryModel.Result(name: "SwiftGuide"),
21 | RepositoryModel.Result(name: "SwiftterSwift")
22 | ]
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Repository/RepositoryModel.swift:
--------------------------------------------------------------------------------
1 | struct RepositoryModel: Decodable, Equatable, Sendable {
2 | var items: [Result]
3 |
4 | struct Result: Decodable, Equatable, Sendable {
5 | var name: String
6 |
7 | enum CodingKeys: String, CodingKey {
8 | case name = "full_name"
9 | }
10 | }
11 | }
12 |
13 | // MARK: - Mock data
14 |
15 | extension RepositoryModel {
16 | static let mock = Self(
17 | items: [
18 | RepositoryModel.Result(name: "Swift"),
19 | RepositoryModel.Result(name: "SwiftyJSON"),
20 | RepositoryModel.Result(name: "SwiftGuide"),
21 | RepositoryModel.Result(name: "SwiftterSwift")
22 | ]
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Repository/RepoSearchView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | import ComposableArchitecture
4 |
5 | struct RepoSearchView: View {
6 | let store: StoreOf
7 |
8 | var body: some View {
9 | WithViewStore(self.store) { viewStore in
10 | NavigationView {
11 | Group {
12 | Text("\(viewStore.requestCount)")
13 | Spacer()
14 |
15 | if(viewStore.isLoading) {
16 | ProgressView()
17 | } else {
18 | List {
19 | ForEach(viewStore.searchResults, id: \.self) { repo in
20 | Text(repo)
21 | }
22 | }
23 | }
24 | Spacer()
25 | }
26 | .searchable(text: viewStore.binding(\.$keyword))
27 | .navigationTitle("Github Search")
28 | }
29 | }
30 | }
31 | }
32 |
33 | struct RepoSearchView_Previews: PreviewProvider {
34 | static var previews: some View {
35 | RepoSearchView(
36 | store: Store(
37 | initialState: RepoSearch.State(),
38 | reducer: RepoSearch()
39 | )
40 | )
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Repository/RepoSearchView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | struct RepoSearchView: View {
4 | @State private var keyword = ""
5 | @State private var searchResults: [String] = []
6 |
7 | private let sampleRepoLists = [
8 | "Swift",
9 | "SwiftyJSON",
10 | "SwiftGuide",
11 | "SwiftterSwift",
12 | ]
13 |
14 | var body: some View {
15 | NavigationView {
16 | VStack {
17 | HStack {
18 | TextField("Search repo", text: self.$keyword)
19 | .textFieldStyle(.roundedBorder)
20 |
21 | Button("Search") {
22 | self.searchResults = self.sampleRepoLists.filter {
23 | $0.contains(self.keyword)
24 | }
25 | }
26 | .buttonStyle(.borderedProminent)
27 | }
28 | .padding()
29 |
30 | List {
31 | ForEach(self.searchResults, id: \.self) { Text($0) }
32 | }
33 | }
34 | .navigationTitle("Github Search")
35 | }
36 | }
37 | }
38 |
39 | struct RepoSearchView_Previews: PreviewProvider {
40 | static var previews: some View {
41 | RepoSearchView()
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 TheComposers
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/final/GitHubSearchTests/RepositoryTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import ComposableArchitecture
4 |
5 | @testable import GitHubSearch_final
6 |
7 | @MainActor
8 | final class RepositoryTests: XCTestCase {
9 | func test_user_get_repo_search_results_when_search() async {
10 | let store = TestStore(
11 | initialState: RepoSearch.State(),
12 | reducer: RepoSearch()
13 | )
14 |
15 | store.dependencies.repoSearchClient.search = { _ in .mock }
16 | store.dependencies.continuousClock = ImmediateClock()
17 |
18 | await store.send(.set(\.$keyword, "Swift")) {
19 | $0.keyword = "Swift"
20 | }
21 |
22 | await store.receive(.search) {
23 | $0.isLoading = true
24 | $0.requestCount = 1
25 | }
26 |
27 | await store.receive(.dataLoaded(.success(.mock))) {
28 | $0.isLoading = false
29 | $0.searchResults = [
30 | "Swift",
31 | "SwiftyJSON",
32 | "SwiftGuide",
33 | "SwiftterSwift",
34 | ]
35 | }
36 | }
37 |
38 | func test_request_count_not_changed_when_keyword_cleared_within_debounce_time() async {
39 | let store = TestStore(
40 | initialState: RepoSearch.State(),
41 | reducer: RepoSearch()
42 | )
43 |
44 | store.dependencies.repoSearchClient.search = { _ in .mock }
45 |
46 | let clock = TestClock()
47 | store.dependencies.continuousClock = clock
48 |
49 | await store.send(.set(\.$keyword, "Swift")) {
50 | $0.keyword = "Swift"
51 | }
52 |
53 |
54 | await clock.advance(by: .seconds(0.3))
55 |
56 | await store.send(.set(\.$keyword, "")) {
57 | $0.keyword = ""
58 | $0.requestCount = 0
59 | $0.isLoading = false
60 | $0.searchResults = []
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/starter/GitHubSearch/Repository/RepoSearchClient.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | import ComposableArchitecture
4 | import XCTestDynamicOverlay
5 |
6 | struct RepoSearchClient {
7 | var search: @Sendable (String) async throws -> RepositoryModel
8 | }
9 |
10 | extension DependencyValues {
11 | var repoSearchClient: RepoSearchClient {
12 | get { self[RepoSearchClient.self] }
13 | set { self[RepoSearchClient.self] = newValue }
14 | }
15 | }
16 |
17 | // MARK: - Live API implementation
18 |
19 | extension RepoSearchClient: DependencyKey {
20 | static let liveValue = RepoSearchClient(
21 | search: { keyword in
22 | guard let url = URL(string: "https://api.github.com/search/repositories?q=\(keyword)") else {
23 | throw APIError.invalidURL
24 | }
25 | let (data, _) = try await URLSession.shared.data(from: url)
26 | return try JSONDecoder().decode(RepositoryModel.self, from: data)
27 | }
28 | )
29 | }
30 |
31 | extension RepoSearchClient: TestDependencyKey {
32 | static let previewValue = Self(
33 | search: { _ in .mock }
34 | )
35 |
36 | static let testValue = Self(
37 | search: unimplemented("\(Self.self).search")
38 | )
39 | }
40 |
41 | // Workshop 진행 중에 임시로 활용할 코드
42 | //
43 | //func sampleSearchRequest(keyword: String, send: Send) async throws {
44 | // guard let url = URL(string: "https://api.github.com/search/repositories?q=\(keyword)") else {
45 | // await send(RepoSearch.Action.dataLoaded(.failure(APIError.invalidURL)))
46 | // return
47 | // }
48 | // let (data, _) = try await URLSession.shared.data(from: url)
49 | // let result = await TaskResult { try JSONDecoder().decode(RepositoryModel.self, from: data) }
50 | //
51 | // await send(RepoSearch.Action.dataLoaded(result))
52 | //}
53 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Repository/RepoSearchClient.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | import ComposableArchitecture
4 | import XCTestDynamicOverlay
5 |
6 | struct RepoSearchClient {
7 | var search: @Sendable (String) async throws -> RepositoryModel
8 | }
9 |
10 | extension DependencyValues {
11 | var repoSearchClient: RepoSearchClient {
12 | get { self[RepoSearchClient.self] }
13 | set { self[RepoSearchClient.self] = newValue }
14 | }
15 | }
16 |
17 | // MARK: - Live API implementation
18 |
19 | extension RepoSearchClient: DependencyKey {
20 | static let liveValue = RepoSearchClient(
21 | search: { keyword in
22 | guard let url = URL(string: "https://api.github.com/search/repositories?q=\(keyword)") else {
23 | throw APIError.invalidURL
24 | }
25 | let (data, _) = try await URLSession.shared.data(from: url)
26 | return try JSONDecoder().decode(RepositoryModel.self, from: data)
27 | }
28 | )
29 | }
30 |
31 | extension RepoSearchClient: TestDependencyKey {
32 | static let previewValue = Self(
33 | search: { _ in .mock }
34 | )
35 |
36 | static let testValue = Self(
37 | search: unimplemented("\(Self.self).search")
38 | )
39 | }
40 |
41 | // Workshop 진행 중에 임시로 활용할 코드
42 | //
43 | //func sampleSearchRequest(keyword: String, send: Send) async throws {
44 | // guard let url = URL(string: "https://api.github.com/search/repositories?q=\(keyword)") else {
45 | // await send(RepoSearch.Action.dataLoaded(.failure(APIError.invalidUrlError)))
46 | // return
47 | // }
48 | // let (data, _) = try await URLSession.shared.data(from: url)
49 | // let result = await TaskResult { try JSONDecoder().decode(RepositoryModel.self, from: data) }
50 | //
51 | // await send(RepoSearch.Action.dataLoaded(result))
52 | //}
53 |
--------------------------------------------------------------------------------
/final/GitHubSearch/Repository/RepoSearch.swift:
--------------------------------------------------------------------------------
1 | import ComposableArchitecture
2 |
3 | struct RepoSearch: ReducerProtocol {
4 | struct State: Equatable {
5 | @BindingState var keyword = ""
6 | var searchResults = [String]()
7 | var isLoading = false
8 | var requestCount = 0
9 | }
10 |
11 | enum Action: Equatable, BindableAction {
12 | case binding(BindingAction)
13 | case search
14 | case dataLoaded(TaskResult)
15 | }
16 |
17 | @Dependency(\.repoSearchClient) var repoSearchClient
18 | @Dependency(\.continuousClock) var clock
19 |
20 | private enum SearchDebounceId {}
21 | var body: some ReducerProtocol {
22 | BindingReducer()
23 | Reduce { state, action in
24 | switch action {
25 | case .binding(\.$keyword):
26 | if state.keyword == "" {
27 | state.isLoading = false
28 | state.searchResults = []
29 | return .cancel(id: SearchDebounceId.self)
30 | }
31 |
32 | return .run { send in
33 | try await self.clock.sleep(for: .seconds(0.5))
34 | await send(.search)
35 | }
36 | .cancellable(id: SearchDebounceId.self, cancelInFlight: true)
37 |
38 | case .search:
39 | state.isLoading = true
40 | state.requestCount += 1
41 | return EffectTask.run { [keyword = state.keyword] send in
42 | let result = await TaskResult { try await repoSearchClient.search(keyword) }
43 | await send(.dataLoaded(result))
44 | }
45 |
46 | case let .dataLoaded(.success(repositoryModel)):
47 | state.isLoading = false
48 | state.searchResults = repositoryModel.items.map { $0.name }
49 | return .none
50 |
51 | case .dataLoaded(.failure):
52 | state.isLoading = false
53 | state.searchResults = []
54 | return .none
55 |
56 | case .binding:
57 | return .none
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/starter/GitHubSearch.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "combine-schedulers",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/pointfreeco/combine-schedulers",
7 | "state" : {
8 | "revision" : "882ac01eb7ef9e36d4467eb4b1151e74fcef85ab",
9 | "version" : "0.9.1"
10 | }
11 | },
12 | {
13 | "identity" : "swift-case-paths",
14 | "kind" : "remoteSourceControl",
15 | "location" : "https://github.com/pointfreeco/swift-case-paths",
16 | "state" : {
17 | "revision" : "bb436421f57269fbcfe7360735985321585a86e5",
18 | "version" : "0.10.1"
19 | }
20 | },
21 | {
22 | "identity" : "swift-clocks",
23 | "kind" : "remoteSourceControl",
24 | "location" : "https://github.com/pointfreeco/swift-clocks",
25 | "state" : {
26 | "revision" : "20b25ca0dd88ebfb9111ec937814ddc5a8880172",
27 | "version" : "0.2.0"
28 | }
29 | },
30 | {
31 | "identity" : "swift-collections",
32 | "kind" : "remoteSourceControl",
33 | "location" : "https://github.com/apple/swift-collections",
34 | "state" : {
35 | "revision" : "f504716c27d2e5d4144fa4794b12129301d17729",
36 | "version" : "1.0.3"
37 | }
38 | },
39 | {
40 | "identity" : "swift-composable-architecture",
41 | "kind" : "remoteSourceControl",
42 | "location" : "https://github.com/pointfreeco/swift-composable-architecture",
43 | "state" : {
44 | "revision" : "52dca7e5edd6ec9e0b529380843a8cb13f57d7d7",
45 | "version" : "0.46.0"
46 | }
47 | },
48 | {
49 | "identity" : "swift-custom-dump",
50 | "kind" : "remoteSourceControl",
51 | "location" : "https://github.com/pointfreeco/swift-custom-dump",
52 | "state" : {
53 | "revision" : "ead7d30cc224c3642c150b546f4f1080d1c411a8",
54 | "version" : "0.6.1"
55 | }
56 | },
57 | {
58 | "identity" : "swift-identified-collections",
59 | "kind" : "remoteSourceControl",
60 | "location" : "https://github.com/pointfreeco/swift-identified-collections",
61 | "state" : {
62 | "revision" : "a08887de589e3829d488e0b4b707b2ca804b1060",
63 | "version" : "0.5.0"
64 | }
65 | },
66 | {
67 | "identity" : "xctest-dynamic-overlay",
68 | "kind" : "remoteSourceControl",
69 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
70 | "state" : {
71 | "revision" : "5a5457a744239896e9b0b03a8e1a5069c3e7b91f",
72 | "version" : "0.6.0"
73 | }
74 | }
75 | ],
76 | "version" : 2
77 | }
78 |
--------------------------------------------------------------------------------
/final/GitHubSearch-final.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "combine-schedulers",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/pointfreeco/combine-schedulers",
7 | "state" : {
8 | "revision" : "882ac01eb7ef9e36d4467eb4b1151e74fcef85ab",
9 | "version" : "0.9.1"
10 | }
11 | },
12 | {
13 | "identity" : "swift-case-paths",
14 | "kind" : "remoteSourceControl",
15 | "location" : "https://github.com/pointfreeco/swift-case-paths",
16 | "state" : {
17 | "revision" : "fc45e7b2cfece9dd80b5a45e6469ffe67fe67984",
18 | "version" : "0.14.1"
19 | }
20 | },
21 | {
22 | "identity" : "swift-clocks",
23 | "kind" : "remoteSourceControl",
24 | "location" : "https://github.com/pointfreeco/swift-clocks",
25 | "state" : {
26 | "revision" : "20b25ca0dd88ebfb9111ec937814ddc5a8880172",
27 | "version" : "0.2.0"
28 | }
29 | },
30 | {
31 | "identity" : "swift-collections",
32 | "kind" : "remoteSourceControl",
33 | "location" : "https://github.com/apple/swift-collections",
34 | "state" : {
35 | "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
36 | "version" : "1.0.4"
37 | }
38 | },
39 | {
40 | "identity" : "swift-composable-architecture",
41 | "kind" : "remoteSourceControl",
42 | "location" : "https://github.com/pointfreeco/swift-composable-architecture",
43 | "state" : {
44 | "revision" : "3e8eee1efe99d06e99426d421733b858b332186b",
45 | "version" : "0.52.0"
46 | }
47 | },
48 | {
49 | "identity" : "swift-custom-dump",
50 | "kind" : "remoteSourceControl",
51 | "location" : "https://github.com/pointfreeco/swift-custom-dump",
52 | "state" : {
53 | "revision" : "84b30e1af72e0ffe6dfbfe39d53b8173caacf224",
54 | "version" : "0.10.2"
55 | }
56 | },
57 | {
58 | "identity" : "swift-dependencies",
59 | "kind" : "remoteSourceControl",
60 | "location" : "https://github.com/pointfreeco/swift-dependencies",
61 | "state" : {
62 | "revision" : "98650d886ec950b587d671261f06d6b59dec4052",
63 | "version" : "0.4.1"
64 | }
65 | },
66 | {
67 | "identity" : "swift-identified-collections",
68 | "kind" : "remoteSourceControl",
69 | "location" : "https://github.com/pointfreeco/swift-identified-collections",
70 | "state" : {
71 | "revision" : "f52eee28bdc6065aa2f8424067e6f04c74bda6e6",
72 | "version" : "0.7.1"
73 | }
74 | },
75 | {
76 | "identity" : "swiftui-navigation",
77 | "kind" : "remoteSourceControl",
78 | "location" : "https://github.com/pointfreeco/swiftui-navigation",
79 | "state" : {
80 | "revision" : "47dd574b900ba5ba679f56ea00d4d282fc7305a6",
81 | "version" : "0.7.1"
82 | }
83 | },
84 | {
85 | "identity" : "xctest-dynamic-overlay",
86 | "kind" : "remoteSourceControl",
87 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
88 | "state" : {
89 | "revision" : "ab8c9f45843694dd16be4297e6d44c0634fd9913",
90 | "version" : "0.8.4"
91 | }
92 | }
93 | ],
94 | "version" : 2
95 | }
96 |
--------------------------------------------------------------------------------
/starter/GitHubSearch.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EC4BC239293463F4001B2F91 /* APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC4BC238293463F4001B2F91 /* APIError.swift */; };
11 | ECC8142829334ADF0038A09F /* GitHubSearchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */; };
12 | ECC8142C29334AE00038A09F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECC8142B29334AE00038A09F /* Assets.xcassets */; };
13 | ECC8142F29334AE00038A09F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECC8142E29334AE00038A09F /* Preview Assets.xcassets */; };
14 | ECC8143929334AE00038A09F /* RepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8143829334AE00038A09F /* RepositoryTests.swift */; };
15 | ECC8145429334C590038A09F /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = ECC8145329334C590038A09F /* ComposableArchitecture */; };
16 | ECC8145629334C590038A09F /* Dependencies in Frameworks */ = {isa = PBXBuildFile; productRef = ECC8145529334C590038A09F /* Dependencies */; };
17 | ECC8145C29334CB70038A09F /* RepoSearchClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145829334CB70038A09F /* RepoSearchClient.swift */; };
18 | ECC8145D29334CB70038A09F /* RepoSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145929334CB70038A09F /* RepoSearch.swift */; };
19 | ECC8145E29334CB70038A09F /* RepositoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145A29334CB70038A09F /* RepositoryModel.swift */; };
20 | ECC8145F29334CB70038A09F /* RepoSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145B29334CB70038A09F /* RepoSearchView.swift */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | ECC8143529334AE00038A09F /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = ECC8141C29334ADF0038A09F /* Project object */;
27 | proxyType = 1;
28 | remoteGlobalIDString = ECC8142329334ADF0038A09F;
29 | remoteInfo = GitHubSearch;
30 | };
31 | /* End PBXContainerItemProxy section */
32 |
33 | /* Begin PBXFileReference section */
34 | EC4BC238293463F4001B2F91 /* APIError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIError.swift; sourceTree = ""; };
35 | ECC8142429334ADF0038A09F /* GitHubSearch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitHubSearch.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 | ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubSearchApp.swift; sourceTree = ""; };
37 | ECC8142B29334AE00038A09F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
38 | ECC8142E29334AE00038A09F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
39 | ECC8143429334AE00038A09F /* GitHubSearchTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GitHubSearchTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
40 | ECC8143829334AE00038A09F /* RepositoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryTests.swift; sourceTree = ""; };
41 | ECC8145829334CB70038A09F /* RepoSearchClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearchClient.swift; sourceTree = ""; };
42 | ECC8145929334CB70038A09F /* RepoSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearch.swift; sourceTree = ""; };
43 | ECC8145A29334CB70038A09F /* RepositoryModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoryModel.swift; sourceTree = ""; };
44 | ECC8145B29334CB70038A09F /* RepoSearchView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearchView.swift; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | ECC8142129334ADF0038A09F /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | ECC8145429334C590038A09F /* ComposableArchitecture in Frameworks */,
53 | ECC8145629334C590038A09F /* Dependencies in Frameworks */,
54 | );
55 | runOnlyForDeploymentPostprocessing = 0;
56 | };
57 | ECC8143129334AE00038A09F /* Frameworks */ = {
58 | isa = PBXFrameworksBuildPhase;
59 | buildActionMask = 2147483647;
60 | files = (
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | /* End PBXFrameworksBuildPhase section */
65 |
66 | /* Begin PBXGroup section */
67 | ECC8141B29334ADF0038A09F = {
68 | isa = PBXGroup;
69 | children = (
70 | ECC8142629334ADF0038A09F /* GitHubSearch */,
71 | ECC8143729334AE00038A09F /* GitHubSearchTests */,
72 | ECC8142529334ADF0038A09F /* Products */,
73 | );
74 | sourceTree = "";
75 | };
76 | ECC8142529334ADF0038A09F /* Products */ = {
77 | isa = PBXGroup;
78 | children = (
79 | ECC8142429334ADF0038A09F /* GitHubSearch.app */,
80 | ECC8143429334AE00038A09F /* GitHubSearchTests.xctest */,
81 | );
82 | name = Products;
83 | sourceTree = "";
84 | };
85 | ECC8142629334ADF0038A09F /* GitHubSearch */ = {
86 | isa = PBXGroup;
87 | children = (
88 | ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */,
89 | EC4BC238293463F4001B2F91 /* APIError.swift */,
90 | ECC8145729334C6B0038A09F /* Repository */,
91 | ECC8145129334AFC0038A09F /* Resources */,
92 | );
93 | path = GitHubSearch;
94 | sourceTree = "";
95 | };
96 | ECC8142D29334AE00038A09F /* Preview Content */ = {
97 | isa = PBXGroup;
98 | children = (
99 | ECC8142E29334AE00038A09F /* Preview Assets.xcassets */,
100 | );
101 | path = "Preview Content";
102 | sourceTree = "";
103 | };
104 | ECC8143729334AE00038A09F /* GitHubSearchTests */ = {
105 | isa = PBXGroup;
106 | children = (
107 | ECC8143829334AE00038A09F /* RepositoryTests.swift */,
108 | );
109 | path = GitHubSearchTests;
110 | sourceTree = "";
111 | };
112 | ECC8145129334AFC0038A09F /* Resources */ = {
113 | isa = PBXGroup;
114 | children = (
115 | ECC8142D29334AE00038A09F /* Preview Content */,
116 | ECC8142B29334AE00038A09F /* Assets.xcassets */,
117 | );
118 | path = Resources;
119 | sourceTree = "";
120 | };
121 | ECC8145729334C6B0038A09F /* Repository */ = {
122 | isa = PBXGroup;
123 | children = (
124 | ECC8145B29334CB70038A09F /* RepoSearchView.swift */,
125 | ECC8145929334CB70038A09F /* RepoSearch.swift */,
126 | ECC8145829334CB70038A09F /* RepoSearchClient.swift */,
127 | ECC8145A29334CB70038A09F /* RepositoryModel.swift */,
128 | );
129 | path = Repository;
130 | sourceTree = "";
131 | };
132 | /* End PBXGroup section */
133 |
134 | /* Begin PBXNativeTarget section */
135 | ECC8142329334ADF0038A09F /* GitHubSearch */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = ECC8144829334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch" */;
138 | buildPhases = (
139 | ECC8142029334ADF0038A09F /* Sources */,
140 | ECC8142129334ADF0038A09F /* Frameworks */,
141 | ECC8142229334ADF0038A09F /* Resources */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | );
147 | name = GitHubSearch;
148 | packageProductDependencies = (
149 | ECC8145329334C590038A09F /* ComposableArchitecture */,
150 | ECC8145529334C590038A09F /* Dependencies */,
151 | );
152 | productName = GitHubSearch;
153 | productReference = ECC8142429334ADF0038A09F /* GitHubSearch.app */;
154 | productType = "com.apple.product-type.application";
155 | };
156 | ECC8143329334AE00038A09F /* GitHubSearchTests */ = {
157 | isa = PBXNativeTarget;
158 | buildConfigurationList = ECC8144B29334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearchTests" */;
159 | buildPhases = (
160 | ECC8143029334AE00038A09F /* Sources */,
161 | ECC8143129334AE00038A09F /* Frameworks */,
162 | ECC8143229334AE00038A09F /* Resources */,
163 | );
164 | buildRules = (
165 | );
166 | dependencies = (
167 | ECC8143629334AE00038A09F /* PBXTargetDependency */,
168 | );
169 | name = GitHubSearchTests;
170 | productName = GitHubSearchTests;
171 | productReference = ECC8143429334AE00038A09F /* GitHubSearchTests.xctest */;
172 | productType = "com.apple.product-type.bundle.unit-test";
173 | };
174 | /* End PBXNativeTarget section */
175 |
176 | /* Begin PBXProject section */
177 | ECC8141C29334ADF0038A09F /* Project object */ = {
178 | isa = PBXProject;
179 | attributes = {
180 | BuildIndependentTargetsInParallel = 1;
181 | LastSwiftUpdateCheck = 1410;
182 | LastUpgradeCheck = 1410;
183 | TargetAttributes = {
184 | ECC8142329334ADF0038A09F = {
185 | CreatedOnToolsVersion = 14.1;
186 | };
187 | ECC8143329334AE00038A09F = {
188 | CreatedOnToolsVersion = 14.1;
189 | TestTargetID = ECC8142329334ADF0038A09F;
190 | };
191 | };
192 | };
193 | buildConfigurationList = ECC8141F29334ADF0038A09F /* Build configuration list for PBXProject "GitHubSearch" */;
194 | compatibilityVersion = "Xcode 14.0";
195 | developmentRegion = en;
196 | hasScannedForEncodings = 0;
197 | knownRegions = (
198 | en,
199 | Base,
200 | );
201 | mainGroup = ECC8141B29334ADF0038A09F;
202 | packageReferences = (
203 | ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */,
204 | );
205 | productRefGroup = ECC8142529334ADF0038A09F /* Products */;
206 | projectDirPath = "";
207 | projectRoot = "";
208 | targets = (
209 | ECC8142329334ADF0038A09F /* GitHubSearch */,
210 | ECC8143329334AE00038A09F /* GitHubSearchTests */,
211 | );
212 | };
213 | /* End PBXProject section */
214 |
215 | /* Begin PBXResourcesBuildPhase section */
216 | ECC8142229334ADF0038A09F /* Resources */ = {
217 | isa = PBXResourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | ECC8142F29334AE00038A09F /* Preview Assets.xcassets in Resources */,
221 | ECC8142C29334AE00038A09F /* Assets.xcassets in Resources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | ECC8143229334AE00038A09F /* Resources */ = {
226 | isa = PBXResourcesBuildPhase;
227 | buildActionMask = 2147483647;
228 | files = (
229 | );
230 | runOnlyForDeploymentPostprocessing = 0;
231 | };
232 | /* End PBXResourcesBuildPhase section */
233 |
234 | /* Begin PBXSourcesBuildPhase section */
235 | ECC8142029334ADF0038A09F /* Sources */ = {
236 | isa = PBXSourcesBuildPhase;
237 | buildActionMask = 2147483647;
238 | files = (
239 | ECC8145C29334CB70038A09F /* RepoSearchClient.swift in Sources */,
240 | ECC8145E29334CB70038A09F /* RepositoryModel.swift in Sources */,
241 | ECC8142829334ADF0038A09F /* GitHubSearchApp.swift in Sources */,
242 | ECC8145F29334CB70038A09F /* RepoSearchView.swift in Sources */,
243 | ECC8145D29334CB70038A09F /* RepoSearch.swift in Sources */,
244 | EC4BC239293463F4001B2F91 /* APIError.swift in Sources */,
245 | );
246 | runOnlyForDeploymentPostprocessing = 0;
247 | };
248 | ECC8143029334AE00038A09F /* Sources */ = {
249 | isa = PBXSourcesBuildPhase;
250 | buildActionMask = 2147483647;
251 | files = (
252 | ECC8143929334AE00038A09F /* RepositoryTests.swift in Sources */,
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | /* End PBXSourcesBuildPhase section */
257 |
258 | /* Begin PBXTargetDependency section */
259 | ECC8143629334AE00038A09F /* PBXTargetDependency */ = {
260 | isa = PBXTargetDependency;
261 | target = ECC8142329334ADF0038A09F /* GitHubSearch */;
262 | targetProxy = ECC8143529334AE00038A09F /* PBXContainerItemProxy */;
263 | };
264 | /* End PBXTargetDependency section */
265 |
266 | /* Begin XCBuildConfiguration section */
267 | ECC8144629334AE00038A09F /* Debug */ = {
268 | isa = XCBuildConfiguration;
269 | buildSettings = {
270 | ALWAYS_SEARCH_USER_PATHS = NO;
271 | CLANG_ANALYZER_NONNULL = YES;
272 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
273 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
274 | CLANG_ENABLE_MODULES = YES;
275 | CLANG_ENABLE_OBJC_ARC = YES;
276 | CLANG_ENABLE_OBJC_WEAK = YES;
277 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
278 | CLANG_WARN_BOOL_CONVERSION = YES;
279 | CLANG_WARN_COMMA = YES;
280 | CLANG_WARN_CONSTANT_CONVERSION = YES;
281 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
282 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
283 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
284 | CLANG_WARN_EMPTY_BODY = YES;
285 | CLANG_WARN_ENUM_CONVERSION = YES;
286 | CLANG_WARN_INFINITE_RECURSION = YES;
287 | CLANG_WARN_INT_CONVERSION = YES;
288 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
289 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
290 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
291 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
292 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
293 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
294 | CLANG_WARN_STRICT_PROTOTYPES = YES;
295 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
296 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
297 | CLANG_WARN_UNREACHABLE_CODE = YES;
298 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
299 | COPY_PHASE_STRIP = NO;
300 | DEBUG_INFORMATION_FORMAT = dwarf;
301 | ENABLE_STRICT_OBJC_MSGSEND = YES;
302 | ENABLE_TESTABILITY = YES;
303 | GCC_C_LANGUAGE_STANDARD = gnu11;
304 | GCC_DYNAMIC_NO_PIC = NO;
305 | GCC_NO_COMMON_BLOCKS = YES;
306 | GCC_OPTIMIZATION_LEVEL = 0;
307 | GCC_PREPROCESSOR_DEFINITIONS = (
308 | "DEBUG=1",
309 | "$(inherited)",
310 | );
311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
313 | GCC_WARN_UNDECLARED_SELECTOR = YES;
314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
315 | GCC_WARN_UNUSED_FUNCTION = YES;
316 | GCC_WARN_UNUSED_VARIABLE = YES;
317 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
318 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
319 | MTL_FAST_MATH = YES;
320 | ONLY_ACTIVE_ARCH = YES;
321 | SDKROOT = iphoneos;
322 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
323 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
324 | };
325 | name = Debug;
326 | };
327 | ECC8144729334AE00038A09F /* Release */ = {
328 | isa = XCBuildConfiguration;
329 | buildSettings = {
330 | ALWAYS_SEARCH_USER_PATHS = NO;
331 | CLANG_ANALYZER_NONNULL = YES;
332 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
334 | CLANG_ENABLE_MODULES = YES;
335 | CLANG_ENABLE_OBJC_ARC = YES;
336 | CLANG_ENABLE_OBJC_WEAK = YES;
337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
338 | CLANG_WARN_BOOL_CONVERSION = YES;
339 | CLANG_WARN_COMMA = YES;
340 | CLANG_WARN_CONSTANT_CONVERSION = YES;
341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
343 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
344 | CLANG_WARN_EMPTY_BODY = YES;
345 | CLANG_WARN_ENUM_CONVERSION = YES;
346 | CLANG_WARN_INFINITE_RECURSION = YES;
347 | CLANG_WARN_INT_CONVERSION = YES;
348 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
349 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
350 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
351 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
352 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
353 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
354 | CLANG_WARN_STRICT_PROTOTYPES = YES;
355 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
356 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
357 | CLANG_WARN_UNREACHABLE_CODE = YES;
358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
359 | COPY_PHASE_STRIP = NO;
360 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
361 | ENABLE_NS_ASSERTIONS = NO;
362 | ENABLE_STRICT_OBJC_MSGSEND = YES;
363 | GCC_C_LANGUAGE_STANDARD = gnu11;
364 | GCC_NO_COMMON_BLOCKS = YES;
365 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
366 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
367 | GCC_WARN_UNDECLARED_SELECTOR = YES;
368 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
369 | GCC_WARN_UNUSED_FUNCTION = YES;
370 | GCC_WARN_UNUSED_VARIABLE = YES;
371 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
372 | MTL_ENABLE_DEBUG_INFO = NO;
373 | MTL_FAST_MATH = YES;
374 | SDKROOT = iphoneos;
375 | SWIFT_COMPILATION_MODE = wholemodule;
376 | SWIFT_OPTIMIZATION_LEVEL = "-O";
377 | VALIDATE_PRODUCT = YES;
378 | };
379 | name = Release;
380 | };
381 | ECC8144929334AE00038A09F /* Debug */ = {
382 | isa = XCBuildConfiguration;
383 | buildSettings = {
384 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
385 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
386 | CODE_SIGN_STYLE = Automatic;
387 | CURRENT_PROJECT_VERSION = 1;
388 | DEVELOPMENT_ASSET_PATHS = "\"GitHubSearch/Resources/Preview Content\"";
389 | DEVELOPMENT_TEAM = 8B27K52UU7;
390 | ENABLE_PREVIEWS = YES;
391 | GENERATE_INFOPLIST_FILE = YES;
392 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
393 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
394 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
395 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
396 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
397 | LD_RUNPATH_SEARCH_PATHS = (
398 | "$(inherited)",
399 | "@executable_path/Frameworks",
400 | );
401 | MARKETING_VERSION = 1.0;
402 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearch";
403 | PRODUCT_NAME = "$(TARGET_NAME)";
404 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
405 | SUPPORTS_MACCATALYST = NO;
406 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
407 | SWIFT_EMIT_LOC_STRINGS = YES;
408 | SWIFT_VERSION = 5.0;
409 | TARGETED_DEVICE_FAMILY = 1;
410 | };
411 | name = Debug;
412 | };
413 | ECC8144A29334AE00038A09F /* Release */ = {
414 | isa = XCBuildConfiguration;
415 | buildSettings = {
416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
417 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
418 | CODE_SIGN_STYLE = Automatic;
419 | CURRENT_PROJECT_VERSION = 1;
420 | DEVELOPMENT_ASSET_PATHS = "\"GitHubSearch/Resources/Preview Content\"";
421 | DEVELOPMENT_TEAM = 8B27K52UU7;
422 | ENABLE_PREVIEWS = YES;
423 | GENERATE_INFOPLIST_FILE = YES;
424 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
425 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
426 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
427 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
428 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
429 | LD_RUNPATH_SEARCH_PATHS = (
430 | "$(inherited)",
431 | "@executable_path/Frameworks",
432 | );
433 | MARKETING_VERSION = 1.0;
434 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearch";
435 | PRODUCT_NAME = "$(TARGET_NAME)";
436 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
437 | SUPPORTS_MACCATALYST = NO;
438 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
439 | SWIFT_EMIT_LOC_STRINGS = YES;
440 | SWIFT_VERSION = 5.0;
441 | TARGETED_DEVICE_FAMILY = 1;
442 | };
443 | name = Release;
444 | };
445 | ECC8144C29334AE00038A09F /* Debug */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
449 | BUNDLE_LOADER = "$(TEST_HOST)";
450 | CODE_SIGN_STYLE = Automatic;
451 | CURRENT_PROJECT_VERSION = 1;
452 | DEVELOPMENT_TEAM = 8B27K52UU7;
453 | GENERATE_INFOPLIST_FILE = YES;
454 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
455 | MARKETING_VERSION = 1.0;
456 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearchTests";
457 | PRODUCT_NAME = "$(TARGET_NAME)";
458 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
459 | SUPPORTS_MACCATALYST = NO;
460 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
461 | SWIFT_EMIT_LOC_STRINGS = NO;
462 | SWIFT_VERSION = 5.0;
463 | TARGETED_DEVICE_FAMILY = 1;
464 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GitHubSearch.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/GitHubSearch";
465 | };
466 | name = Debug;
467 | };
468 | ECC8144D29334AE00038A09F /* Release */ = {
469 | isa = XCBuildConfiguration;
470 | buildSettings = {
471 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
472 | BUNDLE_LOADER = "$(TEST_HOST)";
473 | CODE_SIGN_STYLE = Automatic;
474 | CURRENT_PROJECT_VERSION = 1;
475 | DEVELOPMENT_TEAM = 8B27K52UU7;
476 | GENERATE_INFOPLIST_FILE = YES;
477 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
478 | MARKETING_VERSION = 1.0;
479 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearchTests";
480 | PRODUCT_NAME = "$(TARGET_NAME)";
481 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
482 | SUPPORTS_MACCATALYST = NO;
483 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
484 | SWIFT_EMIT_LOC_STRINGS = NO;
485 | SWIFT_VERSION = 5.0;
486 | TARGETED_DEVICE_FAMILY = 1;
487 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GitHubSearch.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/GitHubSearch";
488 | };
489 | name = Release;
490 | };
491 | /* End XCBuildConfiguration section */
492 |
493 | /* Begin XCConfigurationList section */
494 | ECC8141F29334ADF0038A09F /* Build configuration list for PBXProject "GitHubSearch" */ = {
495 | isa = XCConfigurationList;
496 | buildConfigurations = (
497 | ECC8144629334AE00038A09F /* Debug */,
498 | ECC8144729334AE00038A09F /* Release */,
499 | );
500 | defaultConfigurationIsVisible = 0;
501 | defaultConfigurationName = Release;
502 | };
503 | ECC8144829334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch" */ = {
504 | isa = XCConfigurationList;
505 | buildConfigurations = (
506 | ECC8144929334AE00038A09F /* Debug */,
507 | ECC8144A29334AE00038A09F /* Release */,
508 | );
509 | defaultConfigurationIsVisible = 0;
510 | defaultConfigurationName = Release;
511 | };
512 | ECC8144B29334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearchTests" */ = {
513 | isa = XCConfigurationList;
514 | buildConfigurations = (
515 | ECC8144C29334AE00038A09F /* Debug */,
516 | ECC8144D29334AE00038A09F /* Release */,
517 | );
518 | defaultConfigurationIsVisible = 0;
519 | defaultConfigurationName = Release;
520 | };
521 | /* End XCConfigurationList section */
522 |
523 | /* Begin XCRemoteSwiftPackageReference section */
524 | ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {
525 | isa = XCRemoteSwiftPackageReference;
526 | repositoryURL = "https://github.com/pointfreeco/swift-composable-architecture";
527 | requirement = {
528 | kind = exactVersion;
529 | version = 0.46.0;
530 | };
531 | };
532 | /* End XCRemoteSwiftPackageReference section */
533 |
534 | /* Begin XCSwiftPackageProductDependency section */
535 | ECC8145329334C590038A09F /* ComposableArchitecture */ = {
536 | isa = XCSwiftPackageProductDependency;
537 | package = ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
538 | productName = ComposableArchitecture;
539 | };
540 | ECC8145529334C590038A09F /* Dependencies */ = {
541 | isa = XCSwiftPackageProductDependency;
542 | package = ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
543 | productName = Dependencies;
544 | };
545 | /* End XCSwiftPackageProductDependency section */
546 | };
547 | rootObject = ECC8141C29334ADF0038A09F /* Project object */;
548 | }
549 |
--------------------------------------------------------------------------------
/final/GitHubSearch-final.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EC4BC239293463F4001B2F91 /* APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC4BC238293463F4001B2F91 /* APIError.swift */; };
11 | ECC8142829334ADF0038A09F /* GitHubSearchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */; };
12 | ECC8142C29334AE00038A09F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECC8142B29334AE00038A09F /* Assets.xcassets */; };
13 | ECC8142F29334AE00038A09F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECC8142E29334AE00038A09F /* Preview Assets.xcassets */; };
14 | ECC8143929334AE00038A09F /* RepositoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8143829334AE00038A09F /* RepositoryTests.swift */; };
15 | ECC8145429334C590038A09F /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = ECC8145329334C590038A09F /* ComposableArchitecture */; };
16 | ECC8145629334C590038A09F /* Dependencies in Frameworks */ = {isa = PBXBuildFile; productRef = ECC8145529334C590038A09F /* Dependencies */; };
17 | ECC8145C29334CB70038A09F /* RepoSearchClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145829334CB70038A09F /* RepoSearchClient.swift */; };
18 | ECC8145D29334CB70038A09F /* RepoSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145929334CB70038A09F /* RepoSearch.swift */; };
19 | ECC8145E29334CB70038A09F /* RepositoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145A29334CB70038A09F /* RepositoryModel.swift */; };
20 | ECC8145F29334CB70038A09F /* RepoSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC8145B29334CB70038A09F /* RepoSearchView.swift */; };
21 | FFFF0B4B29ED3F49005830E8 /* LoadingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFFF0B4A29ED3F49005830E8 /* LoadingState.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | ECC8143529334AE00038A09F /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = ECC8141C29334ADF0038A09F /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = ECC8142329334ADF0038A09F;
30 | remoteInfo = GitHubSearch;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXFileReference section */
35 | EC4BC238293463F4001B2F91 /* APIError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIError.swift; sourceTree = ""; };
36 | ECC8142429334ADF0038A09F /* GitHubSearch-final.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GitHubSearch-final.app"; sourceTree = BUILT_PRODUCTS_DIR; };
37 | ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubSearchApp.swift; sourceTree = ""; };
38 | ECC8142B29334AE00038A09F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
39 | ECC8142E29334AE00038A09F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
40 | ECC8143429334AE00038A09F /* GitHubSearch-finalTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GitHubSearch-finalTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
41 | ECC8143829334AE00038A09F /* RepositoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepositoryTests.swift; sourceTree = ""; };
42 | ECC8145829334CB70038A09F /* RepoSearchClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearchClient.swift; sourceTree = ""; };
43 | ECC8145929334CB70038A09F /* RepoSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearch.swift; sourceTree = ""; };
44 | ECC8145A29334CB70038A09F /* RepositoryModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoryModel.swift; sourceTree = ""; };
45 | ECC8145B29334CB70038A09F /* RepoSearchView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepoSearchView.swift; sourceTree = ""; };
46 | FFFF0B4A29ED3F49005830E8 /* LoadingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingState.swift; sourceTree = ""; };
47 | /* End PBXFileReference section */
48 |
49 | /* Begin PBXFrameworksBuildPhase section */
50 | ECC8142129334ADF0038A09F /* Frameworks */ = {
51 | isa = PBXFrameworksBuildPhase;
52 | buildActionMask = 2147483647;
53 | files = (
54 | ECC8145429334C590038A09F /* ComposableArchitecture in Frameworks */,
55 | ECC8145629334C590038A09F /* Dependencies in Frameworks */,
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | ECC8143129334AE00038A09F /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXFrameworksBuildPhase section */
67 |
68 | /* Begin PBXGroup section */
69 | ECC8141B29334ADF0038A09F = {
70 | isa = PBXGroup;
71 | children = (
72 | ECC8142629334ADF0038A09F /* GitHubSearch */,
73 | ECC8143729334AE00038A09F /* GitHubSearchTests */,
74 | ECC8142529334ADF0038A09F /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | ECC8142529334ADF0038A09F /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | ECC8142429334ADF0038A09F /* GitHubSearch-final.app */,
82 | ECC8143429334AE00038A09F /* GitHubSearch-finalTests.xctest */,
83 | );
84 | name = Products;
85 | sourceTree = "";
86 | };
87 | ECC8142629334ADF0038A09F /* GitHubSearch */ = {
88 | isa = PBXGroup;
89 | children = (
90 | ECC8142729334ADF0038A09F /* GitHubSearchApp.swift */,
91 | EC4BC238293463F4001B2F91 /* APIError.swift */,
92 | FFFF0B4A29ED3F49005830E8 /* LoadingState.swift */,
93 | ECC8145729334C6B0038A09F /* Repository */,
94 | ECC8145129334AFC0038A09F /* Resources */,
95 | );
96 | path = GitHubSearch;
97 | sourceTree = "";
98 | };
99 | ECC8142D29334AE00038A09F /* Preview Content */ = {
100 | isa = PBXGroup;
101 | children = (
102 | ECC8142E29334AE00038A09F /* Preview Assets.xcassets */,
103 | );
104 | path = "Preview Content";
105 | sourceTree = "";
106 | };
107 | ECC8143729334AE00038A09F /* GitHubSearchTests */ = {
108 | isa = PBXGroup;
109 | children = (
110 | ECC8143829334AE00038A09F /* RepositoryTests.swift */,
111 | );
112 | path = GitHubSearchTests;
113 | sourceTree = "";
114 | };
115 | ECC8145129334AFC0038A09F /* Resources */ = {
116 | isa = PBXGroup;
117 | children = (
118 | ECC8142D29334AE00038A09F /* Preview Content */,
119 | ECC8142B29334AE00038A09F /* Assets.xcassets */,
120 | );
121 | path = Resources;
122 | sourceTree = "";
123 | };
124 | ECC8145729334C6B0038A09F /* Repository */ = {
125 | isa = PBXGroup;
126 | children = (
127 | ECC8145B29334CB70038A09F /* RepoSearchView.swift */,
128 | ECC8145929334CB70038A09F /* RepoSearch.swift */,
129 | ECC8145829334CB70038A09F /* RepoSearchClient.swift */,
130 | ECC8145A29334CB70038A09F /* RepositoryModel.swift */,
131 | );
132 | path = Repository;
133 | sourceTree = "";
134 | };
135 | /* End PBXGroup section */
136 |
137 | /* Begin PBXNativeTarget section */
138 | ECC8142329334ADF0038A09F /* GitHubSearch-final */ = {
139 | isa = PBXNativeTarget;
140 | buildConfigurationList = ECC8144829334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch-final" */;
141 | buildPhases = (
142 | ECC8142029334ADF0038A09F /* Sources */,
143 | ECC8142129334ADF0038A09F /* Frameworks */,
144 | ECC8142229334ADF0038A09F /* Resources */,
145 | );
146 | buildRules = (
147 | );
148 | dependencies = (
149 | );
150 | name = "GitHubSearch-final";
151 | packageProductDependencies = (
152 | ECC8145329334C590038A09F /* ComposableArchitecture */,
153 | ECC8145529334C590038A09F /* Dependencies */,
154 | );
155 | productName = GitHubSearch;
156 | productReference = ECC8142429334ADF0038A09F /* GitHubSearch-final.app */;
157 | productType = "com.apple.product-type.application";
158 | };
159 | ECC8143329334AE00038A09F /* GitHubSearch-finalTests */ = {
160 | isa = PBXNativeTarget;
161 | buildConfigurationList = ECC8144B29334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch-finalTests" */;
162 | buildPhases = (
163 | ECC8143029334AE00038A09F /* Sources */,
164 | ECC8143129334AE00038A09F /* Frameworks */,
165 | ECC8143229334AE00038A09F /* Resources */,
166 | );
167 | buildRules = (
168 | );
169 | dependencies = (
170 | ECC8143629334AE00038A09F /* PBXTargetDependency */,
171 | );
172 | name = "GitHubSearch-finalTests";
173 | productName = GitHubSearchTests;
174 | productReference = ECC8143429334AE00038A09F /* GitHubSearch-finalTests.xctest */;
175 | productType = "com.apple.product-type.bundle.unit-test";
176 | };
177 | /* End PBXNativeTarget section */
178 |
179 | /* Begin PBXProject section */
180 | ECC8141C29334ADF0038A09F /* Project object */ = {
181 | isa = PBXProject;
182 | attributes = {
183 | BuildIndependentTargetsInParallel = 1;
184 | LastSwiftUpdateCheck = 1410;
185 | LastUpgradeCheck = 1410;
186 | TargetAttributes = {
187 | ECC8142329334ADF0038A09F = {
188 | CreatedOnToolsVersion = 14.1;
189 | };
190 | ECC8143329334AE00038A09F = {
191 | CreatedOnToolsVersion = 14.1;
192 | TestTargetID = ECC8142329334ADF0038A09F;
193 | };
194 | };
195 | };
196 | buildConfigurationList = ECC8141F29334ADF0038A09F /* Build configuration list for PBXProject "GitHubSearch-final" */;
197 | compatibilityVersion = "Xcode 14.0";
198 | developmentRegion = en;
199 | hasScannedForEncodings = 0;
200 | knownRegions = (
201 | en,
202 | Base,
203 | );
204 | mainGroup = ECC8141B29334ADF0038A09F;
205 | packageReferences = (
206 | ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */,
207 | );
208 | productRefGroup = ECC8142529334ADF0038A09F /* Products */;
209 | projectDirPath = "";
210 | projectRoot = "";
211 | targets = (
212 | ECC8142329334ADF0038A09F /* GitHubSearch-final */,
213 | ECC8143329334AE00038A09F /* GitHubSearch-finalTests */,
214 | );
215 | };
216 | /* End PBXProject section */
217 |
218 | /* Begin PBXResourcesBuildPhase section */
219 | ECC8142229334ADF0038A09F /* Resources */ = {
220 | isa = PBXResourcesBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | ECC8142F29334AE00038A09F /* Preview Assets.xcassets in Resources */,
224 | ECC8142C29334AE00038A09F /* Assets.xcassets in Resources */,
225 | );
226 | runOnlyForDeploymentPostprocessing = 0;
227 | };
228 | ECC8143229334AE00038A09F /* Resources */ = {
229 | isa = PBXResourcesBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | );
233 | runOnlyForDeploymentPostprocessing = 0;
234 | };
235 | /* End PBXResourcesBuildPhase section */
236 |
237 | /* Begin PBXSourcesBuildPhase section */
238 | ECC8142029334ADF0038A09F /* Sources */ = {
239 | isa = PBXSourcesBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | ECC8145C29334CB70038A09F /* RepoSearchClient.swift in Sources */,
243 | FFFF0B4B29ED3F49005830E8 /* LoadingState.swift in Sources */,
244 | ECC8145E29334CB70038A09F /* RepositoryModel.swift in Sources */,
245 | ECC8142829334ADF0038A09F /* GitHubSearchApp.swift in Sources */,
246 | ECC8145F29334CB70038A09F /* RepoSearchView.swift in Sources */,
247 | ECC8145D29334CB70038A09F /* RepoSearch.swift in Sources */,
248 | EC4BC239293463F4001B2F91 /* APIError.swift in Sources */,
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | ECC8143029334AE00038A09F /* Sources */ = {
253 | isa = PBXSourcesBuildPhase;
254 | buildActionMask = 2147483647;
255 | files = (
256 | ECC8143929334AE00038A09F /* RepositoryTests.swift in Sources */,
257 | );
258 | runOnlyForDeploymentPostprocessing = 0;
259 | };
260 | /* End PBXSourcesBuildPhase section */
261 |
262 | /* Begin PBXTargetDependency section */
263 | ECC8143629334AE00038A09F /* PBXTargetDependency */ = {
264 | isa = PBXTargetDependency;
265 | target = ECC8142329334ADF0038A09F /* GitHubSearch-final */;
266 | targetProxy = ECC8143529334AE00038A09F /* PBXContainerItemProxy */;
267 | };
268 | /* End PBXTargetDependency section */
269 |
270 | /* Begin XCBuildConfiguration section */
271 | ECC8144629334AE00038A09F /* Debug */ = {
272 | isa = XCBuildConfiguration;
273 | buildSettings = {
274 | ALWAYS_SEARCH_USER_PATHS = NO;
275 | CLANG_ANALYZER_NONNULL = YES;
276 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
277 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
278 | CLANG_ENABLE_MODULES = YES;
279 | CLANG_ENABLE_OBJC_ARC = YES;
280 | CLANG_ENABLE_OBJC_WEAK = YES;
281 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
282 | CLANG_WARN_BOOL_CONVERSION = YES;
283 | CLANG_WARN_COMMA = YES;
284 | CLANG_WARN_CONSTANT_CONVERSION = YES;
285 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
286 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
287 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
288 | CLANG_WARN_EMPTY_BODY = YES;
289 | CLANG_WARN_ENUM_CONVERSION = YES;
290 | CLANG_WARN_INFINITE_RECURSION = YES;
291 | CLANG_WARN_INT_CONVERSION = YES;
292 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
293 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
294 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
295 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
296 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
297 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
298 | CLANG_WARN_STRICT_PROTOTYPES = YES;
299 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
300 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
301 | CLANG_WARN_UNREACHABLE_CODE = YES;
302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
303 | COPY_PHASE_STRIP = NO;
304 | DEBUG_INFORMATION_FORMAT = dwarf;
305 | ENABLE_STRICT_OBJC_MSGSEND = YES;
306 | ENABLE_TESTABILITY = YES;
307 | GCC_C_LANGUAGE_STANDARD = gnu11;
308 | GCC_DYNAMIC_NO_PIC = NO;
309 | GCC_NO_COMMON_BLOCKS = YES;
310 | GCC_OPTIMIZATION_LEVEL = 0;
311 | GCC_PREPROCESSOR_DEFINITIONS = (
312 | "DEBUG=1",
313 | "$(inherited)",
314 | );
315 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
316 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
317 | GCC_WARN_UNDECLARED_SELECTOR = YES;
318 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
319 | GCC_WARN_UNUSED_FUNCTION = YES;
320 | GCC_WARN_UNUSED_VARIABLE = YES;
321 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
322 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
323 | MTL_FAST_MATH = YES;
324 | ONLY_ACTIVE_ARCH = YES;
325 | SDKROOT = iphoneos;
326 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
327 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
328 | };
329 | name = Debug;
330 | };
331 | ECC8144729334AE00038A09F /* Release */ = {
332 | isa = XCBuildConfiguration;
333 | buildSettings = {
334 | ALWAYS_SEARCH_USER_PATHS = NO;
335 | CLANG_ANALYZER_NONNULL = YES;
336 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
337 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
338 | CLANG_ENABLE_MODULES = YES;
339 | CLANG_ENABLE_OBJC_ARC = YES;
340 | CLANG_ENABLE_OBJC_WEAK = YES;
341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
342 | CLANG_WARN_BOOL_CONVERSION = YES;
343 | CLANG_WARN_COMMA = YES;
344 | CLANG_WARN_CONSTANT_CONVERSION = YES;
345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
347 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
348 | CLANG_WARN_EMPTY_BODY = YES;
349 | CLANG_WARN_ENUM_CONVERSION = YES;
350 | CLANG_WARN_INFINITE_RECURSION = YES;
351 | CLANG_WARN_INT_CONVERSION = YES;
352 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
353 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
354 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
355 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
356 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
357 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
358 | CLANG_WARN_STRICT_PROTOTYPES = YES;
359 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
360 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
361 | CLANG_WARN_UNREACHABLE_CODE = YES;
362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
363 | COPY_PHASE_STRIP = NO;
364 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
365 | ENABLE_NS_ASSERTIONS = NO;
366 | ENABLE_STRICT_OBJC_MSGSEND = YES;
367 | GCC_C_LANGUAGE_STANDARD = gnu11;
368 | GCC_NO_COMMON_BLOCKS = YES;
369 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
370 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
371 | GCC_WARN_UNDECLARED_SELECTOR = YES;
372 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
373 | GCC_WARN_UNUSED_FUNCTION = YES;
374 | GCC_WARN_UNUSED_VARIABLE = YES;
375 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
376 | MTL_ENABLE_DEBUG_INFO = NO;
377 | MTL_FAST_MATH = YES;
378 | SDKROOT = iphoneos;
379 | SWIFT_COMPILATION_MODE = wholemodule;
380 | SWIFT_OPTIMIZATION_LEVEL = "-O";
381 | VALIDATE_PRODUCT = YES;
382 | };
383 | name = Release;
384 | };
385 | ECC8144929334AE00038A09F /* Debug */ = {
386 | isa = XCBuildConfiguration;
387 | buildSettings = {
388 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
389 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
390 | CODE_SIGN_STYLE = Automatic;
391 | CURRENT_PROJECT_VERSION = 1;
392 | DEVELOPMENT_ASSET_PATHS = "\"GitHubSearch/Resources/Preview Content\"";
393 | DEVELOPMENT_TEAM = 8B27K52UU7;
394 | ENABLE_PREVIEWS = YES;
395 | GENERATE_INFOPLIST_FILE = YES;
396 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
397 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
398 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
399 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
400 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
401 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
402 | LD_RUNPATH_SEARCH_PATHS = (
403 | "$(inherited)",
404 | "@executable_path/Frameworks",
405 | );
406 | MARKETING_VERSION = 1.0;
407 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearch";
408 | PRODUCT_NAME = "$(TARGET_NAME)";
409 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
410 | SUPPORTS_MACCATALYST = NO;
411 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
412 | SWIFT_EMIT_LOC_STRINGS = YES;
413 | SWIFT_VERSION = 5.0;
414 | TARGETED_DEVICE_FAMILY = 1;
415 | };
416 | name = Debug;
417 | };
418 | ECC8144A29334AE00038A09F /* Release */ = {
419 | isa = XCBuildConfiguration;
420 | buildSettings = {
421 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
422 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
423 | CODE_SIGN_STYLE = Automatic;
424 | CURRENT_PROJECT_VERSION = 1;
425 | DEVELOPMENT_ASSET_PATHS = "\"GitHubSearch/Resources/Preview Content\"";
426 | DEVELOPMENT_TEAM = 8B27K52UU7;
427 | ENABLE_PREVIEWS = YES;
428 | GENERATE_INFOPLIST_FILE = YES;
429 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
430 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
431 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
432 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
433 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
434 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
435 | LD_RUNPATH_SEARCH_PATHS = (
436 | "$(inherited)",
437 | "@executable_path/Frameworks",
438 | );
439 | MARKETING_VERSION = 1.0;
440 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearch";
441 | PRODUCT_NAME = "$(TARGET_NAME)";
442 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
443 | SUPPORTS_MACCATALYST = NO;
444 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
445 | SWIFT_EMIT_LOC_STRINGS = YES;
446 | SWIFT_VERSION = 5.0;
447 | TARGETED_DEVICE_FAMILY = 1;
448 | };
449 | name = Release;
450 | };
451 | ECC8144C29334AE00038A09F /* Debug */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
455 | BUNDLE_LOADER = "$(TEST_HOST)";
456 | CODE_SIGN_STYLE = Automatic;
457 | CURRENT_PROJECT_VERSION = 1;
458 | DEVELOPMENT_TEAM = 8B27K52UU7;
459 | GENERATE_INFOPLIST_FILE = YES;
460 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
461 | MARKETING_VERSION = 1.0;
462 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearchTests";
463 | PRODUCT_NAME = "$(TARGET_NAME)";
464 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
465 | SUPPORTS_MACCATALYST = NO;
466 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
467 | SWIFT_EMIT_LOC_STRINGS = NO;
468 | SWIFT_VERSION = 5.0;
469 | TARGETED_DEVICE_FAMILY = 1;
470 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GitHubSearch-final.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/GitHubSearch-final";
471 | };
472 | name = Debug;
473 | };
474 | ECC8144D29334AE00038A09F /* Release */ = {
475 | isa = XCBuildConfiguration;
476 | buildSettings = {
477 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
478 | BUNDLE_LOADER = "$(TEST_HOST)";
479 | CODE_SIGN_STYLE = Automatic;
480 | CURRENT_PROJECT_VERSION = 1;
481 | DEVELOPMENT_TEAM = 8B27K52UU7;
482 | GENERATE_INFOPLIST_FILE = YES;
483 | IPHONEOS_DEPLOYMENT_TARGET = 16.0;
484 | MARKETING_VERSION = 1.0;
485 | PRODUCT_BUNDLE_IDENTIFIER = "com.dy-kim.GitHubSearchTests";
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
488 | SUPPORTS_MACCATALYST = NO;
489 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
490 | SWIFT_EMIT_LOC_STRINGS = NO;
491 | SWIFT_VERSION = 5.0;
492 | TARGETED_DEVICE_FAMILY = 1;
493 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GitHubSearch-final.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/GitHubSearch-final";
494 | };
495 | name = Release;
496 | };
497 | /* End XCBuildConfiguration section */
498 |
499 | /* Begin XCConfigurationList section */
500 | ECC8141F29334ADF0038A09F /* Build configuration list for PBXProject "GitHubSearch-final" */ = {
501 | isa = XCConfigurationList;
502 | buildConfigurations = (
503 | ECC8144629334AE00038A09F /* Debug */,
504 | ECC8144729334AE00038A09F /* Release */,
505 | );
506 | defaultConfigurationIsVisible = 0;
507 | defaultConfigurationName = Release;
508 | };
509 | ECC8144829334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch-final" */ = {
510 | isa = XCConfigurationList;
511 | buildConfigurations = (
512 | ECC8144929334AE00038A09F /* Debug */,
513 | ECC8144A29334AE00038A09F /* Release */,
514 | );
515 | defaultConfigurationIsVisible = 0;
516 | defaultConfigurationName = Release;
517 | };
518 | ECC8144B29334AE00038A09F /* Build configuration list for PBXNativeTarget "GitHubSearch-finalTests" */ = {
519 | isa = XCConfigurationList;
520 | buildConfigurations = (
521 | ECC8144C29334AE00038A09F /* Debug */,
522 | ECC8144D29334AE00038A09F /* Release */,
523 | );
524 | defaultConfigurationIsVisible = 0;
525 | defaultConfigurationName = Release;
526 | };
527 | /* End XCConfigurationList section */
528 |
529 | /* Begin XCRemoteSwiftPackageReference section */
530 | ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {
531 | isa = XCRemoteSwiftPackageReference;
532 | repositoryURL = "https://github.com/pointfreeco/swift-composable-architecture";
533 | requirement = {
534 | kind = exactVersion;
535 | version = 0.52.0;
536 | };
537 | };
538 | /* End XCRemoteSwiftPackageReference section */
539 |
540 | /* Begin XCSwiftPackageProductDependency section */
541 | ECC8145329334C590038A09F /* ComposableArchitecture */ = {
542 | isa = XCSwiftPackageProductDependency;
543 | package = ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
544 | productName = ComposableArchitecture;
545 | };
546 | ECC8145529334C590038A09F /* Dependencies */ = {
547 | isa = XCSwiftPackageProductDependency;
548 | package = ECC8145229334C590038A09F /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
549 | productName = Dependencies;
550 | };
551 | /* End XCSwiftPackageProductDependency section */
552 | };
553 | rootObject = ECC8141C29334ADF0038A09F /* Project object */;
554 | }
555 |
--------------------------------------------------------------------------------