changeset 90:c59c01f70a55

Improve CloudKit fetch
author Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com>
date Thu, 28 Jan 2021 16:43:27 +0100
parents 76b4a3be4d46
children 9138585de5ea
files LazyBear.xcodeproj/project.pbxproj LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate WatchlistCompany+CoreDataClass.swift WatchlistCompany+CoreDataProperties.swift lazybear/CloudKitManager.swift lazybear/LazyBear.xcdatamodeld/LazyBear.xcdatamodel/contents lazybear/Models/ApiModel.swift lazybear/Persistence.swift lazybear/Supply views/LogoPlaceholder.swift lazybear/Supply views/Price.swift lazybear/Supply views/Watchlist.swift lazybear/Supply views/WatchlistRow.swift
diffstat 12 files changed, 75 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/LazyBear.xcodeproj/project.pbxproj	Wed Jan 27 22:46:43 2021 +0100
+++ b/LazyBear.xcodeproj/project.pbxproj	Thu Jan 28 16:43:27 2021 +0100
@@ -30,8 +30,6 @@
 		95D1BF4925ADCF7700E5D063 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95D1BF4825ADCF7700E5D063 /* Persistence.swift */; };
 		95E4118F25BEC35D00A9C23F /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 95E4118E25BEC35D00A9C23F /* SDWebImageSwiftUI */; };
 		95E4119225BEC56F00A9C23F /* SuperTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E4119125BEC56F00A9C23F /* SuperTitle.swift */; };
-		95E411A225BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411A025BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift */; };
-		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 */; };
 		95E411BE25BEEA6C00A9C23F /* WatchlistRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */; };
@@ -42,6 +40,9 @@
 		95F6F45C25C20D8D002AC66A /* Price.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6F45B25C20D8D002AC66A /* Price.swift */; };
 		95F6F46125C20E63002AC66A /* ListHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95F6F46025C20E63002AC66A /* ListHeader.swift */; };
 		95F7CAF625ADC7B7009E0E7C /* LazyBear.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 95F7CAF425ADC7B7009E0E7C /* LazyBear.xcdatamodeld */; };
+		95FE646725C2DC580052832E /* WatchlistCompany+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FE646525C2DC570052832E /* WatchlistCompany+CoreDataClass.swift */; };
+		95FE646825C2DC580052832E /* WatchlistCompany+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FE646625C2DC570052832E /* WatchlistCompany+CoreDataProperties.swift */; };
+		95FE646B25C30B880052832E /* ApiModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FE646A25C30B880052832E /* ApiModel.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -70,8 +71,6 @@
 		95C28AB825BC46250033D16A /* ScalateChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScalateChart.swift; path = lazybear/Functions/ScalateChart.swift; sourceTree = SOURCE_ROOT; };
 		95D1BF4825ADCF7700E5D063 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Persistence.swift; path = LazyBear/Persistence.swift; sourceTree = SOURCE_ROOT; };
 		95E4119125BEC56F00A9C23F /* SuperTitle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuperTitle.swift; sourceTree = "<group>"; };
-		95E411A025BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WatchlistCompany+CoreDataClass.swift"; sourceTree = "<group>"; };
-		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>"; };
 		95E411BD25BEEA6C00A9C23F /* WatchlistRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchlistRow.swift; sourceTree = "<group>"; };
@@ -82,6 +81,9 @@
 		95F6F45B25C20D8D002AC66A /* Price.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Price.swift; sourceTree = "<group>"; };
 		95F6F46025C20E63002AC66A /* ListHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListHeader.swift; sourceTree = "<group>"; };
 		95F7CAF525ADC7B7009E0E7C /* LazyBear.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LazyBear.xcdatamodel; sourceTree = "<group>"; };
+		95FE646525C2DC570052832E /* WatchlistCompany+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WatchlistCompany+CoreDataClass.swift"; sourceTree = "<group>"; };
+		95FE646625C2DC570052832E /* WatchlistCompany+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WatchlistCompany+CoreDataProperties.swift"; sourceTree = "<group>"; };
+		95FE646A25C30B880052832E /* ApiModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ApiModel.swift; path = lazybear/Models/ApiModel.swift; sourceTree = SOURCE_ROOT; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -153,6 +155,7 @@
 			children = (
 				95AB4A7C259DCC0C0064C9C1 /* CompanyModel.swift */,
 				954D992425A2123B001F7F60 /* HistoricalPricesModel.swift */,
+				95FE646A25C30B880052832E /* ApiModel.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -168,8 +171,8 @@
 		95B04EA625212369000AD27F = {
 			isa = PBXGroup;
 			children = (
-				95E411A025BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift */,
-				95E411A125BEDDC400A9C23F /* WatchlistCompany+CoreDataProperties.swift */,
+				95FE646525C2DC570052832E /* WatchlistCompany+CoreDataClass.swift */,
+				95FE646625C2DC570052832E /* WatchlistCompany+CoreDataProperties.swift */,
 				95B04EB125212369000AD27F /* LazyBear */,
 				95B04EB025212369000AD27F /* Products */,
 				9500257E256D17D9008FFD28 /* Frameworks */,
@@ -288,11 +291,10 @@
 				95F6F45C25C20D8D002AC66A /* Price.swift in Sources */,
 				9597CE0125C1DC0A004DDFED /* LogoModifier.swift in Sources */,
 				9597CE0425C1DFE7004DDFED /* LogoPlaceholder.swift in Sources */,
+				95FE646B25C30B880052832E /* ApiModel.swift in Sources */,
 				95F6C30525BAF599003CF389 /* CompanyHeader.swift in Sources */,
-				95E411A225BEDDC400A9C23F /* WatchlistCompany+CoreDataClass.swift in Sources */,
 				95612C512598D48200F7698F /* SearchBar.swift in Sources */,
 				95E411BE25BEEA6C00A9C23F /* WatchlistRow.swift in Sources */,
-				95E411A325BEDDC400A9C23F /* WatchlistCompany+CoreDataProperties.swift in Sources */,
 				950B79F625B1CB7A00E5DB5B /* CompanyList.swift in Sources */,
 				95078FD125BF4E640004FA75 /* CloudKitManager.swift in Sources */,
 				95B04EB525212369000AD27F /* ContentView.swift in Sources */,
@@ -311,8 +313,10 @@
 				95C28AB925BC46250033D16A /* ScalateChart.swift in Sources */,
 				95E411B625BEE84E00A9C23F /* Stock.swift in Sources */,
 				954D992525A2123B001F7F60 /* HistoricalPricesModel.swift in Sources */,
+				95FE646725C2DC580052832E /* WatchlistCompany+CoreDataClass.swift in Sources */,
 				95E411A725BEE03000A9C23F /* Watchlist.swift in Sources */,
 				95F7CAF625ADC7B7009E0E7C /* LazyBear.xcdatamodeld in Sources */,
+				95FE646825C2DC580052832E /* WatchlistCompany+CoreDataProperties.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
Binary file LazyBear.xcodeproj/project.xcworkspace/xcuserdata/dennis.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/WatchlistCompany+CoreDataClass.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/WatchlistCompany+CoreDataClass.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -2,7 +2,7 @@
 //  WatchlistCompany+CoreDataClass.swift
 //  LazyBear
 //
-//  Created by Dennis Concepción Martín on 25/1/21.
+//  Created by Dennis Concepción Martín on 28/1/21.
 //
 //
 
--- a/WatchlistCompany+CoreDataProperties.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/WatchlistCompany+CoreDataProperties.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -2,7 +2,7 @@
 //  WatchlistCompany+CoreDataProperties.swift
 //  LazyBear
 //
-//  Created by Dennis Concepción Martín on 25/1/21.
+//  Created by Dennis Concepción Martín on 28/1/21.
 //
 //
 
@@ -16,20 +16,20 @@
         return NSFetchRequest<WatchlistCompany>(entityName: "WatchlistCompany")
     }
 
-    @NSManaged public var symbol: String?
+    @NSManaged public var cik: String?
+    @NSManaged public var currency: String?
+    @NSManaged public var date: String?
     @NSManaged public var exchange: String?
+    @NSManaged public var exchangeName: String?
     @NSManaged public var exchangeSuffix: String?
-    @NSManaged public var exchangeName: String?
+    @NSManaged public var figi: String?
+    @NSManaged public var iexId: String?
+    @NSManaged public var isEnabled: Bool
+    @NSManaged public var lei: String?
     @NSManaged public var name: String?
-    @NSManaged public var date: String?
+    @NSManaged public var region: String?
+    @NSManaged public var symbol: String?
     @NSManaged public var type: String?
-    @NSManaged public var iexId: String?
-    @NSManaged public var region: String?
-    @NSManaged public var currency: String?
-    @NSManaged public var isEnabled: Bool
-    @NSManaged public var figi: String?
-    @NSManaged public var cik: String?
-    @NSManaged public var lei: String?
 
 }
 
--- a/lazybear/CloudKitManager.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/CloudKitManager.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -9,14 +9,12 @@
 import CloudKit
 
 class CloudKitManager {
-    func query(recordType: String, recordName: String, completition: @escaping ([CKRecord]) -> Void) {  // recordType = "Database", e.g "API"
+    func query(recordType: String, completition: @escaping ([CKRecord]) -> Void) {  // recordType = "Database", e.g "API"
         let publicDatabase = CKContainer.default().publicCloudDatabase
         
         // Query arguments
-        let recordID = CKRecord.ID(recordName: recordName)  // e.g iexApiProduction
-        let predicate = NSPredicate(format: "recordID = %@", recordID)
+        let predicate = NSPredicate(format: "TRUEPREDICATE")
         let query = CKQuery(recordType: recordType, predicate: predicate)
-        
         //query.sortDescriptors = [NSSortDescriptor(key: "name", ascending: false)]
         
         // Query begins
--- a/lazybear/LazyBear.xcdatamodeld/LazyBear.xcdatamodel/contents	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/LazyBear.xcdatamodeld/LazyBear.xcdatamodel/contents	Thu Jan 28 16:43:27 2021 +0100
@@ -17,6 +17,6 @@
         <attribute name="type" optional="YES" attributeType="String"/>
     </entity>
     <elements>
-        <element name="WatchlistCompany" positionX="-63" positionY="-18" width="128" height="14"/>
+        <element name="WatchlistCompany" positionX="-63" positionY="-18" width="128" height="239"/>
     </elements>
 </model>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lazybear/Models/ApiModel.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -0,0 +1,14 @@
+//
+//  ApiModel.swift
+//  LazyBear
+//
+//  Created by Dennis Concepción Martín on 28/1/21.
+//
+
+import SwiftUI
+
+struct ApiModel {
+    var key: String?
+    var name: String?
+    var url: String?
+}
--- a/lazybear/Persistence.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/Persistence.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -13,7 +13,7 @@
     static var preview: PersistenceController = {
         let result = PersistenceController(inMemory: true)
         let viewContext = result.container.viewContext
-        for _ in 0..<13 {
+        for _ in 0..<14 {
             let newItem = WatchlistCompany(context: viewContext)
             newItem.symbol = String()
             newItem.exchange = String()
--- a/lazybear/Supply views/LogoPlaceholder.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/Supply views/LogoPlaceholder.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -8,25 +8,16 @@
 import SwiftUI
 
 struct LogoPlaceholder: View {
-    var placeholder: String
     var body: some View {
-        let customPlaceholder = placeholder[0]
-        Text(customPlaceholder)
-            .fontWeight(.bold)
+        Image(systemName: "building.2")
             .foregroundColor(Color(.systemGray))
             .frame(width: 40, height: 40)
             .background(Color(.systemGray5))
     }
 }
-// Index string to access it
-extension String {
-    subscript(i: Int) -> String {
-        return String(self[index(startIndex, offsetBy: i)])
-    }
-}
 
 struct LogoPlaceholder_Previews: PreviewProvider {
     static var previews: some View {
-        LogoPlaceholder(placeholder: "appl")
+        LogoPlaceholder()
     }
 }
--- a/lazybear/Supply views/Price.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/Supply views/Price.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -6,10 +6,11 @@
 //
 
 import SwiftUI
+import CloudKit
 
 struct Price: View {
     var body: some View {
-        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+        Text("Price")
     }
 }
 
--- a/lazybear/Supply views/Watchlist.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/Supply views/Watchlist.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -9,37 +9,32 @@
 import CloudKit
 
 struct Watchlist: View {
-    @Environment(\.managedObjectContext) private var viewContext  // Core data
-    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])  // Core data
+    @Environment(\.managedObjectContext) private var viewContext
+    @FetchRequest(entity: WatchlistCompany.entity(), sortDescriptors: [])
     var companies: FetchedResults<WatchlistCompany>  // Fetch core data
     
     let cloud = CloudKitManager()
+    @State private var cloudFetch = [CKRecord]() { didSet { self.cloudValues() }}
+    @State private var cloudResults = [ApiModel]()
     @State private var showingView = false
-    @State var cloudResults = [CKRecord]() {
-        didSet {
-            self.showingView = true
-        }
-    }
     
     
     var body: some View {
         if self.showingView {
             ListHeader(header: "Watchlist")
             List {
-                let url = cloudResults[0].object(forKey: "url") as! String
                 ForEach(companies) { company in
-                    WatchlistRow(company: company, url: url)
-                    
+                    //WatchlistRow(company: company, url: url)
                 }
                 .onDelete { indexSet in deleteWatchlist(indexSet: indexSet) }  // Delete from persistent storage
-                //.onMove { self.companies(from: $0, to: $1) }  // Sort
+            }
+            .onAppear {
+                print(cloudResults)
             }
             
         } else {
             Spacer()
-                .onAppear {
-                    cloud.query(recordType: "API", recordName: "iexLogo") { self.cloudResults = $0 }
-                }
+                .onAppear { cloud.query(recordType: "API") { self.cloudFetch = $0 } }
         }
     }
     
@@ -54,6 +49,18 @@
             print(error.localizedDescription)
         }
     }
+    
+    private func cloudValues() {
+        cloudFetch.forEach({ (result) in
+            let key = result.object(forKey: "key") as? String
+            let name = result.object(forKey: "name") as? String
+            let url = result.object(forKey: "url") as? String
+            
+            let value = ApiModel(key: key, name: name, url: url)
+            self.cloudResults.append(value)
+        })
+        self.showingView = true
+    }
 }
 
 struct Watchlist_Previews: PreviewProvider {
--- a/lazybear/Supply views/WatchlistRow.swift	Wed Jan 27 22:46:43 2021 +0100
+++ b/lazybear/Supply views/WatchlistRow.swift	Thu Jan 28 16:43:27 2021 +0100
@@ -18,19 +18,19 @@
     var body: some View {
         Button(action: { companyView.isShowing.toggle() }) {
             HStack {
-                let path = LogoApi.URL.company(symbol: company.symbol!).path
+                let path = LogoApi.URL.company(symbol: company.symbol ?? "").path
                 let endpoint = url + path
                 WebImage(url: URL(string: endpoint))
                     .resizable()
-                    .placeholder { LogoPlaceholder(placeholder: company.symbol!) }  // If there is no logo
+                    .placeholder { LogoPlaceholder() }  // If there is no logo
                     .indicator(.activity)
                     .modifier(LogoModifier())
                 
                 VStack(alignment: .leading) {
-                    Text(company.symbol!.uppercased())
+                    Text(company.symbol ?? "".uppercased())
                         .fontWeight(.semibold)
                     
-                    Text(company.name!.capitalized)
+                    Text(company.name ?? "".capitalized)
                         .font(.caption)
                 }
                 
@@ -40,9 +40,13 @@
                 }
             }
         }
+        .fullScreenCover(isPresented: $companyView.isShowing) {
+            Company(name: company.name ?? "", symbol: company.symbol ?? "")
+        }
     }
 }
 
+
 struct WatchlistRow_Previews: PreviewProvider {
     // Avoid preview crashing
     static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)