Post

Replies

Boosts

Views

Activity

Reply to New Vision API
I've just done a prototype app for recognising text from photos of product labels, using the new Vision API with Xcode 16.2 beta 2 and images from an iPad Pro (2020 M1 chip) and iPhone 15 Pro. The recognition is very accurate, even correctly recognising neatly handwritten label text. These are the settings I'm using: ocrRequest.recognitionLevel = .accurate ocrRequest.usesLanguageCorrection = true ocrRequest.automaticallyDetectsLanguage = true Some of the labels are very small (1cm x 2cm), but even then with the iPhone camera on x2 or x3 and macro-mode the recognition is near perfect. Regards, Michaela
3w
Reply to Heic format image incompatibility issue
I don't know if it's related, but in a test project I'm using to try out text recognition from photos Xcode does not recognise .HEIC as a valid extension for images in the Asset catalogue. Changing (in Finder's Get Info) the extension to .heic (i.e. lowercase) solves the issue. A device/app interoperability issue methinks..... Images from my iPhone and iPad all have the .HEIC extension, which (of course) doesn't get changed to lowercase on Airdrop to my Mac. I'm using Xcode 16.2 Beta 2 with iOS devices on 18.2 and Mac on 15.2. Regards, Michaela
Nov ’24
Reply to SwiftUI FormView not updating after value creation/updating in a SubView
UPDATE: The problem with this sample (Test) code was with the way I passed the CoreData Entity to the Form. My in-development app updates the NSManaged vars correctly and recomputes the derived data, but there's a problem (yet to be resolved) in getting all those back into the Form for display, something to do with the way I've generalised the Form's processing. Apologies for any inconvenience. Regards, Michaela
Nov ’24
Reply to iOS 17.2 Simulator Error Xcode
I was having the same problem with Xcode 15 betas on an M1MacMini with Ventura betas. For me it seems to have been a space problem: Developer files on the main HD kept ballooning to over 60GB on an already constrained machine. When I moved Xcode to an external USB-C SSD and set Locations in Xcode Settings to that drive - the download and registration worked fine, plus there's more free space for other uses.
Dec ’23
Reply to How to fix NSCloudKitMirroringDelegate unhandled exception after faulty model change
Fixed the problem by these steps: Created a backup of the MacMini's persistent store, using code for a temporary persistent store coordinator.migratePersistentStore. Also created CSV file backups of all objects of all entities (as a fall-back if the migrate didn't work correctly). Deleted all objects of all Entities in the MacMini persistent store. Waited for deletions (Step 3) to be propagated to the CloudKit container. Checked the CloudKit container (Web Console) and manually deleted any Entity Objects not deleted by Steps 3 and 4 - there were quite a few. Restored the MacMini persistent store by code for: a persistentStoreCoordinator.destroyPersistentStore of the original MacMini store b persistentStoreCoordinator.addPersistentStore based on the backup store c persistentStoreCoordinator.migratePersistentStore from the backup to the "new" store (step 6 b) Waited for the "new store" Entity Objects to be propagated to the CloudKit container. Checked the CloudKit container (Web Console) - all good Checked that additions/deletions worked correctly whether on the MacMini or via The CloudKit Console - all good. Somewhat of a pain, but necessary given the amount of data and its complexity. An advantage is that I now have backup and restore functions in the file menu of the MacMini App. Regards, Michaela
Oct ’23
Reply to How to fix NSCloudKitMirroringDelegate unhandled exception after faulty model change
I've created a test app, with CoreData records synced via CloudKit. Records created on the Mac get synced to the iPad Pro. It's a very simple app, just Listing records from a FetchedResults. I then Reset development environment in the CloudKit console Web Portal, with both devices' app closed. This Reset, of course, deleted all records, schema and coredata.cloudkit zone from the Development environment. On restarting each app, CoreData records on both devices remained and the app worked correctly, fetching existing records and also recreated the CloudKit zone, schema and records. Thereafter new records on the Mac were correctly synced to the iPad Pro. I'll do some more testing, making the test app more complex with the sort of relationship I was trying to achieve in the messed-up app, then might be bold enough to use this approach to fix the problem app. However, it would still be better if I could somehow purge the CloudKit update queue - although I can't be sure that the schema is correct anyway: probably not. Regards, Michaela
Oct ’23
Reply to preload core data from cloud kit
This what I use in my apps (during the initialisation of my Data Controller): self.mainContainer = { let container = NSPersistentCloudKitContainer(name: "MyDataModel") container.loadPersistentStores(completionHandler: { description, error in if let error = error { print("**** ERROR loading persistent store \(error)") } //Setup auto merge of Cloudkit data container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy //Set the Query generation to .current. for dynamically updating views from Cloudkit try? container.viewContext.setQueryGenerationFrom(.current) }) return container }() The key lines are the 2 below //Setup auto merge. Also, be sure to have enabled Remote Notifications in Background modes of the App's Signing and Capabilities. I hope this helps. Regards, Michaela
Apr ’23
Reply to ECG Anomaly Dataset
If the app referenced by Claude31 is available to you/your university, then this would be the way to go in getting data from a variety of volunteer subjects who have an ECG capable Apple Watch and an iPhone. However, if you're a developer with an Apple Watch & iPhone and/or have colleagues with them and you're only collecting your data (or your colleagues') , then a fairly simple Swift App will suffice to get the raw data, which are a timestamp and voltage. The Apple documentation is https://developer.apple.com/documentation/healthkit/hkelectrocardiogram I use my such app to create a CSV file, which I then import to an ECG Viewer. I use this setup quite frequently, as well as data from a Polar H10 ECG app, to monitor my various arrhythmias and provide data to EDs as required (unfortunately, too often for comfort!). Regards, Michaela
Mar ’23
Reply to Scrollable Plot Area
I'm about to implement a similar use-case: I already chart data for the current week, current month, quarter and year, as selected by a picker. The key to the paging solution is to replace the chart dataset (series), when the user swipes left or right, with the appropriate next or previous set (period) of data. In my case, I'll use my existing Coredata fetch function with startDate, endDate parameters - called from within the Gesture Recogniser. We'll need a var with the currently displayed period in order to set the required retrieval startDate, endDate. And there also needs be a @State var to trigger a chart redraw once the new dataset has been returned (maybe the dataset itself or the period or a flag). Or, the period and dataset creation/recreation can be handled in the DataModel (my usual approach) with @Published vars. This should work fine for discrete periods (i.e. week, month, etc), but continuous scrolling over a large dataset is a different proposition. I've done it with a SwiftUI Canvas app, but it was hard to get smooth scrolling with many fetches from a large database. I'll post more when my paging solution works (or doesn't......). Regards, Michaela
Sep ’22
Reply to Will AFib History be an open data source?
I can confirm that current versions of iOS and Watch OS (14+ and 7+) provide access to ECG classifications (e.g. Atrial Fibrillation). The relevant code is: let ecgType = HKObjectType.electrocardiogramType() let ecgPredicate = HKQuery.predicateForElectrocardiograms(classification: .atrialFibrillation) let ecgQuery = HKSampleQuery(sampleType: ecgType,                                      predicate: ecgPredicate,                                      limit: HKObjectQueryNoLimit,                                      sortDescriptors: nil) { (query, samples, error) in ............... If you then need to access the actual ECG Voltages (500 measurements per second, I think) for a sample: let voltageQuery = HKElectrocardiogramQuery(ecgSample) { (query, result) in             switch(result) {             case .measurement(let measurement):                 if let voltageQuantity = measurement.quantity(for: .appleWatchSimilarToLeadI) { // process each voltage measurement ........... } // Execute the query.         healthStore.execute(voltageQuery) Regards, Michaela
Aug ’22
Reply to Combine Duplicate Items in an Array
Create a function in your PersistenceController class to detect and remove duplicates: func deDup(_ items: [Item]) { let context = container.viewContext var prevItem : Item? for item in items { if prevItem == nil { prevItem = item continue } if item.name! == prevItem!.name! { // this is a duplicate prevItem!.value += item.value context.delete(item) } else { prevItem = item } } contextSave() } Change you combineItemsButton action to be Button(action:{ //combine duplicates here             persistence.deDup(items)             items = persistence.getItems() I have not tested this within any app (i.e. just written the code here) and have done it in a hurry, but I think that the logic is correct. I hope it works!!!! Regards, Michaela
Jun ’22
Reply to Calendar with Correlating Data. Please Help!!!
Main Struct @main struct TestForWeagleWeagleApp: App {     let persistence = PersistenceController.shared  // initiates the CoreData stack     var body: some Scene {         WindowGroup {             ContentView()         }     } } Persistence import Foundation import CoreData class PersistenceController : ObservableObject {     static let shared = PersistenceController()     let container: NSPersistentContainer     init(inMemory: Bool = false) {         container = NSPersistentContainer(name: "Test")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })         container.viewContext.automaticallyMergesChangesFromParent = true     }     func addItem(date: Date){         let context = container.viewContext         let item = Item(context: context)         item.timestamp = date         item.word = nil         contextSave()     }     func addToItem(item: Item) {         item.word = "Test"         contextSave()     }     func removeFromItem(item: Item){         item.word = nil         contextSave()     }     func contextSave() {         let context = container.viewContext         if context.hasChanges {             do {                 try context.save()                 self.objectWillChange.send()             } catch {                 print("**** ERROR: Unable to save context \(error)")             }         }     }     func getItemsFor(_ date: Date) -> [Item] {         let context = container.viewContext         var request = NSFetchRequest<Item>()         request = Item.fetchRequest()         //request.fetchLimit = 1         request.entity = NSEntityDescription.entity(forEntityName: "Item", in: context)         request.predicate = NSPredicate(format: "timestamp >= %@ and timestamp <= %@", Calendar.current.startOfDay(for: date) as CVarArg, Calendar.current.startOfDay(for: date).addingTimeInterval(86399.0) as CVarArg)         do {             let items = try context.fetch(request)             if items.count == 0 { return []}                   return items.sorted(by: {$0.timestamp! > $1.timestamp!})         } catch {             print("**** ERROR: items fetch failed \(error)")             return []         }     } } ContentView import SwiftUI struct ContentView: View {     @ObservedObject var persistence = PersistenceController.shared     @State private var items = PersistenceController.shared.getItemsFor(Date())     @State private var date = Date.now     var body: some View {         NavigationView{                 VStack {                     DatePicker("Calendar", selection: $date, in: Date.now...,displayedComponents: [.date])                     .datePickerStyle(.graphical)                     .onAppear(perform: {                         if items.isEmpty {                             persistence.addItem(date: date)                             items = persistence.getItemsFor(date)                         }                     })                 if !(items.isEmpty) {                     PlannedMealsView(item: items.last!)                     Spacer()                 }             }                  .navigationBarTitle("My Planner")         }         .onChange(of: date){ newDate in             items = persistence.getItemsFor(newDate)             if items.isEmpty {                 persistence.addItem(date: newDate)                 items = persistence.getItemsFor(newDate)             }         }     }     func getTitle(date: Date)->String{         let formatter = DateFormatter()         formatter.dateStyle = .medium         return formatter.string(from: date)     } } PerformanceMealsView import SwiftUI struct PlannedMealsView: View {     @ObservedObject var persistence = PersistenceController.shared     var item: Item     @State private var forceRefresh : Bool = false     var body: some View {         VStack{             Text(item.timestamp!, style: .date)                 .font(.title2)                 .bold()             Section("Word"){                 if(item.word != nil){                     HStack{                         Spacer()                         Text(item.word!)                         Spacer()                         Button(action: {                             persistence.removeFromItem(item: item)                         }){                             Image(systemName: "minus.circle").bold()                         }                         Spacer()                     }                 } else {                     Button(action: {                         persistence.addToItem(item: item)                         forceRefresh.toggle()                     }){                         Image(systemName: "plus.circle").bold()                             .padding(.vertical, 10)                             .padding(.horizontal, 20)                     }                 }             }             Spacer()         }     } } This works on my system, except that (probably unwisely) I used my development environment, which uses beta Xcode and beta iOS. I couldn't backwards convert the Xcode project (new format) to test on my production equipment without redoing everything. I hope this works for you too!!! Regards, Michaela
Jun ’22
Reply to Calendar with Correlating Data. Please Help!!!
As per my comment on your other post, I've had a good look at your code and make the following observations: Your PersistenceController is a struct and you reference it a number of times in your Views e.g. PersistenceController().removeFromItem(item: items[0], context: managedObjContext), which means that your CoreData stack is being recreated each time (ie numerous copies) - with unpredictable results. The PersistenceController needs to be an ObservableObject class singleton, i.e. with let shared =PersistenceController(), and then refer to the shared instance. the date that you set from the calendar picker is the time of picking, i.e. date and time, so your predicate, which also uses the current date and time, will probably never match. I assume that you're looking for an item (or items) that occur on a selected day (date only, not time). The predicate therefore needs to search for a timestamp that occurs within the start and end of a day (date). It's not clear where, or if, you created the @StateObject for the @Environment(\.managedObjectContext) var managedObjContext, without which the @FetchedResults are unlikely to work (plus the problem of multiple CoreData stack instances). When the above issues are resolved, there remains the problem of getting SwiftUI to re-execute the Fetch on a change of date i.e. a dynamic predicate with immediate effect. I've created a working version of your code, but without the FetchRequest and Results in ContentView: I use a fetch function in PersistenceController to return Items with a timestamp that falls within the specified day (midnight to 11:59:59pm). When the selected date changes, the function gets called to return the item(s) for that date. That's the item (or item array) that then gets used in your existing code. I'll post the full solution tomorrow morning (about 00:00 UTC Sunday 26 June ) after I've further tested it. Regards, Michaela
Jun ’22
Reply to View References
I haven’t done this in UIKit, but in SwiftUI I pass the entity to the second view, modify the attribute on that entity, then perform a Context save of the Entity (by using a function in my CodeData stack). CoreData entities are classes and therefore get passed by reference. Having modified and saved the Entity + attribute, you then probably need to force a view refresh, which can be tricky depending on your implementation of CoreData in your views and whether UIKit or SwiftUI. regards, Michaela
Jun ’22