Post

Replies

Boosts

Views

Activity

Reply to Setup LaunchAgent in Xcode
Probably. Both of your examples seem kinda wonky to me. Yeah this is garbage code anyway. I'll prolly use a singleton or instantiate it in the App stuct. You have double dots in that screen shot, that is, this: I already fixed this :) But it did not fixed it. I put the code into this repo: https://github.com/tony-go/NetworkMonitor The only missing part is the ~/Library/LaunchAgents/W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc.plist file: <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc</string> <key>ProgramArguments</key> <array> <string>/Users/tonygorez/Desktop/Builds/Release/NetworkMonitor</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <false/> <key>MachServices</key> <dict> <key>com.tonygo.NetworkMonitorAgent</key> <true/> </dict> </dict> </plist>
Jan ’24
Reply to Setup LaunchAgent in Xcode
Hey 👋 The next to me is to enable the App Sandbox again and use App groups. So I did the following: Create an app group on Xcode Change the entitlements of each target Change the MACH_SERVICE_NAME var (used to establish connection) let MACH_SERVICE_NAME = "W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc" Change the name of launchd agent in the .plist and change the name of the file ➜ LaunchAgents launchctl list | grep tonygo\ 49603 0 W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc I see logs of the loaded agent, But I still have the lookup error... Did I miss something @eskimo ?
Jan ’24
Reply to Setup LaunchAgent in Xcode
I spotted it; this is probably the moment you throw virtual tomatoes at me, haha. This seems to come from how I instantiate the Client class: The code that does not work: struct ContentView: View { @State private var networkStatus: String = "Off" var body: some View { Text("Network status: \(networkStatus)") .onAppear { NetworkMonitorXPCClient().getNetworkStatus { status in DispatchQueue.main.async { self.networkStatus = status ? "Online" : "Offline" } } } } } The code that works: struct ContentView: View { @State private var networkStatus: String = "Off" private var xpc = NetworkMonitorXPCClient() var body: some View { Text("Network status: \(networkStatus)") .onAppear { xpc.getNetworkStatus { status in DispatchQueue.main.async { self.networkStatus = status ? "Online" : "Offline" } } } } } This maybe due to how the onAppear code is executed?
Jan ’24
Reply to Setup LaunchAgent in Xcode
You’re doing that from Terminal app, logged in to the same GUI login context as the client app, right? Yeah. Do you see any additional log messages in the system log when you run your app and try to connect? No, but I observe another thing, once the macOS is up, I see two launchd agents in the console. ➜ ~ launchctl list | grep tonygo 22718 0 application.com.tonygo.NetworkMonitorApp.138426740.138426852.1D8FCF73-1582-44D3-AA62-4888F3AC0D07 22433 0 com.tonygo.NetworkMonitorAgent But this probably the app itself as, the build identifier is different and even if I comment the whole NSXPCConnection logic and re-run (after a clean build) again, I see the Xcode agent. So this is probably not related. Maybe should I publish the code somewhere?
Jan ’24
Reply to Setup LaunchAgent in Xcode
As to your invalidation problem, that’s likely because the service name isn’t being registered properly. What does your agent’s property list look like? And how are you loading it? The code is: import Foundation import OSLog class NetworkMonitorXPCService: NSObject, NetworkMonitorXPCProtocol, NSXPCListenerDelegate { func getNetworkStatus(reply: @escaping (Bool) -> Void) { // Implement your logic to determine the network status let networkStatus: Bool = true reply(networkStatus) } /// This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { Logger.agent.debug("In listener") // Configure the connection. // First, set the interface that the exported object implements. newConnection.exportedInterface = NSXPCInterface(with: NetworkMonitorXPCProtocol.self) Logger.agent.debug("After Exported Interface") // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object. newConnection.exportedObject = self Logger.agent.debug("After Exported Object") // Resuming the connection allows the system to deliver more incoming messages. newConnection.resume() Logger.agent.debug("After Exported Resume") // Returning true from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call invalidate() on the connection and return false. return true } } Logger.agent.info("Start agent") let delegate = NetworkMonitorXPCService() let listener = NSXPCListener.init(machServiceName: MACH_SERVICE_NAME) // declared as: let MACH_SERVICE_NAME = "com.tonygo.NetworkMonitorAgent" listener.delegate = delegate listener.resume() Logger.agent.info("Agent started") RunLoop.main.run() I have this .plist file: <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.tonygo.NetworkMonitorAgent</string> <key>ProgramArguments</key> <array> <string>/Users/tonygorez/Desktop/Builds/Release/NetworkMonitor</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <false/> <key>MachServices</key> <dict> <key>com.tonygo.NetworkMonitorAgent</key> <true/> </dict> </dict> </plist> For the loading I just run: launchctl load ~/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent.plist ➜ ~ launchctl list | grep tonygo 11588 0 com.tonygo.NetworkMonitorAgent I also take a look at the console. (see joined screen)
Jan ’24
Reply to Setup LaunchAgent in Xcode
Again thanks @eskimo , for your answers :) Before diving into SMAppService, I try to load the agent manually and start a macOS app that will connect with the Agent. (I'd like to use a minimalist setup at first and add layers as much as I face limitations, this is the way I'd like to discover new topics :) ) I faced several issues: Sandbox: NetworkMonitorApp(2330) deny(1) mach-lookup com.tonygo.NetworkMonitorAgent from the agent log, then I add com.apple.security.temporary-exception.mach-lookup.global-name (I Imagine that SMAppService will remove this) - The message dissapeard. I still have a The connection to service named com.tonygo.NetworkMonitorAgent was invalidated from this process. from th macOS app. Note: I also authorize Server and Client connextion from sandbox or even remove the sandbox, but it did not change... Either it is not possible at all to do this kind of unsafe XPC connection, or I miss something :)
Jan ’24
Reply to Impossible to use $R* variables after `continue` command
Edit: (lldb) b -[NSView hitTest:] Breakpoint 1: where = AppKit`-[NSView hitTest:], address = 0x0000000183857e18 (lldb) process launch -e /dev/null -- Process 4125 launched: '/System/Applications/Notes.app/Contents/MacOS/Notes' (arm64e) Process 4125 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x000000018c093e18 AppKit` -[NSView hitTest:] AppKit`-[NSView hitTest:]: -> 0x18c093e18 <+0>: pacibsp 0x18c093e1c <+4>: sub sp, sp, #0x70 0x18c093e20 <+8>: stp x24, x23, [sp, #0x30] 0x18c093e24 <+12>: stp x22, x21, [sp, #0x40] 0x18c093e28 <+16>: stp x20, x19, [sp, #0x50] 0x18c093e2c <+20>: stp x29, x30, [sp, #0x60] 0x18c093e30 <+24>: add x29, sp, #0x60 0x18c093e34 <+28>: mov x19, x0 Target 0: (Notes) stopped. (lldb) p $arg1 (unsigned long) $2 = 4312972736 (lldb) po $2 <NSTitlebarContainerView: 0x10112bdc0> (lldb) c Process 4125 resuming -- later Process 4125 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x000000018c093e18 AppKit` -[NSView hitTest:] AppKit`-[NSView hitTest:]: -> 0x18c093e18 <+0>: pacibsp 0x18c093e1c <+4>: sub sp, sp, #0x70 0x18c093e20 <+8>: stp x24, x23, [sp, #0x30] 0x18c093e24 <+12>: stp x22, x21, [sp, #0x40] 0x18c093e28 <+16>: stp x20, x19, [sp, #0x50] 0x18c093e2c <+20>: stp x29, x30, [sp, #0x60] 0x18c093e30 <+24>: add x29, sp, #0x60 0x18c093e34 <+28>: mov x19, x0 Target 0: (Notes) stopped. (lldb) po $2 <NSTitlebarContainerView: 0x10112bdc0> (lldb) c -- later, after pausing -- (lldb) po $2 <NSTitlebarContainerView: 0x10112bdc0>
Jul ’23
Reply to Impossible to use $R* variables after `continue` command
I tried outside of Xcode, attaching the debugger to the Notes app: (lldb) b -[NSView hitTest:] Breakpoint 1: where = AppKit`-[NSView hitTest:], address = 0x0000000183857e18 (lldb) process launch -e /dev/null -- Process 4125 launched: '/System/Applications/Notes.app/Contents/MacOS/Notes' (arm64e) Process 4125 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x000000018c093e18 AppKit` -[NSView hitTest:] AppKit`-[NSView hitTest:]: -> 0x18c093e18 <+0>: pacibsp 0x18c093e1c <+4>: sub sp, sp, #0x70 0x18c093e20 <+8>: stp x24, x23, [sp, #0x30] 0x18c093e24 <+12>: stp x22, x21, [sp, #0x40] 0x18c093e28 <+16>: stp x20, x19, [sp, #0x50] 0x18c093e2c <+20>: stp x29, x30, [sp, #0x60] 0x18c093e30 <+24>: add x29, sp, #0x60 0x18c093e34 <+28>: mov x19, x0 Target 0: (Notes) stopped. (lldb) p $arg1 (unsigned long) $2 = 4312972736 (lldb) po $2 <NSTitlebarContainerView: 0x10112bdc0> It seems to work in this context.
Jul ’23