1+ import SwiftUI
2+ import gitdiff
3+
4+ struct ExamplesView : View {
5+ @State private var selectedExample = 0
6+
7+ var body : some View {
8+ NavigationView {
9+ VStack {
10+ Picker ( " Example " , selection: $selectedExample) {
11+ Text ( " Simple " ) . tag ( 0 )
12+ Text ( " Rename " ) . tag ( 1 )
13+ Text ( " New File " ) . tag ( 2 )
14+ Text ( " Deleted " ) . tag ( 3 )
15+ Text ( " Binary " ) . tag ( 4 )
16+ Text ( " Large " ) . tag ( 5 )
17+ }
18+ . pickerStyle ( . segmented)
19+ . padding ( )
20+
21+ ScrollView {
22+ DiffRenderer ( diffText: SampleDiffs . allDiffs [ selectedExample] )
23+ . padding ( )
24+ }
25+ }
26+ . navigationTitle ( " Diff Examples " )
27+ . navigationBarTitleDisplayMode ( . inline)
28+ }
29+ }
30+ }
31+
32+ struct SampleDiffs {
33+ static let allDiffs = [
34+ simpleChanges,
35+ fileRename,
36+ newFile,
37+ deletedFile,
38+ binaryFile,
39+ largeDiff
40+ ]
41+
42+ static let simpleChanges = """
43+ diff --git a/ContentView.swift b/ContentView.swift
44+ index 1234567..abcdefg 100644
45+ --- a/ContentView.swift
46+ +++ b/ContentView.swift
47+ @@ -10,14 +10,16 @@ import SwiftUI
48+
49+ struct ContentView: View {
50+ @State private var counter = 0
51+ + @State private var message = " Hello "
52+
53+ var body: some View {
54+ VStack {
55+ - Text( " Count: \\ (counter) " )
56+ + Text( " \\ (message): \\ (counter) " )
57+ .font(.largeTitle)
58+ + .foregroundColor(.blue)
59+
60+ Button( " Increment " ) {
61+ - counter += 1
62+ + withAnimation { counter += 1 }
63+ }
64+ .buttonStyle(.borderedProminent)
65+ }
66+ """
67+
68+ static let fileRename = """
69+ diff --git a/OldName.swift b/NewName.swift
70+ similarity index 95%
71+ rename from OldName.swift
72+ rename to NewName.swift
73+ index 1234567..abcdefg 100644
74+ --- a/OldName.swift
75+ +++ b/NewName.swift
76+ @@ -1,8 +1,8 @@
77+ //
78+ -// OldName.swift
79+ +// NewName.swift
80+ // MyProject
81+ //
82+
83+ -struct OldName {
84+ +struct NewName {
85+ let id: UUID
86+ let title: String
87+ }
88+ """
89+
90+ static let newFile = """
91+ diff --git a/NewFeature.swift b/NewFeature.swift
92+ new file mode 100644
93+ index 0000000..1234567
94+ --- /dev/null
95+ +++ b/NewFeature.swift
96+ @@ -0,0 +1,15 @@
97+ +//
98+ +// NewFeature.swift
99+ +// MyProject
100+ +//
101+ +
102+ +import Foundation
103+ +
104+ +struct NewFeature {
105+ + let id = UUID()
106+ + let name: String
107+ +
108+ + func activate() {
109+ + print( " Feature \\ (name) activated " )
110+ + }
111+ +}
112+ """
113+
114+ static let deletedFile = """
115+ diff --git a/DeprecatedCode.swift b/DeprecatedCode.swift
116+ deleted file mode 100644
117+ index 1234567..0000000
118+ --- a/DeprecatedCode.swift
119+ +++ /dev/null
120+ @@ -1,20 +0,0 @@
121+ -//
122+ -// DeprecatedCode.swift
123+ -// MyProject
124+ -//
125+ -
126+ -import Foundation
127+ -
128+ -@available(*, deprecated, message: " Use NewFeature instead " )
129+ -struct DeprecatedCode {
130+ - let id: String
131+ -
132+ - init() {
133+ - self.id = UUID().uuidString
134+ - }
135+ -
136+ - func oldMethod() {
137+ - print( " This method is deprecated " )
138+ - }
139+ -}
140+ """
141+
142+ static let binaryFile = """
143+ diff --git a/Assets.xcassets/AppIcon.appiconset/icon.png b/Assets.xcassets/AppIcon.appiconset/icon.png
144+ index 1234567..abcdefg 100644
145+ Binary files a/Assets.xcassets/AppIcon.appiconset/icon.png and b/Assets.xcassets/AppIcon.appiconset/icon.png differ
146+ """
147+
148+ static let largeDiff = """
149+ diff --git a/NetworkManager.swift b/NetworkManager.swift
150+ index 1234567..abcdefg 100644
151+ --- a/NetworkManager.swift
152+ +++ b/NetworkManager.swift
153+ @@ -15,8 +15,10 @@ class NetworkManager: ObservableObject {
154+ static let shared = NetworkManager()
155+
156+ private let session: URLSession
157+ + private let cache = URLCache.shared
158+
159+ private init() {
160+ + let config = URLSessionConfiguration.default
161+ self.session = URLSession.shared
162+ }
163+
164+ @@ -25,18 +27,35 @@ class NetworkManager: ObservableObject {
165+
166+ do {
167+ let (data, response) = try await session.data(from: url)
168+ +
169+ + // Check response
170+ + guard let httpResponse = response as? HTTPURLResponse,
171+ + httpResponse.statusCode == 200 else {
172+ + throw NetworkError.invalidResponse
173+ + }
174+ +
175+ return data
176+ } catch {
177+ - throw NetworkError.requestFailed
178+ + throw NetworkError.requestFailed(error)
179+ }
180+ }
181+
182+ + func fetchJSON<T: Decodable>(_ type: T.Type, from url: URL) async throws -> T {
183+ + let data = try await fetchData(from: url)
184+ +
185+ + do {
186+ + return try JSONDecoder().decode(type, from: data)
187+ + } catch {
188+ + throw NetworkError.decodingFailed(error)
189+ + }
190+ + }
191+ +
192+ enum NetworkError: Error {
193+ case invalidURL
194+ - case requestFailed
195+ + case invalidResponse
196+ + case requestFailed(Error)
197+ + case decodingFailed(Error)
198+ }
199+ }
200+ """
201+ }
0 commit comments