-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Minor improvements and tidying up of SwiftUI tech test #6
base: master
Are you sure you want to change the base?
Changes from all commits
a782886
3c91f70
a493233
85a86bf
3aa7a88
d931efe
d42aec8
8b760e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// ContentView.swift | ||
// iOSTest | ||
// | ||
// Created by m.houghton on 12/12/2022. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct ContentView: View { | ||
var body: some View { | ||
AuthorityListView() | ||
} | ||
} | ||
|
||
struct ContentView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
ContentView() | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"colors" : [ | ||
{ | ||
"color" : { | ||
"color-space" : "srgb", | ||
"components" : { | ||
"alpha" : "1.000", | ||
"blue" : "0xFF", | ||
"green" : "0xFF", | ||
"red" : "0xFF" | ||
} | ||
}, | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>UILaunchScreen</key> | ||
<dict> | ||
<key>UIColorName</key> | ||
<string>LaunchScreenBackground</string> | ||
<key>UIImageName</key> | ||
<string>FSALogo</string> | ||
<key>UIImageRespectsSafeAreaInsets</key> | ||
<true/> | ||
</dict> | ||
</dict> | ||
</plist> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,21 +2,16 @@ import Foundation | |
|
||
|
||
protocol NetworkProvider { | ||
func getAuthorities() async throws -> Result<[Authority], Error> | ||
func getAuthorities() async throws -> AuthoritiesResponse | ||
} | ||
|
||
class NetworkService: NetworkProvider { | ||
|
||
enum AuthoritiesFetcherError: Error { | ||
case invalidURL | ||
case missingData | ||
} | ||
|
||
private static let baseUrl = "https://api.ratings.food.gov.uk" | ||
|
||
func getAuthorities() async throws -> Result<[Authority], Error> { | ||
func getAuthorities() async throws -> AuthoritiesResponse { | ||
guard let url = URL(string: NetworkService.baseUrl + "/authorities/basic") else { | ||
return .failure(AuthoritiesFetcherError.invalidURL) | ||
throw AuthoritiesFetcherError.invalidURL | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated this to make use of the |
||
} | ||
|
||
var urlRequest = URLRequest(url: url) | ||
|
@@ -26,6 +21,15 @@ class NetworkService: NetworkProvider { | |
let (data, _) = try await URLSession.shared.data(for: urlRequest) | ||
|
||
let authoritiesResult = try JSONDecoder().decode(AuthoritiesResponse.self, from: data) | ||
return .success(authoritiesResult.authorities) | ||
return authoritiesResult | ||
} | ||
} | ||
|
||
extension NetworkService { | ||
enum AuthoritiesFetcherError: Error { | ||
case invalidURL | ||
case unexpected(error: Error) | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
import SwiftUI | ||
|
||
struct AuthorityListView: View { | ||
@StateObject var viewModel = ViewModel() | ||
@StateObject private var viewModel = AuthorityListViewModel() | ||
@State private var showingCopyright = false | ||
|
||
var body: some View { | ||
VStack(alignment: .leading) { | ||
NavigationView { | ||
if viewModel.loading { | ||
if viewModel.isLoading { | ||
ProgressView() | ||
} else if viewModel.error { | ||
Text("Network Error") | ||
} else if viewModel.hasError { | ||
networkErrorView | ||
} else { | ||
List { | ||
ForEach(viewModel.authorities, id: \.self) { authority in | ||
|
@@ -19,16 +20,37 @@ struct AuthorityListView: View { | |
} | ||
} | ||
.navigationTitle("Local Authorities") | ||
.navigationBarTitleDisplayMode(.inline) | ||
.toolbar { | ||
Button { | ||
showingCopyright.toggle() | ||
} label: { | ||
Image(systemName: "info.circle") | ||
} | ||
} | ||
.alert("Copyright © 2022 Infinity Works, Part of Accenture.", isPresented: $showingCopyright) { | ||
} message: { | ||
Text("All rights reserved.") | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new launch screen loses the copyright message, so I added it as a toolbar button alert instead. |
||
} | ||
}.task { | ||
await viewModel.update() | ||
} | ||
} | ||
} | ||
|
||
var networkErrorView: some View { | ||
VStack { | ||
Image(systemName: "wifi.exclamationmark") | ||
Text("Network Error") | ||
.font(.headline) | ||
Text("Something went wrong...") | ||
.font(.subheadline) | ||
.foregroundColor(.gray) | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simple error view for if network request fails. |
||
} | ||
|
||
struct ContentView_Previews: PreviewProvider { | ||
struct AuthorityListView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
AuthorityListView() | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Launch Screens can now be done entirely within Info.plist without the need to maintain a storyboard.