Mercurial > public > lazybear
changeset 232:439e94a2200d
Implement PriceView
author | Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> |
---|---|
date | Tue, 02 Mar 2021 18:45:55 +0000 |
parents | 5bf2fcb7ad66 |
children | 108fe992c703 |
files | LazyBear/Functions/Request.swift LazyBear/Models/PriceModel.swift LazyBear/Tests/TestPullScroll.swift LazyBear/UI/CompanyView.swift LazyBear/UI/IexAttribution.swift LazyBear/UI/PriceView.swift LazyBear/UI/Settings.swift |
diffstat | 7 files changed, 120 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/LazyBear/Functions/Request.swift Mon Mar 01 18:42:34 2021 +0000 +++ b/LazyBear/Functions/Request.swift Tue Mar 02 18:45:55 2021 +0000 @@ -7,29 +7,33 @@ import Foundation -// Network request -func request<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) { - // We take some model data T.Type - guard let url = URL(string: url) else { - print("Invalid URL") - return +class Network: ObservableObject { + @Published var showingProgress = false + + // Network request + func request<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) { + // We take some model data T.Type + guard let url = URL(string: url) else { + print("Invalid URL") + return + } + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + do { + // Decode response with the model passed + let decodedResponse = try JSONDecoder().decode(model, from: data) + DispatchQueue.main.async { + //print(decodedResponse) + completion(decodedResponse) + } + return + } catch { + print(error) + } + } + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + } + .resume() } - let request = URLRequest(url: url) - URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data { - do { - // Decode response with the model passed - let decodedResponse = try JSONDecoder().decode(model, from: data) - DispatchQueue.main.async { - //print(decodedResponse) - completion(decodedResponse) - } - return - } catch { - print(error) - } - } - print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") - } - .resume() }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LazyBear/Models/PriceModel.swift Tue Mar 02 18:45:55 2021 +0000 @@ -0,0 +1,13 @@ +// +// PriceModel.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 2/3/21. +// + +import SwiftUI + +struct PriceModel: Codable { + var latestPrice: Float + var changePercent: Double +}
--- a/LazyBear/Tests/TestPullScroll.swift Mon Mar 01 18:42:34 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -// -// TestPullScroll.swift -// LazyBear -// -// Created by Dennis Concepción Martín on 28/2/21. -// - -import SwiftUI - -struct TestPullScroll: View { - var body: some View { - NavigationView { - ScrollView { - ForEach((1...10), id: \.self) { - Text("Row \($0)") - Divider() - } - } - } - } - - func action() { - print("Action") - } -} - -struct Row: View { - var body: some View { - Text("Hello row") - } -} - -struct TestPullScroll_Previews: PreviewProvider { - static var previews: some View { - TestPullScroll() - } -}
--- a/LazyBear/UI/CompanyView.swift Mon Mar 01 18:42:34 2021 +0000 +++ b/LazyBear/UI/CompanyView.swift Tue Mar 02 18:45:55 2021 +0000 @@ -18,14 +18,14 @@ var body: some View { GeometryReader { geo in ScrollView { - //PriceView(symbol: symbol) + PriceView(symbol: symbol) HistoricalPriceView(symbol: symbol, chartHeight: geo.size.width / 2) NewsView(symbol: symbol) } } .toolbar { ToolbarItem(placement: .principal) { - Text("Change view") + // Here I will add the view selector (Stock news, insiders, etc) } ToolbarItem(placement: .navigationBarTrailing) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LazyBear/UI/IexAttribution.swift Tue Mar 02 18:45:55 2021 +0000 @@ -0,0 +1,27 @@ +// +// IexAttribution.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 2/3/21. +// + +import SwiftUI + +struct IexAttribution: View { + var text: String + + var body: some View { + Link(destination: URL(string: "https://iexcloud.io")!) { + Text(text) + .font(.caption) + .opacity(0.6) + + } + } +} + +struct IexAttribution_Previews: PreviewProvider { + static var previews: some View { + IexAttribution(text: "IEX Cloud") + } +}
--- a/LazyBear/UI/PriceView.swift Mon Mar 01 18:42:34 2021 +0000 +++ b/LazyBear/UI/PriceView.swift Tue Mar 02 18:45:55 2021 +0000 @@ -9,12 +9,60 @@ struct PriceView: View { var symbol: String + @State private var latestPrice = Float() + @State private var changePercent = Double() + @State private var negativeChange = false + + @State private var timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() // Set recurrent price request var body: some View { - Text("Price View") + VStack(alignment: .leading) { + HStack { + Text("\(latestPrice, specifier: "%.2f")") + .font(.title3) + .fontWeight(.bold) + .padding(.horizontal) + + Text("\(changePercent*100, specifier: "%.2f")%") + .font(.headline) + .foregroundColor(negativeChange ? Color(.systemRed) : Color(.systemGreen)) + .padding(.trailing) + + IexAttribution(text: "IEX Cloud") + Spacer() + + } + + } + .onReceive(timer) { _ in call(); print("requested") } + .onAppear { + call() + self.timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() // Restart timer + } + .onDisappear { self.timer.upstream.connect().cancel() } // Stop timer + } + + private func getUrl() -> String { + let baseUrl = Bundle.main.infoDictionary?["IEX_URL"] as? String ?? "Empty url" + let apiKey = Bundle.main.infoDictionary?["IEX_API"] as? String ?? "Empty key" + let url = "\(baseUrl)/stock/\(symbol)/quote?token=\(apiKey)" + + return url + } + + private func call() { + request(url: getUrl(), model: PriceModel.self) { result in + self.latestPrice = result.latestPrice + if result.changePercent < 0 { + self.negativeChange = true + } + + self.changePercent = result.changePercent + } } } + struct PriceView_Previews: PreviewProvider { static var previews: some View { PriceView(symbol: "aapl")
--- a/LazyBear/UI/Settings.swift Mon Mar 01 18:42:34 2021 +0000 +++ b/LazyBear/UI/Settings.swift Tue Mar 02 18:45:55 2021 +0000 @@ -26,7 +26,7 @@ Text("App icon") } - Section { + Section(footer: IexAttribution(text: "Data provided by IEX Cloud").padding(.top)) { ForEach((0...3), id: \.self) { index in Link(destination: URL(string: setting.links[index])!) { HStack {