Post

Replies

Boosts

Views

Activity

Clarification needed regarding requirements for geofencing
In my app, I am using geofencing to perform an action when the user enter or leaves a specified location. The geofencing (CLMonitor) is active permanently, and should work across multiple app sessions or after the device is restarted. It should also work after the app was minimized or terminated. This worked perfectly with iOS 17 and prior, but with iOS 18, things changed. As soon as iOS 18 dropped, users were informing me that the app does no longer perform the entry/exit action reliably (without me making any changes to the app). Most of the times, events are missed entirely. Sometimes, after the user opens or resumes the app, duplicate events are delivered and/or events with the current time instead of the correct time of entry/exit. I am making sure that the app has the "Always" location permission before geofencing is enabled The gefocence radius is between 20 and 500m, but even with the max. radius specified, the geofencing is unreliable For the same user and geofence, the entry/exit event is delivered occasionally, but not always I am currently not using CLLocationManager.allowsBackgroundLocationUpdates (even though it's documented as "Apps that receive location updates when running in the background must include the UIBackgroundModes key (with the location value) in their app’s Info.plist file") because it wasn't necessary on iOS 17 and in my tests, using it didn't yield any improvements In my search for what could have caused this change, I found this WWDC video about location authorization: . It appears that with iOS 18, it is now required to have an active CLServiceSession to ensure that location updates are delivered to my app. Even though the video is long (and I've watched it multiple times), some things are still unclear. For example, the docs state: If your app actively receives and processes location updates and terminates, it should restart those APIs upon launch in order to continue receiving updates. Also, in the video it is stated that: ... So your job, ..., is to make sure that your process launch logic knows what features it has been tasked with pursuing, and re-takes session objects... But on the other hand it's also said that: you can only start holding one (a CLServiceSession) when your app is in the foreground and also ... CLMonitor.events won’t yield results when it is not in use, unless a session which was started in the foreground, .... To summarize my questions, for the geofencing to work as described above: when exactly do I need to create a CLServiceSession if the app is launched into the backgorund? Immediately in the applicationDidFinishLaunching method, even though the app is still in the background (applicationState is background)? Or later on, when the app is opened again by the user, e.g. in applicationDidBecomeActive (and applicationState is active)? do I need to specify the background mode capability as noted in the Handling location updates in the background article? do I need to create a CLBackgroundActivitySession as noted in the Handling location updates in the background article? does it matter, which of the four initializer methods I am using to create the CLServiceSession (with CLServiceSessionAuthorizationRequirementAlways)? does it matter if I specify NSLocationRequireExplicitServiceSession in the Info.plist or not when I already do ensure that the app has the "Always" location permission when the feature is being enabled Does a CLServiceSession last indefinitely and should it only be invalidated once the user disables the feature?
1
4
353
Nov ’24
NSMenuToolbarItem not showing first menu item when using NSMenuDelegate
I am using NSMenuToolbarItem to show a drop-down menu in my NSToolbar. This works as expected when creating an NSMenu beforehand and assign it to the menu property of NSMenuToolbarItem. However, my menu needs to be built dynamically when the user clicks the dropdown button. To do that, I am using NSMenuDelegate. When creating the menu in the menuNeedsUpdate of the delegate, the first menu item isn't shown to the user. Why? Menu when using delegate: Menu when pre-assigning menu: I also cannot just add a placeholder menu item at the start of the NSMenuToolbarItem as all menu items do show in the overflow menu. Example code: import Cocoa class AppDelegate: NSObject, NSApplicationDelegate, NSToolbarDelegate, NSMenuDelegate { var window: NSWindow! func applicationDidFinishLaunching(_ aNotification: Notification) { window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 400, height: 300), styleMask: [.titled, .closable, .resizable], backing: .buffered, defer: false) window.makeKeyAndOrderFront(nil) let toolbar = NSToolbar(identifier: "MainToolbar") toolbar.delegate = self window.toolbar = toolbar } func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [NSToolbarItem.Identifier("item1"), NSToolbarItem.Identifier("item2")] } func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [NSToolbarItem.Identifier("item1"), NSToolbarItem.Identifier("item2")] } func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar: Bool) -> NSToolbarItem? { let item = NSMenuToolbarItem(itemIdentifier: itemIdentifier) if itemIdentifier == NSToolbarItem.Identifier("item1") { let menu = NSMenu() fillMenuWithItems(menu) item.menu = menu } else if itemIdentifier == NSToolbarItem.Identifier("item2") { item.menu = NSMenu() item.menu.delegate = self } return item } func menuNeedsUpdate(_ menu: NSMenu) { menu.removeAllItems() fillMenuWithItems(menu) } func fillMenuWithItems(_ menu: NSMenu) { menu.addItem(NSMenuItem(title: "Option 1", action: nil, keyEquivalent: "")) menu.addItem(NSMenuItem(title: "Option 2", action: nil, keyEquivalent: "")) } }
1
0
271
Sep ’24
iOS 18 rotate animation not working by layer for custom icon
I have created a custom logo in the SFSymbols 6.1 app and exported it as SVG. clock.arrow.trianglehead.clockwise.rotate.90.svg The icon consists of two layers and I want them to animate by layer. This works for the wiggle effect (the two layers are moving independently), but not for the rotate effect (the logo moves as a whole). Why? This is my code: let imageView = UIImageView() imageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(scale: .large) imageView.image = UIImage(named: "clock.arrow.trianglehead.clockwise.rotate.90", in: nil, with: nil) imageView.translatesAutoresizingMaskIntoConstraints = false let imageView2 = UIImageView() imageView2.preferredSymbolConfiguration = UIImage.SymbolConfiguration(scale: .large) imageView2.image = UIImage(named: "clock.arrow.trianglehead.clockwise.rotate.90", in: nil, with: nil) imageView2.translatesAutoresizingMaskIntoConstraints = false imageView.addSymbolEffect(.rotate.byLayer, options: .repeat(.continuous)); imageView2.addSymbolEffect(.wiggle.byLayer, options: .repeat(.continuous)); view.addSubview(imageView) view.addSubview(imageView2) NSLayoutConstraint.activate([ imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor), imageView2.centerXAnchor.constraint(equalTo: view.centerXAnchor), imageView2.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 40), ])
2
0
427
Sep ’24
NSTextList not rendering on MacOS
In the WWDC22 talk "What's new in TextKit and text views" (https://developer.apple.com/videos/play/wwdc2022/10090?time=408), it was announced (at minute 6:45) that TextKit 2 & NSTextList is supposed to be working on both UIKit and AppKit. While NSTextLists are correctly rendering on iOS, they are not working on macOS. The paragraphs aren't inset and the numbers/bullets do not render in front of the list items. Any help? let textView = NSTextView(frame: self.view.bounds) textView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(textView) let safeArea = view.safeAreaLayoutGuide NSLayoutConstraint.activate([ textView.topAnchor.constraint(equalTo: safeArea.topAnchor), textView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor), textView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor), textView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor) ]) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.textLists = [NSTextList(markerFormat: NSTextList.MarkerFormat("{decimal}."), options: 0)] let attributedText = NSMutableAttributedString("Item 1\nItem 2\nItem 3\nItem 4f") attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length)) textView.textStorage?.setAttributedString(attributedText)
6
0
392
Sep ’24
[AppKit] CNPropertyNotFetchedException when using CNContactFormatter on CNContact retrieved from CNContactPicker
I am using CNContactPicker (with "CNContactKey.PostalAddresses" as "displayedKeys") to allow users to pick a contact + postal address. Upon selection, I am retrieving the postal address using CNPostalAddressFormatter - this works without problems. However, when trying to retrieve the contact name using CNContactFormatter, this only works when the contact type is "Person". When it is "company", the app crashes with "CNPropertyNotFetchedException Reason: A property was not requested when contact was fetched" (because the formatter attempts to access "organizationName", which it apparently can't. There also doesn't seem to be a way to "retrieve" this information without having to request contacts permissions manually. The same code (just using CNContactPickerViewController, but also without requesting contacts permissions) works without issue on iOS.
2
0
628
Jun ’24
REST API returns 404 error for October 29th
In my app I retrieve the daily weather for a location via the REST API. This works fine in almost all cases. However, for October 29th (yesterday) it returns a 404 Not Found error. This is an example request that fails: https://weatherkit.apple.com/api/v1/weather/en/48.1582271841334/11.5418646663957?dataSets=forecastDaily&dailyStart=2023-10-28T22:00:00.0000000Z&dailyEnd=2023-10-29T22:00:00.0000000Z I have also tried to append the timezone &timezone=Europe/Berlin - but the problem persists. Maybe it has to do with the fact that Daylight saving time ended yesterday at the location requested (Germany)? It certainly looks like a bug. Where can I report it if this isn't the right place to do so?
0
0
456
Oct ’23
CKQueryOperation returns new cursor, but no results, eventually rejects requests
In my app, I am using CloudKit and one thing I need to do is to query all records of a certain record type. I am creating a CKQueryOperation with the record type I am interested in, leaving the rest to the defaults basically (resultsLimit, desiredKeys, qualityOfService etc). Most times, the app does not return any results at all, but does return a queryCursor, indicating there are more results to fetch. So I add a new CKQueryOperation with a CKQuery created with the returned queryCursor. But the same thing happens again (most of the times) - no results (or maybe a single result) and a new queryCursor. This goes on and on until either all results are returned (which usually is not the case) or CloudKit errors out with "Server rejected the request" (perhaps for rate-limiting reasons?). The same behaviour can be observed when using the CloudKit web API, and it doesn't seem to matter what values I set for resultsLimit, desiredKeys, qualityOfService etc... So, what am I doing wrong? How can I query all records of a record type without errors?
2
0
493
Sep ’23
Get weather for given date on given location (REST API)
My goal ist to get the weather of a given day (e.g. 2022-01-14) and a given location (without knowing the timezone) using the "forecastDaily" dataSet. The API does not seem to accept timestamps without date information so I use UTC midnight as dailyStart (e.g. "2022-01-14T00:00:00Z") and dailyEnd (e.g. "2022-01-15T00:00:00Z") . This seems to work for most regions, like with the ones with a positive longitude, but the more I go west, the API returns 2 days in the "days" list of "forecastDaily" and in some extremes (like Hawaii) the wrong (previous) day is returned from the API. Specific example: dailyStart: 2022-01-14T00:00:00Z dailyEnd: 2022-01-15T00:00:00Z request weather for Kiribati (UTC+14): returns day with forecastStart 2022-01-13T10:00:00Z -> this is what I want request weather for Hawaii (UTC-10): returns day with forecastStart 2022-01-13T10:00:00Z -> this is not what I want, as this is the weather for 2022-01-13 and not 2022-01-14 As Hawaii and Kiribati are about the same longitude I also cannot make any assumptions based on longitude alone. As the API doesn't return the local timezone (as the DarkSky API has been doing) I also cannot use this info that. I would have to have full knowledge of where the timezone boundaries are. The core problem is that I have to provide a "timezoned" parameter for dailyStart and dailyEnd. I would want to provide just the date, like "2022-01-14". Is there no easy way to get the weather for any place on earth solely based on the date?
1
1
899
Jan ’23