Post not yet marked as solved
I am attempting to dynamically clone a class object in Swift using reflection and the setValue function. This class contains an enum property that is backed with an Int, which is causing this dynamic reflection to crash:
@objc enum Status : Int {
case green
case yellow
case red
}
@objc class State : NSObject {
@objc var status : Status
init(_ status: Status) {
self.status = status
}
}
func testReflectiveClone() {
let state1 = State(.green)
let state2 = State(.yellow)
let state1Mirror = Mirror(reflecting: state1)
for property in state1Mirror.children.enumerated() {
let label = property.element.label
state2.setValue(property.element.value, forKey: label!) //crashes here
}
}
This test function is throwing the following error in XCode:
-[__SwiftValue longLongValue]: unrecognized selector sent to instance 0x600001e5a340 (NSInvalidArgumentException)
Is it even possible to dynamically set enum values? What modification would I need to make to get this to work?
Post not yet marked as solved
I have an XCode Workspace that builds a product as a universal binary for Intel and Apple Silicon.
On an Intel-based machine, I am attempting to import a Swift Package dependency by accessing a private git repository.
When I attempt to import my dependency into my code and build, I'm getting the following error:
Could not find module '<swift package name>' for target 'arm64-apple-macos'; found: x86_64, x86_64-apple-macos
The project has Standard Architectures set for the ARCHS build setting and ONLY_ACTIVE_ARCH = NO. When I switch ONLY_ACTIVE_ARCH = YES, it builds fine.
Is there a way to instruct the compiler to build the swift package dependency as universal and resolve this issue?
I have a use case in which I have a launch daemon (as the XPC service) than needs to communicate with two XPC clients. Each of these clients has different functional cases for communication that do not overlap. Therefore, the NSXPCInterface for client A would be configured with a different protocol than the NSXPCInterface that would be configured for client B. Client A and Client B do not need to talk to each other; they each just need to communicate with the daemon.
I am confused how to appropriately set up the NSXPCListener and NSXPCListenerDelegate on the daemon to support NSXPCConnections with proxy objects that adhere to varying interfaces to support these two clients.
Is there a way for a single NSXPCListener (and associated delegate) to listen for connections requiring the exportedInterface to be different?
Is there a way to send data through the NSXPCConnection that will allow the NSXPCListenerDelegate to conditionally determine which exported interface and object to configure?
One idea I had was to have the daemon contain two NSXPCListeners. Each listener would be responsible for connections coming from the respective clients.
Will this option work? If so, it is the advisable approach?
I have small integration test that is confirming behavior in XPC communications (leveraging NSXPCConnection) between a dummy XPC service and an XPC client. My test is flaky, which is indicating to me that I don't fully understand the nature of connections between services and clients, and I was hoping to get clarity as to what's happening in my test.
My test involves the following steps.
XCode Pre-Action: Load the plist for a dummy XPC service into launchctl.
Create 2 XPC client objects (in the same client process), each with their own NSXPCConnection to the dummy service, and connect.
Tell client 1 to disconnect, which calls NSXPCConnection.invalidate()
Using client 2, send a message to the same dummy XPC service over it's own NSXPCConnection object.
Wait for the echo response from the dummy XPC service
XCode Post-Action: Unload the plist for the dummy XPC service from launchctl
func testMultipleConnections() {
let delegate1 = MockClientDelegate()
let delegate2 = MockClientDelegate()
let client1 = XPCMessagingClientFacade(withServiceName: serviceName, andXPCErrorHandler: {error in })
let client2 = XPCMessagingClientFacade(withServiceName: serviceName, andXPCErrorHandler: {error in })
client1.processMessageDelegate = delegate1
client2.processMessageDelegate = delegate2
_ = client1.connect()
_ = client2.connect()
_ = client1.disconnect()
delegate2.expectation = XCTestExpectation(description: "Message received from echo service")
_ = client2.sendMessage(ofMessageType: eMTAction_Uninstall, withData: ["dummy": "data"])
wait(for: [delegate2.expectation!], timeout: timeout)
}
This test sometimes succeeds and sometimes fails. Sometimes, the test expectation at the bottom is fulfilled, and sometimes the timeout is hit. I have tested with excessively long timeouts to rule-out processing-time as as factor.
I am suspecting that calling invalidate() on one NSXPCConnection object is somehow causing a separate connection between the same client and service process to also be invalidated.
Is it even a valid use-case to have multiple NSXPCConnection objects between a single XPC Service and XPC Client?
When NSXPCConnection.invalidate() is called, does it inherently mean nothing can connect and communicate anymore, or is it just for that specific connection?
When invalidate() is called, what does launchctl do to manage that service? Does it shut it down and allow subsequent connection attempts to spool the service up again? Does it prevent from any connections from ever being made again?