Hi Devs,
I’ve created an app intent shortcut for our Best Buy app. This shortcut is visible on iOS 17.2 and later. However, I’ve marked it to support iOS 16+ as shown below:
import AppIntents
@available(iOS 16.0, *)
struct LaunchIntent: OpenIntent {
why we are not able to see shortcuts for iOS 16?
General
RSS for tagDelve 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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Currently, I am working on an iOS app with a Deployment Target set to iOS 15.0, and macOS 12.0. The app is allowed to run on Macs with Apple Silicon.
A customer with a Mac running macOS Monterey (12) is complaining that in the TestFlight app, they cannot install the app since it shows "Requires OS Update", even though the deployment target is smaller than the installed version of macOS 12.
Are there any specifications available on which macOS version is required in order to use iOS apps on Silicon Macs?
Hey, I’m having some issues with DeviceActivitySchedule and DeviceActivityMonitor. I want to create a schedule that blocks apps (by family control) when it starts. However, even when the schedule is supposed to start on this iPhone, nothing happens, and no logs are being recorded
main target:
// TestView_.swift
// Sloth
//
// Created by on 11/01/2025.
//
import SwiftUI
import DeviceActivity
import FamilyControls
import ManagedSettings
struct TestView_: View {
var body: some View {
VStack(spacing: 20) {
Text("Test DeviceActivityMonitor")
.font(.title)
Button("Start test mon") {
let now = Date()
let start = Calendar.current.date(byAdding: .minute, value: 2, to: now)!
let end = Calendar.current.date(byAdding: .minute, value: 20, to: now)!
print("thd")
DeviceScheduleTester().scheduleTestActivity(startDate: start, endDate: end)
}
}
.padding()
}
}
extension DeviceActivityName {
static let daily = DeviceActivityName("daily")
}
DeviceActivityMonitor:
class DeviceScheduleTester {
private let center = DeviceActivityCenter()
func scheduleTestActivity(startDate: Date, endDate: Date) {
let calendar = Calendar.current
let startComponents = calendar.dateComponents([.hour, .minute], from: startDate)
let endComponents = calendar.dateComponents([.hour, .minute], from: endDate)
// Tworzymy schedule
let schedule = DeviceActivitySchedule(
intervalStart: startComponents,
intervalEnd: endComponents,
repeats: true
)
do {
try center.startMonitoring(.daily, during:schedule)
print("startMonit /(\(schedule))")
} catch {
print("ghfgh")
}
}
}
struct TestView__Previews: PreviewProvider {
static var previews: some View {
TestView_()
}
}
DeviceActivityMonitor target:
// BlockingAppsMonitorExtension
//
// Created by on 10/01/2025.
import DeviceActivity
import FamilyControls
import ManagedSettings
import os
let logger = Logger()
public class BlockingAppsMonitor: DeviceActivityMonitor {
private let store = ManagedSettingsStore()
public override func intervalDidStart(for activity: DeviceActivityName) {
super.intervalDidStart(for: activity)
print("Rozpoczęcie interwału blokowania \(activity.rawValue)")
logger.info("intervalDidStart")
startBlocking()
}
public override func intervalDidEnd(for activity: DeviceActivityName) {
super.intervalDidEnd(for: activity)
print("Zakończenie interwału blokowania \(activity.rawValue)")
logger.info("intervalDidend")
stopBlocking()
}
@discardableResult
private func startBlocking() -> Int {
print("number of unique apps")
return 51
store.shield.applicationCategories = .all()
// return exceptions.count
}
private func stopBlocking() {
store.shield.applicationCategories = nil
store.shield.applications = nil
}
}
INB4:
In both files are added family controls
Secent file is added in DeviceActivityMonitor target.
Apple answer please?
I am currently building a screen time app and I am trying to figure out how to persist the family activity picker so that when my app closes and re-opens, the app selections in it are saved. I've successfully implemented core data and figured out how to store names of the selected apps in a list like this -
Core Data addApp Function -
func addApp(name: String, context: NSManagedObjectContext){
let newApp = AppToken(context: context)
newApp.bundleIdentifier = name
saveData(context: context)
}
Adding app selections to Core Data (after the family activity picker has updated the selection) -
.onChange(of: model.selectionToDiscourage)
{
for i in model.selectionToDiscourage.applications {
print(i)
dataController.addApp(name:i.localizedDisplayName ?? "Temp", context: moc)
}
Printing saved selections in a list (bundleIdentifier is my attribute for my appToken entity, but I am just pulling the names here. For whatever reason all of them end up being Temp" as shown above anyway. In other words name:i.localizedDisplayName is not working and Temp is shown in the list for every app chosen) -
if dataController.savedSelection.isEmpty {
Text("No Apps Selected")
.foregroundColor(.gray)
} else {
List(dataController.savedSelection, id: \.self) { app in
Text(app.bundleIdentifier ?? "Unknown App")
}
.scrollContentBackground(.hidden)
}
So, when my app closes and reopens, the list of app names persists. Now, my issue is figuring out how to write back to selectionToDiscourage and loading the family activity picker with those saved apps. I have no idea if I should be doing this a different way and if using Core Data is overkill, but I cannot figure out how it's syntactically possible to write back to this family activity picker when the app reopens -
.familyActivityPicker(isPresented: $isPresented, selection:$model.selectionToDiscourage)
Thank you to whoever takes a look at this!!
Hi there,
I am using WeatherKit to display weather forecast information in an app.
I would like to include some information about when the weather forecast was issued for my users to see.
This information is included in the response Metadata as documented in the WeatherKit REST API docs:
https://developer.apple.com/documentation/weatherkitrestapi/metadata
Specifically there is a “reportedTime” property which I would like to use here.
However I am consuming WeatherKit via the Swift API, I don’t see this property available via the Swift APIs.
How can I access the reportedTime property via the WeatherKit Swift APIs? Or is it not exposed via the Swift APIs?
Bellow I created Manager to be easier for me to handle app limits, but for some reason It never reached callbacks function, I have permission for screen time, I added the capabilities for it also, I'm sure, I send correctly the appTokens, categoriesTokens ... and the time limit and it also reach ✅ Monitoring started for..., I don't know what to do anymore:
import SwiftUI
import DeviceActivity
import FamilyControls
import ManagedSettings
@MainActor
class AppUsageManager: DeviceActivityMonitor, ObservableObject {
static let shared = AppUsageManager()
private let deviceActivityCenter = DeviceActivityCenter()
private var monitoringSelections: [DeviceActivityName: (selection: FamilyActivitySelection, timeLimit: DateComponents)] = [:]
private var resetTimer: Timer?
private override init() {
super.init()
print("🟢 AppUsageManager initialized.")
}
// MARK: - Public Methods
/// Configures monitoring for a selection with a specific event name and time limit.
func configureMonitoring(
for selection: FamilyActivitySelection,
timeLimitInMinutes: Int,
activityName: String,
eventName: String
) {
let activityName = DeviceActivityName(activityName)
let eventName = DeviceActivityEvent.Name(eventName)
monitoringSelections[activityName] = (selection, DateComponents(minute: timeLimitInMinutes))
setupMonitoring(for: activityName, with: eventName)
}
/// Stops monitoring for a specific event.
func stopMonitoring(for activityName: String) {
let activityName = DeviceActivityName(activityName)
Task {
print("🛑 Stopping monitoring for \(activityName.rawValue).")
deviceActivityCenter.stopMonitoring([activityName])
monitoringSelections.removeValue(forKey: activityName)
}
}
/// Stops all monitoring.
func stopAllMonitoring() {
print("🛑 Stopping monitoring")
deviceActivityCenter.stopMonitoring()
}
// MARK: - Private Methods
/// Sets up monitoring for a specific event.
private func setupMonitoring(
for activityName: DeviceActivityName,
with eventName: DeviceActivityEvent.Name
) {
stopAllMonitoring()
guard let (selection, timeLimit) = monitoringSelections[activityName] else {
print("⚠️ No selection configured for \(activityName.rawValue).")
return
}
print("🛠 Setting up monitoring for \(activityName.rawValue).")
print("📋 Monitoring Details:")
print("- Time Limit: \(timeLimit.minute ?? 0) minutes.")
let warningThreshold = DateComponents(minute: 3)
let timeZone = TimeZone.current
let schedule = DeviceActivitySchedule(
intervalStart: DateComponents(timeZone: timeZone, hour: 0, minute: 0, second: 0),
intervalEnd: DateComponents(timeZone: timeZone, hour: 23, minute: 59, second: 59),
repeats: true,
warningTime: warningThreshold
)
let events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [
eventName: DeviceActivityEvent(
applications: selection.applicationTokens,
categories: selection.categoryTokens,
webDomains: selection.webDomainTokens,
threshold: timeLimit
)
]
do {
try deviceActivityCenter.startMonitoring(
activityName,
during: schedule,
events: events
)
print("✅ Monitoring started for \(activityName.rawValue) with time limit \(timeLimit.minute ?? 0) minutes.")
} catch {
print("❌ Failed to start monitoring \(activityName.rawValue): \(error.localizedDescription)")
}
}
// MARK: - DeviceActivityMonitor Overrides
override func intervalDidStart(for activity: DeviceActivityName) {
print("🟢 Interval for \(activity.rawValue) started.")
}
override func intervalWillStartWarning(for activity: DeviceActivityName) {
print("⚠️ Warning: \(activity.rawValue) is about to start.")
}
/// Handles warnings for approaching the time limit.
override func eventWillReachThresholdWarning(
_ event: DeviceActivityEvent.Name,
activity: DeviceActivityName
) {
super.eventWillReachThresholdWarning(event, activity: activity)
print("⚠️ Warning: \(activity.rawValue) is about to reach its time limit.")
print("⚠️ Event: \(event.rawValue)")
}
/// Handles when the time limit is reached.
override func eventDidReachThreshold(
_ event: DeviceActivityEvent.Name,
activity: DeviceActivityName
) {
super.eventDidReachThreshold(event, activity: activity)
print("🟢 Limit reached.")
Task { @MainActor in
print("🕒 \(activity.rawValue) has reached its time limit.")
print("🕒 Event: \(event.rawValue)")
guard let (selection, _) = monitoringSelections[activity] else {
print("⚠️ No selection configured for \(activity.rawValue).")
return
}
blockApps(for: selection)
}
}
// MARK: - Blocking Logic
/// Blocks the selected apps/categories.
private func blockApps(for selection: FamilyActivitySelection) {
print("🔒 Blocking apps/categories for selection.")
print("- Applications: \(selection.applicationTokens)")
print("- Categories: \(selection.categoryTokens)")
let store = ManagedSettingsStore()
store.shield.applications = selection.applicationTokens
store.shield.applicationCategories = .specific(selection.categoryTokens)
print("🔒 Apps/categories blocked successfully.")
}
}
Our watch app, Regatta Timer, is a specialised countdown timer for sailing competitions. It is crucial that the beeps & haptics continue when 'wrist down' on alway on displays. We tried to enable this by adding 'background mode' but that only works in the Xcode Apple Watch simulator, not on an actual device with always on display. Any idea how we can get this working also on the Apple Watch device?
In ContentView.swift we currently added this code:
WKInterfaceDevice.current().play(sound)
}
but that doesnt work - regardless of adding , phase == .active`
or not.
STEPS TO REPRODUCE
Install on an ACTUAL DEVICE with always on display
start the countdown timer: beeps & sounds are OK (each minute,...)
do 'wrist down': the countdown timer continues on the dimmed display, but the sounds & haptics stop working until you raise your wrist to wake up the display.
After updating to watchOS 11.1, updates using WidgetCenter.shared.reloadAllTimelines() in WKRefreshBackgroundTask stopped working. When the background task is triggered, it gets data from the phone and updates the WidgetKit complications. But now the refresh call WidgetCenter.shared.reloadAllTimelines() does not update the complications.
I've developed a new Quicklook data-based preview extension for a custom file type that generates an image preview of the file. I previously used a Quick Look generator plug-in but support for it was deprecated and now removed in macOS Sequoia.
My app opens files using a
open(url.path, O_RDWR | O_NONBLOCK | O_EXLOCK)
call. The locking flags are used to prevent other clients from writing the file if it's already open.
I discovered that when Finder is showing the “large” file previews (such as when in column or gallery modes) from a SMB share, the open call fails with EWOULDBLOCK as if the file is locked.
It does work just fine on local files. Opening with O_SHLOCK also has the issue. Surprisingly it does work just fine for previews that return Plain Text data instead of Image data.
Using the lsof command, it seems like the Quicklook process has some kind of lock on the file.
This is the output of the lsof command:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE
QuickLook 48487 XXXX txt REG 1,15 125000611 3161369
Attached is a test project that tries a few different opening and locking functions. It also includes a test file and a sample image preview extension that displays a red square.
When everything is working, regular console messages show the progress of the tests. When the file is on a SMB share and selected in Finder Gallery mode, the open test will fail with a fault message in the console.
Notably, locking with flock works, which is weird because it should have similar semantics according to the man page for open(2).
Filed this as FB15051186
Topic:
App & System Services
SubTopic:
General
Tags:
Extensions
QuickLook
QuickLook Thumbnailing
Files and Storage
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?
Not sure if my question is weird or not, but I didnt find any documentation about an sdks access to an apps documents directory.
Im assuming that because sdk is part of the sandbox that it can access and read from the documents directory? i.e. if i used
NSFileManager.defaultManager.URLForDirectory(
directory = NSCachesDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = false,
error = null,
)
to write a file called "file.txt", then any sdk my app used has the ability to access the contents of said directory?
If yes, why isnt this considered something more worth mentioning? usually in filemanager tutorials they never warn about this.
FYI: Im asking more for iOS and iPadOs then MacOs.
There's a 128mb limit for donating items to core spotlight. As far as I understand, there's a warning that shows in the Xcode console when either approaching or hitting that limit. It would be great if there was an API to check the current status of available storage for QA purposes to see if we're either donating too much or can donate more. Thanks!
I’ve implemented an Intent Extension and added support for handling the INSendMessageIntent in the intent handler class.
Currently, this intent is automatically visible in the Shortcuts app by default. However, for security reasons (as it involves handling phone numbers), I want to restrict the use of this intent to Siri only and ensure it does not appear in the Shortcuts app.
Has anyone encountered this requirement before or knows a way to prevent the intent from appearing in the Shortcuts app, while still keeping it functional via Siri?
Looking forward to your suggestions!
Hi!
I am moving a contact management app (Contact Clearout) to CNContactStore.
For users to have full info when choosing between duplicates they need the creation and modification dates.
I don't want to have to use an extra access to ABAddressBook just to get these and I can see they are on the CNContact objects.
How to do I get these values?
Thanks
I'm working on adding CFBundleDocumentTypes to my Info.plist so that a user can share an image from other apps on their device and have it open inside my iPhone app.
I seem to be able to get this to work for sharing a single photo from the Photos app, but not for (1) multiple photos from the Photos app or (2) images from Safari.
One thing that makes this difficult is that my changes to Info.plist sometimes have no effect. I can remove CFBundleDocumentTypes and still see the icon, for example. Or I can add a new accepted UTI, but it has no effect. I've tried cleaning and rebuilding, deleting and reinstalling the app...no success. I tried in the simulator, too, and even Erase Content and Settings didn't force changes to be applied. I'm not sure what else to try here.
Anyway, I'd like my app to appear in the Share sheet for photo(s) from the Photos app, Mail and Safari, in particular, but really from any app that supports sharing photos.
I can share the config that seemed to work, but since changing it doesn't always have an effect, I can't guarantee that this was the one that worked. At the moment, it doesn't work, but I'm not sure why. Here it is:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
<string>public.jpeg</string>
<string>public.png</string>
<string>public.image</string>
<string>public.gif</string>
<string>public.url</string>
<string>public.content</string>
</array>
</dict>
</array>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
In my code, I also defined the following method in my SceneDelegate (though I think the problem is just with Info.plist):
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
Here are my questions:
How do I make sure that my changes to Info.plist apply? Is there a cache somewhere that I have to force to clear? This is the trickiest part of this, because I can't reliably try an experiment and see if it worked.
Adding the specific image UTI’s (public.jpeg, public.png) seemed to help, even though those types should conform to public.image, which conforms to public.data and public.content. Is it actually necessary to specify those?
If the user selects multiple photos in the Photos app, my app doesn’t appear, but other third-party apps on my phone do. How can I support multiple photos?
This configuration doesn't reliably show my app for Safari images - what do I need to do to make that happen?
I had to use “public.data” when I briefly had Safari sharing working, but there doesn't seem to be a way to get a UTI from UIOpenURLContext. Right now, my code just tries to load the data as an image and aborts if UIImage(data:) returns nil. Is this a safe way of doing this? Is there a way to get the UTI for the data?
Topic:
App & System Services
SubTopic:
General
Tags:
iOS
UIKit
Core Services
Uniform Type Identifiers
The server returns a response content-type must be text/html when universal links are configured
application/json can be used?
Hello.
Our app uses PTT framework and "Always" location tracking at the same time. By some reason, after backgrounding app, Dynamic Island shows only location tracking icon instead if PTT icon. And when user taps on it - application foregrounding instead of system PTT UI show. Only after first incoming PTT user can access system PTT UI.
Is it a bug or intended behaviour?
Prior to iOS18, the incoming/outgoing call history display in the Phone app matched the CallDirectory content, but starting with iOS18, changing the information tied to the same number results in the incoming/outgoing call history not matching the CallDirectory content, as it remains unchanged before the change. Is this a strongly intended change? If not, we would like to have it reverted back to the way it worked before iOS18.
Befor iOS18
Register the target phone number and name1 to CallRirectory
Incoming call using the target phone number
The target phone number and name1 is recorded as an incoming call history
Register the target phone number and name2 to CallRirectory
Incoming call using the target phone number again
The target phone number and name2 is recorded as an incoming call history
Also 1st incoming call history’s name is changed to name2
After iOS18
Register the target phone number and name1 to CallRirectory
Incoming call using the target phone number
The target phone number and name1 is recorded as an incoming call history
Register the target phone number and name2 to CallRirectory
Incoming call using the target phone number again
The target phone number and name2 is recorded as an incoming call history
But 1st incoming call history’s name is still name1
Why does this difference occur?
Is there any way to limit use of the iOS 18 Live Caller ID extension to subscribed users? My team has been trying to figure out a workable approach to only allow full call blocking / identification via this feature for users with an active subscription and so far we have not found a workable approach.
One solution we’ve looked into is invalidating access tokens on the backend and only calling refreshPIRParameters(forExtensionWithIdentifier:) for users with a current valid subscription but it seems that this won’t work since the device will attempt to refresh on its own eventually.
We’ve also looked into swapping out the userTierToken in the extension based on subscription status but this also does not seem to be possible.
Is limiting/modifying this feature's functionality based on subscription status just not possible, likely by design due to the privacy-focused nature of it, or is there some other approach we’re overlooking?
Hi,
My env. is ..
Xcode: Version 16.2 (16C5032a)
macOS Sequoia: Version 15.1
And I have 2 problems.
Please give me the advice..
Failed Message.
When I run the automatically generated app as it is, the following error(warning?) message appears in the terminal.
Can't find or decode reasons
Failed to get or decode unavailable reasons
NSBundle file:///System/Library/PrivateFrameworks/MetalTools.framework/ principal class is nil because all fallbacks have failed
Not on the simulator
And the result is not running in the simulator, but instead appears as a window. (The simulator works fine when launched separately, but the app from the current project doesn’t show up in it.)