DeviceActivityReport presents statistics for a device: https://developer.apple.com/documentation/deviceactivity/deviceactivityreport
The problem: DeviceActivityReport can present statistics with a delay for a parent device (when DeviceActivityReport is presenting, the DeviceActivityReportExtension is called to process the statistics). One possible solution is to call DeviceActivityReport periodically throughout the day in a child device. However, the app will not be available all day. Is there any way to run DeviceActivityReport in the background?
I have tried the following approach, but it didn’t work (DeviceActivityReportExtension didnt call):
let hostingController: UIHostingController? = .init(rootView: DeviceActivityReport(context, filter: filter))
hostingController?.view.frame = .init(origin: .zero, size: .init(width: 100, height: 100))
hostingController?.beginAppearanceTransition(true, animated: false)
hostingController?.loadView()
hostingController?.viewDidLoad()
try? await Task.sleep(for: .seconds(0.5))
hostingController?.viewWillAppear(true)
hostingController?.viewWillLayoutSubviews()
try? await Task.sleep(for: .seconds(0.5))
hostingController?.viewDidAppear(true)
try? await Task.sleep(for: .seconds(0.5))
hostingController?.didMove(toParent: rootVC)
try? await Task.sleep(for: .seconds(0.5))
hostingController?.viewWillLayoutSubviews()
hostingController?.viewDidLayoutSubviews()
hostingController?.view.layoutIfNeeded()
hostingController?.view.layoutSubviews()
hostingController?.endAppearanceTransition()
Is there any way to run DeviceActivityReport in the background? (when app is not visible/closed). The main problem is call DeviceActivityReport
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Post
Replies
Boosts
Views
Activity
why do I need to set the font of an image of an SF symbol to get the effect to work? This should be a bug, it's bad behavior. Xcode 16.1 iOS 18.1, so frustrating.
for example: this works
Image(systemName: "arrow.trianglehead.2.clockwise.rotate.90.circle.fill")
.symbolEffect(.rotate, options: .repeat(.continuous), value: isActive)
.font(.largeTitle)
.onAppear() {
isActive = true
}
but this does not animate, which makes no sense
Image(systemName: "arrow.trianglehead.2.clockwise.rotate.90.circle.fill")
.symbolEffect(.rotate, options: .repeat(.continuous), value: isActive)
.onAppear() {
isActive = true
}
its the same if you use a simple setup and different font size, and whether font is before or after the symbol effect
Image(systemName: "arrow.trianglehead.2.clockwise.rotate.90.circle.fill")
.font(.headline) // only works if this line is here
.symbolEffect(.rotate, options: .repeat(.continuous))
Hello everyone! I've encountered an issue related to SwiftUI and StoreKit. Please take a look at the SwiftUI code snippet below:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink {
Page1()
} label: {
Text("Go to Page 1")
}
}
}
}
}
struct Page1: View {
@Environment(\.dismiss) private var dismiss
@State private var string: String = ""
var body: some View {
List {
NavigationLink {
List {
Page2(string: $string)
.simpleValue(4)
}
} label: {
Text("Tap this button will freeze the app")
}
}
.navigationTitle("Page 1")
}
}
struct Page2: View {
@Binding var string: String?
init(string: Binding<String>) {
self._string = Binding(string)
}
var body: some View {
Text("Page 2")
}
}
extension EnvironmentValues {
@Entry var simpleValue: Int = 3
}
extension View {
func simpleValue(_ value: Int) -> some View {
self.environment(\.simpleValue, value)
}
}
This view runs normally until the following symbol is referenced anywhere in the project:
import StoreKit
extension View {
func notEvenUsed() -> some View {
self.manageSubscriptionsSheet(isPresented: .constant(false))
}
}
It seems that once the project links the View.manageSubscriptionsSheet(isPresented:) method, regardless of whether it's actually used, it causes the above SwiftUI view to freeze.
Steps to Reproduce:
Clone the repository: https://github.com/gongzhang/StrangeFreeze
Open it in Xcode 16 and run on iOS 17-18.1
Navigate to the second page and tap the button, causing the app to freeze.
Remove manageSubscriptionsSheet(...), then everything will work fine
Hi all,
I’ve been facing a behavior issue with shouldAutomaticallyForwardAppearanceMethods in UITabBarController. According to Apple’s documentation, this property should default to YES, which means that the appearance lifecycle methods (like viewWillAppear and viewDidAppear) should be automatically forwarded to child view controllers.
However, in my current development environment, I’ve noticed that shouldAutomaticallyForwardAppearanceMethods returns NO by default in UITabBarController, and this is causing some issues with lifecycle management in my app. I even tested this behavior in several projects, both in Swift and Objective-C, and the result is consistent.
Here are some details about my setup:
I’m using Xcode 16.0 with iOS 16.4 Simulator.
I’ve tested the behavior in both a new UIKit project and a simple SwiftUI project that uses a UITabBarController.
Even with a clean new project, the value of shouldAutomaticallyForwardAppearanceMethods is NO by default.
This behavior contradicts the official documentation, which states that it should be YES by default. Could someone clarify if this is expected behavior in newer versions of iOS or if there is a known issue regarding this?
Any help or clarification would be greatly appreciated!
Thanks in advance!
How to reproduce: create blank Xcode project run on physical iPhone(mine 14 pro) not simulator, updated iOS18.1.1 most up to date, on Xcode 16.1 make a text field enter any value in it in console:
Can't find or decode reasons
Failed to get or decode unavailable reasons
This is happening in my other projects as well and I don't know a fix for it is this just an Xcode bug random log noise? It makes clicking the text field lag sometimes on initial tap.
So I'm following this code here where I'm using a tableview to display the files contained in a folder along with a group cell to display the name of the current folder:
Here's my tableView:isGroupRow method: method which basically turns every row with the folder name into a group row (which is displayed in red in the previous image ).
-(BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row
{
DesktopEntity *entity = _tableContents[row];
if ([entity isKindOfClass:[DesktopFolderEntity class]])
{
return YES;
}
return NO;
}
and here's my tableView:viewForTableColumn:row: method where I have two if statements to decide whether the current row is a group row (meaning it's a folder) or an image:
-(NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
{
DesktopEntity *entity = _tableContents[row];
if ([entity isKindOfClass:[DesktopFolderEntity class]])
{
NSTextField *groupCell = [tableView makeViewWithIdentifier:@"GroupCell" owner:self];
[groupCell setStringValue: entity.name];
[groupCell setFont:[NSFont fontWithName:@"Arial" size:40]];
[groupCell setTextColor:[NSColor magentaColor]];
return groupCell;
}
else if ([entity isKindOfClass:[DesktopImageEntity class]])
{
NSTableCellView *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self];
[cellView.textField setStringValue: entity.name];
[cellView.textField setFont:[NSFont fontWithName:@"Impact" size:20]];
[cellView.imageView setImage: [(DesktopImageEntity *)entity image]];
return cellView;
}
return nil;
}
Now, if the current row is an image, I change its font to Impact with a size of 40 and that works perfectly, the problem here is with the first IF statement, for a group row I wanted to change the font size to arial with a size of 40 with a magenta color but for some reason I can only get the color to work:
You can see that my changes to the font size didn't work here, what gives?
How can I change the font size for the group row ?
I am trying to get my head around how to implement a MapKit view using UIViewRepresentable (I want the map to rotate to align with heading, which Map() can't handle yet to my knowledge). I am also playing with making my LocationManager an Actor and setting up a listener. But when combined with UIViewRepresentable this seems to create a rather convoluted data flow since the @State var of the vm needs to then be passed and bound in the UIViewRepresentable. And the listener having this for await location in await lm.$lastLocation.values seems at least like a code smell. That double await just feels wrong. But I am also new to Swift so perhaps what I have here actually is a good approach?
struct MapScreen: View {
@State private var vm = ViewModel()
var body: some View {
VStack {
MapView(vm: $vm)
}
.task {
vm.startWalk()
}
}
}
extension MapScreen {
@Observable
final class ViewModel {
private var lm = LocationManager()
private var listenerTask: Task<Void, Never>?
var course: Double = 0.0
var location: CLLocation?
func startWalk() {
Task {
await lm.startLocationUpdates()
}
listenerTask = Task {
for await location in await lm.$lastLocation.values {
await MainActor.run {
if let location {
withAnimation {
self.location = location
self.course = location.course
}
}
}
}
}
Logger.map.info("started Walk")
}
}
struct MapView: UIViewRepresentable {
@Binding var vm: ViewModel
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
func makeUIView(context: Context) -> MKMapView {
let view = MKMapView()
view.delegate = context.coordinator
view.preferredConfiguration = MKHybridMapConfiguration()
return view
}
func updateUIView(_ view: MKMapView, context: Context) {
context.coordinator.parent = self
if let coordinate = vm.location?.coordinate {
if view.centerCoordinate != coordinate {
view.centerCoordinate = coordinate
}
}
}
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(parent: MapView) {
self.parent = parent
}
}
}
actor LocationManager{
private let clManager = CLLocationManager()
private(set) var isAuthorized: Bool = false
private var backgroundActivity: CLBackgroundActivitySession?
private var updateTask: Task<Void, Never>?
@Published var lastLocation: CLLocation?
func startLocationUpdates() {
updateTask = Task {
do {
backgroundActivity = CLBackgroundActivitySession()
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if let location = update.location {
lastLocation = location
}
}
} catch {
Logger.location.error("\(error.localizedDescription)")
}
}
}
func stopLocationUpdates() {
updateTask?.cancel()
updateTask = nil
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch clManager.authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
isAuthorized = true
// clManager.requestLocation() // ??
case .notDetermined:
isAuthorized = false
clManager.requestWhenInUseAuthorization()
case .denied:
isAuthorized = false
Logger.location.error("Access Denied")
case .restricted:
Logger.location.error("Access Restricted")
@unknown default:
let statusString = clManager.authorizationStatus.rawValue
Logger.location.warning("Unknown Access status not handled: \(statusString)")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
Logger.location.error("\(error.localizedDescription)")
}
}
Hello
i ve implemented progressview and updating the state via push notification.
the progress view wants closedrange which i followed but whenever i get update, the progress value resets to beginning
my range is like :
Date.now..endDate
but i dont get it, lets assume that i get the date from database and initialized already then how the code will understand that what progress value will be as current ?
it has to be something like i suppose :
startDate..Date.now..endDate
thanks
Adding an Import... menu item using .commands{CommandGroup... on
DocumentGroup(
...
) {
ContentView()
}
.commands {
CommandGroup(replacing: .importExport) {
Button("Import…") {
isImporting = true
}
.keyboardShortcut("I", modifiers: .option)
.fileImporter(
isPresented: $isImporting,
allowedContentTypes: [.commaSeparatedText],
allowsMultipleSelection: false
) { result in
switch result {
case .success(let urls):
print("File import success")
ImportCSV.importCSV(url: urls, in: context) // This is the issue
case .failure(let error):
print("File import error: \(error)")
}
}
}
I could get this to work if I were not using DocumentGroup but instead programmatically creating the modelContext.
using the shared modelContext in ImportCSV is not possible since that is not a View
passing the context as shown above would work if I knew how to get the modelContext but does it even exist yet in Main?
Is this the right place to put the commands code?
Perhaps the best thing is to have a view appear on import, then used the shared modelContext. In Xcode menu File/Add Package Dependencies... opens a popup. How is that done?
When user enters in a textfield, is the input of textfield gets stored in a String ?
If yes, then String in swift being immutable, as user keeps on typing does new memory for storing that text gets allocated with each key stroke ?
And when we read users input by using delegate method textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) from textfield.text, we get users input in a String. Is it same storage as used by textfield for storing the user input on key stroke or is it some other storage with copy of the user's input in it?
Or is UItextfield using a diffrent data structure (buffer) for storing the user input and when we do textfield.text, it gives a copy of data stored in original buffer?
When call:
[UITabBarController setViewControllers:animated:]
It crashed and raise an Fatal Exception:
Fatal Exception: NSInternalInconsistencyException Attempting to select a view controller that isn't a child! (null)
the crash stack is:
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x8408c __exceptionPreprocess
1 libobjc.A.dylib 0x172e4 objc_exception_throw
2 Foundation 0x82215c _userInfoForFileAndLine
3 UIKitCore 0x38a468 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
4 UIKitCore 0x3fa8a4 -[UITabBarController _setSelectedViewController:performUpdates:]
5 UIKitCore 0x3fa710 -[UITabBarController setSelectedIndex:]
6 UIKitCore 0x8a5fc +[UIView(Animation) performWithoutAnimation:]
7 UIKitCore 0x3e54e0 -[UITabBarController _setViewControllers:animated:]
8 UIKitCore 0x45d7a0 -[UITabBarController setViewControllers:animated:]
And it appear sometimes, what's the root cause?
I used .tint(.yellow) to change the default back button color. However, I noticed that the color of the alert button text, except for .destructive, also changed. Is this a bug or Apple’s intended behavior?
this occurs in iOS 18.1 and 18.1.1
Below is my code:
// App
struct TintTestApp: App {
var body: some Scene {
WindowGroup {
MainView()
.tint(.yellow)
}
}
}
// MainView
var mainContent: some View {
Text("Next")
.foregroundStyle(.white)
.onTapGesture {
isShowingAlert = true
}
.alert("Go Next View", isPresented: $isShowingAlert) {
Button("ok", role: .destructive) {
isNextButtonTapped = true
}
Button("cancel", role: .cancel) { }
}
}
thank you!
I used .tint(.yellow) to change the default back button color. However, I noticed that the color of the alert button text, except for .destructive, also changed. Is this a bug or Apple’s intended behavior?
Thank you!
Below is my code:
// App
struct tintTestApp: App {
var body: some Scene {
WindowGroup {
MainView()
.tint(.yellow)
}
}
// MainView
var mainContent: some View {
Text("Next")
.foregroundStyle(.white)
.onTapGesture {
isShowingAlert = true
}
.alert("Go Next View", isPresented: $isShowingAlert) {
Button("ok", role: .destructive) {
isNextButtonTapped = true
}
Button("cancel", role: .cancel){}
}
}
Hi,
How to customize tables in SwiftUI its color background for example, the background modifier doesn't work ? how to change separator lines ? rows background colors ? give header row different colors to its text and background color ?
Kind Regards
I have a CALayer and I'd like to animate a property on it. But, the property that triggers the animation change is different to the one that is being changed. A basic example of what I'm trying to do is below. I'm trying to create an animation on count by changing triggerProperty. This example is simplified (in my project, the triggerProperty is not an Int, but a more complex non-animatable type. So, I'm trying to animate it by creating animations for some of it's properties that can be matched to CABasicAnimation - and rendering a version of that class based on the interpolated values).
@objc
class AnimatableLayer: CALayer {
@NSManaged var triggerProperty: Int
@NSManaged var count: Int
override init() {
super.init()
triggerProperty = 1
setNeedsDisplay()
}
override init(layer: Any) {
super.init(layer: layer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override class func needsDisplay(forKey key: String) -> Bool {
return key == String(keypath: \AnimatableLayer.triggerProperty) || super.needsDisplay(forKey: key)
}
override func action(forKey event: String) -> (any CAAction)? {
if event == String(keypath: \AnimatableLayer.triggerProperty) {
if let presentation = self.presentation() {
let keyPath = String(keypath: \AnimatableLayer.count)
let animation = CABasicAnimation(keyPath: keyPath)
animation.duration = 2.0
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
animation.fromValue = presentation.count
animation.toValue = 10
return animation
}
}
return super.action(forKey: event)
}
override func draw(in ctx: CGContext) {
print("draw")
NSGraphicsContext.saveGraphicsState()
let nsctx = NSGraphicsContext(cgContext: ctx, flipped: true) // create NSGraphicsContext
NSGraphicsContext.current = nsctx // set current context
let renderText = NSAttributedString(string: "\(self.presentation()?.count ?? self.count)", attributes: [.font: NSFont.systemFont(ofSize: 30)])
renderText.draw(in: bounds)
NSGraphicsContext.restoreGraphicsState()
}
func animate() {
print("animate")
self.triggerProperty = 10
}
}
With this code, the animation isn't triggered. It seems to get triggered only if the animation's keypath matches the one on the event (in the action func).
Is it possible to do something like this?
I have a SwiftUI based program that has compiled and run consistently on previous macos versions. After upgrading to 15.2 beta 4 to address a known issue with TabView in 15.1.1, my app is now entering a severe hang and crashing with:
"The window has been marked as needing another Update Contraints in Window pass, but it has already had more Update Constraints in Window passes than there are views in the window. .<SwiftUI.AppKitWindow: 0x11d82a800> 0x87 (2071) {{44,0},{1468,883}} en"
Is there a known bug that could be causing this crash or known change in the underlying layout model?
Hi, would anyone be so kind and try to guide me, which technologies, Kits, APIs, approaches etc. are useful for creating a horizontal window with map (preferrably MapKit) on visionOS using SwiftUI?
I was hoping to achieve scenario: User can walk around and interact with horizontal map window and also interact with (3D) pins on the map. Similar thing was done by SAP in their "SAP Analytics Cloud" app (second image from top).
Since I am complete beginner in this area, I was looking for a clean, simple solution. I need to know, if AR/RealityKit is necessary or is this achievable only using native SwiftUI? I tried using just Map() with .rotation3DEffect() which actually makes the map horizontal, but gestures on the map are out of sync and I really dont know, if this approach is valid or complete rubbish.
Any feedback appreciated.
I can't shake the "I don't think I did this correctly" feeling about a change I'm making for Image Playground support.
When you create an image via an Image Playground sheet it returns a URL pointing to where the image is temporarily stored. Just like the Image Playground app I want the user to be able to decide to edit that image more.
The Image Playground sheet lets you pass in a source URL for an image to start with, which is perfect because I could pass in the URL of that temp image.
But the URL is NOT optional. So what do I populate it with when the user is starting from scratch?
A friendly AI told me to use URL(string: "")! but that crashes when it gets forced unwrapped.
URL(string: "about:blank")! seems to work in that it is ignored (and doesn't crash) when I have the user create the initial image (that shouldn't have a source image).
This feels super clunky to me. Am I overlooking something?
If I have a Catalyst app with a WKWebView and I select text, I can drag forward to extend the selection, but I can't reduce the length of the selected range by dragging backwards. I've reproduced this in a trivial sample app.
Is there some property I need to set somewhere?
I've filed this as FB15645411.
Our tvOS app makes use of top shelf Carousel style slides to promote our content.
We would like to detect when tvOS transitions between individual top shelf slides, regardless of whether the slide transition is made by a user (via the Siri remote), or by the system idle auto-transition.
Has anyone achieved this, maybe there are undocumented system hooks or events we can listen to?