Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.

Post

Replies

Boosts

Views

Activity

ShieldConfiguration does not update when token is moved from one store to another (while app in foreground)
Hello fellow Screen Time Fans! I am encountering a strange problem since I started working with the Screen Time framework, and I don’t know what I’m doing wrong: Imagine the app has two ManagedSettingsStores: one to block apps during work hours (let’s say from 9am to 5pm) and one to block apps in the evening (let’s say from 5:30pm till midnight). Imagine, the user has blocked Instagram in both. When the user has Instagram open at 4:59pm it shows the Block during Work Hours Shield (so far, so good). At 5pm, the shield is removed, and the user can use Instagram. Then, at 5:30 the a shield is activated again: this time, the Instagram token is added to the evening store. However, there is no new ShieldConfiguration requested from the ShieldConfigurationDataSource. Instead, the previous shield from the work hour block is re-used and shown. To me, it appears that the Framework does not request new shields, when the token is moved from one store to another while the app remains in foreground. The Shield is only re-rendered when the user closes the shielded app and re-opens it. This is really confusing behavior and I would like to fix it. Did anyone here encounter something similar, and has a suggestion or workaround? My feedback is also documented in FB14237883.
1
0
191
3w
Setting tint for widget snapshot tests iOS 18
We have widget snapshot tests using XCTest as shown below: func testHomeWidgetView() { let widgetView = HomeWidgetView( state: .done, text: "All done!" ).frame(width: 170, height: 170) assertSnapshot(matching: widgetView, as: .image) } } Is it possible to apply a tint to the widgets in snapshot tests like a user can from their home screen in iOS 18? We'd like to capture snapshots of our widget while tinted via the home screen.
1
2
182
Oct ’24
Issue with Message Filter Extension service?
My server that backs my Message Filter Extension stopped receiving messages last night. I thought maybe I had broken something in the iOS code, even though I hadn't touched any of the logic related to filtering. So I rolled back my code to a previous version that was definitely working in both test and production and ran it on my test device, setting a breakpoint on the first line of the func handle(_ queryRequest: ILMessageFilterQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterQueryResponse) -> Void) method in the extension. When sending a message to it from an unknown number, the breakpoint is never even hit. To ensure it was somehow not my code, I started a new blank app and added the Message Filter Extension target. Running it on my test device, it also doesn't ever hit the breakpoint. Is there some Apple service involved in determining whether to send unknown sender messages to Message Filter Extensions that might be down. Maybe it's a beta issue? I'm on iOS 18.1 Beta 4. But it seems odd that all of my users' devices would be encountering a beta-related issue at essentially the same time.
2
0
216
Oct ’24
AppDependcy in Widgets Extension
I am trying to get Controls working using AppIntents. My Intents make use of @Dependency, which get set up during application launch using AppDependencyManager.shared.add { ... }. When the app has been launched, my Controls work fine. However, when the app gets killed using the app switcher or by the system, my Controls cease to work. Checking in Console.app, I found the following: PROGRAMMING ERROR: Failed to retrieve dependency of type {my dependency}. Please register your dependency with AppDependencyManager before performing a dependent intent. My intents use openAppWhenRun = true, so I don't understand why the dependencies are not registered when running the Intent. Alternatively, I would like to know how to register AppDependencies in a Widgets Extension.
0
0
137
3w
App Clip card can be opened by tapping universal link or custom links?
Can the App Clip card be invoked by tapping on a link (not a default appclip link) which is shared through message box or whatsApp chat or Email? I gone through the reference of App Clip Card invocation from scanning QR code, App Clip Code, NFC Tag, Safari smart banner, default App Clip links and link presentation framework. But I didn't find any reference or documentation that custom links will invoke App Clip Card or won't invoke App Clip Card. So, need reference if possible that App Clip card be invoked by tapping on a custom link which is shared through whatsApp chat or message box or Email.
0
0
114
3w
"AVSpeechSynthesisVoice" choppy at start.
So, I'm trying to create my own text-to-speech setup. Problem I'm having is whenever I do a test run, the speech gets a bit choppy at the start kind of skipping over maybe a word or a few characters. A few details: I've essentially built a separate class for handling the speech events. AVSpeechSynthesizer is set up as a private variable for the class so I don't expect deallocation to be the issue. Especially since it's a problem at the start. I've got a queue set up for what it's worth so that shouldn't be a problem. I'd appreciate any advice.
2
0
147
3w
Non Optional AppIntent Param
After building my app with Xcode 16 beta 6 I'm getting this warning in my AppIntents. Encountered a non-optional type for parameter: computer. Conformance to the following AppIntent protocols requires all parameter types to be optional: AppIntents.WidgetConfigurationIntent, AppIntents.ControlConfigurationIntent The intent looks something like this struct WakeUp: AppIntent, WidgetConfigurationIntent, PredictableIntent { @Parameter(title: "intent.param.computer", requestValueDialog:"intent.param.request_dialog.computer") var computer: ComputerEntity init(computer: ComputerEntity) { self.computer = computer } init() { } public static var parameterSummary: some ParameterSummary { Summary("Wake Up \(\.$computer)") } static var predictionConfiguration: some IntentPredictionConfiguration { IntentPrediction(parameters: (\.$computer)) { computer in DisplayRepresentation( title: "Wake Up \(computer)" ) } } @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { } } According to the docs though specifying optional is how we say if the value is required or not. https://developer.apple.com/documentation/appintents/adding-parameters-to-an-app-intent#Make-a-parameter-optional-or-required So is this warning accurate? If so, how do I specify that a parameter is required by the intent now?
2
7
479
Sep ’24
BadDeviceToken Error in Live Activities
Hello everyone, I’m currently receiving feedback from clients in a production environment who are encountering a BadDeviceToken error with Live Activities, which is preventing their states from updating. However, for other clients, the token is working fine and everything functions as expected. I’m collaborating with the back-end developers to gather more information about this issue, but the only log message we’re seeing is: Failed to send a push, APNS reported an error: BadDeviceToken I would greatly appreciate it if anyone could provide some insight or information on how to resolve this issue.
2
0
139
3w
Spotlight App shortcut can't refresh when refresh the AppEntity
I have encountered a problem about AppEntity and AppIntent shortcut. Here is what i have done. I created some shortcuts use AppShortcutsProvider. Each shortcut created by AppEntity. I search my app name in spotlight, so these shortcut can be shown in the spotlight. I don't click the shortcut and back to home screen. Then I delete these shortcuts by modify the Entity.defaultQuery and call AppShortcutsProvider.updateAppShortcutParameters() Going back to the spotlight, I can see my previous query and result. When I clicked the shortcut, I got an error WFBackgroundShortcutRunnerErrorDomain Should the spotlight result need to be refreshed when i come back to it?
2
0
205
Oct ’24
Siri not picking up app intent
Hello, I have written the following app intent and I can access it via shortcuts. But I can't get Siri to pick it up. I want it to have a dynamic book title (which could be anything) so that the user can say "Add (bookname) to my (app name). I need it to work for ios 17.1 onwards. I have added siri as a capability for my ios app. import AppIntents struct AddBookToReadingListIntent: AppIntent { static var title: LocalizedStringResource = "Add my Book" @Parameter(title: "Book Title", requestValueDialog: "What's the title of the book you want to add?") var bookTitle: String static var parameterSummary: some ParameterSummary { Summary("Add my '\(\.$bookTitle)'") } func perform() async throws -> some IntentResult & ReturnsValue<String> { return .result(value: "Added '\(bookTitle)' to your app") } } struct AppShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: AddBookToReadingListIntent(), phrases: [ "Add \(\.$bookTitle) in \(.applicationName)" ], shortTitle: "Add Book to app name", systemImageName: "book" ) } }
2
0
199
Oct ’24
App Intents is not able to start an outgoing call with CallKit when the app is backgrounded
I am currently working on integrating an app with Siri, adding support for starting VOIP calls and sending messages. Although it is understood it is recommended to use SiriKit for calling and messaging, I would like to allow users to select a profile to use for calling. As far as I am aware the notion of selecting a profile to call from is not something SiriKit supports, therefore, it was decided to go with App Intents to allow for more control over the parameters utilized to start calls. After integrating VOIP calling with App Intents, I noticed CallKit is not able to start calls when the App Intent is invoked from the background. I get the following error: Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)” This seems to correspond to the CXErrorCodeRequestTransactionError invalidAction. This error only happens when the intent is invoked from the background. Changing the App Intent property openAppWhenRun to true solves the issue as it brings the app to foreground before running the intent. However, I would like to support starting calls from the background to avoid making users unlock their phones prior to starting a call with Siri to make it a truly hands-free experience. I suspect the desired behavior is possible, most likely with SiriKit, as some famous VOIP calling apps (i.e. WhatsApp, Messenger, etc) exhibit the behavior I described. However, is there any way to start calls from the background with App Intents? Or is the desired behavior something exclusive to SiriKit? I have pasted three code snippets below that can replicate the issue. At the moment I am on Xcode Version 15.3, macOS Sonoma 14.6.1, and testing on iOS 16.6.1 To demonstrate the issue I have created the following CXProviderDelegate: class CallManager: NSObject, CXProviderDelegate { func startCall() { let callKitProvider = CXProvider(configuration: CXProviderConfiguration()) callKitProvider.setDelegate(self, queue: nil) let callKitController = CXCallController() let recipient = CXHandle(type: .generic, value: "Demo Outgoing Call") let uuid = UUID() let startCallAction = CXStartCallAction(call: uuid, handle: recipient) let transaction = CXTransaction(action: startCallAction) callKitController.request(transaction) { error in if let error { print(error) } else { print("no errors") } } callKitProvider.reportOutgoingCall(with: uuid, connectedAt: nil) } func providerDidReset(_ provider: CXProvider) { // no-op, not required to demonstrate the issue } } Then, I have a UIViewController that is the only screen of this example app: class ViewController: UIViewController { @IBOutlet weak var startCallButton: UIButton! override func viewDidLoad() { super.viewDidLoad() startCallButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) } @objc func buttonTapped() { let manager = CallManager() manager.startCall() } } As for app intents, I put together a very simple intent to trigger the start of an outgoing call: struct StartCall: AppIntent { static var title: LocalizedStringResource = "Start Call" static var openAppWhenRun = false func perform() async throws -> some IntentResult { let manager = CallManager() manager.startCall() return .result() } } When the UIViewController is presented and I tap the button to start a call I see the green call banner appear and "no errors" is printed to the console as intended. However, when I open the Shortcuts app and run the app intent, the green banner does not appear and the message Error Domain=com.apple.CallKit.error.requesttransaction Code=6 "(null)” is printed to the console.
1
0
175
Oct ’24
Deep/universal links not working in ios with edge broser
Deeplinks in our Mobile (native) application work fine from email clients such as Gmail and Outlook with a default browser such as Safari. If the app is already installed, clicking the link launches it. However, when we click on the same link from Outlook email with the default browser, Edge, it opens directly in the browser, because any external links in Outlook email route through safe links, which prevents deep linking to the APP. The current behavior is as follows: When Safari is the default browser, the process works seamlessly, and the app opens directly. outlook->deep link pressed -> redirect to safari ->opens the app if already installed However, when Microsoft Edge is set as the default browser, it opens the App Store link in a popover, with an option to open the app if installed. outlook->deep link pressed -> redirect to Edge->opens the app store inside edge even app already installed Note : outlook is enforcing safe link policies and also App protection policies. I would like to achieve the same behavior with Microsoft Edge as with Safari, where the app opens directly rather than redirecting to the App Store. Is there a specific configuration or workaround to ensure that Microsoft Edge, when set as the default browser, opens the app directly instead of redirecting to the App Store? Any insights or suggestions would be greatly appreciated. I am expecting that this safe link works the same as works with a safari in iOS Devices. I have also tried this - https://learn.microsoft.com/en-us/mem/intune/apps/app-protection-policy-settings-ios#exempt-universal-links but not working I'd appreciate it if you could assist me with this matter as soon as possible. How to handle deep links in Outlook when using a default browser like Edge
0
0
149
3w
@IntentParameterDependency Always Returns nil in iOS 18
The following code works perfectly fine in iOS 17, where I can retrieve the desired dependency value through @IntentParameterDependency as expected. However, in iOS 18, addTransaction always returns nil. struct CategoryEntityQuery: EntityStringQuery { @Dependency private var persistentController: PersistentController @IntentParameterDependency<AddTransactionIntent>( \.$categoryType ) var addTransaction func entities(matching string: String) async throws -> [CategoryEnitity] { guard let addTransaction else { return [] } // ... } func entities(for identifiers: [CategoryEnitity.ID]) async throws -> [CategoryEnitity] { guard let addTransaction else { return [] } // ... } func suggestedEntities() async throws -> [CategoryEnitity] { guard let addTransaction else { return [] } // ... } } Has anyone else encountered the same issue? Any insights or potential workarounds would be greatly appreciated. iOS: 18.0 (22A3354) Xcode 16.0 (16A242d)
2
2
365
Sep ’24
Screen Time API - Device Activity Report
I need some assistance with the Screen Time API’s DeviceActivityReport extension. I know the extension is sandboxed but I need the data inside my app. Jomo is currently doing this so it’s not impossible. I see they’re saying it’s an estimate which is about 5 - 10 off of the actual screen time, but how are they doing this? Any attempt to store the screen time data inside some sort of database or UserDefaults always fails of course due to the sandbox. Any advice would be greatly appreciated!
0
0
172
3w
Difficulty blocking and scheduling with the Screen Time API
Hello, I'm currently facing some technical difficulties in implementing features related to application restrictions using the ScreenTime API. In our app, we allow users to set up restrictions for specific apps and app categories, with scheduled times and days (for example, Mondays and Thursdays, from 2pm to 5pm). The blocking sessions must run independently and simultaneously, allowing different sets of applications to be restricted at different times. However, I ran into two main problems: 1. Applying restrictions in the DeviceActivityMonitor extension: Although I can enable and disable restrictions, I haven't found an effective way to apply multiple FamilyActivitySelections directly in the DeviceActivityMonitor extension. The extension has to manage different blocking sessions independently, restricting different sets of applications and categories simultaneously or separately. I would like to know if it is possible to transmit this list of selected applications via UserDefaults or CoreData to the extension in order to facilitate this integra To better illustrate, here is a snippet of the code I am using: import Foundation import FamilyControls import ManagedSettings import DeviceActivity class AppBlockManager: ObservableObject { private let store = ManagedSettingsStore() private let center = DeviceActivityCenter() @Published var activitySelection: FamilyActivitySelection private var activityName: DeviceActivityName private var schedule: DeviceActivitySchedule init(selection: FamilyActivitySelection, activityName: DeviceActivityName, schedule: DeviceActivitySchedule) { self.activitySelection = selection self.activityName = activityName self.schedule = schedule } func startBlock() { do { try center.startMonitoring(activityName, during: schedule) if let applications = activitySelection.applications.isEmpty ? nil : activitySelection.applicationTokens { store.shield.applications = applications } if let categories = activitySelection.categories.isEmpty ? nil : activitySelection.categoryTokens { store.shield.applicationCategories = ShieldSettings .ActivityCategoryPolicy .specific(categories) store.shield.webDomainCategories = ShieldSettings .ActivityCategoryPolicy .specific(categories) } if let webDomains = activitySelection.webDomains.isEmpty ? nil : activitySelection.webDomainTokens { store.shield.webDomains = webDomains } } catch { print("Error starting monitoring: \(error)") } } func stopBlock() { store.shield.applications = nil store.shield.webDomains = nil store.shield.applicationCategories = nil store.shield.webDomainCategories = nil center.stopMonitoring([activityName]) } } Currently, this AppBlockManager is part of the main app target, not within the DeviceActivityMonitor extension, which is currently empty. With this configuration, I can only have one blocking session active at a time, and when it is deactivated, all restrictions are removed. I tried using different ManagedSettingsStore instances, each named individually, but without success. 2. Problems with scheduling restrictions: Currently, when setting up scheduled monitoring via DeviceActivitySchedule, the restrictions are activated immediately, ignoring the specific times scheduled (e.g. starting at 2pm and ending at 5pm). I need the schedule to work correctly, applying the restrictions only during the defined periods. Alternatively, I've considered running a background task that checks whether active sessions (up to a maximum of 3) should apply the restrictions at that time, but I'm still looking for a more suitable solution. In view of these challenges, I would like some guidance on the following points: What would be the best way to configure the DeviceActivityMonitor extension to receive and apply different FamilyActivitySelections, ensuring that the blocking sessions are independent and can run simultaneously? Is there a recommended approach to ensure that restrictions scheduled via DeviceActivitySchedule are applied and removed according to the times and days defined by the user, ensuring that applications are restricted only during the scheduled periods?
0
1
208
3w
WeatherKit moonPhase:full is skipped
HI there, when requesting the daily forecast via the WeatherKit REST API, I found out that under certain circumstances the moon phase full is skipped. Example from Japan (working): { "forecastDaily": { "name": "DailyForecast", "metadata": { "attributionURL": "https://developer.apple.com/weatherkit/data-source-attribution/", "expireTime": "2024-10-21T15:16:10Z", "latitude": 35.650, "longitude": 139.840, "readTime": "2024-10-21T14:16:10Z", "reportedTime": "2024-10-21T12:00:37Z", "units": "m", "version": 1, "sourceType": "modeled" }, "days": [ ..., { "forecastStart": "2024-10-16T15:00:00Z", "forecastEnd": "2024-10-17T15:00:00Z", "conditionCode": "MostlyCloudy", "maxUvIndex": 4, "moonPhase": "waxingGibbous", "moonrise": "2024-10-17T07:47:26Z", "moonset": "2024-10-16T20:09:01Z", "precipitationAmount": 0.09, "precipitationChance": 0.43, "precipitationType": "rain", ... "windSpeedMax": 16.03, }, { "forecastStart": "2024-10-17T15:00:00Z", "forecastEnd": "2024-10-18T15:00:00Z", "conditionCode": "Rain", "maxUvIndex": 4, "moonPhase": "full", "moonrise": "2024-10-18T08:20:34Z", "moonset": "2024-10-17T21:24:49Z", "precipitationAmount": 4.83, "precipitationChance": 0.83, "precipitationType": "rain", ... "windSpeedMax": 15.57, }, { "forecastStart": "2024-10-18T15:00:00Z", "forecastEnd": "2024-10-19T15:00:00Z", "conditionCode": "Drizzle", "maxUvIndex": 5, "moonPhase": "waningGibbous", "moonrise": "2024-10-19T08:58:43Z", "moonset": "2024-10-18T22:42:03Z", "precipitationAmount": 3.85, "precipitationChance": 0.76, ... "windSpeedMax": 28.81, }, ... ] } } Example from Germany where the fullmoon is skipped: { "forecastDaily": { "name": "DailyForecast", "metadata": { "attributionURL": "https://developer.apple.com/weatherkit/data-source-attribution/", "expireTime": "2024-10-21T15:41:17Z", "latitude": 47.760, "longitude": 12.650, "readTime": "2024-10-21T14:41:17Z", "reportedTime": "2024-10-21T13:00:37Z", "units": "m", "version": 1, "sourceType": "modeled" }, "days": [ { "forecastStart": "2024-10-16T22:00:00Z", "forecastEnd": "2024-10-17T22:00:00Z", "conditionCode": "MostlyClear", "maxUvIndex": 3, "moonPhase": "waxingGibbous", "moonrise": "2024-10-17T16:07:30Z", "moonset": "2024-10-17T05:19:30Z", "precipitationAmount": 0.0, ... "windSpeedMax": 8.23, }, { "forecastStart": "2024-10-17T22:00:00Z", "forecastEnd": "2024-10-18T22:00:00Z", "conditionCode": "Cloudy", "maxUvIndex": 2, "moonPhase": "waningGibbous", "moonrise": "2024-10-18T16:30:22Z", "moonset": "2024-10-18T06:48:39Z", "precipitationAmount": 1.17, ... "windSpeedMax": 8.73, }, { "forecastStart": "2024-10-18T22:00:00Z", "forecastEnd": "2024-10-19T22:00:00Z", "conditionCode": "Cloudy", "maxUvIndex": 2, "moonPhase": "waningGibbous", "moonrise": "2024-10-19T16:59:14Z", "moonset": "2024-10-19T08:18:33Z", "precipitationAmount": 0.02, ... "windSpeedMax": 7.16, }, ] } } As you can see here https://moon.nasa.gov/moon-observation/daily-moon-guide/?intent=011#1729171951907::0:: and on several other sites specialized on the lunar cycle) on 2024-10-17 should be shown full moon. I know this error is probably because the forecast starts prior to the full moon phase and ends after it but customers don't care about technicalities. They see that there is a full moon missing and complain to me. And they are right. Can you fix this somehow? For example, if a DailyForecast spans the majority of a full moon this Day is marked as full moon. Another question: Are you considering providing a moonPhase attribute to the "currentWeather" dataset? That would be the best option. (At least for me :))
1
2
122
3w