Documentation seems to say that privacySensitive is supposed to redact on the lockScreen. I've disabled "Allow Access when locked" for "Lock Screen Widgets" just in case. It does not work for me. If I add "redacted(reason:) into the view hierarchy it redacts all the content all the time including on the home screen. I've read articles. I gone through a lot of documentation. None of them seem to give the magic formula for redacting sensitive content on the lock screen.
I'm using iOS 18.7 on a real iPhone 14 Pro Max.
Widgets & Live Activities
RSS for tagDiscuss how to manage and implement Widgets & Live Activities.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Appears during code compilation Provisioning profile "iOS Team Provisioning Profile: ..*" doesn't include the com.apple.developer.ActivityKit entitlement, Has anyone encountered or resolved a similar issue where the ActiveKit feature was not found in the developer's identifier, despite not being activated in the developer's system?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Appears during code compilation Provisioning profile "iOS Team Provisioning Profile: ..*" doesn't include the com.apple.developer.ActivityKit entitlement, Has anyone encountered or resolved a similar issue where the ActiveKit feature was not found in the developer's identifier, despite not being activated in the developer's system?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
I'm currently testing this on a physical device (12 Pro Max, iOS 26). Through shortcuts, I know for a fact that I am able to successfully trigger the perform code to do what's needed. In addition, if I just tell siri the phrase without my unit parameter, and it asks me which unit, I am able to, once again, successfully call my perform. The problem is any of my phrases that I include my unit, it either just opens my application, or says "I can't understand"
Here is my sample code:
My Entity:
import Foundation
import AppIntents
struct Unit: Codable, Identifiable {
let nickname: String
let ipAddress: String
let id: String
}
struct UnitEntity: AppEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation {
TypeDisplayRepresentation(
name: LocalizedStringResource("Unit", table: "AppIntents")
)
}
static let defaultQuery = UnitEntityQuery()
// Unique Identifer
var id: Unit.ID
// @Property allows this data to be available to Shortcuts, Siri, Etc.
@Property var name: String
// By not including @Property, this data is NOT used for queries.
var ipAddress: String
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: "\(name)"
)
}
init(Unit: Unit) {
self.id = Unit.id
self.ipAddress = Unit.ipAddress
self.name = Unit.nickname
}
}
My Query:
struct UnitEntityQuery: EntityQuery {
func entities(for identifiers: [UnitEntity.ID]) async throws -> [UnitEntity] {
print("[UnitEntityQuery] Query for IDs \(identifiers)")
return UnitManager.shared.getUnitUnits()
.map { UnitEntity(Unit: $0) }
}
func suggestedEntities() async throws -> [UnitEntity] {
print("[UnitEntityQuery] Request for suggested entities.")
return UnitManager.shared.getUnitUnits()
.map { UnitEntity(Unit: $0) }
}
}
UnitsManager:
class UnitManager {
static let shared = UnitManager()
private init() {}
var allUnits: [UnitEntity] {
getUnitUnits().map { UnitEntity(Unit: $0) }
}
func getUnitUnits() -> [Unit] {
guard let jsonString = UserDefaults.standard.string(forKey: "UnitUnits"),
let data = jsonString.data(using: .utf8) else {
return []
}
do {
return try JSONDecoder().decode([Unit].self, from: data)
} catch {
print("Error decoding units: \(error)")
return []
}
}
func contactUnit(unit: UnitEntity) async -> Bool {
// Do things here...
}
}
My AppIntent:
import AppIntents
struct TurnOnUnit: AppIntent {
static let title: LocalizedStringResource = "Turn on Unit"
static let description = IntentDescription("Turn on an Unit")
static var parameterSummary: some ParameterSummary {
Summary("Turn on \(\.$UnitUnit)")
}
@Parameter(title: "Unit Unit", description: "The Unit Unit to turn on")
var UnitUnit: UnitEntity
func perform() async throws -> some IntentResult & ProvidesDialog {
//... My code here
}
}
And my ShortcutProvider:
import Foundation
import AppIntents
struct UnitShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: TurnOnUnit(),
phrases: [
"Start an Unit with \(.applicationName)",
"Using \(.applicationName), turn on my \(\.$UnitUnit)",
"Turn on my \(\.$UnitUnit) with \(.applicationName)",
"Start my \(\.$UnitUnit) with \(.applicationName)",
"Start \(\.$UnitUnit) with \(.applicationName)",
"Start \(\.$UnitUnit) in \(.applicationName)",
"Start \(\.$UnitUnit) using \(.applicationName)",
"Trigger \(\.$UnitUnit) using \(.applicationName)",
"Activate \(\.$UnitUnit) using \(.applicationName)",
"Volcano \(\.$UnitUnit) using \(.applicationName)",
],
shortTitle: "Turn on unit",
systemImageName: "bolt.fill"
)
}
}
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
Siri and Voice
Intents
App Intents
I am building a widget with configurable options (dynamic option) where the options are pull from api (ultimately the options are return from a server, but during my development, the response is constructed on the fly from locally).
Right now, I am able to display the widget and able to pull out the widget configuration screen where I can choose my config option . I am constantly having an issue where the loading the available options when selected a particular option (e.g. Category) and display them on the UI. Sometime, when I tap on the option "Category" and the loading indicator keeps spinning for while before it can populate the list of topics (return from methods in NewsCategoryQuery struct via fetchCategoriesFromAPI ). Notice that I already made my fetchCategoriesFromAPI call to return the result on the fly and however the widget configuration UI stills take a very long time to display the result. Even worst, the loading (loading indicator keep spinning) sometime will just kill itself after a while and my guess there are some time threshold where the widget extension or app intent is allow to run, not sure on this?
My questions:
How can I improve the loading time to populate the dynamic options in widget configuration via App Intent
Here is my sample code for my current setup
struct NewsFeedConfigurationIntent: AppIntent, WidgetConfigurationIntent {
static let title: LocalizedStringResource = "Configure News Topic Options"
static let description = IntentDescription("Select a topic for your news.")
@Parameter(title: "Category", default: nil)
var category: NewsCategory?
}
struct NewsCategory: AppEntity, Identifiable {
let id: String
let code: String
let name: String
static let typeDisplayRepresentation: TypeDisplayRepresentation = "News Topic"
static let defaultQuery = NewsCategoryQuery()
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: LocalizedStringResource(stringLiteral: name))
}
}
struct NewsCategoryQuery: EntityQuery {
func entities(for identifiers: [NewsCategory.ID]) async throws -> [NewsCategory] {
let categories = fetchCategoriesFromAPI()
return categories.filter { identifiers.contains($0.id) }
}
func suggestedEntities() async throws -> [NewsCategory] {
fetchCategoriesFromAPI()
}
}
func fetchCategoriesFromAPI() -> [NewsCategory] {
let list = [
"TopicA",
"TopicB",
"TopicC",
.......
]
return list.map { item in
NewsCategory(id: item, code: item, name: item.capitalized)
}
}
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
WidgetKit
Intents
App Intents
Hello everyone,
I am currently developing a media playback app and want to achieve the following functionality:
Display multiple media contents in the Now Playing control center, instead of just showing the currently playing one.
Allow users to select and switch between different contents, such as videos, music, etc., from the control center.
However, I have encountered some issues:
Although I have integrated the Now Playing control center, it only displays the current media being played.
I would like to display multiple selectable media contents (such as a video list, music list, etc.) in the control center, similar to what is done by some media player apps, and allow users to switch between them.
I’ve tried the following methods:
Using MPNowPlayingInfoCenter to update the current playing media information.
Attempting to set MPNowPlayingInfoPropertyPlaybackQueueCount to show multiple items in the queue, but it doesn’t seem to work.
Can anyone provide guidance on how to display multiple media contents in the Now Playing control center? Any experienced developers who could share their insights or suggestions would be greatly appreciated!
Thank you very much for your help and feedback!
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Hi everyone,
I'm working with Live Activities using the ActivityKit(Activity), and I'm trying to find a way to detect when a user manually dismisses a Live Activity by swiping it away — either from the Lock Screen or the Dynamic Island.
Currently, when a Live Activity ends, the activityState changes to .dismissed, which is defined as:
/// The Live Activity ended and is no longer visible because a person or the system removed it.
case dismissed
This doesn’t allow me to determine whether the dismissal was triggered by the user or by the system.
Is there any way — either through ActivityState, notifications, or another approach — to distinguish if a Live Activity was manually dismissed by the user vs. ended by the system?
Thanks in advance!
Is there any way to obtain the ControlWidget installed by user, I use WidgetCenter.shared.getCurrentConfigurations cannot work
Hello,
I am trying to get the elements from my SwiftData databse in the configuration for my widget.
The SwiftData model is the following one:
@Model
class CountdownEvent {
@Attribute(.unique) var id: UUID
var title: String
var date: Date
@Attribute(.externalStorage) var image: Data
init(id: UUID, title: String, date: Date, image: Data) {
self.id = id
self.title = title
self.date = date
self.image = image
}
}
And, so far, I have tried the following thing:
AppIntent.swift
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource { "Configuration" }
static var description: IntentDescription { "This is an example widget." }
// An example configurable parameter.
@Parameter(title: "Countdown")
var countdown: CountdownEntity?
}
Countdowns.swift, this is the file with the widget view
struct Provider: AppIntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
}
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration)
}
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
// func relevances() async -> WidgetRelevances<ConfigurationAppIntent> {
// // Generate a list containing the contexts this widget is relevant in.
// }
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}
struct CountdownsEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
Text("Title:")
Text(entry.configuration.countdown?.title ?? "Default")
}
}
}
struct Countdowns: Widget {
let kind: String = "Countdowns"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
CountdownsEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
}
CountdownEntity.swift, the file for the AppEntity and EntityQuery structs
struct CountdownEntity: AppEntity, Identifiable {
var id: UUID
var title: String
var date: Date
var image: Data
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(title)")
}
static var defaultQuery = CountdownQuery()
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Countdown"
init(id: UUID, title: String, date: Date, image: Data) {
self.id = id
self.title = title
self.date = date
self.image = image
}
init(id: UUID, title: String, date: Date) {
self.id = id
self.title = title
self.date = date
self.image = Data()
}
init(countdown: CountdownEvent) {
self.id = countdown.id
self.title = countdown.title
self.date = countdown.date
self.image = countdown.image
}
}
struct CountdownQuery: EntityQuery {
typealias Entity = CountdownEntity
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Countdown Event")
static var defaultQuery = CountdownQuery()
@Environment(\.modelContext) private var modelContext // Warning here: Stored property '_modelContext' of 'Sendable'-conforming struct 'CountdownQuery' has non-sendable type 'Environment<ModelContext>'; this is an error in the Swift 6 language mode
func entities(for identifiers: [UUID]) async throws -> [CountdownEntity] {
let countdownEvents = getAllEvents(modelContext: modelContext)
return countdownEvents.map { event in
return CountdownEntity(id: event.id, title: event.title, date: event.date, image: event.image)
}
}
func suggestedEntities() async throws -> [CountdownEntity] {
// Return some suggested entities or an empty array
return []
}
}
CountdownsManager.swift, this one just has the function that gets the array of countdowns
func getAllEvents(modelContext: ModelContext) -> [CountdownEvent] {
let descriptor = FetchDescriptor<CountdownEvent>()
do {
let allEvents = try modelContext.fetch(descriptor)
return allEvents
}
catch {
print("Error fetching events: \(error)")
return []
}
}
I have installed it in my phone and when I try to edit the widget, it doesn't show me any of the elements I have created in the app, just a loading dropdown for half a second:
What am I missing here?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
SwiftUI
WidgetKit
App Intents
SwiftData
I found the live activity process cannot write to the app group and FileManger, can only read the app group.
When I write using FileManager in a live activity process, the console prompts me with a permission error.
When I write using UserDefault(suit:) in the live activity process, I read a null value in the main app.
Is this the case for real-time event design? I haven’t seen any documentation mentioning this.
Does anyone know, thank you very much.
I've noticed that the when starting live activities via a remote push-to-start notification, the live activity widget consistently succeeds in displaying on the lock screen. However push-to-update token is not always received by the task observing the pushTokenUpdates async-sequence.
Task {
print("listening for pushTokenUpdates")
for await pushToken in activity.pushTokenUpdates {
let token = pushToken.map {String(format: "%02x", $0)}.joined()
print("Push token: \(token)")
}
}
The log will print "listening for pushTokenUpdates" however occasionally the "Push token: ___" line will not be present even when the widget has displayed on screen. This happens even if the "allow" button has been selected on live activities for that app. The inconsistent behavior leads me to believe there is an issue at the ActivityKit level. Would appreciate any feedback in debugging this!
I tested it on the app I work with and others I use and the notification message is not appearing when using sleep mode
Iphone: 13 mini
IOS: 18.4.1
I have implemented a Live Activity that includes two buttons. Currently, both buttons utilize deep links to open the main application, where I then detect the URL to perform the corresponding action.
My primary question is:
Is it possible to update a button's title and/or color within a Live Activity without requiring the main application to open?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Does live activity require notification permission? If you need to update card data through APNS, I remember that it was required in the past, otherwise the card could not be created. This year I tried it and some apps did not have notification permission, but they could also use live activity and update data
We are developing a service that uses the “More Frequent Updates” feature of Live Activities.
I have a question regarding the push notification budget for Live Activities.
According to the documentation and the following session:
WWDC23 Session 10185 – “What’s New in ActivityKit”
https://developer.apple.com/videos/play/wwdc2023/10185/
At 11:58, it is stated that there is no limit on the number of updates when using low priority (5).
Could you confirm whether updates sent with low priority (5) are indeed not subject to the Live Activity push notification budget?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Hello,
I'm trying to create a widget using the WidgetKit framework. In this part, I'm using Intents along with a DynamicOptionsProvider. As shown in the Medium article below, I want to present multiple options when "Edit Widget" is tapped:
https://levelup.gitconnected.com/swiftui-configurable-widget-to-let-our-user-choose-4a54e398f42f
However, in this example, the options are provided statically. What I want to achieve is to display a list of devices based on the selected HomeId after the user selects a Home. I’ve set up the interface accordingly, but when I select a Home, the device list does not update.
How can I make this work? The two options should be dependent on each other.
body: error when I run the app,and the frame just became freezed.
WatchOS26 ControlWidget cannot display image copy or click
import Foundation
import SwiftUI
import WidgetKit
import AppIntents
internal import Combine
struct WidgetToggle: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "com.example.myApp.performActionButton", provider: TimerValueProvider()) { isRunning in
ControlWidgetToggle("WidgetToggle", isOn: isRunning, action: ToggleTimerIntent()) { isOn in
Label(isOn ? "Running" : "Stopped", systemImage: isOn ? "hourglass.bottomhalf.filled" : "hourglass")
}
}
.displayName("WidgetToggle")
.description("WidgetToggle description")
}
}
struct TimerValueProvider: ControlValueProvider {
var previewValue: Bool {
return false
}
func currentValue() async throws -> Bool {
return TimerManager.shared.isRunning
}
}
struct ToggleTimerIntent: SetValueIntent {
static var title: LocalizedStringResource = "WidgetToggle"
@Parameter(title: "Toggle")
var value: Bool
func perform() async throws -> some IntentResult {
TimerManager.shared.isRunning = value
return .result()
}
}
class TimerManager: ObservableObject {
static let shared = TimerManager()
@Published var isRunning = false
}
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
I am developing Live Activities using Swift. The same code can display the lock screen view and Dynamic Island on most devices, but on one specific iPhone 16 Pro Max, the Dynamic Island is not shown. The system version is iOS 18.0. However, other apps on this phone can display the Dynamic Island normally. How should I troubleshoot the issue? Can anyone help me? Thank you.
我们在使用clip轻应用功能,在App Store Connect中配置了高级轻应用体验,并配置了相关的https链接(在构建版本页面此域名是已验证状态),但是我们在使用此链接进行NFC触碰时,不会拉起来clip轻应用,只会显示“XXXX NFC标签”,使用Apple的官方链接:https://appclip.apple.com/id?p=xxxx,是可以拉起来轻应用的,请问各位大佬,我们的问题出现在哪?该如何解决?