Post

Replies

Boosts

Views

Activity

Reply to How do I measure/get a heartbeat at thousands of seconds from Apple Watch?
Sorry, in my previous answer I didn't explicitly answer your question about the Watch providing complete data for heartbeats for thousands of seconds. Some time ago I looked at the heartbeat data in the Health repository on the phone (as reported from the Watch) and more recently at heartbeat data in workouts on the phone: there appears to be no "complete" dataset, only periodic (every few seconds) data points. This perhaps is understandable given that for an hour's exercise there could be 5-10 thousand heartbeats, requiring a lot of storage and processing on the Watch. This lack of complete data, and my observed inaccuracies in the Watch's heart rate reports, is why I can't reply on the watch data and must use a third-party heart monitor chest strap. In my case, with arrhythmia issues, my phone app, using realtime input from the chest strap, can alert me during a run when arrhythmia stars to occur and/or when my safe heart rate maximum has been exceeded. I'm also able to then share the data with my medical advisors. Once again, best wishes and regards, Michaela PS - I gather that you're in Europe (Czech Republic?): in which case I wish you well in these troubled times.
Mar ’22
Reply to Packages only seem to work for the first platform?
I'm working with a number of multi-platform apps that have local packages, and sometimes have your problem because I'd forgotten key steps. For each Target (platform), build the Library (package) before building the main product of that target (e.g. MacOS). You will probably have to rebuild the Library (package) after any Clean Build Folder. For each target, at the General tab of the Target explorer, make sure you've included the library (package output) in the Frameworks, Libraries and Embedded Content. Each target needs to have the Library specified, not just once at the project level. I've had problems with local packages when I've included the source(s) in my app's project, rather than having the package in a separate directory and included in the app project. Best wishes and regards, Michaela
Mar ’22
Reply to How do I measure/get a heartbeat at thousands of seconds from Apple Watch?
Heart rate data from my Apple Watch Series 4 are very inaccurate, as was the case on my earlier watches. For a while now I've been using the Watch's Workout app while running and comparing that with workout data from an iPhone app that uses a Polar H10 heart monitor strap. For example, on yesterday's run the Watch recorded an average heart rate of 148 bpm, whereas the Polar device data was for 123 - which is almost certainly accurate (I'm 72 with heart issues so don't go very fast). I have several years' worth of data from monitor straps (starting with Garmin), so I know what my heart rate should look like: it's understandably declined over the years as I've aged. Most heart monitor straps record every heartbeat and transmit its time interval as milliseconds, along with the current heart rate (actually a moving average of the intervals in bpm) to a tethered smart device. Most modern straps use Bluetooth LE and therefore can be read by the Watch Workout app, your app and/or an iPhone app. Best wishes and regards, Michaela
Mar ’22
Reply to Core Data+CloudKit:No record on CloudKit Dashboard
CloudKit records from CoreData integration are stored in a special zone (com.apple.coredata.zone) not in _defaultZone, which the CloudKit dashboard shows by default. Also, the dashboard is set by default to view the public database. So, make sure you've selected the correct database (public/private) and zone in order to view records. The "out-of-the-box" implementation of CoreData / CloudKit sync does not, and will not, store any records in the Public database. Also, CoreData record types (entities) and fields (attributes) in CloudKit have their CoreData model names preceded by CD_, e.g. a CoreData entity called Period with startTime and endTime attributes would appear in CloudKit's CoreData zone as CD_Period with CD_startTime and CD_endTime. I'm not sure what you mean with the iCloud account vs Development account. I find that running an app in debug mode in Xcode and accessing the CloudKit console also from Xcode (in "Signing & Capabilities") ensures that I'm looking at the correct CloudKit database. I hope this helps. Regards, Michaela
Feb ’22
Reply to Aggregate Data from Web Sites
I looked at the same sort of app related to COVID case alerts here in NSW, but decided to do it only for myself. Most websites have restrictions on the use/reuse of data - especially for commercial purposes. You would need to check each website that you use (or intent to) for their terms of use: such information is often hard to find and usually legally complex, e.g. in relation to jurisdictional coverage. I imagine that Apple would be cautious about allowing any app that could, or does, contravene copyright or data licensing agreements, otherwise they might face joint liability. Even if Apple were to approve your app, you would be wise to conduct a legal risk analysis of the data collection and aggregation process. Best wishes and regards, Michaela (PS, I spent 30 years as an IT Procurement and Contract Management specialist and had to deal with intellectual property and licensing issues many times).
Feb ’22
Reply to CoreData FetchRequest doesn't update view
I'm a tad tired after a long day's work (it's evening here in Oz) so I haven't really digested what you're doing. However, my first thought is whether you've created a @StateObject to allow your Environment managed object to respond to changes. I normally put the @StateObject in my SwiftUI app's main (App) scene, and then pass .environment(.managedObjectContext.... to whatever view(s) thereafter need it. This way the resulting views respond immediately to changes in the Managed Object, provided you've used the correct @Environment statement in those views (which you seem to have done). Good luck and best wishes, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Use CoreDate with swift
This solution is for a single platform (iOS) with no CloudKit synchronisation:  if you need the latter, then I can provide a sample but it’s a bit more complex.  I’m not sure how far you’ve got with using Coredata, so I’ve included all that’s necessary to get a solution working. If you’re creating a new project, in Xcode’s project options select SwiftUI interface, Swift language, but not Use Core Data: if you do, Xcode creates template code that differs from this solution and needs to be gotten rid of. Create your Xcode data model:  in this example, the model name is “BucketListModel” with 2 entities “BucketItem” and “CostItem”.  Create a one-to-many relationship between BucketItem and CostItem, with a one-to-one inverse of CostItem to BucketItem. NOTE: These one-to-many and inverse relationships are important in understanding some of the quirks of using CoreData with SwiftUI/Swift. While still in Xcode’s data model editor, select both entities (BucketItem and CostItem) then in the Inspector panel (right-hand side of screen) change the Codegen option from Class Definition to Manual/None. Then, still in Xcode’s data model editor, use Editor > Create NSManagedObject Subclass then follow the prompts to select both entities and generate code that goes into your project folder.  You should end up with 4 additional Swift files:  “CostItem+CoreDataClass”, “CostItem+CoreDataProperties”, “BucketItem+CoreDataClass”, “BucketItem+CoreDataProperties”. In Xcode, select the BucketItem+CoreDataProperties file and notice that there’s a property called “costItems” which is of type NSSet.  SwiftUI cannot use this in a List, so it must be converted into a Swift array.  Also, an NSSet is unordered, so it’s best to apply some default sort-order - doing so also creates a Swift array.  I created a computed property called costArray, which performs the sort and set conversion.  Note the other computed property, totalCost, which performs a reduce operation on the costItems.  This is an example of how you add functionality by extending the code in each entitiy’s class. Create a Swift file (e.g. called “DataModel”) with your (not Xcode's) DataModel class as per the sample below.  Key features of this class are:  ObservableObject, a singleton (only one instance in the app), loads and manages the Coredata stack, and publishes the bucketList. import Foundation import CoreData class DataModel : ObservableObject {     static let shared = DataModel()     let persistentContainer : NSPersistentContainer     @Published var bucketList = [BucketItem]() private init() {         self.persistentContainer = {             let container = NSPersistentContainer(name: "BucketListModel")             container.loadPersistentStores(completionHandler: { description, error in                 if let error = error {                     print("ERROR loading persistent store \(error)")                 }             })             return container         }()     }     func saveContext() {         let context = persistentContainer.viewContext         if context.hasChanges {             do {                 try context.save()             } catch {                 print("ERROR: Unable to save context")             }         }     }     func addCostItem(bucket: String,name: String,cost: Double) {         let costItem = CostItem(context: persistentContainer.viewContext)         costItem.costName = name         costItem.costAmount = cost         guard let thisBucketItem = getBucketItemFor(bucket) else { return }         thisBucketItem.addToCostItems(costItem)         saveContext()         bucketList = getBucketList()     }     func addBucketItem(name: String,priority: Int, cost: Double, location: String) {         let bucketItem = BucketItem(context: persistentContainer.viewContext)         bucketItem.name = name         bucketItem.priority = Int16(priority)         bucketItem.cost = cost         bucketItem.location = location         bucketItem.date = Date()         saveContext()         bucketList = getBucketList()     }          func getBucketItemFor(_ name: String) -> BucketItem? {         let context = persistentContainer.viewContext         var request = NSFetchRequest<BucketItem>()         request = BucketItem.fetchRequest()         request.fetchLimit = 1         request.entity = NSEntityDescription.entity(forEntityName: "BucketItem", in: context)         request.predicate = NSPredicate(format: "name == %@", name)         do {             let bucketItems = try context.fetch(request)             if bucketItems.count != 1 { return nil}             return bucketItems.first         } catch {             print("ERROR: course fetch failed \(error)")             return nil         }     }     func getBucketList() -> [BucketItem] {         var tempList = [BucketItem]()         let context = persistentContainer.viewContext         let request = NSFetchRequest<BucketItem>()         request.sortDescriptors = [NSSortDescriptor(keyPath: \BucketItem.priority, ascending: true)]         request.entity = NSEntityDescription.entity(forEntityName: "BucketItem", in: context)         do {             if !bucketList.isEmpty { bucketList.removeAll()}             tempList = try context.fetch(request)         } catch {             print("ERROR: fetch failed \(error)")         }         return tempList          }     func getCostTotal() -> Double {         var total = 0.0         let tempList = getBucketList()         total = tempList.reduce(0.0, {$0 + $1.cost})         return total     } }``
Sep ’21
Reply to Use CoreDate with swift
PART 2 of answer (had to split because of character limit) EXAMPLE of Coredata Class Properties generated by Xcode and added to by developer (me) import Foundation import CoreData extension BucketItem {     @nonobjc public class func fetchRequest() -> NSFetchRequest<BucketItem> {         return NSFetchRequest<BucketItem>(entityName: "BucketItem")     }     @NSManaged public var cost: Double     @NSManaged public var date: Date?     @NSManaged public var location: String?     @NSManaged public var name: String?     @NSManaged public var priority: Int16     @NSManaged public var costItems: NSSet? } // MARK: Generated accessors for costItems extension BucketItem {     @objc(addCostItemsObject:)     @NSManaged public func addToCostItems(_ value: CostItem)     @objc(removeCostItemsObject:)     @NSManaged public func removeFromCostItems(_ value: CostItem)     @objc(addCostItems:)     @NSManaged public func addToCostItems(_ values: NSSet)     @objc(removeCostItems:)     @NSManaged public func removeFromCostItems(_ values: NSSet)     // MARK: Developer Generated properties for costItems MUST be replaced if Xcode regenerates other code     public var costArray : [CostItem] {         if costItems == nil { return [CostItem]() }         return costItems?.sorted(by: {($0 as! CostItem).costAmount < ($1 as! CostItem).costAmount}) as! [CostItem]     }     public var totalCost : Double {         if costItems  == nil { return 0.0 }         return costItems?.reduce(0.0, {$0 + ($1 as! CostItem).costAmount}) ?? 0.0     } } extension BucketItem : Identifiable { } There are 3 ways of accessing the DataModel (and CoreData stack) within SwiftUI Views: With a @StateObject (e.g. in the main App view) definition and subsequent environment method @StateObject var persistenceController = DataModel.shared ..... ContentView()                 .environment(\.managedObjectContext, persistenceController.persistentContainer.viewContext) Reference to the data model as an ObservedObject. @ObservedObject var dataModel = DataModel.shared ... List(dataModel.getBucketList(), id:\.name) { item in Direct reference to DataModel properties and methods  DataModel.shared.addCostItem(bucket: "RTW Trip", name: "Lots", cost: 40000.0) Which to use depends on the need and the volatility/mutability of the data. I hope this helps.  Regards, Michaela
Sep ’21
Reply to Multi-platform CoreData synchronisation: deleting data from all devices except one?
This seems to be the way https://developer.apple.com/documentation/coredata/linking_data_between_two_core_data_stores, at least in the first part of the problem ( separate stores). I haven’t done the watch part yet because I’ve been importing historical records into the Mac’s raw data container from an old iOS app to make sure the historical concepts are feasible. I’m thinking of keeping raw data on the watch for a couple of weeks before deletion, but will send each session (as a batch) to CloudKit, then the Mac, after session completion. Cheers, Michaela
Sep ’21
Reply to Stuck downloading Big Sur
I had a similar problem a few weeks ago. It was because TimeMachine was set for automatic backups: when I set to Manual ( and disconnected the backup drive) the Big Sur download succeeded. Maybe this is your cause (and maybe not ☹️) Regards, Michaela
Topic: App & System Services SubTopic: Core OS Tags:
Sep ’21