Ah, I've just discovered why my Transaction entity was giving problems: SwiftUI uses a Transaction struct to pass an animation between views in a view hierarchy. It's too late to change my entity name, and the above mentioned solution works anyway.
Cheers, Michaela
Post
Replies
Boosts
Views
Activity
It's great to hear from another coder from the card-punch era: there's a few of us around on here, but not many. I'm currently rewriting my budgeting/expense management app, from Swift/SQLite to SwiftUI & CoreData-CloudKit to allow multi-platform syncing. Thanks for the feedback. Regards, Michaela
Could you explain a bit more about what you're trying to achieve and what you mean by "inclusive help"? Also, are you able to say more about @MasEmpathyCommunity (assuming that it is a community-based programme)?
I'm a retired IT Professional (50+ years experience) and still developing apps, using latest Apple technology, but mainly for my own / family / friends use, or for a worthwhile public app, e.g. symptom tracker for a rare cancer. I don't claim to be an Apple expert, but can usually figure things out as needs be from reading this forum and Stack Overflow.
I'd be happy to assist you, if I'm able, once I've better understood your needs.
Best wishes, Michaela (in Australia)
The problem is in the initialisation of your @Published var pp: [[CGFloat]] = [[0]], because this is initialising pp with a single 0 value - to which you append tuples in updateP. Changing it to @Published var pp = [[CGFloat]]() fixes the problem.
If you want to start with [0,0], then change the initialisation of pp to be @Published var pp: [[CGFloat]] = [[0,0]]
Best wishes and regards, Michaela
Here's an example of ForEach with an enum:
The enum
enum WordLength : Int, CaseIterable {
case random = 0
case five = 5
case six = 6
case seven = 7
}
The ForEach
ForEach(WordLength.allCases,id:\.self) { wordLength in
Text(String(describing:wordLength).capitalized)
}
The enum doesn't have to be Int: I've taken this example from an app that uses the numeric value (Int) in processing, whereas in the ForEach it's for showing Picker options as text (string).
Regards, Michaela
Here's a working example for Mac OS (but should be the same for iOS except for the URL setup for the incoming csv file).
The csv test data are in 3 columns, with headers of "Name", "Position" and "Score" - so as to test data types of String, Integer and Double.
The Data Model (ViewModel)
import Foundation
import TabularData
class DataModel {
static let shared = DataModel()
@Published var dataTable: DataFrame?
init() {
getData()
}
func getData() {
var url: URL?
do {
url = try FileManager.default.url(for: FileManager.SearchPathDirectory.downloadsDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: true)
} catch{
print("Failed to get Downsloads URL \(error)")
return
}
let csvOptions = CSVReadingOptions(hasHeaderRow: true, ignoresEmptyLines: true, delimiter: ",")
let fileURL = url?.appendingPathComponent("TestCSV.csv")
do {
dataTable = try DataFrame(contentsOfCSVFile: fileURL!,columns: nil, rows: nil, types: ["Name":CSVType.string,"Position":CSVType.integer,"Score":CSVType.double], options: csvOptions)
} catch {
print("Failed to get load datatable from CSV \(error)")
return
}
}
}
extension DataFrame.Rows : RandomAccessCollection {
}
SwiftUI ContentView
import SwiftUI
import TabularData
struct ContentView: View {
var model = DataModel.shared
var body: some View {
List(model.dataTable!.rows,id:\.index) { row in
HStack{
Text(row["Name"] as! String)
Text(String(row["Position"] as! Int))
Text(String(row["Score"] as! Double))
}
}
}
}
With forced unwrap (as!) the app will crash if the processed column does not contain the correct type, so I tend to use a function that checks and returns a string - which then gets used in the View:
// in Data Model
func columnToString(_ column: Any) -> String {
if let str = column as? String {
return str
}
if let int = column as? Int {
return String(int)
}
if let double = column as? Double {
return String(double)
}
return ""
}
// a row in ContentView
Text(model.columnToString(row["Position"] as Any))
I hope this helps. Regards, Michaela
There are 4 methods for phone/watch communication under Watch Connectivity, each related to the amount/type of data and the required immediacy of transfer. Now that I better understand what you're doing, my perception is that your use-case needs the sendMessage method, which you seem to have done, rather than transferUserInfo (which is simpler to implement and more reliable, but less immediate).
However there are some potential issues with sendMessage from the watch to the phone if the phone is not reachable or not active, as reported here (as recently as 3 months ago). Advances in iOS over the last year or two have improved the ability for background processing (in essence, when the app is not active on screen) - but I haven't had cause to delve into it and so can't offer advice. I suggest, if you haven't already done so, that you test your watch/phone/autopilot communication with your phone (phone app) in various states - to ensure that the watch's commands to the autopilot are reliably implemented.
Best wishes and regards, Michaela
It's still happening with Xcode Version 13.3 beta 2 (13E5095k) and Monterey 12.3 Beta (21E5227a).
I tried running a working iPad app under Mac Catalyst with MKMapView as UIViewRepresentable. It also shows the messages AND then crashes with __validateTextureView:557: failed assertion `Texture View Validationtexture usage (0x05) doesn't specify MTLTextureUsagePixelFormatView (0x10)'_.
My understanding is that MapView uses Metal for its rendering, hence the messages re syncing screen refresh, and requires the MLTextureUsagePixelFormatView to be set. However, since everything works fine on iOS (iPad), it appears that there's a problem with the Mac OS and Catalyst implementation of MapView under SwiftUI.
I tried adding (blindly) MetalLayer and Metal Device instances and required settings to my code, but to no avail. When I get some spare time I'll collect all the evidence and submit a bug report.
Cheers,
Michaela
I helped with a similar question a few months ago in this post https://developer.apple.com/forums/thread/689484?answerId=686982022#686982022
If your iPhone app is in SwiftUI, the sample code I provided should form a workable basis for your use case. Note that the phone app and watch app both use a Data Model (i.e. standalone class, not a SwiftUI View) for communicating with each other and processing the data. The models also provide and collect data from their respective SwiftUI Views, i.e the user presses a button or enters data on the device in a SwiftUI view, which then gets collected by the Data Model and processed and/or transmitted to the other device.
In my sample code (above) the user wanted to transmit count data from the watch: in your case you (presumably) want to transmit a command to the phone. You can do this by having a common struct e.g named Command, in each Data Model, that describes the command that you're passing. Then in the transferUserInfo (i.e. send) and didReceiveUserInfo (receive) functions you use an instance of Command to send/receive your navigation instructions. Having received the Command from the watch, your iPhone Data Model would then send the appropriate instructions to the BLE autopilot.
My original post is a very simplified version of watch connectivity and there are circumstances where things can get more complicated. I therefore advise that, at some point, you read the documentation link I provided earlier.
I hope that this helps. Regards, Michaela
PS - it's also possible for the watch to communicate directly with your BLE navigation device, using the same code as on the iPhone (except for the UI, given the watch's small screen): but maybe that's another question/answer for another day.
Second PS - depending on how the iPhone app and device are configured, the phone app might not on-send the command to the autopilot immediately - which could be problematic!!! My suggestion therefore is that your watch app communicates directly with the autopilot, as per the phone app.
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.
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
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
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
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).
It's still happening with latest betas (Xcode 13E5095K and Mac OS 21E5212f). Also, I still haven't got NSClickGestureRecognizer to work, so it does seem related to the log messages or their underlying problem.