Post

Replies

Boosts

Views

Activity

Reply to Safari not opening on macOS big sur
There's a bug related to the Start page, as set in Safari Preferences. To fix: use a link in some other app (e.g. Notes) to invoke Safari, rather than from the Launchpad or Finder in Safari, Preferences, General - change the HomePage url to something you know works, e.g. the link you used from Notes. Set "New Windows Open With" and "New Tabs Open With" to "HomePage" This worked for me. Regards, Michaela
Jul ’20
Reply to Safari in Big Sur
This didn't work for me. What did was to: use a link in some other app (e.g. Notes) to invoke Safari, rather than from the Launchpad or Finder in Safari, Preferences, General - change the HomePage url to something you know works, e.g. the link you used from Notes. Set "New Windows Open With" and "New Tabs Open With" to "HomePage" Thereafter Safari opens from Launchpad without crashing. Regards, Michaela
Jul ’20
Reply to Sharing a Boolean variable in SwiftUI between views
I've run into problems in the past with getting SwiftUI Views to detect changes from ObservableObject classes with Published variables. My solution is to use Combine in the publishing class (your GettingData), creating a specific Publisher, e.g. let statusUpdate = PassthroughSubject<(Bool), Never>(). When doneGettingData changes, e..g. in your didSet, issue a call to statusUpdate.send(doneGettingData) In your UIView, have .onReceive(shared.statusUpdate, perform: {  doneGettingData in ... do something with doneGettingData status change } You'll probably have to toggle a @State private var to force the View to update. Don't forget to import Combine. Also, as an alternative approach, you could try changing let shared in your UIView to @ObservedObject var shared - but I haven’t thought through your code in detail so not sure. I hope this helps: good luck. Michaela. PS: The advantage of the Combine method is that if a class makes several data changes, you can do just one send at an appropriate point to get UIView to show all of the changes, rather than the UIView doing updates one by one - which can be annoying to the user.
Sep ’20
Reply to SwiftUI iOS 14 MapKit Annotation Tap Gesture (didSelect)
iOS 14 SwiftUI Map() is missing a lot of the functionality of MKMapView. I just tried to create a "pure" SwiftUI app, with Map(), for converting a sequence of taps on a map into a polyline. TapGesture does not report the View location of the tap, nor does Map() have access to the convert to coordinate method. I too was reluctant to return to the UIViewRepresentable approach. In developing SwiftUI apps I always use a singleton DataModel, as an ObservableObject with Published properties. For my recent mapping app I therefore added MKMapViewDelegate and UIGestureRecognizerDelegate to the DataModel class and created a mapView = MKMapView() in the model, then added all necessary delegate functions. All processing of taps, polyline points etc occur in the model. I often use Combine's PassthroughSubject (though not in this case, wasn't needed) to trigger some behaviour in a SwiftUI View, via .onReceive. The UIViewRepresentable is then as simple as: struct MapView: UIViewRepresentable {     func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {         return DataModel.shared.mapView     }     func updateUIView(_ view: MKMapView, context: UIViewRepresentableContext<MapView>) {         view.setRegion(DataModel.shared.region, animated: true)     } } There's no need for a Coordinator, and panning, zooming etc all work fine along with the Tap recogniser. I realise that this is not what you're seeking, but the approach might be useful given the limitations of Map(). Regards, Michaela
Nov ’20
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
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
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
Mar ’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
Mar ’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.
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
Jul ’21