From cb893cb8a9b4c9bf2c350996585fc98c92f3e704 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 5 Oct 2023 14:04:31 -0700 Subject: [PATCH 1/9] fix: add homebrew location to PATH when running upload-symbols.sh in Xcode GUI --- upload-symbols.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/upload-symbols.sh b/upload-symbols.sh index 7ae1f97..1dc2e35 100755 --- a/upload-symbols.sh +++ b/upload-symbols.sh @@ -1,5 +1,7 @@ #!/bin/sh +export PATH="$PATH:/opt/homebrew/bin:/usr/local/bin" + if which sentry-cli >/dev/null; then # get SENTRY_ORG and SENTRY_PROJECT values From cdc5936fac45fbe66af7e432b7c21d4743184458 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 26 Sep 2023 17:46:23 -0800 Subject: [PATCH 2/9] fix: make navbar buttons same tint as other button colors --- EmpowerPlant/Base.lproj/Main.storyboard | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EmpowerPlant/Base.lproj/Main.storyboard b/EmpowerPlant/Base.lproj/Main.storyboard index c8dbeec..3990e88 100644 --- a/EmpowerPlant/Base.lproj/Main.storyboard +++ b/EmpowerPlant/Base.lproj/Main.storyboard @@ -4,6 +4,7 @@ + @@ -223,7 +224,7 @@ - + @@ -239,6 +240,9 @@ + + + From fdd1ff14bbcd4e035994b0db312ef2540af4b469 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 27 Sep 2023 10:34:49 -0800 Subject: [PATCH 3/9] wip making back button same color --- EmpowerPlant/Base.lproj/Main.storyboard | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EmpowerPlant/Base.lproj/Main.storyboard b/EmpowerPlant/Base.lproj/Main.storyboard index 3990e88..f724a72 100644 --- a/EmpowerPlant/Base.lproj/Main.storyboard +++ b/EmpowerPlant/Base.lproj/Main.storyboard @@ -48,7 +48,9 @@ - + + + From 078af26963465caf1420a32da21e8237d6ce131f Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 5 Oct 2023 14:16:54 -0700 Subject: [PATCH 4/9] fix some colors mismatches and titles --- EmpowerPlant/Base.lproj/Main.storyboard | 16 +++++++++++----- EmpowerPlant/CartViewController.swift | 1 - EmpowerPlant/EmpowerPlantViewController.swift | 2 -- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/EmpowerPlant/Base.lproj/Main.storyboard b/EmpowerPlant/Base.lproj/Main.storyboard index f724a72..998cc56 100644 --- a/EmpowerPlant/Base.lproj/Main.storyboard +++ b/EmpowerPlant/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -27,7 +27,11 @@ - + + + + + @@ -211,7 +215,9 @@ - + + + @@ -249,7 +255,7 @@ - + diff --git a/EmpowerPlant/CartViewController.swift b/EmpowerPlant/CartViewController.swift index 01f8151..31cd381 100644 --- a/EmpowerPlant/CartViewController.swift +++ b/EmpowerPlant/CartViewController.swift @@ -62,7 +62,6 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData target: self, action: #selector(purchase) ) - self.navigationItem.rightBarButtonItem?.tintColor = UIColor.blue self.navigationItem.rightBarButtonItem?.accessibilityIdentifier = "Purchase" } diff --git a/EmpowerPlant/EmpowerPlantViewController.swift b/EmpowerPlant/EmpowerPlantViewController.swift index 07baf05..5bf92a6 100644 --- a/EmpowerPlant/EmpowerPlantViewController.swift +++ b/EmpowerPlant/EmpowerPlantViewController.swift @@ -146,7 +146,6 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable target: self, action: #selector(goToCart) // addToDb ) - self.navigationItem.rightBarButtonItem?.tintColor = UIColor.blue self.navigationItem.rightBarButtonItem?.accessibilityIdentifier = "Cart" //self.navigationItem.rightBarButtonItem?.badgeValue = "\(1)" @@ -156,7 +155,6 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable target: self, action: #selector(goToListApp) // clearDb ) - self.navigationItem.leftBarButtonItem?.tintColor = UIColor.blue } // Writes to CoreData database From 20050a6c64d57c62b3f81a0e9abe970a41928741 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Fri, 22 Sep 2023 15:46:53 -0800 Subject: [PATCH 5/9] wip: add way to generate large amounts of db items to slow down db spans --- .../xcschemes/EmpowerPlant.xcscheme | 10 ++++++++ EmpowerPlant/AppDelegate.swift | 7 +++++- EmpowerPlant/EmpowerPlantViewController.swift | 25 ++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme index e42ed4b..3b79c1b 100644 --- a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme +++ b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme @@ -67,6 +67,16 @@ ReferencedContainer = "container:EmpowerPlant.xcodeproj"> + + + + + + Bool { // Override point for customization after application launch. SentrySDK.start { options in - options.dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" + var dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" + if let dsnOverride = ProcessInfo.processInfo.environment["--dsn-override"] { + dsn = dsnOverride + } + options.dsn = dsn // options.debug = true // Enabled debug when first installing is always helpful // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. @@ -29,6 +33,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { options.attachScreenshot = true options.attachViewHierarchy = true options.enableTimeToFullDisplayTracing = true + options.enableAutoPerformanceTracing = true options.enableUserInteractionTracing = false } SentrySDK.configureScope{ scope in diff --git a/EmpowerPlant/EmpowerPlantViewController.swift b/EmpowerPlant/EmpowerPlantViewController.swift index 5bf92a6..11bd85b 100644 --- a/EmpowerPlant/EmpowerPlantViewController.swift +++ b/EmpowerPlant/EmpowerPlantViewController.swift @@ -190,8 +190,29 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable } func getAllProductsFromDb() { + if ProcessInfo.processInfo.arguments.contains("--generate-many-products") { + for i in 0..<1_000_000 { + let newProduct = Product(context: context) + + newProduct.productId = "Product \(i)" // 'id' was a reserved word in swift + newProduct.title = "Product \(i)" + newProduct.productDescription = "Description for product \(i)" // 'description' was a reserved word in swift + newProduct.productDescriptionFull = "Full description for product (i)" + newProduct.img = "img" + newProduct.imgCropped = "img.cropped" + newProduct.price = "\(i)" + } + do { + try context.save() + } catch { + fatalError("failed to store generated products in db") + } + } + do { + print("time: \(Date())") self.products = try context.fetch(Product.fetchRequest()) + print("time: \(Date())") // for product in self.products { // print(product.productId, product.title, product.productDescriptionFull) // } @@ -225,7 +246,9 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable if (self.products.count == 0) { for product in productsResponse { // Writes to CoreData database - self.createProduct(productId: String(product.id), title: product.title, productDescription: product.description, productDescriptionFull: product.descriptionfull, img: product.img, imgCropped: product.imgcropped, price: String(product.price)) + DispatchQueue.main.async { + self.createProduct(productId: String(product.id), title: product.title, productDescription: product.description, productDescriptionFull: product.descriptionfull, img: product.img, imgCropped: product.imgcropped, price: String(product.price)) + } } } } else { From 7be05f6377fca2b463197bceb9551597feba264c Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 5 Oct 2023 14:28:49 -0700 Subject: [PATCH 6/9] remove dsn override option; no longer necessary with user tagging --- EmpowerPlant/AppDelegate.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/EmpowerPlant/AppDelegate.swift b/EmpowerPlant/AppDelegate.swift index 3f1d701..86792e3 100644 --- a/EmpowerPlant/AppDelegate.swift +++ b/EmpowerPlant/AppDelegate.swift @@ -17,11 +17,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. SentrySDK.start { options in - var dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" - if let dsnOverride = ProcessInfo.processInfo.environment["--dsn-override"] { - dsn = dsnOverride - } - options.dsn = dsn + options.dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" // options.debug = true // Enabled debug when first installing is always helpful // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. From 2a1551972a20fe1b2471ba7340e9cf211caca359 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 5 Oct 2023 14:35:52 -0700 Subject: [PATCH 7/9] enable SDK debug mode for debug builds --- EmpowerPlant.xcodeproj/project.pbxproj | 2 +- .../xcschemes/EmpowerPlant.xcscheme | 4 --- EmpowerPlant/AppDelegate.swift | 30 ++++++++++--------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/EmpowerPlant.xcodeproj/project.pbxproj b/EmpowerPlant.xcodeproj/project.pbxproj index 22b5613..d96d7ca 100644 --- a/EmpowerPlant.xcodeproj/project.pbxproj +++ b/EmpowerPlant.xcodeproj/project.pbxproj @@ -461,8 +461,8 @@ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_SWIFT_FLAGS = "-D DEBUG"; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; diff --git a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme index 3b79c1b..6391cf9 100644 --- a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme +++ b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme @@ -72,10 +72,6 @@ argument = "--generate-many-products" isEnabled = "YES"> - - Bool { // Override point for customization after application launch. SentrySDK.start { options in - options.dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" -// options.debug = true // Enabled debug when first installing is always helpful + options.dsn = "https://c88045e430864a8e864af6233e7c18ea@o87286.ingest.sentry.io/6249899" + #if DEBUG + options.debug = true + #endif - // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. - // We recommend adjusting this value in production. - options.tracesSampleRate = 1.0 - options.profilesSampleRate = 1.0 - options.enableCoreDataTracing = true - options.enableFileIOTracing = true - options.attachScreenshot = true - options.attachViewHierarchy = true - options.enableTimeToFullDisplayTracing = true - options.enableAutoPerformanceTracing = true - options.enableUserInteractionTracing = false - } + // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. + // We recommend adjusting this value in production. + options.tracesSampleRate = 1.0 + options.profilesSampleRate = 1.0 + options.enableCoreDataTracing = true + options.enableFileIOTracing = true + options.attachScreenshot = true + options.attachViewHierarchy = true + options.enableTimeToFullDisplayTracing = true + options.enableAutoPerformanceTracing = true + options.enableUserInteractionTracing = false + } SentrySDK.configureScope{ scope in scope.setTag(value: ["corporate", "enterprise", "self-serve"].randomElement() ?? "unknown", key: "customer.type") scope.setTag(value: ProcessInfo.processInfo.environment["USER"] ?? "tda", key: "se") From 6f6e49104580079af489bd634d14e01582a80a08 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Fri, 6 Oct 2023 13:54:10 -0700 Subject: [PATCH 8/9] working: generate many items and automatically update the table view (inefficient) --- EmpowerPlant.xcodeproj/project.pbxproj | 4 + .../xcschemes/EmpowerPlant.xcscheme | 4 +- EmpowerPlant/AppDelegate.swift | 10 +- EmpowerPlant/Base.lproj/Main.storyboard | 43 ++++-- EmpowerPlant/CartViewController.swift | 21 ++- EmpowerPlant/EmpowerPlantViewController.swift | 144 ++++++++---------- EmpowerPlant/ListAppViewController.swift | 50 ++++++ EmpowerPlant/Product+CoreDataClass.swift | 2 +- EmpowerPlant/Utils.swift | 24 +++ Podfile | 1 + upload-symbols.sh | 6 +- 11 files changed, 192 insertions(+), 117 deletions(-) create mode 100644 EmpowerPlant/Utils.swift diff --git a/EmpowerPlant.xcodeproj/project.pbxproj b/EmpowerPlant.xcodeproj/project.pbxproj index d96d7ca..d526ae6 100644 --- a/EmpowerPlant.xcodeproj/project.pbxproj +++ b/EmpowerPlant.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 674899180B469D888700A555 /* Pods_EmpowerPlant.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74014747DE857D26E9BD7B24 /* Pods_EmpowerPlant.framework */; }; + 843BD60F2AD08CE900B0098F /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843BD60E2AD08CE900B0098F /* Utils.swift */; }; 8B21663C29D3F8C80009C890 /* RandomErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B21663B29D3F8C80009C890 /* RandomErrors.swift */; }; 8BA3AB382A20212C00BE1EA8 /* CartViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BA3AB372A20212C00BE1EA8 /* CartViewControllerTests.swift */; }; D15EDF12282BF7FB00FC13D6 /* Product+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15EDF11282BF7FB00FC13D6 /* Product+CoreDataProperties.swift */; }; @@ -37,6 +38,7 @@ /* Begin PBXFileReference section */ 57BE79023D12DCDCB69BA73D /* Pods-EmpowerPlant.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EmpowerPlant.release.xcconfig"; path = "Target Support Files/Pods-EmpowerPlant/Pods-EmpowerPlant.release.xcconfig"; sourceTree = ""; }; 74014747DE857D26E9BD7B24 /* Pods_EmpowerPlant.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EmpowerPlant.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 843BD60E2AD08CE900B0098F /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 846BEA1A2ABE46880032F77F /* upload-symbols.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "upload-symbols.sh"; sourceTree = ""; }; 8474F0482ACCE2D800F21E06 /* deploy_project.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = deploy_project.sh; sourceTree = ""; }; 8474F04D2ACE54F300F21E06 /* .github */ = {isa = PBXFileReference; lastKnownFileType = folder; path = .github; sourceTree = ""; }; @@ -130,6 +132,7 @@ D15EDF13282BF80400FC13D6 /* Product+CoreDataClass.swift */, D15EDF11282BF7FB00FC13D6 /* Product+CoreDataProperties.swift */, D17C73D127D83321006650AF /* ListAppViewController.swift */, + 843BD60E2AD08CE900B0098F /* Utils.swift */, D15FCDA727E00F0D00258BF3 /* Model.xcdatamodeld */, D17C73CB27D82EB8006650AF /* EmpowerPlantViewController.swift */, D19EBE6E2805ED52007022DC /* ShoppingCart.swift */, @@ -330,6 +333,7 @@ D17C73CF27D82ED1006650AF /* CartViewController.swift in Sources */, 8B21663C29D3F8C80009C890 /* RandomErrors.swift in Sources */, D19EBE6F2805ED52007022DC /* ShoppingCart.swift in Sources */, + 843BD60F2AD08CE900B0098F /* Utils.swift in Sources */, D17C73B327D8291D006650AF /* AppDelegate.swift in Sources */, D17C73B527D8291D006650AF /* SceneDelegate.swift in Sources */, D15EDF12282BF7FB00FC13D6 /* Product+CoreDataProperties.swift in Sources */, diff --git a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme index 6391cf9..30a919c 100644 --- a/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme +++ b/EmpowerPlant.xcodeproj/xcshareddata/xcschemes/EmpowerPlant.xcscheme @@ -69,8 +69,8 @@ + argument = "--wipe-db" + isEnabled = "NO"> diff --git a/EmpowerPlant/AppDelegate.swift b/EmpowerPlant/AppDelegate.swift index 26d2e28..119ede7 100644 --- a/EmpowerPlant/AppDelegate.swift +++ b/EmpowerPlant/AppDelegate.swift @@ -38,6 +38,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { scope.setTag(value: ["corporate", "enterprise", "self-serve"].randomElement() ?? "unknown", key: "customer.type") scope.setTag(value: ProcessInfo.processInfo.environment["USER"] ?? "tda", key: "se") } + + if ProcessInfo.processInfo.arguments.contains("--wipe-db") { + wipeDB() + } + return true } @@ -90,10 +95,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { do { try context.save() } catch { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. - let nserror = error as NSError - fatalError("Unresolved error \(nserror), \(nserror.userInfo)") + // TODO: error } } } diff --git a/EmpowerPlant/Base.lproj/Main.storyboard b/EmpowerPlant/Base.lproj/Main.storyboard index 998cc56..6482efd 100644 --- a/EmpowerPlant/Base.lproj/Main.storyboard +++ b/EmpowerPlant/Base.lproj/Main.storyboard @@ -17,15 +17,8 @@ - - - - - - - - + @@ -49,7 +42,7 @@ - + @@ -142,7 +135,7 @@ - + + + + @@ -254,11 +271,5 @@ - - - - - - diff --git a/EmpowerPlant/CartViewController.swift b/EmpowerPlant/CartViewController.swift index 31cd381..2ed4594 100644 --- a/EmpowerPlant/CartViewController.swift +++ b/EmpowerPlant/CartViewController.swift @@ -23,6 +23,7 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData let tableView: UITableView = { let table = UITableView() table.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + table.translatesAutoresizingMaskIntoConstraints = false return table }() @@ -44,13 +45,17 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData self.view.addSubview(tableView) tableView.delegate = self tableView.dataSource = self - - // Comment this out and to see the green background and no data in the rows - tableView.frame = view.bounds + + NSLayoutConstraint.activate([ + tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), + tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + ]) configureNavigationItems() - // TODO make this 'total' appear in a UI element + // TODO: make this 'total' appear in a UI element print("CartViewController | TOTAL", ShoppingCart.instance.total) SentrySDK.reportFullyDisplayed() } @@ -77,7 +82,7 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData request.httpMethod = "POST" let json: [String: Any] = [ - "form": ["email":"will@chat.io"], // TODO email update + check if all tx's+errors have email + "form": ["email":"will@chat.io"], // TODO: email update + check if all tx's+errors have email "cart": [ "total": 100, "quantities": ["4": 3], @@ -128,10 +133,10 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData // total DONE // quantities DONE below - // items TODO + // TODO: items let json: [String: Any] = [ - "form": ["email":"will@chat.io"], // TODO email update + check if all tx's+errors have email + "form": ["email":"will@chat.io"], // TODO: email update + check if all tx's+errors have email "cart": [ "total": ShoppingCart.instance.total, "quantities": [ @@ -151,7 +156,7 @@ class CartViewController: UIViewController, UITableViewDelegate, UITableViewData } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - // TODO could compute the length based on length of quantities.botanaVoice, plantStroller, nodeVoices, etc. + // TODO: could compute the length based on length of quantities.botanaVoice, plantStroller, nodeVoices, etc. // or continue showing all products, even if quantity is 0. the screen looks more full this way return 4 // products.count } diff --git a/EmpowerPlant/EmpowerPlantViewController.swift b/EmpowerPlant/EmpowerPlantViewController.swift index 11bd85b..529d899 100644 --- a/EmpowerPlant/EmpowerPlantViewController.swift +++ b/EmpowerPlant/EmpowerPlantViewController.swift @@ -8,14 +8,15 @@ import UIKit import Sentry -class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { - +class EmpowerPlantViewController: UIViewController { + // CoreData database let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext let tableView: UITableView = { - let table = UITableView() + let table = UITableView(frame: .zero, style: .plain) table.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + table.translatesAutoresizingMaskIntoConstraints = false return table }() @@ -24,29 +25,40 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable override func viewDidLoad() { super.viewDidLoad() - SentrySDK.reportFullyDisplayed() - title = "Empower Plant" - + title = "Empower Plants" + self.view.addSubview(tableView) tableView.delegate = self tableView.dataSource = self - - // Comment this out and to see the green background and no data in the rows - tableView.frame = view.bounds + NSLayoutConstraint.activate([ + tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), + tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + ]) // Configures the nav bar buttons configureNavigationItems() - - /* TODO + + // ???: looks like this was already done? + /* TODO: implement: 1 get products from server (so we get http.client span) 2 check if any products in Core Data -> If Not -> insert the products from response into Core Data 3 get products from DB (so we get db.query span) and reload the table with this data */ - getAllProductsFromServer() +// getAllProductsFromServer() getAllProductsFromDb() readCurrentDirectory() + NotificationCenter.default.addObserver(forName: generatedDBItemsNotificationName, object: nil, queue: nil) { _ in + self.getAllProductsFromDb() + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + SentrySDK.reportFullyDisplayed() } func readCurrentDirectory() { @@ -58,7 +70,7 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable readDirectory(path: path) } } catch { - + // TODO: error } } @@ -77,28 +89,29 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable } } } catch { + // TODO: error } } func fibonacciSeries(num: Int) -> Int{ - // The value of 0th and 1st number of the fibonacci series are 0 and 1 - var n1 = 0 - var n2 = 1 - - // To store the result - var nR = 0 - // Adding two previous numbers to find ith number of the series - for _ in 0.. refresh table") + // ???: why is this executing so many times on load? + // !!!: because it is called from createProduct, which is called for each item in the response from the network request to get products from server. In general, it's better to use UITableView.insertRow(...) instead of UITableView.reloadData() when simply adding things to the table. DispatchQueue.main.async { self.tableView.reloadData() } } - +} + +// MARK: UITableViewDataSource +extension EmpowerPlantViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return products.count } @@ -293,32 +290,17 @@ class EmpowerPlantViewController: UIViewController, UITableViewDelegate, UITable return cell } + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return "\(products.count) items" + } +} + +// MARK: UITableViewDelegate +extension EmpowerPlantViewController: UITableViewDelegate { // Code that executes on Click'ing table row, adds the product item to shopping cart func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let product = products[indexPath.row] ShoppingCart.addProduct(product: product) } - - - // Don't deprecate this until major release of this demo - func updateProduct(product: Product, newTitle: String) { - product.title = newTitle - do { - try context.save() - } - catch { - - } - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ } diff --git a/EmpowerPlant/ListAppViewController.swift b/EmpowerPlant/ListAppViewController.swift index 475c26e..1a8c196 100644 --- a/EmpowerPlant/ListAppViewController.swift +++ b/EmpowerPlant/ListAppViewController.swift @@ -85,6 +85,7 @@ class ListAppViewController: UIViewController { // It contains all data but mutations only influence the event being sent scope.setTag(value: "value", key: "myTag") } + // TODO: error } } @@ -253,4 +254,53 @@ class ListAppViewController: UIViewController { @IBAction func close(_ sender: Any) { SentrySDK.close() } + + @IBAction func generateDBEntities(_ sender: Any) { + let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext + let totalItems = 1_000_000 + + let batches = 1_000 + let itemsPerBatch = totalItems / batches + + DispatchQueue.global(qos: .utility).async { + for i in 0.. 'https://github.com/getsentry/sentry-cocoa.git', :tag => '8.10.0' + pod 'SwiftMessages' end diff --git a/upload-symbols.sh b/upload-symbols.sh index 1dc2e35..b540b8a 100755 --- a/upload-symbols.sh +++ b/upload-symbols.sh @@ -33,11 +33,7 @@ if which sentry-cli >/dev/null; then exit 1 fi - ERROR=$(sentry-cli upload-dif --force-foreground --include-sources --log-level debug -o $SENTRY_ORG -p $SENTRY_PROJECT --auth-token $SENTRY_AUTH_TOKEN "$DWARF_DSYM_FOLDER_PATH" ) - if [ ! $? -eq 0 ]; then - echo "warning: sentry-cli - $ERROR" - exit 1 - fi +# sentry-cli upload-dif --force-foreground --include-sources -o $SENTRY_ORG -p $SENTRY_PROJECT --auth-token $SENTRY_AUTH_TOKEN "$DWARF_DSYM_FOLDER_PATH" else echo "error: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases" exit 1 From 74cc3e16714358061d396ada8e1f77de07e8224c Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 11 Oct 2023 16:26:25 -0800 Subject: [PATCH 9/9] make db gen/wipe accessible from main screen action sheet and alert --- EmpowerPlant/Base.lproj/Main.storyboard | 26 +---- EmpowerPlant/EmpowerPlantViewController.swift | 99 ++++++++++++++++--- EmpowerPlant/ListAppViewController.swift | 49 --------- EmpowerPlant/Product+CoreDataProperties.swift | 4 +- EmpowerPlant/Utils.swift | 2 +- 5 files changed, 90 insertions(+), 90 deletions(-) diff --git a/EmpowerPlant/Base.lproj/Main.storyboard b/EmpowerPlant/Base.lproj/Main.storyboard index 6482efd..b34a9f7 100644 --- a/EmpowerPlant/Base.lproj/Main.storyboard +++ b/EmpowerPlant/Base.lproj/Main.storyboard @@ -135,7 +135,7 @@ - + - - - diff --git a/EmpowerPlant/EmpowerPlantViewController.swift b/EmpowerPlant/EmpowerPlantViewController.swift index 529d899..a9c09bd 100644 --- a/EmpowerPlant/EmpowerPlantViewController.swift +++ b/EmpowerPlant/EmpowerPlantViewController.swift @@ -47,11 +47,11 @@ class EmpowerPlantViewController: UIViewController { 3 get products from DB (so we get db.query span) and reload the table with this data */ -// getAllProductsFromServer() + getAllProductsFromServer() getAllProductsFromDb() readCurrentDirectory() - NotificationCenter.default.addObserver(forName: generatedDBItemsNotificationName, object: nil, queue: nil) { _ in + NotificationCenter.default.addObserver(forName: modifiedDBNotificationName, object: nil, queue: nil) { _ in self.getAllProductsFromDb() } } @@ -162,12 +162,76 @@ class EmpowerPlantViewController: UIViewController { self.navigationItem.rightBarButtonItem?.accessibilityIdentifier = "Cart" //self.navigationItem.rightBarButtonItem?.badgeValue = "\(1)" - self.navigationItem.leftBarButtonItem = UIBarButtonItem( + self.navigationItem.leftBarButtonItems = [UIBarButtonItem( image: UIImage(systemName: "ellipsis"), style: .plain, target: self, - action: #selector(goToListApp) // clearDb - ) + action: #selector(goToListApp) + ), UIBarButtonItem(title: "DB", style: .plain, target: self, action: #selector(dbActions))] + } + + @objc func dbActions() { + let actionSheet = UIAlertController(title: "Database actions", message: nil, preferredStyle: .actionSheet) + actionSheet.addAction(UIAlertAction(title: "Generate items", style: .default, handler: { _ in + self.generateDBItems() + })) + actionSheet.addAction(UIAlertAction(title: "Clear DB", style: .default, handler: { _ in + wipeDB() + NotificationCenter.default.post(name: modifiedDBNotificationName, object: nil) + })) + actionSheet.addAction(UIAlertAction(title: "Cancel", style: .destructive)) + present(actionSheet, animated: true) + } + + func generateDBItems() { + let defaultTotalItems = 100_000 + let alert = UIAlertController(title: "Add items", message: nil, preferredStyle: .alert) + + var numberOfItemsTextField: UITextField? + alert.addTextField { textfield in + textfield.placeholder = "Number of items (default: \(defaultTotalItems))" + textfield.keyboardType = .numberPad + numberOfItemsTextField = textfield + } + alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in + var totalItems = (numberOfItemsTextField?.text as? NSString)?.integerValue ?? defaultTotalItems + if totalItems == 0 { + totalItems = defaultTotalItems + } + var itemsPerBatch = 1_000 + let batches = totalItems / itemsPerBatch + + let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext + DispatchQueue.global(qos: .utility).async { + for i in 0.. 0 { + operations.append(saveOp) + OperationQueue.main.addOperations(operations, waitUntilFinished: false) } } } else { diff --git a/EmpowerPlant/ListAppViewController.swift b/EmpowerPlant/ListAppViewController.swift index 1a8c196..fec1bea 100644 --- a/EmpowerPlant/ListAppViewController.swift +++ b/EmpowerPlant/ListAppViewController.swift @@ -254,53 +254,4 @@ class ListAppViewController: UIViewController { @IBAction func close(_ sender: Any) { SentrySDK.close() } - - @IBAction func generateDBEntities(_ sender: Any) { - let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext - let totalItems = 1_000_000 - - let batches = 1_000 - let itemsPerBatch = totalItems / batches - - DispatchQueue.global(qos: .utility).async { - for i in 0.. NSFetchRequest { - return NSFetchRequest(entityName: "Product") + let fr = NSFetchRequest(entityName: "Product") + fr.sortDescriptors = [.init(key: "title", ascending: true)] + return fr } // @NSManaged public var text: String? diff --git a/EmpowerPlant/Utils.swift b/EmpowerPlant/Utils.swift index 157d2c0..0c01399 100644 --- a/EmpowerPlant/Utils.swift +++ b/EmpowerPlant/Utils.swift @@ -7,7 +7,7 @@ import UIKit -public let generatedDBItemsNotificationName = Notification.Name("io.sentry.empowerplants.newly-generated-db-items-available") +public let modifiedDBNotificationName = Notification.Name("io.sentry.empowerplants.newly-generated-db-items-available") public func wipeDB() { guard let url = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.persistentStoreCoordinator.persistentStores.first?.url else {