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.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

A Summary of the WWDC25 Group Lab - UI Frameworks
At WWDC25 we launched a new type of Lab event for the developer community - Group Labs. A Group Lab is a panel Q&A designed for a large audience of developers. Group Labs are a unique opportunity for the community to submit questions directly to a panel of Apple engineers and designers. Here are the highlights from the WWDC25 Group Lab for UI Frameworks. How would you recommend developers start adopting the new design? Start by focusing on the foundational structural elements of your application, working from the "top down" or "bottom up" based on your application's hierarchy. These structural changes, like edge-to-edge content and updated navigation and controls, often require corresponding code modifications. As a first step, recompile your application with the new SDK to see what updates are automatically applied, especially if you've been using standard controls. Then, carefully analyze where the new design elements can be applied to your UI, paying particular attention to custom controls or UI that could benefit from a refresh. Address the large structural items first then focus on smaller details is recommended. Will we need to migrate our UI code to Swift and SwiftUI to adopt the new design? No, you will not need to migrate your UI code to Swift and SwiftUI to adopt the new design. The UI frameworks fully support the new design, allowing you to migrate your app with as little effort as possible, especially if you've been using standard controls. The goal is to make it easy to adopt the new design, regardless of your current UI framework, to achieve a cohesive look across the operating system. What was the reason for choosing Liquid Glass over frosted glass, as used in visionOS? The choice of Liquid Glass was driven by the desire to bring content to life. The see-through nature of Liquid Glass enhances this effect. The appearance of Liquid Glass adapts based on its size; larger glass elements look more frosted, which aligns with the design of visionOS, where everything feels larger and benefits from the frosted look. What are best practices for apps that use customized navigation bars? The new design emphasizes behavior and transitions as much as static appearance. Consider whether you truly need a custom navigation bar, or if the system-provided controls can meet your needs. Explore new APIs for subtitles and custom views in navigation bars, designed to support common use cases. If you still require a custom solution, ensure you're respecting safe areas using APIs like SwiftUI's safeAreaInset. When working with Liquid Glass, group related buttons in shared containers to maintain design consistency. Finally, mark glass containers as interactive. For branding, instead of coloring the navigation bar directly, consider incorporating branding colors into the content area behind the Liquid Glass controls. This creates a dynamic effect where the color is visible through the glass and moves with the content as the user scrolls. I want to know why new UI Framework APIs aren’t backward compatible, specifically in SwiftUI? It leads to code with lots of if-else statements. Existing APIs have been updated to work with the new design where possible, ensuring that apps using those APIs will adopt the new design and function on both older and newer operating systems. However, new APIs often depend on deep integration across the framework and graphics stack, making backward compatibility impractical. When using these new APIs, it's important to consider how they fit within the context of the latest OS. The use of if-else statements allows you to maintain compatibility with older systems while taking full advantage of the new APIs and design features on newer systems. If you are using new APIs, it likely means you are implementing something very specific to the new design language. Using conditional code allows you to intentionally create different code paths for the new design versus older operating systems. Prefer to use if #available where appropriate to intentionally adopt new design elements. Are there any Liquid Glass materials in iOS or macOS that are only available as part of dedicated components? Or are all those materials available through new UIKit and AppKit views? Yes, some variations of the Liquid Glass material are exclusively available through dedicated components like sliders, segmented controls, and tab bars. However, the "regular" and "clear" glass materials should satisfy most application requirements. If you encounter situations where these options are insufficient, please file feedback. If I were to create an app today, how should I design it to make it future proof using Liquid Glass? The best approach to future-proof your app is to utilize standard system controls and design your UI to align with the standard system look and feel. Using the framework-provided declarative API generally leads to easier adoption of future design changes, as you're expressing intent rather than specifying pixel-perfect visuals. Pay close attention to the design sessions offered this year, which cover the design motivation behind the Liquid Glass material and best practices for its use. Is it possible to implement your own sidebar on macOS without NSSplitViewController, but still provide the Liquid Glass appearance? While technically possible to create a custom sidebar that approximates the Liquid Glass appearance without using NSSplitViewController, it is not recommended. The system implementation of the sidebar involves significant unseen complexity, including interlayering with scroll edge effects and fullscreen behaviors. NSSplitViewController provides the necessary level of abstraction for the framework to handle these details correctly. Regarding the SceneDelagate and scene based life-cycle, I would like to confirm that AppDelegate is not going away. Also if the above is a correct understanding, is there any advice as to what should, and should not, be moved to the SceneDelegate? UIApplicationDelegate is not going away and still serves a purpose for application-level interactions with the system and managing scenes at a higher level. Move code related to your app's scene or UI into the UISceneDelegate. Remember that adopting scenes doesn't necessarily mean supporting multiple scenes; an app can be scene-based but still support only one scene. Refer to the tech note Migrating to the UIKit scene-based life cycle and the Make your UIKit app more flexible WWDC25 session for more information.
Topic: UI Frameworks SubTopic: General
0
0
738
Jun ’25
Adding Markdown support in notes app
Hi guys, I’m making a simple note taking app and I want to support markdown functionality. I have tried to find libraries and many other GitHub repos but some of them are slow and some of them are very hard to implement and not very customizable. In WWDC 22 apple also made a markdown to html document app and I also looked at that code and it was awesome. It was fast and reliable (Apple btw). But the only problem I am facing is that the markdown text is on the left side and the output format is on the right in the form of html. I don’t want that I want both in the same line. In bear notes and things 3 you can write in markdown and you can see that it is converting in the same line. I have also attached example videos. So, I have markdown parser by apple but the only thing in the way is that it is converting it into a html document. Please help me with this. Also please look into the things 3 video they have also completely customized the text attributes selection menu. By default with UITextView we can only enable text attributes and it shows like this. By clicking more we get the complete formatting menu but not the slider menu which is more convenient. Please also help me this. I don’t know if I can provide apple file but it is from wwdc 22 supporting desktop class interaction
0
0
385
Feb ’25
Task cancellation behaviour
Hi everyone, I believe this should be a simple and expected default behavior in a real-world app, but I’m unable to make it work: 1. I have a View (a screen/page in this case) that calls an endpoint using async/await. 2. If the endpoint hasn’t finished, but I navigate forward to a DetailView, I want the endpoint to continue fetching data (i.e., inside the @StateObject ViewModel that the View owns). This way, when I go back, the View will have refreshed with the fetched data once it completes. 3. If the endpoint hasn’t finished and I navigate back to the previous screen, I want it to be canceled, and the @StateObject ViewModel should be deinitialized. I can achieve 1 and 3 using the .task modifier, since it automatically cancels the asynchronous task when the view disappears: view .task { await vm.getData() } I can achieve 1 and 2 using a structured Task in the View (or in the ViewModel, its the same behavior), for example: .onFirstAppearOnly { Task { away vm.getData() } } onFirstAppearOnly is a custom modifier that I have for calling onAppear only once in view lifecycle. Just to clarify, dont think that part is important for the purpose of the example But the question is: How can I achieve all three behaviors? Is this really such an unusual requirement? My minimum deployment target is iOS 15, and I’m using NavigationView + NavigationLink. However, I have also tried using NavigationStack + NavigationPath and still couldn’t get it to work. Any help would be much appreciated. Thank you, folks!
0
0
419
Feb ’25
SwiftUI Tabview - how to "kill" the views we do not use
I have the MainView as the active view if the user is logged in(authenticated). the memory allocations when we run profile is pretty good. We have graphql fetching, we have token handling eg: This is All heap: 1 All Heap & Anonymous VM 13,90 MiB 65408 308557 99,10 MiB 373965 Ratio: %0.14, %0.86 After what i have checked this is pretty good for initialise and using multiple repositories eg. But when we change tabs: 1 All Heap & Anonymous VM 24,60 MiB 124651 543832 156,17 MiB 668483 Ratio: %0.07, %0.40 And that is not pretty good. So i guess we need to "kill" it or something. How? I have tried some techniques in a forum this was a recommended way: public struct LazyView<Content: View>: View { private let build: () -> Content @State private var isVisible = false public init(_ build: @escaping () -> Content) { self.build = build } public var body: some View { build() Group { if isVisible { build() } else { Color.clear } } .onAppear { isVisible = true } .onDisappear { isVisible = false } } } But this did not help at all. So under here is the one i use now. So pleace guide me for making this work. import DIKit import CoreKit import PresentationKit import DomainKit public struct MainView: View { @Injected((any MainViewModelProtocol).self) private var viewModel private var selectedTabBinding: Binding<MainTab> { Binding( get: { viewModel.selectedTab }, set: { viewModel.selectTab($0) } ) } public init() { // No additional setup needed } public var body: some View { NavigationStack(path: Binding( get: { viewModel.navigationPath }, set: { _ in } )) { TabView(selection: selectedTabBinding) { LazyView { FeedTabView() } .tabItem { Label("Feed", systemImage: "house") } .tag(MainTab.feed) LazyView { ChatTabView() } .tabItem { Label("Chat", systemImage: "message") } .tag(MainTab.chat) LazyView { JobsTabView() } .tabItem { Label("Jobs", systemImage: "briefcase") } .tag(MainTab.jobs) LazyView { ProfileTabView() } .tabItem { Label("Profile", systemImage: "person") } .tag(MainTab.profile) } .accentColor(.primary) .navigationDestination(for: MainNavigationDestination.self) { destination in switch destination { case .profile(let userId): Text("Profile for \(userId)") case .settings: Text("Settings") case .jobDetails(let id): Text("Job details for \(id)") case .chatThread(let id): Text("Chat thread \(id)") } } } } } import SwiftUI public struct LazyView<Content: View>: View { private let build: () -> Content public init(_ build: @escaping () -> Content) { self.build = build } public var body: some View { build() } }
0
0
207
Mar ’25
SwiftUI: How to change `contentInset` of `List`
Hi, Is there any way of changing the contentInset (UIKit variant) of a List in SwiftUI? I do not see any APIs for doing so, the closest I gotten is to use safeAreaInset . While visually that works the UX is broken as you can no longer "scroll" from the gap made by the .safeAreaInset(edge:alignment:spacing:content:) I have subbmited a feedback suggestion: FB16866956
0
0
181
Mar ’25
SwiftUI @Observable Causes Extra Initializations When Using Reference Type Properties
I've encountered an issue where using @Observable in SwiftUI causes extra initializations and deinitializations when a reference type is included as a property inside a struct. Specifically, when I include a reference type (a simple class Empty {}) inside a struct (Test), DetailsViewModel is initialized and deinitialized twice instead of once. If I remove the reference type, the behavior is correct. This issue does not occur when using @StateObject instead of @Observable. Additionally, I've submitted a feedback report: FB16631081. Steps to Reproduce Run the provided SwiftUI sample code (tested on iOS 18.2 & iOS 18.3 using Xcode 16.2). Observe the console logs when navigating to DetailsView. Comment out var empty = Empty() in the Test struct. Run again and compare console logs. Change @Observable in DetailsViewModel to @StateObject and observe that the issue no longer occurs. Expected Behavior The DetailsViewModel should initialize once and deinitialize once, regardless of whether Test contains a reference type. Actual Behavior With var empty = Empty() present, DetailsViewModel initializes and deinitializes twice. However, if the reference type is removed, or when using @StateObject, the behavior is correct (one initialization, one deinitialization). Code Sample import SwiftUI enum Route { case details } @MainActor @Observable final class NavigationManager { var path = NavigationPath() } struct ContentView: View { @State private var navigationManager = NavigationManager() var body: some View { NavigationStack(path: $navigationManager.path) { HomeView() .environment(navigationManager) } } } final class Empty { } struct Test { var empty = Empty() // Comment this out to make it work } struct HomeView: View { private let test = Test() @Environment(NavigationManager.self) private var navigationManager var body: some View { Form { Button("Go To Details View") { navigationManager.path.append(Route.details) } } .navigationTitle("Home View") .navigationDestination(for: Route.self) { route in switch route { case .details: DetailsView() .environment(navigationManager) } } } } @MainActor @Observable final class DetailsViewModel { var fullScreenItem: Item? init() { print("DetailsViewModel Init") } deinit { print("DetailsViewModel Deinit") } } struct Item: Identifiable { let id = UUID() let value: Int } struct DetailsView: View { @State private var viewModel = DetailsViewModel() @Environment(NavigationManager.self) private var navigationManager var body: some View { ZStack { Color.green Button("Show Full Screen Cover") { viewModel.fullScreenItem = .init(value: 4) } } .navigationTitle("Details View") .fullScreenCover(item: $viewModel.fullScreenItem) { item in NavigationStack { FullScreenView(item: item) .navigationTitle("Full Screen Item: \(item.value)") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { withAnimation(completionCriteria: .logicallyComplete) { viewModel.fullScreenItem = nil } completion: { var transaction = Transaction() transaction.disablesAnimations = true withTransaction(transaction) { navigationManager.path.removeLast() } } } } } } } } } struct FullScreenView: View { @Environment(\.dismiss) var dismiss let item: Item var body: some View { ZStack { Color.red Text("Full Screen View \(item.value)") .navigationTitle("Full Screen View") } } } Console Output With var empty = Empty() in Test DetailsViewModel Init DetailsViewModel Init DetailsViewModel Deinit DetailsViewModel Deinit Without var empty = Empty() in Test DetailsViewModel Init DetailsViewModel Deinit Using @StateObject Instead of @Observable DetailsViewModel Init DetailsViewModel Deinit Additional Notes This issue occurs only when using @Observable. Switching to @StateObject prevents it. This behavior suggests a possible issue with how SwiftUI handles reference-type properties inside structs when using @Observable. Using a struct-only approach (removing Empty class) avoids the issue, but that’s not always a practical solution. Questions for Discussion Is this expected behavior with @Observable? Could this be an unintended side effect of SwiftUI’s state management? Are there any recommended workarounds apart from switching to @StateObject? Would love to hear if anyone else has run into this or if Apple has provided any guidance!
0
0
341
Feb ’25
Focused Views Get Clipped When Using NavigationStack or Form in Split-Screen Layout on tvOS
When attempting to replicate the tvOS Settings menu layout, where the screen is divided horizontally into two sections, placing a NavigationStack or a Form view on either side of the screen causes focusable views (such as Button, TextField, Toggle, etc.) to be visually clipped when they receive focus and apply the default scaling animation. Specifically: If the Form or NavigationStack is placed on the right side, the left edge of the focused view gets clipped. If placed on the left side, the right edge of the focused view gets clipped. This issue affects any focusable child view inside the Form or NavigationStack when focus scaling is triggered. Example code: struct TVAppMenuMainView: View { var body: some View { VStack { Text("Settings Menu") .font(.title) HStack { VStack { Text("Left Pane") } .frame(width: UIScreen.main.bounds.width * 0.4) // represents only 40% of the screen .frame(maxHeight: .infinity) .padding(.bottom) Divider() NavigationStack { Form { // All the buttons will get cut on the left side when each button is focused Button("First Button"){} Button("Second Button"){} Button("Third Button"){} Button("Forth Button"){} } } } .frame(maxHeight: .infinity) .frame(maxWidth: .infinity) } .background(.ultraThickMaterial) } } How it looks: What I have tried: .clipped modifiers .ignoresSafeArea Modifying the size manually Using just a ScrollView with VStack works as intended, but as soon as NavigationStack or Form are added, the buttons get clipped. This was tested on the latest 18.5 tvOS BETA
0
0
82
Apr ’25
LiveCommunicationKit events
how can i watch the LiveCommunicationKit event? i have codes likes this: import UIKit import LiveCommunicationKit @available(iOS 17.4, *) class LiveCallKit: NSObject, ConversationManagerDelegate { @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, conversationChanged conversation: Conversation) { } @available(iOS 17.4, *) func conversationManagerDidBegin(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManagerDidReset(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, perform action: ConversationAction) { switch action.state { case .idle: self.completionHandler!(InterfaceKind.reject,self.payload!) case .running: self.completionHandler!(InterfaceKind.reject,self.payload!) case .complete: self.completionHandler!(InterfaceKind.reject,self.payload!) case .failed(let reason): self.completionHandler!(InterfaceKind.reject,self.payload!) default: self.completionHandler!(InterfaceKind.reject,self.payload!) } } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, timedOutPerforming action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didActivate audioSession: AVAudioSession) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didDeactivate audioSession: AVAudioSession) { } @objc public enum InterfaceKind : Int, Sendable, Codable, Hashable { /// 拒绝/挂断 case reject /// 接听. case answer } var sessoin: ConversationManager var callId: UUID var completionHandler: ((_ actionType: InterfaceKind,_ payload: [AnyHashable : Any]) -> Void)? var payload: [AnyHashable : Any]? @objc init(icon: UIImage!) { let data:Data = icon.pngData()!; let cfg: ConversationManager.Configuration = ConversationManager.Configuration(ringtoneName: "ring.mp3", iconTemplateImageData: data, maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 1, includesConversationInRecents: false, supportsVideo: false, supportedHandleTypes: Set([Handle.Kind.generic])) self.sessoin = ConversationManager(configuration: cfg) self.callId = UUID() super.init() self.sessoin.delegate = self } @objc func toIncoming(_ payload: [AnyHashable : Any], displayName: String,actBlock: @escaping(_ actionType: InterfaceKind,_ payload: [AnyHashable : Any])->Void) async { self.completionHandler = actBlock do { self.payload = payload self.callId = UUID() var update = Conversation.Update(members: [Handle(type: .generic, value: displayName, displayName: displayName)]) let actNumber = Handle(type: .generic, value: displayName, displayName: displayName) update.activeRemoteMembers = Set([actNumber]) update.localMember = Handle(type: .generic, value: displayName, displayName: displayName); update.capabilities = [ .playingTones ]; try await self.sessoin.reportNewIncomingConversation(uuid: self.callId, update: update) try await Task.sleep(nanoseconds: 2000000000); } catch { } } } i want to watch the buttons action,how should i do?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
250
Mar ’25
tvOS: Using .onExitCommand to Navigate to Home Tab Before Exiting — Is This Acceptable?
Hi Apple Developer Team, In my tvOS app built with SwiftUI, I have a tab-based interface with several sections. The first tab (index 0) is the Home tab. Other tabs include Contact, WiFi, Welcome, etc. I want to handle the remote's Menu / Back button (.onExitCommand) so that: If the user is on any tab other than Home (tabs 1, 2, 3, etc.), pressing the Menu button takes them back to the Home tab. If the user is already on the Home tab, then pressing the TV/Home button (not Menu) behaves as expected — suspending or exiting the app (handled by the system, no code involved). Here's a simplified version of what I implemented: .onExitCommand { if selectedTab != 0 { selectedTab = 0 focusedTab = 0 } else { // Let system handle the exit when user presses the TV/Home button } } This behavior ensures users don’t accidentally exit the app when they're browsing other tabs, and provides a consistent navigation experience. Question: Is this an acceptable and App Store-compliant use of .onExitCommand on tvOS? I'm not calling exit(0) or trying to force-terminate the app — just using .onExitCommand for in-app navigation purposes. Any official guidance or best practices would be greatly appreciated! Thanks, Prashant
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
0
97
May ’25
Data fetching issue from SensorKit
I want SensorKit data for research purposes in my current application. I have applied for and received permission from Apple to access SensorKit data. During implementation, I encountered an issue in which no data was being retrieved despite granting all the necessary permissions. I am using did CompleteFetch & didFetchResult delegate methods for retrieving data from Sensorkit. CompleteFetch method calls but where I can find different event data like Device usage, Ambient Light, etc? & didFetchResult method does not call. Methods I am using: 1. func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest) 2. func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated.
0
0
376
Feb ’25
Mixing NavigationLink types (value: and non-value: types)
Hello, I was wondering if someone could clear-up my thinking here. e.g. consider the code below... It has a rootView with a navlink to a childView which in turn has navlinks to GrandchildViews. The root view uses basic navLInks NavigationLink{View} label: {View} The child view uses type-based navLinks navigationLink(value:) {View} and .navigationDestination(for:) {View} I would expect the basic navlinks to work in the root view and the type-based ones to work in the child view. However it appears that both are active when one taps on a link in the child view. e.g. User actions: Start -> RootView is only view on the stack -> (tap on ‘Child View’) -> ChildView is top of the stack -> tap on ‘Alice’ -> a second ChildView is top of the stack with a GrandchildView underneath…. Why does this happen, why are the basic links also applied to the childView's links? Thanks. struct Thing: Identifiable, Hashable { let id = UUID() let name: String } struct RootView: View { var body: some View { NavigationStack { List { NavigationLink { ChildView() } label: { Label("Child View", systemImage: "figure.and.child.holdinghands") } NavigationLink { Text("Hello") } label: { Label("Another navLink item in the list", systemImage: "circle") } } .padding() } } } struct ChildView: View { private var things = [ Thing(name: "Alice"), Thing(name: "Bob"), Thing(name: "Charlie"), ] var body: some View { Text("This is the child view") List { ForEach(things) { thing in NavigationLink(value: thing) { Text(thing.name) } } } .navigationTitle("Child View") .navigationDestination(for: Thing.self) { thing in GrandchildView(thing: thing) } } } struct GrandchildView: View { let thing: Thing var body: some View { Text("This is the GrandchildView: \(thing.name)") } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
128
Mar ’25
LazyHstack in SwiftUI not supporting varying height views
In SwiftUI I want to create a list with LazyVstack and each row item in the LazyVstack is a LazyHstack of horizontally scrollable list of images with some description with line limit of 3 and width of every item is fixed to 100 but height of every item is variable as per description text content. But in any of the rows if the first item has image description of 1 line and the remaining items in the same row has image description of 3 lines then the LazyHStack is truncating all the image descriptions in the same row to one line making all the items in that row of same height. Why LazyHStack is not supporting items of varying height ? Expected behaviour should be that height of every LazyHStack should automatically adjust as per item content height. But it seems SwiftUI is not supporting LazyHstack with items of varying height. Will SwiftUI ever support this feature?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
267
Feb ’25
CPTabBarTemplate in CarPlay Simulator: Tab Becomes Inactive on Re-selection
I am facing an issue in my CarPlay app using CPTabBarTemplate. The app has two tabs, and on launch, the first tab is correctly selected. However, when I tap on the first tab again, instead of staying active, it becomes inactive. This behavior is unexpected, as re-selecting the active tab should typically maintain its selected state. Has anyone else encountered this issue or found a workaround to prevent the tab from becoming inactive?
0
0
58
May ’25
SensorKit Data Not Retrieving
I have received permission from Apple to access SensorKit data for my app. I have granted all necessary permissions, but no data is being retrieved. The didCompleteFetch method is being called, but I’m unsure where to find event data like Device Usage and Ambient Light. Additionally, the didFetchResult method is never called. Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated. import SensorKit class ViewController: UIViewController, SRSensorReaderDelegate { let store = SRSensorReader(sensor: .deviceUsageReport) override func viewDidLoad() { super.viewDidLoad() requestSensorAuthorization() } func requestSensorAuthorization() { var sensors: Set<SRSensor> = [ .accelerometer, .deviceUsageReport, .messagesUsageReport, .visits, .keyboardMetrics, .phoneUsageReport, .ambientLightSensor ] if #available(iOS 16.4, *) { sensors.insert(.mediaEvents) } SRSensorReader.requestAuthorization(sensors: sensors) { error in if let error = error { print("Authorization failed: \(error.localizedDescription)") } else { self.store.startRecording() self.requestSensorData() print("Authorization granted for requested sensors.") } } } func requestSensorData() { let fromTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().addingTimeInterval(-60 * 60).timeIntervalSinceReferenceDate) let toTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().timeIntervalSinceReferenceDate) let request = SRFetchRequest() request.from = fromTime request.to = toTime request.device = SRDevice.current store.fetch(request) store.delegate = self } func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest) { print("Fetch request completed: \(fetchRequest.from) to \(fetchRequest.to)") Task { do { let samples = try await reader.fetch(fetchRequest) print("Samples count: \(samples)") } catch { print("Error Fetching Data: \(error.localizedDescription)") } } } func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool { print(result) return true } }
0
0
229
Mar ’25
AppKit: presentAsModalWindow doesn't center the presented window on macOS 15
When I present a view controller, whose view is a SwiftUI View, via presentAsModalWindow(_:) the presented window is no longer centered horizontally to the screen, but rather its origin is there. I know this issue occurs for macOS 15.2+, but can't tell if it is from 15.0+. I couldn't find any documentation on why was this changed. Here's an example code that represents my architecture: class RootViewController: NSViewController { private lazy var button: NSButton = NSButton( title: "Present", target: self, action: #selector(presentView)) override func viewDidLoad() { super.viewDidLoad() // Add button to tree } @objc func presentView() { presentAsModalWindow(PresentedViewController()) } } class PresentedViewController: NSViewController { override loadView() { view = NSHostingView(rootView: MyView()) } } struct MyView: View { /* impl */ }
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
182
Mar ’25
Improving references to localized strings in App Intents
In order to make referencing keys for localized strings a little more reliable, our application references generated constants for localized string keys: This eliminates the potential for developers to misspell a key when referencing a localized strings. And because these constants are automatically generated by the exact same process that provides localized strings for the application, each and every constant is guaranteed to have a localized string associated with it. I’m currently attempting to implement something similar for the localized strings referenced by our new App Intents. Our initial release of App Intent functionality is simply using string literals to reference localized strings: However, I am running into several issues when trying to reference the string keys as a constant. The closest I managed to get was defining the constant as either a LocalizationValue or as a StaticString and referencing the constant while initializing the LocalizedStringResource. With this approach, I see no errors from Xcode until I try and compile. What’s more is that the wording of the error being thrown is quite peculiar: As you can see with the sample code above, I am clearly calling LocalizedStringResource’s initializer directly as Indicated by the error. Is what I’m trying to do even possible with App Intents? From my research, it does look like iOS app localization is moving more towards using string literals for localized strings. Like with String Catalog’s ability to automatically generate entries from strings referenced in UI without the need for a key. However, we’d prefer to use constants if possible for the reasons listed above.
0
0
120
Apr ’25