Post

Replies

Boosts

Views

Activity

Reply to Porting Thread & Delegate Code to Swift 6 Using Tasks
Hello and thank you for your reply. The problem is that I simply have not found a working example for what I am actually trying to do. In one of my tests I also tried to simulate a long running operation with await Task.sleep(...) and it worked. But as soon as I want to run some other code (that by default is not await able because it is not async), I don't know what to do. That's why I thought that putting the code into an async function so I could use await would be the correct move. I have created another small demo. In it, a 512 MB file is written to a rather old (and slow) external hard disk: import Observation import AppKit @Observable final class Model : Sendable { @MainActor var controller = AsyncController() init() { } } @Observable // Too good to not use. @MainActor // Required for Observable to work? Can't get it to work without it. class AsyncController { private(set) var isWorking = false public func heavyWork() async throws { self.isWorking = true do { try await self.save() } catch { Swift.print(error.localizedDescription) } self.isWorking = false } func save() async throws { let task = Task { let data = Data(count: 512 * 1024 * 1024) let url = URL(fileURLWithPath: "/Volumes/LaCie/out.bin") try data.write(to: url) } return try await task.value } } In this example, the Observable property works fine. As soon as I click the button, the ProgressView is shown. However, the GUI is unresponsive (we are using the Main Actor, so this is to be expected I guess, but I created a new Task so that's what I don't understand). I also don't see why this should be done in a separate Task, I am already using a Task when clicking the button: func save() throws { let data = Data(count: 512 * 1024 * 1024) let url = URL(fileURLWithPath: "/Volumes/LaCie/out.bin") try data.write(to: url) } So my next best guess was to simply remove the @MainActor from the AsyncController to get this thing off the main thread: @Observable class AsyncController { } But now the compiler complains: Button("Write") { Task { try await self.model.controller.heavyWork() // Error: Sending 'self.model.controller' risks causing data races } } Regards, Sascha
Jul ’24
Reply to Loading NSImage from icns file takes very long for Visual Studio Code icon
I also tested this on my Mac mini with a M1 processor. I used the following code: private func loadImage(from: String) { let start = Date.now.timeIntervalSince1970 let image = NSImage(contentsOf: URL(string: from)!) let duration = Date.now.timeIntervalSince1970 - start Swift.print(duration) } I called the function with a local and a remote URL: self.loadImage(from: "https://sascha-simon.com/Code.icns") self.loadImage(from: "/Users/inexcitus/Downloads/Code.icns") When calling this code from an app, everything seems to work fine. Both functions run rather quickly: 0.044709205627441406 0.002862215042114258 I then ran the code inside of a unit test and then it is slow again (more than four seconds). I added the following code inside one of my unit tests: let icon = self.loadImage(from: "/Applications/Visual Studio Code.app/Contents/Resources/Code.icns") // For this URL I had to use another init function for the URL: let image = NSImage(contentsOf: URL(filePath: from)) Output: 4.394075155258179 It is somehow related to my code running in the xctest executable. Other icons work just fine, it is always this icon in particular. There is no cacheing on my side, when I load the same icon later, it loads almost immediately so I guess Cocoa uses cacheing.
Aug ’23
Reply to Get Model Identifier of Device in Network
Hello, thank you for your information. I have tried searching for any devices that publish this information, but I do not get any results. I assumed that the service is _device-info._tcp. I have added the Bonjour Services key to my Info.plist. I also tried searching for this service using the Terminal using this command: dns-sd -B _device-info._tcp Nothing is shown on my Terminal (dns-sd -B _ssh._tcp lists a couple of items, so the syntax seems to be correct). I also tried using the IP address: dns-sd -B _device-info._tcp 192.168.178.101 I tried "asking" the host directly: let service = NetService(domain: "local.", type: "_device-info._tcp", name: "Mac-Mini.fritz.box") service.delegate = self service.startMonitoring() No results though. This also does not give any results. As you mentioned, there is no public API so I guess I can not get any detailed information. But am I at least on the right track? 😀
Mar ’23
Reply to Porting existing LoginItem Logic to the new SMAppService
Hello, I completely reset my test machine and now it works as expected. One item was a duplicate of a test version of my app. I have one additional question: if a user has used my app prior to the release of macOS 13 and set the auto start via SMLoginItemSetEnabled, the item will probably be visible in System Preferences. I would like to remove this Login Item entry and enable the main item entry. Is there any way of doing this? I tried to use SMAppService.unregister, which sets the state properly. However, the item is not removed (like you said, it only shows if the item could make any changes in the background). Can I completely remove the entry (only for my app of course). Regards
Sep ’22
Reply to Porting existing LoginItem Logic to the new SMAppService
Update: This is my code now: try? SMAppService.loginItem(identifier: "com.somecompany.something").unregister() // Successful SMAppService.loginItem(identifier: "com.somecompany.something").status == .enabled // Returns false, the actual status is 'notRegistered' However, the app is started automatically after restart. Either there is some sort of remnant of the past on my system...or there is a bug?
Sep ’22
Reply to Porting existing LoginItem Logic to the new SMAppService
So I guess using the main app is wrong then, I still have to use the LoginItem? try? SMAppService.loginItem(identifier: "com.somecompany.something").register() Instead of SMLoginItemSetEnabled( "com.somecompany.something" as CFString, true) Maybe the description of the Background section could be updated to reflect auto starting apps (via LoginItems). Edit: Seems to work, I just did not understand it properly. Thanks. Regards, Sascha
Sep ’22
Reply to Can not get FileHandle on MS-DOS file systems: The operation couldn’t be completed. Operation not permitted
Hello, thanks for your reply. If I disable the sandbox, it works as expected, no error is shown. I have created an empty MS-DOS image and this also works, if the sandbox is enabled. The following error messages are shown in the Console: error 15:10:01.039684+0200 kernel System Policy: Process(2659) deny(1) file-read-data /Volumes/SD CARD/File.tmp error 15:10:01.046855+0200 kernel System Policy: Process(2659) deny(1) file-write-unlink /Volumes/SD CARD/FileRead.tmp error 15:10:01.047082+0200 kernel System Policy: Process(2659) deny(1) file-read-data /Volumes/SD CARD/FileRead.tmp error 15:10:01.047214+0200 kernel System Policy: Process(2659) deny(1) file-write-unlink /Volumes/SD CARD/File.tmp error 15:10:01.047332+0200 kernel System Policy: Process(2659) deny(1) file-write-unlink /Volumes/SD CARD/FileRead.tmp error 15:10:01.047454+0200 kernel System Policy: Process(2659) deny(1) file-write-unlink /Volumes/SD CARD/File.tmp error 15:10:01.047671+0200 kernel System Policy: Process(2659) deny(1) file-write-unlink /Volumes/SD CARD/FileRead.tmp Sometimes, writing to the SD card is successful, but then the read access is denied. Further write attempts also fail, but if I wait a couple of seconds, writing will succeed. Reading always fails though. Hopefully this explanation helps a little bit. Regards, Sascha
May ’22