Post

Replies

Boosts

Views

Activity

Reply to Vertical Accuracy Definition
Gualtier is correct. However, the CLLocation provided Vertical Accuracy is often itself wrong. I have tracks that have a constant claimed vertical accuracy of 3 metres, but I know that many points are 5 metres or more different from a known elevation. Furthermore, CLLocations from the iPhone/Watch Fitness app claim Vertical Accuracy of less than 1 metre, but have exactly the same errors (i.e. > 5 metres) as data from a 3rd-party iOS app using CoreLocation. When plotted, the elevation profiles are the same (and not as per reality), it's just that the WorkOut data have been "cleaned" and therefore have less variance. I have found that CMAltimeter provides far more consistent and accurate data (+/- a few centimetres). CLLocation.altitude is way too inaccurate, and inconsistently so, for me to be able to create meaningful running course profiles; whereas CMAltimeter data are usually very close to reality, with low variance (making programatic identification of slope segments easy). I have a chart of CMAltimeter vs CLLocation altitude comparisons, but I can't find a way of posting it in this answer. Regards, Michaela
Dec ’20
Reply to Altitude fusing GPS and barometer
I've wondered the same, having the need for accurate elevation profiles for running-workout courses. From my recent testing, it's clear that CoreLocation is pure GPS - and it's very inaccurate (sometimes > 5 metres different from the actual absolute or relative elevation). CMAltimeter provides consistently accurate data (+/- a few centimetres), with very little "noise" - thus making it easy to programmatically identify slope segments. Being barometer based, CMAltimeter is prone to rapidly changing weather events such as a thunderstorm or a passing front, so that any longer period workout (eg marathon) could see spurious altitude values. Regards, Michaela
Dec ’20
Reply to Is HomeKit Temperature Sensor Resolution ±0.5 °C ?
The HomeKit Accessory Protocol (HAP) specifies a step value of 0.1 Celsius for Current Temperature (with the actual value as a float), so the HomeKit app should be displaying your value correctly. It's strange that you're getting 0.5 intervals: maybe there's some Step interval being applied elsewhere (Homebridge?) or a numeric type conversion issue? Interestingly, HAP specifies a minimum value for Current Temperature as 0 degrees Celsius - which may have caused a few issues in Texas recently. Regards, Michaela
Topic: App & System Services SubTopic: General Tags:
Feb ’21
Reply to HomeKit framework capabilities regarding time based automations
I’ve just started a project to monitor BLE sensors, which are not HomeKit compatible nor bridgeable, and trigger HomeKit accessory actions based on time of day and/or sensor state. Sensor updates will be every few minutes (configurable). My approach is to have a “SensorServer” app (SwiftUI) running on an always-on HomeKit compatible device (Apple TV or Mac) that sends HomeKit characteristic.write commands to HomeKit accessories (e.g. power outlet), based on time and sensor state. These “automation” definitions will be in some form of persistent storage, under the control of the SensorServer admin user. You could perhaps use a similar approach and might not need persistent storage (I.e. database) if your automations are static and not numerous: you could hard code them in your app. The accessory statuses changed by your app will be promulgated to all users of the Apple Home app that are connected to your Home. i hope this helps. Regards, Michaela
Feb ’21
Reply to How to make a list with a filter field in SwiftUI on Mac
Now you mention it Mussau, I vaguely remember having problems with UUID as the List's ID in iOS apps. The integer ID approach (as per my example) works fine without specifically specifying the id: parameter in List - although sometimes the compiler complains in iOS if the View is complex, then I have to specify. It looks like the UUID situation might be a bug, unless it's because the UUID is automatically generated by the system whereas my Int isn't. Anyhow, well done! Good luck and best wishes, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’21
Reply to How to make a list with a filter field in SwiftUI on Mac
To make a List selectable, the binding must be to the id of the items, in your case UUID. So, you would need @State private var selectedItem: UUID? In MacOS, there's no Selection marker (as there is in iOS), so clicking on a row in a selectable list in MacOS highlights the row. At that point the ID of the row (Item) is in selectedItem as the UUID. To do anything further with the selected Item (row) you would need to retrieve it from the sourceList by filtering on the selected UUID. I normally create a sequential Integer ID, starting from 0, when setting up the source data for a list so that I can use that as an index to the source data, provided I don't ever delete any item(s) - otherwise I would have to filter on the integer ID. I also usually use a singleton, class based, data model that is an Observable Object with Published vars and perform all data processing in that model, with changes reflected in the SwiftUI views by a binding to the shared Data Model. For your example the SwiftUI View would be: *** In my example, the user can select an Item without searching, just by clicking on a row. struct ContentView: View {     @ObservedObject var dataModel = DataModel.shared     var body: some View {         VStack() {             TextField("Filter", text: $dataModel.searchString)             Spacer()             List(dataModel.filteredList, selection: $dataModel.selectedEntry) { entry in                 HStack{                     Text(entry.code)                     Text(entry.name)                     Text(entry.other)                 }             }             Text("Selected Item is " + String(dataModel.selectedEntry ?? -1)). // negative means no current selection         }     } } The Data Model would be: struct RegistryEntry: Identifiable, Hashable {     var id = 0     var code = ""     var name = ""     var other = "" } class DataModel : ObservableObject {     static let shared = DataModel()     var sourceList = [RegistryEntry]()     @Published var searchString = "" {         didSet {             if searchString == "" {                 filteredList = sourceList                 return             }             filteredList = sourceList.filter { $0.name.localizedCaseInsensitiveContains(searchString) }         }     }     @Published var selectedEntry : Int?     @Published var filteredList = [RegistryEntry]()     init() {       // set up sourceList by hardcoding or importing // then set initial filtered list to source list         filteredList = sourceList     } } Regards, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’21
Reply to TabularData Framework: DataFrame as a List in SwiftUI
Ah, fixed it :). All I needed to do was add protocol compliance in an extension for DataFrame.Rows extension DataFrame.Rows : RandomAccessCollection { }. Then use the index property of rows as the id in the SwiftUI ForEach (or List) with yourDataFrame.rows as the source, handling the optionals as required. Cheers, Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to Create Instance of class
products is created as an empty array of type ProductModel, I.e. no product (ProductModel) has yet been instantiated. You will need to look at the definition of ProductModel to see what is required for initiation. You can do this in Xcode (jump to Definition), or autocomplete will probably prompt for the required/available parameters.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to swift ui
Best to start at this Developer document https://developer.apple.com/documentation/swiftui When I started with SwiftUI, my biggest challenge was in rethinking state and data flow, i.e. creation and manipulation of data, which is now well covered here https://developer.apple.com/documentation/swiftui/state-and-data-flow Although SwiftUI has a lot of inbuilt management of state changes, for complex data models I now use Combine to control what gets published from the data model and when, picking up changes by an onReceive in SwiftUI views. To my mind, the key to SwiftUI is a well designed data model, where all data creation and manipulation is done in the model (using Swift) and SwiftUI only presents data, from a single source of truth data model, to the user. Where the user enters data in SwiftUI, this is handed off to the model, by bindings, for processing. Good luck! Michaela
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’21
Reply to Activity recognition using core motion
Here's some sample code using a Data Model and SwiftUI **** The Data Model import Foundation import CoreMotion class DataModel : ObservableObject {     var activityManager : CMMotionActivityManager?     @Published var activities = [CMMotionActivity] () // (remove the space before the ()     init() {         if !CMMotionActivityManager.isActivityAvailable() {             print("Activity Monitoring not available")             return         }         activityManager = CMMotionActivityManager()         if activityManager == nil {  // check just to be sure initialised OK             print("Unable to initialise Activity Manager")             return         }         activityManager!.startActivityUpdates(to: OperationQueue.main) { (motion) in             guard let newMotion = motion else { return }             self.activities.append(newMotion)         }     } } extension CMMotionActivity {     func activityString() -> String {         // returns a compound string of activities e.g. Stationary Automotive         var output = ""         if stationary { output = output + "Stationary "}         if walking { output = output + "Walking "}         if running { output = output + "Running "}         if automotive { output = output + "Automotive "}         if cycling { output = output + "Cycling "}         if unknown { output = output + "Unknown "}         return output     } } **** The Main App (if generated in Xcode 12+) import SwiftUI @main struct Activity_TrackerApp: App {     @StateObject var dataModel = DataModel()     var body: some Scene {         WindowGroup {             ContentView()                 .environmentObject(dataModel)         }     } } **** The Content View import SwiftUI struct ContentView: View {     @EnvironmentObject var dataModel: DataModel     var body: some View {         ScrollView {             ForEach(dataModel.activities, id:\.startDate) {activity in                 HStack{                     Text(activity.startDate, style: .date)                     Text(activity.startDate, style: .time)                     Text(activity.activityString())                 }             }         }     } } You must also add a Plist key for Privacy - Motion Usage Description and say why you're recording activity. This is a very rough UI, but it should get you started. You'll also need (??) to turn off monitoring at some point and deal with entering and exiting background mode. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Jul ’21
Reply to How to develop the server of app ?
I'm not sure if I've understood you correctly (maybe you're after App Store Server information), but here goes: SwiftUI apps typically consist of a number of Views (i.e. the User Interface) and a single Data Model, which handles all of the data processing logic. The Data Model might also interact with a server to store and/or retrieve data. One of my complex apps has servers for SQLite, iCloud, BlueTooth devices and Home Appliances. The Data Model handles all of these servers, consolidating data as required for use by the SwftUI View(s). The Data Model acts as the single point of truth throughout the app: all SwiftUI Views should normally get their UI output from the Data Model and provide UI input (e.g. keyboard input) to the Data Model for processing. SwiftUI monitors for changes to the Data Model, according to developer specified configuration, in order to update the relevant View(s). A simple example of this arrangement is in my answer to this post https://developer.apple.com/forums/thread/685018, which uses Core Motion data to report user activity. The @StateObject var dataModel = DataModel() line in the App View ensures that there's only one copy of dataModel throughout the app, provided conventions for .environmentObject(dataModel) are followed. This Developer document https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app describes how to manage Model Data. Regards, Michaela
Jul ’21
Reply to CreateML on iOS
As of iOS 15 (beta), CreateML can be used within an app to create (or replace) a model within the app, with access to prediction accuracy to determine whether the latest training improves on a previous model.  This requires Xcode 13 (beta) and Mac OS Monterey (beta).  There's also a new TabularData framework that works similarly to CreateML for data input (e.g. from CSV), but appears to have expanded features (not that I've explored them all). CreateML is a set of types and methods for ingesting data, preprocessing those data (e.g. filtering, mapping, transforming), then using the data for training models. Typically, a user would not be aware that these actions are taking place, so it's not, strictly speaking, a UI (i.e there's nothing on-screen). TabularData is an alternative to CreateML's ingestion and preprocessing features, although there are some annoying issues (beta??). I'm trying this out (e.g. time prediction) with a running app that I've developed over the years, and for which I have a lot of historical data. It makes sense to retrain the model after running a new course and also every few weeks as the user improves (or, in my case, degrades). Good luck and regards, Michaela
Topic: Machine Learning & AI SubTopic: General Tags:
Jul ’21
Reply to User Activity Recognition
With your activityManager (CMMotionActivityManager instance in your Data Model) do a query when an app is restarted ref https://developer.apple.com/documentation/coremotion/cmmotionactivitymanager/1615929-queryactivitystarting HOWEVER, only the last 7 days of activity are available - and you'd need to know when the app was terminated or suspended so as not to double count. It might also be possible to schedule a batch background task (e.g. at night) to run the query and place results in permanent data storage. Check out this reference https://developer.apple.com/documentation/backgroundtasks/choosing_background_strategies_for_your_app particularly"Wake Your App with a Background Push". I've never done this, only knowing about it from the documentation. Good luck and regards, Michaela
Topic: App & System Services SubTopic: Hardware Tags:
Jul ’21