Post

Replies

Boosts

Views

Activity

Reply to Set 12 vs 24 hour with the new date formatting API in iOS 15
It seems you have to override the environment locale and switch between one that defaults to am/pm (like GB) and one that is 24hr (like US), e.g. @State var is12h = false let date = Date() ... Text(date, format: .dateTime.hour(.twoDigits(amPM: .abbreviated)).minute(.twoDigits)) .environment(\.locale, Locale(identifier: is12h ? "en_GB" : "en_US")) ... 11:01PM 23:01
Topic: App & System Services SubTopic: General Tags:
Nov ’23
Reply to iOS 16.1 Crashes when scroll (LazyVStack and LazyVGrid)
Can reproduce this with Xcode Version 15.1 beta 3 (15C5059c) deploying to iPhone 14 Pro running iOS 17.1.1. Make a test project with Apple's LazyVGrid sample code. Launch app in portrait, scroll to bottom, rotate to landscape, rotate to portrait, scroll to top, crash! let columns = [GridItem(.flexible()), GridItem(.flexible())] var body: some View { ScrollView { LazyVGrid(columns: columns) { ForEach(0x1f600...0x1f679, id: \.self) { value in Text(String(format: "%x", value)) Text(emoji(value)) .font(.largeTitle) } } } } private func emoji(_ value: Int) -> String { guard let scalar = UnicodeScalar(value) else { return "?" } return String(Character(scalar)) } id: \.self tut tut Apple sample code developer! (this is not the cause of this crash though).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’23
Reply to Heavy Duty Work With Async Await
You need to mark the func as nonisolated if you want a background thread, e.g. nonisolated func startWriteImagesNext() async -> Bool { Because you defined it in a ViewController it inherited the @MainActor which doesn't seem what you want to nonisolated bypasses that. Check the NSViewController/UIViewController header to see its @MainActor annotation. You could also declare the func outside of the ViewController to achieve the same effect, e.g. in a struct that is not marked as @MainActor, or a actor if you want some shared state between all the image tasks.
Topic: Programming Languages SubTopic: Swift Tags:
Feb ’24
Reply to CLMonitor Add region after starting to monitor for event changes
I'm experiencing the same bug with Xcode Version 15.3 and iPhone Simulator 17.4. When the app is launched monitoring events are received but are not received for any regions added while app already running. I noticed this sample (which is some very ropey SwiftUI by the way) shows the bug too so I will include that in my feedback report as the test harness: https://developer.apple.com/documentation/corelocation/monitoring_location_changes_with_core_location
Mar ’24
Reply to CLMonitor Add region after starting to monitor for event changes
I experienced the same bug and have reported it as FB13696956 You can find my report on openradar (the link is not allowed here for some reason?). Another issue I noticed is the for try await events does not throw a cancellation exception when the outer task is cancelled like normal streams do. Please submit your own feedback and reference my report so hopefully it will bring more attention to it so it can be fixed!
Mar ’24
Reply to @Observable does not conform with Equatable (and Hashable)
It's simple to provide conformance using ObjectIdentifier, e.g. import SwiftUI @Observable class ObservableContent: Hashable { var text1 = "Default" var text2 = "" static func == (lhs: ObservableContent, rhs: ObservableContent) -> Bool { lhs === rhs } func hash(into hasher: inout Hasher) { hasher.combine(ObjectIdentifier(self)) } } struct ContentView: View { @State var observableContent: ObservableContent? var body: some View { Group { if let observableContent { NavigationStack { NavigationLink(value: observableContent) { Text("Navigation Link") } .navigationDestination(for: ObservableContent.self) { content in ObservableContentView(content: content) } } } } .onAppear { if observableContent == nil { observableContent = ObservableContent() } } .onDisappear { observableContent = nil } } } struct ObservableContentView: View { @Bindable var content: ObservableContent var body: some View { Form { TextField("Text1", text: $content.text1) Text(content.text1) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’24
Reply to @Observable observation outside of SwiftUI
You can use @Observable outside of SwiftUI with AsyncStream like this: struct CountingService { @Observable class Model { public var count: Int = 0 } let model = Model() static var shared = CountingService() init() { Task { [model] in let modelDidChange = AsyncStream { await withCheckedContinuation { continuation in let _ = withObservationTracking { model.count } onChange: { continuation.resume() } } } var iterator = modelDidChange.makeAsyncIterator() repeat { let x = model.count // do something } while await iterator.next() != nil } } } Or if you want the count in the stream, like this: let countDidChange = AsyncStream { await withCheckedContinuation { continuation in let _ = withObservationTracking { model.count } onChange: { continuation.resume() } } return model.count } for await count in countDidChange { } Inside of SwiftUI, @Observable is only designed for model data, for view data please use the View struct hierarchy with @State structs to model your view data and .task for async/await. You'll avoid consistency issues that way and can use many of the powerful features like environment and preferences which you would lose if you attempt to use classes for view data instead.
Topic: App & System Services SubTopic: General Tags:
May ’24
Reply to Regression in Concurrent Task Execution on macOS 15 Beta: Seeking Clarification
To use async/await from SwiftUI it is .task not Task and to get a background thread for a func declared inside the View struct (which is annotated MainActor) use nonisolated func, e.g. Button(isRunning ? "Stop" : "Run Concurrent Tasks") { results.removeAll() isRunning.toggle() } .task(id: isRunning) { // main thread if isRunning { async let task1 = countingTask(name: "Task 1", target: 1000) } } ... } // without nonisolated it would be main actor and thus always on main thread func nonisolated countingTask(name: String, target: Int) async -> String { // background thread If you moved the func to a custom struct then it wouldn't need nonisolated. If that controller struct was an EnvironmentKey then it could be mocked for Previews.
Topic: Programming Languages SubTopic: Swift Tags:
Aug ’24