Post

Replies

Boosts

Views

Activity

Reply to Live changes of depending State values
I got it now working by using no longer calculated properties but an update function. Here is my working code (Swift Playground on macOS 26): import SwiftUI import Combine @Observable class AppData : ObservableObject { var baseValue : Int = 0 var intValue : String = "0" var hexValue : String = "0" func updateValue(_ v : Int) { //if self.baseValue == v { return } // no short cut here so that illegal chars are filtered self.objectWillChange.send() self.baseValue = v self.intValue = String(v) self.hexValue = String(v, radix: 16).uppercased() } } struct ContentView: View { @State var model = AppData() var body: some View { VStack { Text("Base Value: \(model.baseValue)") HStack { Text("Decimal Value") TextField("Decimal Value", text: $model.intValue) .textFieldStyle(.roundedBorder) .onReceive(Just(model.intValue)) { newValue in let allowedCharacters = "0123456789" let filtered = newValue.filter { allowedCharacters.contains($0) } if let v = Int(filtered) { model.updateValue(v) } } } HStack { Text("Hex Value") TextField("Hex Value", text: $model.hexValue) .textFieldStyle(.roundedBorder) .onReceive(Just(model.hexValue)) { newValue in let allowedCharacters = "0123456789ABCDEFabcdef" let filtered = newValue.filter { allowedCharacters.contains($0) } if let v = Int(filtered, radix: 16) { model.updateValue(v) } } } } .padding() } }
Topic: UI Frameworks SubTopic: SwiftUI
Aug ’26
Reply to Print a SwiftUI view on macOS?
No idea. I've implemented a workaround by creating a PDF. This works well for me. Here is some sample code: func savePDF(docName : String?) { guard let saveURL = showSavePDFPanel(docName) else { return } var mediaBox = NSRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 1100, height: 600)) if let dataConsumer = CGDataConsumer(url: saveURL as CFURL) { if let pdfContext = CGContext(consumer: dataConsumer, mediaBox: &mediaBox, nil) { let options: [CFString: Any] = [kCGPDFContextMediaBox: mediaBox] for sem in ItrSemester.allCases { pdfContext.beginPDFPage(options as CFDictionary) let renderer = ImageRenderer(content: MyView().environmentObject(appData)) renderer.render { size, renderFunction in pdfContext.translateBy(x: (mediaBox.width - size.width) / 2.0, y: (mediaBox.height - size.height) / 2.0) renderFunction(pdfContext) } /// Add a day header to each page with document name let titleString = "\(docName ?? "Ohne Titel")" let attrs : [NSAttributedString.Key : Any] = [.font: NSFont.boldSystemFont(ofSize: 16.0)] let day = NSAttributedString(string: titleString, attributes: attrs) let path = CGMutablePath() let strWidth = day.size().width + 1 let strHeight = day.size().height + 1 let dayXPos = 20.0 let dayYPos = mediaBox.height - strHeight - 32 path.addRect(CGRect(x: dayXPos, y: dayYPos, width: strWidth, height: strHeight)) let fSetter = CTFramesetterCreateWithAttributedString(day as CFAttributedString) let frame = CTFramesetterCreateFrame(fSetter, CFRangeMake(0, day.length), path, nil) CTFrameDraw(frame, pdfContext) pdfContext.endPDFPage() } pdfContext.closePDF() } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’24
Reply to "reset" users home dir to archived content
Meanwhile I got a solution I want to share here: It seems so that the OS has some "voodoo" to protect used home directories. So a change of users home dir via dscl . -change /Users/USER NFSHomeDirectory /Users/USER /doesNotExist allows removing the HOMEDIR and re-create it from a template. Afterwards the command dscl . -change /Users/USER NFSHomeDirectory /doesNotExist /Users/USER does set the homedir back to the old value.
Topic: App & System Services SubTopic: Core OS Tags:
Feb ’24
Reply to SwiftUI alert buttons order issue
How about using no role at all? Without a role there is no reason for the OS to rearrange the buttons. Something like .alert( "Test alert", isPresented: $isAlertPresented, actions: { Button("Default role", action: { }) Button("Cancel role", role: .none, action: { isAlertPresented = false }) }, message: { Text("Test message") }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’23
Reply to Swift Regex too slow als grep replacement?
I note that none of your regular expressions actually need to be regular expressions, i.e. they are just fixed text strings. For example, where you have "non.sense", I think you only want it to literally match "non.sense", not "non0sense". Yes. The first two filters are fixed strings but the last one contains a lot of different search strings. Therefore RegEx makes sense. You're right that a simple string search may be faster but since it takes now just 3 seconds I'm fine with it. Thanks for sharing your thoughts on my code.
Topic: Programming Languages SubTopic: Swift Tags:
Jul ’23
Reply to Swift Regex too slow als grep replacement?
There was another discussion on https://forums.swift.org/t/use-regexbuilder-als-grep-replacement/65782 where I was able to get much faster code. This code does now run in 3 seconds. let paths = ["regTest/logs/access.log", "/regTest/logs/access.log.1"] var startDate = Date() let matchedLines = try await withThrowingTaskGroup(of: [String].self, body: { group in for aPath in paths { group.addTask { let lines = FileHandle(forReadingAtPath: aPath)!.bytes.lines .filter { $0.contains("26/Apr") } .filter { $0.contains("\"GET ") } .filter{ !$0.contains(botListRegEx) } var matched : [String] = [] for try await line in lines { if let m = line.firstMatch(of: ipAtStartRegEx) { let (s, _) = m.output matched.append(String(s)) } } return matched } } var matchedLines : [String] = [] for try await partialMatchedLines in group { matchedLines.append(contentsOf: partialMatchedLines) } return matchedLines }) let uniqArray = Set(matchedLines) print("Match time: \(abs(startDate.timeIntervalSinceNow)) s") print("Found \(matchedLines.count) lines.") print("Found \(uniqArray.count) IP adresses.")
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’23
Reply to Swift Regex too slow als grep replacement?
Good catch. Did you also change the definition of the regex to remove the Capture { } ? Nope. I did just replace "firstMatch". Now I used a plain string and it is much faster. Also I use now another split which is way faster (20 vs. 50s). So here is the code let matchedLines = fullText.split(whereSeparator: \.isNewline) .filter{ $0.contains(yesterdayRegEx) } .filter{ $0.contains(botListRegEx) } Match time: 52.7 s let matchedLines = fullText.split(whereSeparator: \.isNewline) .filter{ $0.contains("26/Apr") } .filter{ $0.contains(botListRegEx) } Match time: 21.8 s So the slow part is now the Split which take most of the time (21 s).
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’23
Reply to Swift Regex too slow als grep replacement?
The Swift code is fast for everything but the RegEx. The file read takes about 1 s but the RegEx takes more than 80 s. That's why I ask for help to speed-up the RegEx. My Swift sample code does no sort and uniq as in the shell example. This will be added after the RegEx is usable. I won´t care if the code in not quite so fast as my shell but it must be much quicker to be usable.
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’23
Reply to Random SwiftUI crashes
Here is a smaller version which does also crash (now tested with new Xcode 14.3): import SwiftUI struct vTime : Codable { var hour : Int var min : Int } struct RecDate : Codable { var day : Int var start: vTime var end : vTime private enum CodingKeys : String, CodingKey { case day case start case end } func duration() -> CGFloat { let dTime : CGFloat = abs(CGFloat(end.hour - start.hour) * 4.0 + CGFloat(end.min - start.min) / 15.0) return dTime } } class Record : Hashable, Equatable, Identifiable, ObservableObject { let vID = UUID() @Published var subject : String @Published var date : RecDate init(subject: String, date : RecDate) { self.subject = subject self.date = date } static func == (lhs: Record, rhs: Record) -> Bool { var r = lhs.subject.compare(rhs.subject) == .orderedSame r = r && lhs.date.start.hour == rhs.date.start.hour r = r && lhs.date.start.min == rhs.date.start.min r = r && lhs.date.end.hour == rhs.date.end.hour r = r && lhs.date.end.min == rhs.date.end.min r = r && lhs.vID == rhs.vID return r } func hash(into hasher: inout Hasher) { hasher.combine(subject) hasher.combine(date.start.hour) hasher.combine(date.start.min) hasher.combine(date.end.hour) hasher.combine(date.end.min) hasher.combine(vID) } func isSelected(appSelection : UUID?) -> Bool { return appSelection == vID } public func incDate() { if !(self.date.end.hour == 19 && self.date.end.min == 0) { self.date.start.min += 15 self.date.end.min += 15 if self.date.start.min == 60 { self.date.start.min = 0 self.date.start.hour += 1 } if self.date.end.min == 60 { self.date.end.min = 0 self.date.end.hour += 1 } } } public func decDate() { if !(self.date.start.hour == 8 && self.date.start.min == 0) { self.date.start.min -= 15 self.date.end.min -= 15 if self.date.start.min < 0 { self.date.start.min = 45 self.date.start.hour -= 1 } if self.date.end.min < 0 { self.date.end.min = 45 self.date.end.hour -= 1 } } } } public class RecordHandler : ObservableObject { @Published var records : [Record] = [ Record(subject: "banana", date: RecDate(day: 0, start: vTime(hour: 8, min: 0), end: vTime(hour: 10, min: 0))), Record(subject: "strawberry", date: RecDate(day: 1, start: vTime(hour: 11, min: 0), end: vTime(hour: 14, min: 0))) ] @Published var selectedID : UUID? = nil func setSel(newID : UUID) { if selectedID == nil { selectedID = newID } else { if selectedID == newID { selectedID = nil } else { selectedID = newID } } } } struct EntryView: View { @EnvironmentObject var appData : RecordHandler @ObservedObject var setup : Record @State private var showDataView : Bool = false struct SelView : View { var body: some View { Rectangle() .inset(by: -2) .stroke(.blue, lineWidth: 5.0) } } var body: some View { let qCount = setup.date.duration() let height = qCount * 10.0 let xPos = 100.0 let yPos = 7.0 + (CGFloat(setup.date.start.hour) - 8.0) * 40.0 + CGFloat(setup.date.start.min) / 1.5 + (qCount - 1.0) * 5.0 ZStack { RoundedRectangle(cornerRadius: 10) .foregroundColor(.red.opacity(0.80)) Text(setup.subject) if setup.isSelected(appSelection: appData.selectedID) { SelView() } } .frame(width: 200, height: height) .position(x: xPos, y: yPos) .onTapGesture(count: 1) { appData.setSel(newID: setup.vID) } } } struct DayView: View { @EnvironmentObject var appData : RecordHandler var day : Int var body: some View { VStack { ForEach(appData.records, id: \.self) { value in if value.date.day == day { EntryView(setup: value) .environmentObject(appData) } } } } } struct ContentView: View { @EnvironmentObject var appData : RecordHandler var body: some View { NavigationStack { HStack { DayView(day: 0) .environmentObject(appData) DayView(day: 1) .environmentObject(appData) } } .toolbar { ToolbarItemGroup(placement: .automatic) { Button("↑") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.decDate() } } .disabled(appData.selectedID == nil) Button("↓") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.incDate() } } .disabled(appData.selectedID == nil) } } } } struct ContentView_Previews: PreviewProvider { @StateObject static var previewData = RecordHandler() static var previews: some View { ContentView() .environmentObject(previewData) } } @main struct crasherApp: App { @StateObject private var appData = RecordHandler() var body: some Scene { WindowGroup { ContentView() .environmentObject(appData) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’23
Reply to Random SwiftUI crashes
import SwiftUI struct vTime : Codable { var hour : Int var min : Int } struct RecDate : Codable { var day : Int var start: vTime var end : vTime private enum CodingKeys : String, CodingKey { case day case start case end } func duration() -> CGFloat { let dTime : CGFloat = abs(CGFloat(end.hour - start.hour) * 4.0 + CGFloat(end.min - start.min) / 15.0) return dTime } } class Record : Hashable, Equatable, Identifiable, ObservableObject { let vID = UUID() @Published var subject : String @Published var date : RecDate init(subject: String, date : RecDate) { self.subject = subject self.date = date } static func == (lhs: Record, rhs: Record) -> Bool { var r = lhs.subject.compare(rhs.subject) == .orderedSame r = r && lhs.date.start.hour == rhs.date.start.hour r = r && lhs.date.start.min == rhs.date.start.min r = r && lhs.date.end.hour == rhs.date.end.hour r = r && lhs.date.end.min == rhs.date.end.min r = r && lhs.vID == rhs.vID return r } func hash(into hasher: inout Hasher) { hasher.combine(subject) hasher.combine(date.start.hour) hasher.combine(date.start.min) hasher.combine(date.end.hour) hasher.combine(date.end.min) hasher.combine(vID) } func isSelected(appSelection : UUID?) -> Bool { return appSelection == vID } public func incDate() { if !(self.date.end.hour == 19 && self.date.end.min == 0) { self.date.start.min += 15 self.date.end.min += 15 if self.date.start.min == 60 { self.date.start.min = 0 self.date.start.hour += 1 } if self.date.end.min == 60 { self.date.end.min = 0 self.date.end.hour += 1 } } } public func decDate() { if !(self.date.start.hour == 8 && self.date.start.min == 0) { self.date.start.min -= 15 self.date.end.min -= 15 if self.date.start.min < 0 { self.date.start.min = 45 self.date.start.hour -= 1 } if self.date.end.min < 0 { self.date.end.min = 45 self.date.end.hour -= 1 } } } } public class RecordHandler : ObservableObject { @Published var records : [Record] = [ Record(subject: "banana", date: RecDate(day: 0, start: vTime(hour: 8, min: 0), end: vTime(hour: 10, min: 0))), Record(subject: "strawberry", date: RecDate(day: 1, start: vTime(hour: 11, min: 0), end: vTime(hour: 14, min: 0))) ] @Published var selectedID : UUID? = nil func updateRecord(oldID : UUID?, newV : Record) { self.records.removeAll { value in value.vID == oldID } self.records.append(newV) } func setSel(newID : UUID) { if selectedID == nil { selectedID = newID } else { if selectedID == newID { selectedID = nil } else { selectedID = newID } } } } struct EntryView: View { @EnvironmentObject var appData : RecordHandler @ObservedObject var setup : Record @State private var showDataView : Bool = false struct SelView : View { var body: some View { ZStack { Rectangle() .inset(by: -2) .stroke(.blue, lineWidth: 5.0) } } } var body: some View { let qCount = setup.date.duration() let height = qCount * 10.0 let xPos = 100.0 let yPos = 7.0 + (CGFloat(setup.date.start.hour) - 8.0) * 40.0 + CGFloat(setup.date.start.min) / 1.5 + (qCount - 1.0) * 5.0 ZStack { RoundedRectangle(cornerRadius: 10) .foregroundColor(.red.opacity(0.80)) VStack { Text(setup.subject) .bold() .allowsTightening(true) .multilineTextAlignment(.center) .truncationMode(.tail) } .font(.system(size: 10)) .padding([.leading, .trailing], 5) if setup.isSelected(appSelection: appData.selectedID) { SelView() } } .frame(width: 200, height: height) .position(x: xPos, y: yPos) .onTapGesture(count: 1) { appData.setSel(newID: setup.vID) } } } struct RoomView: View { @EnvironmentObject var appData : RecordHandler var body: some View { VStack() { VStack { ForEach(appData.records, id: \.self) { value in EntryView(setup: value) .environmentObject(appData) } } } } } struct DayView: View { @EnvironmentObject var appData : RecordHandler var day : Int var body: some View { VStack { ForEach(appData.records, id: \.self) { value in if value.date.day == day { EntryView(setup: value) .environmentObject(appData) } } } } } struct ContentView: View { @EnvironmentObject var appData : RecordHandler var body: some View { NavigationStack { HStack { DayView(day: 0) .environmentObject(appData) DayView(day: 1) .environmentObject(appData) } } .toolbar { ToolbarItemGroup(placement: .automatic) { Button("↑") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.decDate() } } .disabled(appData.selectedID == nil) Button("↓") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.incDate() } } .disabled(appData.selectedID == nil) } } } } struct ContentView_Previews: PreviewProvider { @StateObject static var previewData = RecordHandler() static var previews: some View { ContentView() .environmentObject(previewData) } } @main struct crasherApp: App { @StateObject private var appData = RecordHandler() var body: some Scene { WindowGroup { ContentView() .environmentObject(appData) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’23
Reply to Random SwiftUI crashes
Now I was able to build a (not so small) example which shows the issue. It shows two rectangles which can be selected. After selection it is possible to move them via the toolbar buttons. Click a rectangle and move it up and down. Change selection and repeat. After some tries it will crash. I post the example in the next post because the message size limit is reached.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Mar ’23
Reply to Live changes of depending State values
I got it now working by using no longer calculated properties but an update function. Here is my working code (Swift Playground on macOS 26): import SwiftUI import Combine @Observable class AppData : ObservableObject { var baseValue : Int = 0 var intValue : String = "0" var hexValue : String = "0" func updateValue(_ v : Int) { //if self.baseValue == v { return } // no short cut here so that illegal chars are filtered self.objectWillChange.send() self.baseValue = v self.intValue = String(v) self.hexValue = String(v, radix: 16).uppercased() } } struct ContentView: View { @State var model = AppData() var body: some View { VStack { Text("Base Value: \(model.baseValue)") HStack { Text("Decimal Value") TextField("Decimal Value", text: $model.intValue) .textFieldStyle(.roundedBorder) .onReceive(Just(model.intValue)) { newValue in let allowedCharacters = "0123456789" let filtered = newValue.filter { allowedCharacters.contains($0) } if let v = Int(filtered) { model.updateValue(v) } } } HStack { Text("Hex Value") TextField("Hex Value", text: $model.hexValue) .textFieldStyle(.roundedBorder) .onReceive(Just(model.hexValue)) { newValue in let allowedCharacters = "0123456789ABCDEFabcdef" let filtered = newValue.filter { allowedCharacters.contains($0) } if let v = Int(filtered, radix: 16) { model.updateValue(v) } } } } .padding() } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Aug ’26
Reply to Live changes of depending State values
I used Swift Playground on macOS 26 for the example. There is something wrong. I look into this and respond later.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Aug ’26
Reply to SwiftSMTP broken: Error ioOnClosedChannel on latest macOS
There is a problem with the SMTP-Server which must be resolved.Sorry for the noise.Unfortunately I cannot delete the post.
Replies
Boosts
Views
Activity
Sep ’25
Reply to Print a SwiftUI view on macOS?
No idea. I've implemented a workaround by creating a PDF. This works well for me. Here is some sample code: func savePDF(docName : String?) { guard let saveURL = showSavePDFPanel(docName) else { return } var mediaBox = NSRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 1100, height: 600)) if let dataConsumer = CGDataConsumer(url: saveURL as CFURL) { if let pdfContext = CGContext(consumer: dataConsumer, mediaBox: &mediaBox, nil) { let options: [CFString: Any] = [kCGPDFContextMediaBox: mediaBox] for sem in ItrSemester.allCases { pdfContext.beginPDFPage(options as CFDictionary) let renderer = ImageRenderer(content: MyView().environmentObject(appData)) renderer.render { size, renderFunction in pdfContext.translateBy(x: (mediaBox.width - size.width) / 2.0, y: (mediaBox.height - size.height) / 2.0) renderFunction(pdfContext) } /// Add a day header to each page with document name let titleString = "\(docName ?? "Ohne Titel")" let attrs : [NSAttributedString.Key : Any] = [.font: NSFont.boldSystemFont(ofSize: 16.0)] let day = NSAttributedString(string: titleString, attributes: attrs) let path = CGMutablePath() let strWidth = day.size().width + 1 let strHeight = day.size().height + 1 let dayXPos = 20.0 let dayYPos = mediaBox.height - strHeight - 32 path.addRect(CGRect(x: dayXPos, y: dayYPos, width: strWidth, height: strHeight)) let fSetter = CTFramesetterCreateWithAttributedString(day as CFAttributedString) let frame = CTFramesetterCreateFrame(fSetter, CFRangeMake(0, day.length), path, nil) CTFrameDraw(frame, pdfContext) pdfContext.endPDFPage() } pdfContext.closePDF() } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’24
Reply to "reset" users home dir to archived content
Meanwhile I got a solution I want to share here: It seems so that the OS has some "voodoo" to protect used home directories. So a change of users home dir via dscl . -change /Users/USER NFSHomeDirectory /Users/USER /doesNotExist allows removing the HOMEDIR and re-create it from a template. Afterwards the command dscl . -change /Users/USER NFSHomeDirectory /doesNotExist /Users/USER does set the homedir back to the old value.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Feb ’24
Reply to SwiftUI alert buttons order issue
How about using no role at all? Without a role there is no reason for the OS to rearrange the buttons. Something like .alert( "Test alert", isPresented: $isAlertPresented, actions: { Button("Default role", action: { }) Button("Cancel role", role: .none, action: { isAlertPresented = false }) }, message: { Text("Test message") }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’23
Reply to Swift Regex too slow als grep replacement?
I note that none of your regular expressions actually need to be regular expressions, i.e. they are just fixed text strings. For example, where you have "non.sense", I think you only want it to literally match "non.sense", not "non0sense". Yes. The first two filters are fixed strings but the last one contains a lot of different search strings. Therefore RegEx makes sense. You're right that a simple string search may be faster but since it takes now just 3 seconds I'm fine with it. Thanks for sharing your thoughts on my code.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Swift Regex too slow als grep replacement?
There was another discussion on https://forums.swift.org/t/use-regexbuilder-als-grep-replacement/65782 where I was able to get much faster code. This code does now run in 3 seconds. let paths = ["regTest/logs/access.log", "/regTest/logs/access.log.1"] var startDate = Date() let matchedLines = try await withThrowingTaskGroup(of: [String].self, body: { group in for aPath in paths { group.addTask { let lines = FileHandle(forReadingAtPath: aPath)!.bytes.lines .filter { $0.contains("26/Apr") } .filter { $0.contains("\"GET ") } .filter{ !$0.contains(botListRegEx) } var matched : [String] = [] for try await line in lines { if let m = line.firstMatch(of: ipAtStartRegEx) { let (s, _) = m.output matched.append(String(s)) } } return matched } } var matchedLines : [String] = [] for try await partialMatchedLines in group { matchedLines.append(contentsOf: partialMatchedLines) } return matchedLines }) let uniqArray = Set(matchedLines) print("Match time: \(abs(startDate.timeIntervalSinceNow)) s") print("Found \(matchedLines.count) lines.") print("Found \(uniqArray.count) IP adresses.")
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’23
Reply to Swift Regex too slow als grep replacement?
Good catch. Did you also change the definition of the regex to remove the Capture { } ? Nope. I did just replace "firstMatch". Now I used a plain string and it is much faster. Also I use now another split which is way faster (20 vs. 50s). So here is the code let matchedLines = fullText.split(whereSeparator: \.isNewline) .filter{ $0.contains(yesterdayRegEx) } .filter{ $0.contains(botListRegEx) } Match time: 52.7 s let matchedLines = fullText.split(whereSeparator: \.isNewline) .filter{ $0.contains("26/Apr") } .filter{ $0.contains(botListRegEx) } Match time: 21.8 s So the slow part is now the Split which take most of the time (21 s).
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’23
Reply to Swift Regex too slow als grep replacement?
.filter{ $0.contains(yesterdayRegEx) } .filter{ $0.contains(botListRegEx) } Makes no difference. But now I got another idea: I removed the filter to get a clue how much time the spilt needs. It is about 50 s! Therefore the split is the major slowdown and the RegEx take just 30 s.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’23
Reply to Swift Regex too slow als grep replacement?
The Swift code is fast for everything but the RegEx. The file read takes about 1 s but the RegEx takes more than 80 s. That's why I ask for help to speed-up the RegEx. My Swift sample code does no sort and uniq as in the shell example. This will be added after the RegEx is usable. I won´t care if the code in not quite so fast as my shell but it must be much quicker to be usable.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’23
Reply to Open file in Finder does not work on App launch
To answer my own question: There is currently no "SwiftUI like“ way to handle this. So use just the old way via AppDelegate: final class AppDelegate: NSObject, NSApplicationDelegate { func application(_ application: NSApplication, open urls: [URL]) { // Read the provided URLs } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Apr ’23
Reply to Random SwiftUI crashes
Here is a smaller version which does also crash (now tested with new Xcode 14.3): import SwiftUI struct vTime : Codable { var hour : Int var min : Int } struct RecDate : Codable { var day : Int var start: vTime var end : vTime private enum CodingKeys : String, CodingKey { case day case start case end } func duration() -> CGFloat { let dTime : CGFloat = abs(CGFloat(end.hour - start.hour) * 4.0 + CGFloat(end.min - start.min) / 15.0) return dTime } } class Record : Hashable, Equatable, Identifiable, ObservableObject { let vID = UUID() @Published var subject : String @Published var date : RecDate init(subject: String, date : RecDate) { self.subject = subject self.date = date } static func == (lhs: Record, rhs: Record) -> Bool { var r = lhs.subject.compare(rhs.subject) == .orderedSame r = r && lhs.date.start.hour == rhs.date.start.hour r = r && lhs.date.start.min == rhs.date.start.min r = r && lhs.date.end.hour == rhs.date.end.hour r = r && lhs.date.end.min == rhs.date.end.min r = r && lhs.vID == rhs.vID return r } func hash(into hasher: inout Hasher) { hasher.combine(subject) hasher.combine(date.start.hour) hasher.combine(date.start.min) hasher.combine(date.end.hour) hasher.combine(date.end.min) hasher.combine(vID) } func isSelected(appSelection : UUID?) -> Bool { return appSelection == vID } public func incDate() { if !(self.date.end.hour == 19 && self.date.end.min == 0) { self.date.start.min += 15 self.date.end.min += 15 if self.date.start.min == 60 { self.date.start.min = 0 self.date.start.hour += 1 } if self.date.end.min == 60 { self.date.end.min = 0 self.date.end.hour += 1 } } } public func decDate() { if !(self.date.start.hour == 8 && self.date.start.min == 0) { self.date.start.min -= 15 self.date.end.min -= 15 if self.date.start.min < 0 { self.date.start.min = 45 self.date.start.hour -= 1 } if self.date.end.min < 0 { self.date.end.min = 45 self.date.end.hour -= 1 } } } } public class RecordHandler : ObservableObject { @Published var records : [Record] = [ Record(subject: "banana", date: RecDate(day: 0, start: vTime(hour: 8, min: 0), end: vTime(hour: 10, min: 0))), Record(subject: "strawberry", date: RecDate(day: 1, start: vTime(hour: 11, min: 0), end: vTime(hour: 14, min: 0))) ] @Published var selectedID : UUID? = nil func setSel(newID : UUID) { if selectedID == nil { selectedID = newID } else { if selectedID == newID { selectedID = nil } else { selectedID = newID } } } } struct EntryView: View { @EnvironmentObject var appData : RecordHandler @ObservedObject var setup : Record @State private var showDataView : Bool = false struct SelView : View { var body: some View { Rectangle() .inset(by: -2) .stroke(.blue, lineWidth: 5.0) } } var body: some View { let qCount = setup.date.duration() let height = qCount * 10.0 let xPos = 100.0 let yPos = 7.0 + (CGFloat(setup.date.start.hour) - 8.0) * 40.0 + CGFloat(setup.date.start.min) / 1.5 + (qCount - 1.0) * 5.0 ZStack { RoundedRectangle(cornerRadius: 10) .foregroundColor(.red.opacity(0.80)) Text(setup.subject) if setup.isSelected(appSelection: appData.selectedID) { SelView() } } .frame(width: 200, height: height) .position(x: xPos, y: yPos) .onTapGesture(count: 1) { appData.setSel(newID: setup.vID) } } } struct DayView: View { @EnvironmentObject var appData : RecordHandler var day : Int var body: some View { VStack { ForEach(appData.records, id: \.self) { value in if value.date.day == day { EntryView(setup: value) .environmentObject(appData) } } } } } struct ContentView: View { @EnvironmentObject var appData : RecordHandler var body: some View { NavigationStack { HStack { DayView(day: 0) .environmentObject(appData) DayView(day: 1) .environmentObject(appData) } } .toolbar { ToolbarItemGroup(placement: .automatic) { Button("↑") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.decDate() } } .disabled(appData.selectedID == nil) Button("↓") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.incDate() } } .disabled(appData.selectedID == nil) } } } } struct ContentView_Previews: PreviewProvider { @StateObject static var previewData = RecordHandler() static var previews: some View { ContentView() .environmentObject(previewData) } } @main struct crasherApp: App { @StateObject private var appData = RecordHandler() var body: some Scene { WindowGroup { ContentView() .environmentObject(appData) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’23
Reply to Random SwiftUI crashes
import SwiftUI struct vTime : Codable { var hour : Int var min : Int } struct RecDate : Codable { var day : Int var start: vTime var end : vTime private enum CodingKeys : String, CodingKey { case day case start case end } func duration() -> CGFloat { let dTime : CGFloat = abs(CGFloat(end.hour - start.hour) * 4.0 + CGFloat(end.min - start.min) / 15.0) return dTime } } class Record : Hashable, Equatable, Identifiable, ObservableObject { let vID = UUID() @Published var subject : String @Published var date : RecDate init(subject: String, date : RecDate) { self.subject = subject self.date = date } static func == (lhs: Record, rhs: Record) -> Bool { var r = lhs.subject.compare(rhs.subject) == .orderedSame r = r && lhs.date.start.hour == rhs.date.start.hour r = r && lhs.date.start.min == rhs.date.start.min r = r && lhs.date.end.hour == rhs.date.end.hour r = r && lhs.date.end.min == rhs.date.end.min r = r && lhs.vID == rhs.vID return r } func hash(into hasher: inout Hasher) { hasher.combine(subject) hasher.combine(date.start.hour) hasher.combine(date.start.min) hasher.combine(date.end.hour) hasher.combine(date.end.min) hasher.combine(vID) } func isSelected(appSelection : UUID?) -> Bool { return appSelection == vID } public func incDate() { if !(self.date.end.hour == 19 && self.date.end.min == 0) { self.date.start.min += 15 self.date.end.min += 15 if self.date.start.min == 60 { self.date.start.min = 0 self.date.start.hour += 1 } if self.date.end.min == 60 { self.date.end.min = 0 self.date.end.hour += 1 } } } public func decDate() { if !(self.date.start.hour == 8 && self.date.start.min == 0) { self.date.start.min -= 15 self.date.end.min -= 15 if self.date.start.min < 0 { self.date.start.min = 45 self.date.start.hour -= 1 } if self.date.end.min < 0 { self.date.end.min = 45 self.date.end.hour -= 1 } } } } public class RecordHandler : ObservableObject { @Published var records : [Record] = [ Record(subject: "banana", date: RecDate(day: 0, start: vTime(hour: 8, min: 0), end: vTime(hour: 10, min: 0))), Record(subject: "strawberry", date: RecDate(day: 1, start: vTime(hour: 11, min: 0), end: vTime(hour: 14, min: 0))) ] @Published var selectedID : UUID? = nil func updateRecord(oldID : UUID?, newV : Record) { self.records.removeAll { value in value.vID == oldID } self.records.append(newV) } func setSel(newID : UUID) { if selectedID == nil { selectedID = newID } else { if selectedID == newID { selectedID = nil } else { selectedID = newID } } } } struct EntryView: View { @EnvironmentObject var appData : RecordHandler @ObservedObject var setup : Record @State private var showDataView : Bool = false struct SelView : View { var body: some View { ZStack { Rectangle() .inset(by: -2) .stroke(.blue, lineWidth: 5.0) } } } var body: some View { let qCount = setup.date.duration() let height = qCount * 10.0 let xPos = 100.0 let yPos = 7.0 + (CGFloat(setup.date.start.hour) - 8.0) * 40.0 + CGFloat(setup.date.start.min) / 1.5 + (qCount - 1.0) * 5.0 ZStack { RoundedRectangle(cornerRadius: 10) .foregroundColor(.red.opacity(0.80)) VStack { Text(setup.subject) .bold() .allowsTightening(true) .multilineTextAlignment(.center) .truncationMode(.tail) } .font(.system(size: 10)) .padding([.leading, .trailing], 5) if setup.isSelected(appSelection: appData.selectedID) { SelView() } } .frame(width: 200, height: height) .position(x: xPos, y: yPos) .onTapGesture(count: 1) { appData.setSel(newID: setup.vID) } } } struct RoomView: View { @EnvironmentObject var appData : RecordHandler var body: some View { VStack() { VStack { ForEach(appData.records, id: \.self) { value in EntryView(setup: value) .environmentObject(appData) } } } } } struct DayView: View { @EnvironmentObject var appData : RecordHandler var day : Int var body: some View { VStack { ForEach(appData.records, id: \.self) { value in if value.date.day == day { EntryView(setup: value) .environmentObject(appData) } } } } } struct ContentView: View { @EnvironmentObject var appData : RecordHandler var body: some View { NavigationStack { HStack { DayView(day: 0) .environmentObject(appData) DayView(day: 1) .environmentObject(appData) } } .toolbar { ToolbarItemGroup(placement: .automatic) { Button("↑") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.decDate() } } .disabled(appData.selectedID == nil) Button("↓") { if let ds = appData.records.first(where: { $0.vID == appData.selectedID!}) { ds.incDate() } } .disabled(appData.selectedID == nil) } } } } struct ContentView_Previews: PreviewProvider { @StateObject static var previewData = RecordHandler() static var previews: some View { ContentView() .environmentObject(previewData) } } @main struct crasherApp: App { @StateObject private var appData = RecordHandler() var body: some Scene { WindowGroup { ContentView() .environmentObject(appData) } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’23
Reply to Random SwiftUI crashes
Now I was able to build a (not so small) example which shows the issue. It shows two rectangles which can be selected. After selection it is possible to move them via the toolbar buttons. Click a rectangle and move it up and down. Change selection and repeat. After some tries it will crash. I post the example in the next post because the message size limit is reached.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Mar ’23