Mercurial > public > lazybear
changeset 94:fe26349780c8
Implement real-time prices
author | Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> |
---|---|
date | Fri, 29 Jan 2021 20:37:20 +0100 |
parents | 24543d06c24f |
children | a2ed7369be9f |
files | LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate lazybear/ContentView.swift lazybear/Jobs/ReadJson.swift lazybear/Models/QuoteModel.swift lazybear/Network/IexApi.swift lazybear/Views/Price.swift lazybear/Views/WatchlistRow.swift |
diffstat | 8 files changed, 63 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj Fri Jan 29 14:18:52 2021 +0100 +++ b/LazyBear.xcodeproj/project.pbxproj Fri Jan 29 20:37:20 2021 +0100 @@ -12,6 +12,7 @@ 950B79F625B1CB7A00E5DB5B /* CompanyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950B79F525B1CB7A00E5DB5B /* CompanyList.swift */; }; 9537923625BDF85D0001F82B /* LogoApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9537923525BDF85D0001F82B /* LogoApi.swift */; }; 954D992525A2123B001F7F60 /* HistoricalPricesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */; }; + 954DDF0425C456E800848A4B /* QuoteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954DDF0325C456E800848A4B /* QuoteModel.swift */; }; 95612C512598D48200F7698F /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95612C4F2598D48200F7698F /* SearchBar.swift */; }; 95621AD925BF2EDB00BB17FC /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95621AD825BF2EDB00BB17FC /* CloudKit.framework */; }; 95700BC625BD9D12009CEEFE /* IexApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95700BC525BD9D12009CEEFE /* IexApi.swift */; }; @@ -51,6 +52,7 @@ 950B79F525B1CB7A00E5DB5B /* CompanyList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyList.swift; sourceTree = "<group>"; }; 9537923525BDF85D0001F82B /* LogoApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LogoApi.swift; path = LazyBear/Network/LogoApi.swift; sourceTree = SOURCE_ROOT; }; 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HistoricalPricesModel.swift; path = lazybear/Models/HistoricalPricesModel.swift; sourceTree = SOURCE_ROOT; }; + 954DDF0325C456E800848A4B /* QuoteModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = QuoteModel.swift; path = lazybear/Models/QuoteModel.swift; sourceTree = SOURCE_ROOT; }; 95612C4F2598D48200F7698F /* SearchBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; }; 95621AD725BF2EC500BB17FC /* LazyBear.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LazyBear.entitlements; sourceTree = "<group>"; }; 95621AD825BF2EDB00BB17FC /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; @@ -121,6 +123,7 @@ 95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */, 954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */, 95FE646A25C30B880052832E /* ApiModel.swift */, + 954DDF0325C456E800848A4B /* QuoteModel.swift */, ); path = Models; sourceTree = "<group>"; @@ -293,6 +296,7 @@ 95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */, 95F6F45C25C20D8D002AC66A /* Price.swift in Sources */, 9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */, + 954DDF0425C456E800848A4B /* QuoteModel.swift in Sources */, 9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */, 95FE646B25C30B880052832E /* ApiModel.swift in Sources */, 95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/lazybear/ContentView.swift Fri Jan 29 14:18:52 2021 +0100 +++ b/lazybear/ContentView.swift Fri Jan 29 20:37:20 2021 +0100 @@ -12,11 +12,12 @@ struct ContentView: View { @State var searchedCompany = String() @State public var showingSearch: Bool = false - let persistenceController = PersistenceController.shared + @State var cloudFetch = [CKRecord]() { didSet { cloudValues() }} // CloudKit fetch arrives here - let cloud = CloudKitManager() - @State var cloudFetch = [CKRecord]() { didSet { cloudValues() }} // On change, call function - @EnvironmentObject var apiAccess: ApiAccess + let persistenceController = PersistenceController.shared // Core data + let cloud = CloudKitManager() // CloudKit fetch function + + @EnvironmentObject var apiAccess: ApiAccess // Env apis info var body: some View { VStack(alignment: .leading) { @@ -34,10 +35,10 @@ } } } - .onAppear { cloud.query(recordType: "API") { self.cloudFetch = $0 } } // Request CloudKit + .onAppear { cloud.query(recordType: "API") { cloudFetch = $0 } } // Request CloudKit } - // Assign values to the model + // Assign CloudKit fetch to model private func cloudValues() { var results = [ApiModel]() cloudFetch.forEach({ (result) in
--- a/lazybear/Jobs/ReadJson.swift Fri Jan 29 14:18:52 2021 +0100 +++ b/lazybear/Jobs/ReadJson.swift Fri Jan 29 20:37:20 2021 +0100 @@ -7,8 +7,6 @@ import SwiftUI -import SwiftUI - // With this function I parse the local JSON file to read it and create a list with its items. let companiesData: [CompanyModel] = load("companies.json")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lazybear/Models/QuoteModel.swift Fri Jan 29 20:37:20 2021 +0100 @@ -0,0 +1,14 @@ +// +// QuoteModel.swift +// LazyBear +// +// Created by Dennis Concepción Martín on 29/1/21. +// + +import SwiftUI + +struct QuoteModel: Codable { + var latestPrice: Float + var changePercent: Double +} +
--- a/lazybear/Network/IexApi.swift Fri Jan 29 14:18:52 2021 +0100 +++ b/lazybear/Network/IexApi.swift Fri Jan 29 20:37:20 2021 +0100 @@ -8,6 +8,8 @@ import SwiftUI struct IexApi { + @EnvironmentObject var apiAccess: ApiAccess // Env apis info + enum Version { case stable @@ -64,7 +66,7 @@ // Create URL - func getURL(version: Version, stock: Stock, endpoint: Endpoint, range: Range?, parameters: Parameters?) -> String { + func getPath(version: Version, stock: Stock, endpoint: Endpoint, range: Range?, parameters: Parameters?) -> String { let version = version.path let stock = stock.path let endpoint = endpoint.path @@ -78,7 +80,7 @@ } // Request API - func request<T: Decodable>(url: String, model: T.Type, completion: @escaping (T) -> Void) { + 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")
--- a/lazybear/Views/Price.swift Fri Jan 29 14:18:52 2021 +0100 +++ b/lazybear/Views/Price.swift Fri Jan 29 20:37:20 2021 +0100 @@ -9,22 +9,46 @@ import CloudKit struct Price: View { - let iexApi = IexApi() + @State var symbol: String + + @State var url = String() { didSet { giveMePrices() }} + @State var showingView = false + + @State var latestPrice = Float() + @State var changePercent = Double() { didSet { self.showingView = true }} + + let iexApi = IexApi() // Request api function + //let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect() // Set recurrent price request + + @EnvironmentObject var apiAccess: ApiAccess var body: some View { - Text("Price") - .onAppear { - //let url = api[1].url! as String - //let token = api[1].key! as String - //let path = iexApi.getURL(version: .stable, stock: .symbol(company: "AAPL"), endpoint: .quote, range: nil, parameters: nil) - //let endpoint = url + path + token - //print(endpoint) + VStack { + if self.showingView { + Text("\(latestPrice, specifier: "%.2f")") } + } + //.onReceive(timer) { _ in giveMePrices() } + .onAppear { getUrl() } + } + + private func getUrl() { + let baseUrl = apiAccess.results[1].url ?? "" // 1 -> Sandbox / 2 -> Production + let token = apiAccess.results[1].key ?? "" + let path = iexApi.getPath(version: .stable, stock: .symbol(company: symbol), endpoint: .quote, range: nil, parameters: nil) + self.url = baseUrl + path + token + } + + private func giveMePrices() { + iexApi.request(url: url, model: QuoteModel.self) { result in + self.latestPrice = result.latestPrice + self.changePercent = result.changePercent + } } } struct Price_Previews: PreviewProvider { static var previews: some View { - Price() + Price(symbol: "AAPL") } }
--- a/lazybear/Views/WatchlistRow.swift Fri Jan 29 14:18:52 2021 +0100 +++ b/lazybear/Views/WatchlistRow.swift Fri Jan 29 20:37:20 2021 +0100 @@ -37,7 +37,7 @@ Spacer() if self.editMode?.wrappedValue.isEditing ?? true { } else { // If is not editing -> show prices - Price() + Price(symbol: company.symbol ?? "") } } }