changeset 87:104b643a8807

Implementing CloudKit
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Wed, 27 Jan 2021 19:59:58 +0100
parents 1850681a3715
children 2704750d35a0
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate lazybear/CloudKitManager.swift lazybear/GoogleApi.swift lazybear/LazyBearApp.swift lazybear/Supply views/Company.swift lazybear/Supply views/LogoModifier.swift lazybear/Supply views/LogoPlaceholder.swift lazybear/Supply views/Stock.swift lazybear/Supply views/Title.swift lazybear/Supply views/Watchlist.swift lazybear/Supply views/WatchlistRow.swift lazybear/Tests/Test.swift lazybear/Tests/TestStroke.swift
diffstat 14 files changed, 108 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Tue Jan 26 17:25:40 2021 +0100
+++ b/LazyBear.xcodeproj/project.pbxproj	Wed Jan 27 19:59:58 2021 +0100
@@ -17,8 +17,10 @@
 		954D996D25A2461B001F7F60 /* SwiftUICharts in Frameworks */ = {isa = PBXBuildFile; productRef = 954D996C25A2461B001F7F60 /* SwiftUICharts */; };
 		95612C512598D48200F7698F /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95612C4F2598D48200F7698F /* SearchBar.swift */; };
 		95621AD925BF2EDB00BB17FC /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95621AD825BF2EDB00BB17FC /* CloudKit.framework */; };
-		95621ADB25BF32E200BB17FC /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95621ADA25BF32E200BB17FC /* Test.swift */; };
 		95700BC625BD9D12009CEEFE /* IexApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95700BC525BD9D12009CEEFE /* IexApi.swift */; };
+		9597CDFE25C1D484004DDFED /* TestStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9597CDFD25C1D484004DDFED /* TestStroke.swift */; };
+		9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9597CE0025C1DC0A004DDFED /* LogoModifier.swift */; };
+		9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */; };
 		95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */; };
 		95AB4A7D259DCC0C0064C9C1 /* CompanyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */; };
 		95AB4A90259DD66D0064C9C1 /* CompanyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */; };
@@ -37,7 +39,6 @@
 		95E411A325BEDDC400A9C23F /* WatchlistCompany+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411A125BEDDC400A9C23F /* WatchlistCompany+CoreDataProperties.swift */; };
 		95E411A725BEE03000A9C23F /* Watchlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411A625BEE03000A9C23F /* Watchlist.swift */; };
 		95E411B625BEE84E00A9C23F /* Stock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411B525BEE84E00A9C23F /* Stock.swift */; };
-		95E411BA25BEEA4400A9C23F /* Title.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411B925BEEA4400A9C23F /* Title.swift */; };
 		95E411BE25BEEA6C00A9C23F /* WatchlistRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */; };
 		95F6C2F025BAE2ED003CF389 /* Company.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6C2EF25BAE2ED003CF389 /* Company.swift */; };
 		95F6C30125BAEC8B003CF389 /* CompanyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6C30025BAEC8B003CF389 /* CompanyView.swift */; };
@@ -58,8 +59,10 @@
 		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; };
-		95621ADA25BF32E200BB17FC /* Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Test.swift; path = lazybear/Tests/Test.swift; sourceTree = SOURCE_ROOT; };
 		95700BC525BD9D12009CEEFE /* IexApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = IexApi.swift; path = lazybear/IexApi.swift; sourceTree = SOURCE_ROOT; };
+		9597CDFD25C1D484004DDFED /* TestStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestStroke.swift; path = lazybear/Tests/TestStroke.swift; sourceTree = SOURCE_ROOT; };
+		9597CE0025C1DC0A004DDFED /* LogoModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoModifier.swift; sourceTree = "<group>"; };
+		9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoPlaceholder.swift; sourceTree = "<group>"; };
 		95AB4A79259DCBAE0064C9C1 /* ReadJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReadJson.swift; path = lazybear/Functions/ReadJson.swift; sourceTree = SOURCE_ROOT; };
 		95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyModel.swift; path = lazybear/Models/CompanyModel.swift; sourceTree = SOURCE_ROOT; };
 		95AB4A8F259DD66D0064C9C1 /* CompanyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyRow.swift; sourceTree = "<group>"; };
@@ -79,7 +82,6 @@
 		95E411A125BEDDC400A9C23F /* WatchlistCompany+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WatchlistCompany+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		95E411A625BEE03000A9C23F /* Watchlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Watchlist.swift; sourceTree = "<group>"; };
 		95E411B525BEE84E00A9C23F /* Stock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stock.swift; sourceTree = "<group>"; };
-		95E411B925BEEA4400A9C23F /* Title.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Title.swift; sourceTree = "<group>"; };
 		95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchlistRow.swift; sourceTree = "<group>"; };
 		95F6C2EF25BAE2ED003CF389 /* Company.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Company.swift; sourceTree = "<group>"; };
 		95F6C30025BAEC8B003CF389 /* CompanyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompanyView.swift; path = "lazybear/Supply views/CompanyView.swift"; sourceTree = SOURCE_ROOT; };
@@ -117,7 +119,7 @@
 			children = (
 				9537924925BDFCD70001F82B /* LoadImageTest.swift */,
 				95E4119525BEC9DD00A9C23F /* TestViewBuilder.swift */,
-				95621ADA25BF32E200BB17FC /* Test.swift */,
+				9597CDFD25C1D484004DDFED /* TestStroke.swift */,
 			);
 			path = Tests;
 			sourceTree = "<group>";
@@ -136,7 +138,8 @@
 				95E411B525BEE84E00A9C23F /* Stock.swift */,
 				95F6C30425BAF599003CF389 /* CompanyHeader.swift */,
 				95F6C30825BAF7C2003CF389 /* DateSelection.swift */,
-				95E411B925BEEA4400A9C23F /* Title.swift */,
+				9597CE0025C1DC0A004DDFED /* LogoModifier.swift */,
+				9597CE0325C1DFE7004DDFED /* LogoPlaceholder.swift */,
 			);
 			name = "Supply views";
 			path = "lazybear/Supply views";
@@ -292,7 +295,9 @@
 			files = (
 				95AB4A7A259DCBAE0064C9C1 /* ReadJson.swift in Sources */,
 				95E0287B25B88F3C00020CF2 /* FormDescription.swift in Sources */,
+				9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */,
 				952498B625BB47A700B00E22 /* LatestPriceModel.swift in Sources */,
+				9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */,
 				95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */,
 				95E411A225BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift in Sources */,
 				95612C512598D48200F7698F /* SearchBar.swift in Sources */,
@@ -311,14 +316,13 @@
 				95AB4A7D259DCC0C0064C9C1 /* CompanyModel.swift in Sources */,
 				95700BC625BD9D12009CEEFE /* IexApi.swift in Sources */,
 				9537923625BDF85D0001F82B /* GoogleApi.swift in Sources */,
+				9597CDFE25C1D484004DDFED /* TestStroke.swift in Sources */,
 				95C28AB625BC45CF0033D16A /* ChartStyle.swift in Sources */,
 				9537924A25BDFCD70001F82B /* LoadImageTest.swift in Sources */,
 				95C28AB925BC46250033D16A /* ScalateChart.swift in Sources */,
 				95E411B625BEE84E00A9C23F /* Stock.swift in Sources */,
 				954D992525A2123B001F7F60 /* HistoricalPricesModel.swift in Sources */,
 				95E411A725BEE03000A9C23F /* Watchlist.swift in Sources */,
-				95E411BA25BEEA4400A9C23F /* Title.swift in Sources */,
-				95621ADB25BF32E200BB17FC /* Test.swift in Sources */,
 				95F7CAF625ADC7B7009E0E7C /* LazyBear.xcdatamodeld in Sources */,
 				95E4119625BEC9DD00A9C23F /* TestViewBuilder.swift in Sources */,
 			);
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/lazybear/CloudKitManager.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/CloudKitManager.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -9,11 +9,11 @@
 import CloudKit
 
 class CloudKitManager {
-    func query(recordType: String, recordName: String) {  // recordType = "Database", e.g "API"
-        let publicDatabase = CKContainer.default().privateCloudDatabase
+    func query(recordType: String, recordName: String) -> CKRecord {  // recordType = "Database", e.g "API" / recordName = "Name", e.g iexProduction
+        let publicDatabase = CKContainer.default().publicCloudDatabase
         
         // Query arguments
-        let recordID = CKRecord.ID(recordName: recordName)  // e.g iexApiProduction
+        let recordID = CKRecord.ID(recordName: recordName)
         let predicate = NSPredicate(format: "recordID = %@", recordID)
         let query = CKQuery(recordType: recordType, predicate: predicate)
         
@@ -21,19 +21,13 @@
         
         // Query begins
         publicDatabase.perform(query, inZoneWith: nil) { (results, error) in
-            if error != nil {
-                print("CloudKit query went wrong")
-                print(error!.localizedDescription)
-
-            } else {
+            guard error != nil else {  // If error is nil, then print results
+                print("Successfull CloudKit query")
 
-                if let results = results {
-                    print("Succesfull CloudKit query")
-                    
-                    // Results
-                    print(results as Array)
-                }
             }
+            
+            print("CloudKit query went wrong")
+            print(error!.localizedDescription)
         }
     }
 }
--- a/lazybear/GoogleApi.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/GoogleApi.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -14,7 +14,7 @@
         var path: String {
             switch self {
             case let .company(symbol):
-                return "https://storage.googleapis.com/iex/api/logos/\(symbol).png"
+                return "/iex/api/logos/\(symbol.uppercased()).png"
             }
         }
     }
--- a/lazybear/LazyBearApp.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/LazyBearApp.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -13,7 +13,7 @@
 
     var body: some Scene {
         WindowGroup {
-            Test()
+            ContentView()
                 .environment(\.managedObjectContext, persistenceController.container.viewContext)
         }
     }
--- a/lazybear/Supply views/Company.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/Supply views/Company.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -15,7 +15,7 @@
         CompanyHeader(name: self.name, symbol: self.symbol)
         ScrollView {
             VStack(alignment: .leading) {
-                // Stock()
+                Stock(name: name, symbol: symbol)
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Supply views/LogoModifier.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -0,0 +1,17 @@
+//
+//  LogoModifier.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 27/1/21.
+//
+
+import SwiftUI
+
+struct LogoModifier: ViewModifier {
+    func body(content: Content) -> some View {
+        content
+            .aspectRatio(contentMode: .fit)
+            .frame(maxWidth: 40, maxHeight: 40)
+            .clipShape(RoundedRectangle(cornerRadius: 3))
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Supply views/LogoPlaceholder.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -0,0 +1,20 @@
+//
+//  LogoPlaceholder.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 27/1/21.
+//
+
+import SwiftUI
+
+struct LogoPlaceholder: View {
+    var body: some View {
+        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+    }
+}
+
+struct LogoPlaceholder_Previews: PreviewProvider {
+    static var previews: some View {
+        LogoPlaceholder()
+    }
+}
--- a/lazybear/Supply views/Stock.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/Supply views/Stock.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -9,9 +9,14 @@
 
 struct Stock: View {
     @Environment(\.managedObjectContext) private var viewContext
+    var name: String
+    var symbol: String
     
     var body: some View {
-        Text("Hello, World!")
+        Button(action: { addWatchlist(name: name, symbol: symbol) }) {
+            Text("Add to watchlist")
+        }
+
     }
     
     func addWatchlist(name: String, symbol: String) {
@@ -29,6 +34,6 @@
 
 struct Stock_Previews: PreviewProvider {
     static var previews: some View {
-        Stock()
+        Stock(name: "apple inc", symbol: "aapl")
     }
 }
--- a/lazybear/Supply views/Title.swift	Tue Jan 26 17:25:40 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-//
-//  Title.swift
-//  LazyBear
-//
-//  Created by Dennis Concepción Martín on 25/1/21.
-//
-
-import SwiftUI
-
-struct Title: View {
-    var body: some View {
-        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
-    }
-}
-
-struct Title_Previews: PreviewProvider {
-    static var previews: some View {
-        Title()
-    }
-}
--- a/lazybear/Supply views/Watchlist.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/Supply views/Watchlist.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -11,12 +11,14 @@
     @Environment(\.managedObjectContext) private var viewContext  // Core data
     @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])  // Core data
     var companies: FetchedResults<WatchlistCompany>  // Fetch core data
+    let cloud = CloudKitManager()
     
     var body: some View {
         List {
             EditButton()
+            let url = cloud.query(recordType: "API", recordName: "iexLogo")
             ForEach(companies) { company in
-                WatchlistRow(company: company)
+                WatchlistRow(company: company, url: "")
                 
             }
             // Delete from persistent storage
--- a/lazybear/Supply views/WatchlistRow.swift	Tue Jan 26 17:25:40 2021 +0100
+++ b/lazybear/Supply views/WatchlistRow.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -7,20 +7,30 @@
 
 import SwiftUI
 import CoreData
+import SDWebImageSwiftUI
 
 struct WatchlistRow: View {
     @ObservedObject var companyView = CompanyView()
     var company: WatchlistCompany
+    var url: String
     
     var body: some View {
         Button(action: { companyView.isShowing.toggle() }) {
-            VStack(alignment: .leading) {
-                Text(company.symbol!.uppercased())
-                    .fontWeight(.semibold)
+            HStack {
+                let path = GoogleApi.URL.company(symbol: company.symbol!).path
+                WebImage(url: URL(string: url + path))
+                    .resizable()
+                    .placeholder { Rectangle().foregroundColor(.gray) }
+                    .indicator(.activity) // Activity Indicator
+                    .modifier(LogoModifier())
                 
-                Text(company.name!.capitalized)
-                    .font(.caption)
-                
+                VStack(alignment: .leading) {
+                    Text(company.symbol!.uppercased())
+                        .fontWeight(.semibold)
+                    
+                    Text(company.name!.capitalized)
+                        .font(.caption)
+                }
             }
         }
     }
@@ -34,6 +44,6 @@
         let watchlistCompany = WatchlistCompany(context: moc)
         watchlistCompany.name = "apple inc"
         watchlistCompany.symbol = "aapl"
-        return WatchlistRow(company: watchlistCompany)
+        return WatchlistRow(company: watchlistCompany, url: "")
     }
 }
--- a/lazybear/Tests/Test.swift	Tue Jan 26 17:25:40 2021 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-//  TestCloudKit.swift
-//  LazyBear
-//
-//  Created by Dennis Concepción Martín on 25/1/21.
-//
-
-import SwiftUI
-
-struct Test: View {
-    let cloudKit = CloudKitManager()
-    
-    var body: some View {
-        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
-            .onAppear {
-                cloudKit.query(recordType: "API")
-            }
-    }
-}
-
-struct Test_Previews: PreviewProvider {
-    static var previews: some View {
-        Test()
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Tests/TestStroke.swift	Wed Jan 27 19:59:58 2021 +0100
@@ -0,0 +1,21 @@
+//
+//  TestStroke.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 27/1/21.
+//
+
+import SwiftUI
+
+struct TestStroke: View {
+    var body: some View {
+        Circle()
+            .stroke(Color(.blue))
+    }
+}
+
+struct TestStroke_Previews: PreviewProvider {
+    static var previews: some View {
+        TestStroke()
+    }
+}