changeset 345:fde2b30c719e

Implementing Networking in ProfileView
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Thu, 08 Apr 2021 20:15:28 +0200
parents 276e17f11c19
children 80bfa88c6b0f 2132a211820d
files LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate LazyBear.xcodeproj/xcshareddata/xcschemes/LazyBear.xcscheme LazyBear/Global Models/WatchlistCompany+CoreDataProperties.swift LazyBear/Views/Global Helpers/StockItem.swift LazyBear/Views/Global Helpers/StockRectangleRow.swift LazyBear/Views/Profile/Networking/ProfileData.swift LazyBear/Views/Profile/ProfileView.swift
diffstat 7 files changed, 100 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/LazyBear.xcodeproj/xcshareddata/xcschemes/LazyBear.xcscheme	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear.xcodeproj/xcshareddata/xcschemes/LazyBear.xcscheme	Thu Apr 08 20:15:28 2021 +0200
@@ -31,7 +31,7 @@
       </Testables>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Release"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
--- a/LazyBear/Global Models/WatchlistCompany+CoreDataProperties.swift	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear/Global Models/WatchlistCompany+CoreDataProperties.swift	Thu Apr 08 20:15:28 2021 +0200
@@ -16,9 +16,9 @@
         return NSFetchRequest<WatchlistCompany>(entityName: "WatchlistCompany")
     }
 
-    @NSManaged public var symbol: String?
-    @NSManaged public var name: String?
-    @NSManaged public var watchlist: String?
+    @NSManaged public var symbol: String
+    @NSManaged public var name: String
+    @NSManaged public var watchlist: String
 
 }
 
--- a/LazyBear/Views/Global Helpers/StockItem.swift	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear/Views/Global Helpers/StockItem.swift	Thu Apr 08 20:15:28 2021 +0200
@@ -60,9 +60,9 @@
     }
 }
 
-//struct StockItem_Previews: PreviewProvider {
-//    static var previews: some View {
-//        StockItem(company: CompanyQuoteModel(companyName: "Akumin Inc", symbol: "AKU", latestPrice: 120.30, changePercent: 0.03))
-//
-//    }
-//}
+struct StockItem_Previews: PreviewProvider {
+    static var previews: some View {
+        StockItem(company: CompanyQuoteModel(companyName: "Akumin Inc", symbol: "AKU", latestPrice: 120.30, changePercent: 0.03), intradayPrices: [IntradayPricesResult(open: 130.3)])
+
+    }
+}
--- a/LazyBear/Views/Global Helpers/StockRectangleRow.swift	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear/Views/Global Helpers/StockRectangleRow.swift	Thu Apr 08 20:15:28 2021 +0200
@@ -43,8 +43,8 @@
 }
 
 
-//struct StockRectangleRow_Previews: PreviewProvider {
-//    static var previews: some View {
-//        StockRectangleRow(listType: "gainers", list: [CompanyQuoteModel(companyName: "apple inc", symbol: "aapl", latestPrice: 120.30, changePercent: 0.034)])
-//    }
-//}
+struct StockRectangleRow_Previews: PreviewProvider {
+    static var previews: some View {
+        StockRectangleRow(listType: "gainers", list: [CompanyQuoteModel(companyName: "apple inc", symbol: "aapl", latestPrice: 120.30, changePercent: 0.034)], intradayPrices: ["aapl": [IntradayPricesResult(open: 130.3)]])
+    }
+}
--- a/LazyBear/Views/Profile/Networking/ProfileData.swift	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear/Views/Profile/Networking/ProfileData.swift	Thu Apr 08 20:15:28 2021 +0200
@@ -8,31 +8,67 @@
 import SwiftUI
 
 class ProfileData: ObservableObject {
-    @Published var companies = [CompanyQuoteModel]()
     @Published var showView = false
-    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])
-    var watchlistCompanies: FetchedResults<WatchlistCompany>
+    
+    @Published var watchlists = [String(): [CompanyQuoteModel]()]
+    @Published var intradayPrices = [String(): [IntradayPricesResult]()]
     
     private let baseUrl = Bundle.main.infoDictionary?["IEX_URL"] as? String ?? "Empty url"
     private let apiKey = Bundle.main.infoDictionary?["IEX_API"] as? String ?? "Empty key"
     
-    private func get() {
-        var url = "\(baseUrl)/stock/market/batch?symbols="
+    func get(_ watchlistCompanies: FetchedResults<WatchlistCompany>) {
+        let dispatchGroup = DispatchGroup()
+        var url = String()
         
+        let watchlistSymbols = watchlistCompanies.map { $0.symbol }  // Map watchlist symbols
+        
+        // 1. REQUEST LATEST PRICE OF THE COMPANIES IN THE WATCHLIST CORE DATA
+        url = "\(baseUrl)/stock/market/batch?symbols="
+        
+        // If there are no companies in Core Data, do not request
         if !watchlistCompanies.isEmpty {
-            let symbols = watchlistCompanies.map { $0.symbol }
-            for symbol in symbols {
-                if symbols.firstIndex(of: symbol) == 0 {
-                    url += symbol!
+            var counter = 0
+            for symbol in watchlistSymbols {  // Iterate watchlist symbols
+                counter += 1
+                
+                // Append symbols to the URL to make the batch request
+                if counter == 1 {
+                    url += symbol
                 } else {
-                    url += "\(symbol!),"
+                    url += ",\(symbol)"
                 }
             }
             
-            url = "&types=quote&token=\(apiKey)"
-            genericRequest(url: url, model: [String: CompanyQuoteBatch].self) {
-                print($0)
-                self.showView = true
+            url += "&types=quote&token=\(apiKey)"
+            genericRequest(url: url, model: [String: CompanyQuoteBatch].self) { dict in
+                // Iterate symbols in the Batch request (Keys of the dictionary response)
+                for symbol in dict.keys {
+                    // Get index of the requested symbol in the watchlist symbol array
+                    let index = watchlistSymbols.firstIndex(of: symbol)
+                    
+                    // Get watchlist name of that symbol
+                    let watchlistName = watchlistCompanies[index!].watchlist
+                    
+                    // Append the CompanyQuote response to a dictionary with key as the watchlist name. Not trivial
+                    // First create a object of the company I want to add to the dict
+                    let newCompany = dict[symbol]?.quote
+                    
+                    // Second, get an array of the values in the watchlist key
+                    if var companiesInWatchlist = self.watchlists[watchlistName] {
+                        // Third, append the new value to that array
+                        companiesInWatchlist.append(newCompany!)
+                        
+                        // Finally, append the updated array to the key dict
+                        self.watchlists[watchlistName] = companiesInWatchlist
+                    } else {
+                        // If it's nil create the array and add it to dict
+                        let initCompanyArray: [CompanyQuoteModel] = [newCompany!]
+                        self.watchlists[watchlistName] = initCompanyArray
+                    }
+                    
+                    print(self.watchlists)
+                    
+                }
             }
         } else {
             self.showView = true
--- a/LazyBear/Views/Profile/ProfileView.swift	Wed Apr 07 16:40:53 2021 +0200
+++ b/LazyBear/Views/Profile/ProfileView.swift	Thu Apr 08 20:15:28 2021 +0200
@@ -9,18 +9,50 @@
 
 struct ProfileView: View {
     @ObservedObject var profileData = ProfileData()
+    @Environment(\.managedObjectContext) private var moc
+    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])
+    var watchlistCompanies: FetchedResults<WatchlistCompany>
     
     var body: some View {
         NavigationView {
             List {
-                ForEach(profileData.companies, id: \.self) { company in
-                    Text("Hello company")
-                }
+                Text("Hello World")
+                Button("Save company", action: addCompany)
+                Button("Delete company", action: removeCompany)
+                Button("Request", action: {profileData.get(watchlistCompanies)})
+                Button("Print watchlist", action: {print(watchlistCompanies.map {$0.symbol})})
             }
             .navigationTitle("My profile")
             .navigationBarTitleDisplayMode(.inline)
         }
     }
+    
+    // REMOVE IN PRODUCTION
+    private func addCompany() {
+        let watchlistCompany = WatchlistCompany(context: moc)
+        watchlistCompany.symbol = "FB"
+        watchlistCompany.name = "Facebook Inc"
+        watchlistCompany.watchlist = "MyWatchlist"
+        do {
+            try moc.save()
+            print("Company saved")
+        } catch {
+            print(error.localizedDescription)
+        }
+    }
+    
+    private func removeCompany() {
+        let symbols = watchlistCompanies.map { $0.symbol }
+        let index = symbols.firstIndex(of: "aapl")
+        let company = watchlistCompanies[index!]
+        moc.delete(company)
+        do {
+            try moc.save()
+            print("Company deleted")
+        } catch {
+            // Error
+        }
+    }
 }
 
 struct ProfileView_Previews: PreviewProvider {