changeset 452:bb69f9d1d20f

Implement HomeView in WatchOS
author Dennis Concepción Martín <dennisconcepcionmartin@gmail.com>
date Sat, 26 Jun 2021 18:45:31 +0200
parents bb130738b816
children 37c13ebda381
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate LazyBear/Views/Profile/ProfileView.swift LazyBearWatchOS Extension/ContentView.swift LazyBearWatchOS Extension/LazyBearApp.swift LazyBearWatchOS Extension/Views/Home/Helpers/CompanyRow.swift LazyBearWatchOS Extension/Views/Home/HomeView.swift
diffstat 7 files changed, 94 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBear.xcodeproj/project.pbxproj	Sat Jun 26 18:45:31 2021 +0200
@@ -105,6 +105,8 @@
 		95BEA1AD2687791000BF18AB /* ProfileResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C8C0DF262A369F0082D1D9 /* ProfileResponse.swift */; };
 		95BEA1AE2687791800BF18AB /* CompanyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C22F3E26776F010014C98A /* CompanyModel.swift */; };
 		95BEA1AF2687794A00BF18AB /* RequestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E8BAA22656D86E0016AE72 /* RequestType.swift */; };
+		95BEA1B326877BAC00BF18AB /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95672B9725DDA54700DCBE4A /* Persistence.swift */; };
+		95BEA1B426877BBA00BF18AB /* LazyBear.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 95672B9925DDA54800DCBE4A /* LazyBear.xcdatamodeld */; };
 		95C22F3F26776F010014C98A /* CompanyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C22F3E26776F010014C98A /* CompanyModel.swift */; };
 		95C8C0E0262A369F0082D1D9 /* ProfileResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C8C0DF262A369F0082D1D9 /* ProfileResponse.swift */; };
 		95CCFB56266E7A0F00C384A1 /* InsiderTransactionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CCFB55266E7A0F00C384A1 /* InsiderTransactionModel.swift */; };
@@ -443,10 +445,10 @@
 				952457E7267E339C00D5BBCB /* NotificationController.swift */,
 				952457E9267E339C00D5BBCB /* NotificationView.swift */,
 				952457EB267E339C00D5BBCB /* ComplicationController.swift */,
-				9595DC2E2682840C00DC8104 /* Views */,
 				952457ED267E339C00D5BBCB /* Assets.xcassets */,
 				952457F2267E339C00D5BBCB /* Info.plist */,
 				952457F3267E339C00D5BBCB /* PushNotificationPayload.apns */,
+				9595DC2E2682840C00DC8104 /* Views */,
 				952457EF267E339C00D5BBCB /* Preview Content */,
 			);
 			path = "LazyBearWatchOS Extension";
@@ -628,7 +630,6 @@
 			children = (
 				9595DC332682849E00DC8104 /* HomeView.swift */,
 				9595DC322682848B00DC8104 /* Helpers */,
-				9595DC392682858D00DC8104 /* Networking */,
 			);
 			path = Home;
 			sourceTree = "<group>";
@@ -641,13 +642,6 @@
 			path = Helpers;
 			sourceTree = "<group>";
 		};
-		9595DC392682858D00DC8104 /* Networking */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = Networking;
-			sourceTree = "<group>";
-		};
 		95A7C06126163943003E2EC1 /* Search */ = {
 			isa = PBXGroup;
 			children = (
@@ -1036,11 +1030,13 @@
 				952457E8267E339C00D5BBCB /* NotificationController.swift in Sources */,
 				95BEA1AD2687791000BF18AB /* ProfileResponse.swift in Sources */,
 				95BEA1AF2687794A00BF18AB /* RequestType.swift in Sources */,
+				95BEA1B326877BAC00BF18AB /* Persistence.swift in Sources */,
 				95BEA1AA268777CC00BF18AB /* Profile.swift in Sources */,
 				952457E6267E339C00D5BBCB /* ContentView.swift in Sources */,
 				952457EC267E339C00D5BBCB /* ComplicationController.swift in Sources */,
 				95BEA1AE2687791800BF18AB /* CompanyModel.swift in Sources */,
 				9595DC342682849E00DC8104 /* HomeView.swift in Sources */,
+				95BEA1B426877BBA00BF18AB /* LazyBear.xcdatamodeld in Sources */,
 				9595DC382682850000DC8104 /* WatchlistCompany+CoreDataProperties.swift in Sources */,
 				952457E4267E339C00D5BBCB /* LazyBearApp.swift in Sources */,
 				9595DC37268284FA00DC8104 /* WatchlistCompany+CoreDataClass.swift in Sources */,
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/LazyBear/Views/Profile/ProfileView.swift	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBear/Views/Profile/ProfileView.swift	Sat Jun 26 18:45:31 2021 +0200
@@ -96,24 +96,16 @@
      Get symbols in watchlists (Core Data) -> Prepare url -> Request
      */
     private func prepareUrl(_ requestType: RequestType) {
-        let symbols = watchlistCompanies.map { $0.symbol }
-        
-        var symbolString = ""
-        for (index, symbol) in symbols.enumerated() {
-            if index == 0 {
-                symbolString += symbol
-            } else {
-                symbolString += ",\(symbol)"
-            }
-        }
+        let symbols = Set(watchlistCompanies.map { $0.symbol })
+        let symbolsString = symbols.joined(separator:",")
         
         switch requestType {
         case .initial:
-            let url = "https://api.lazybear.app/profile/type=initial/symbols=\(symbolString)"
+            let url = "https://api.lazybear.app/profile/type=initial/symbols=\(symbolsString)"
             profile.request(url, .initial)
             
         default:
-            let url = "https://api.lazybear.app/profile/type=streaming/symbols=\(symbolString)"
+            let url = "https://api.lazybear.app/profile/type=streaming/symbols=\(symbolsString)"
             profile.request(url, .streaming)
         }
     }
--- a/LazyBearWatchOS Extension/ContentView.swift	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBearWatchOS Extension/ContentView.swift	Sat Jun 26 18:45:31 2021 +0200
@@ -10,11 +10,9 @@
 struct ContentView: View {
     var body: some View {
         VStack {
-            ForEach((1..<4)) { _ in
-                Text("Hello")
-            }
-            .navigationTitle("Lazybear")
+            HomeView()
         }
+        .navigationTitle("Lazybear")
     }
 }
 
--- a/LazyBearWatchOS Extension/LazyBearApp.swift	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBearWatchOS Extension/LazyBearApp.swift	Sat Jun 26 18:45:31 2021 +0200
@@ -6,14 +6,16 @@
 //
 
 import SwiftUI
+import CoreData
 
 @main
 struct LazyBearApp: App {
+    let persistenceController = PersistenceController.shared  // Core Data init
+    
     @SceneBuilder var body: some Scene {
         WindowGroup {
-            NavigationView {
-                ContentView()
-            }
+            ContentView()
+                .environment(\.managedObjectContext, persistenceController.container.viewContext)
         }
 
         WKNotificationScene(controller: NotificationController.self, category: "myCategory")
--- a/LazyBearWatchOS Extension/Views/Home/Helpers/CompanyRow.swift	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBearWatchOS Extension/Views/Home/Helpers/CompanyRow.swift	Sat Jun 26 18:45:31 2021 +0200
@@ -8,13 +8,49 @@
 import SwiftUI
 
 struct CompanyRow: View {
+    var company: CompanyModel
+    
     var body: some View {
-        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+        VStack(alignment: .leading) {
+            HStack {
+                Text(company.symbol.uppercased())
+                    .font(.caption2)
+                    .fontWeight(.semibold)
+                
+                Spacer()
+                if let changePercent = company.changePercent {
+                    VStack {
+                        Text("\(changePercent * 100, specifier: "%.2f")%")
+                            .foregroundColor(changePercent < 0 ? .red: .green)
+                    }
+                }
+            }
+            
+            if let latestPrice = company.latestPrice {
+                Text("\(latestPrice, specifier: "%.2f")")
+                    .foregroundColor(company.changePercent ?? 0.0 < 0 ? .red: .green)
+                    .font(.title2)
+            }
+        }
+        .padding()
+        .background(
+            RoundedRectangle(cornerRadius: 10)
+                .foregroundColor(company.changePercent ?? 0.0 < 0 ? .red: .green)
+                .opacity(0.2)
+        )
     }
 }
 
 struct CompanyRow_Previews: PreviewProvider {
     static var previews: some View {
-        CompanyRow()
+        CompanyRow(company:
+            CompanyModel(
+                symbol: "aapl",
+                companyName: "Apple Inc",
+                latestPrice: 120.3,
+                changePercent: 0.03,
+                intradayPrices: [120.3]
+            )
+        )
     }
 }
--- a/LazyBearWatchOS Extension/Views/Home/HomeView.swift	Sat Jun 26 17:04:29 2021 +0200
+++ b/LazyBearWatchOS Extension/Views/Home/HomeView.swift	Sat Jun 26 18:45:31 2021 +0200
@@ -9,12 +9,51 @@
 import CoreData
 
 struct HomeView: View {
+    @ObservedObject var profile = Profile()
+
     @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])
     var watchlistCompanies: FetchedResults<WatchlistCompany>
     
+    @State private var timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect()  /// Set recurrent price request
+    
     var body: some View {
-        VStack {
+        if profile.showView {
+            NavigationView {
+                ScrollView {
+                    VStack {
+                        if let companies = profile.data.quotes {
+                            ForEach(companies, id: \.self) { company in
+                                CompanyRow(company: company)
+                            }
+                        }
+                    }
+                }
+                .navigationTitle("Lazybear")
+                .onAppear { self.timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect() }  /// Start timer
+                .onDisappear { self.timer.upstream.connect().cancel() }  /// Stop timer
+                .onReceive(timer) { _ in prepareUrl(.streaming) }
+            }
+        } else {
+            ProgressView()
+                .onAppear { prepareUrl(.initial) }
+        }
+    }
+    
+    /*
+     Get symbols in watchlists (Core Data) -> Prepare url -> Request
+     */
+    private func prepareUrl(_ requestType: RequestType) {
+        let symbols = Set(watchlistCompanies.map { $0.symbol })
+        let symbolsString = symbols.joined(separator:",")
+        
+        switch requestType {
+        case .initial:
+            let url = "https://api.lazybear.app/profile/type=initial/symbols=\(symbolsString)"
+            profile.request(url, .initial)
             
+        default:
+            let url = "https://api.lazybear.app/profile/type=streaming/symbols=\(symbolsString)"
+            profile.request(url, .streaming)
         }
     }
 }