In response to my feedback submission, apple says that our transparent network proxy is stopping because, somehow, the file descriptor for com.apple.flow-divert is being closed. Only, they haven't (yet?) given any advice on how to debug that -- the extension is written in Swift, and by itself does not close any file descriptor. So I have no idea how I'd go about trying to debug that, let alone fix it.
Anyone have any thoughts about this?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
This has happened a few times, including out in the field; it's happened on macOS 14 and 15 I think.
"This" is: our app runs, activates the extension, it has to get user approval, and... the system dialogue window never appears. The extension stays waiting for user approval. I've got sysdiagnose from one of the systems, and I see the system log about it going into the user approval needed state, and... nothing else.
It's there in Settings, and can be approved then.
Has anyone run into this? Ever?
I spent 20 minutes trying to figure out why codesigning was failing -- I had the pf block set up correctly, my keychains were unlocked, and then, eventually, it occurred to me, hey, maybe an IP address changed, so I disabled IPv6 except for link local, and then amazingly, it went back to working.
I filed FB13706261 over a year ago.
This is ridiculous.
In doing some work, I realized I didn't understand XPC (or at least, the higher-level APIs) at all. So I did what I usually try to do, which is to write a completely, brain-dead simple program to use it, and then keep expanding until I understand it. This also, to my utmost embarrassment, will make it transparently clear how ignorant I am. (Note that, for this, I am not using Xcode -- just using swiftc to compile, and then manually run.)
I started with this, to be the server side:
import Foundation
class ConnectionHandler: NSObject, NSXPCListenerDelegate {
override init() {
super.init()
print("ConnectionHandler.init()")
}
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
print("ConnectionHandler.listener()")
return false
}
}
let handler = ConnectionHandler()
let listener = NSXPCListener(machServiceName: "com.kithrup.test")
listener.delegate = handler
listener.resume()
print("listener = \(listener)")
dispatchMain()
That ... does absolutely nothing, of course, but runs, and then I tried to write the client side:
import Foundation
@objc protocol Hello {
func hello()
}
class HelloClass: NSObject, Hello {
override init() {
super.init()
}
func hello() {
print("In HelloClass.hello()")
}
}
let hello = HelloClass()
let connection = NSXPCConnection(machServiceName: "com.kithrup.test", options: [])
connection.exportedInterface = NSXPCInterface(with: Hello.self)
let proxy = connection.remoteObjectProxyWithErrorHandler({ error in
print("Got error \(error)")
}) as? Hello
print("proxy = \(proxy)")
connection.resume()
dispatchMain()
That gets proxy as nil. Because it can't coerce it to something of Hello protocol. And at no point, do I get the message from the server-side listener.
So clearly I am doing everything wrong. Can anyone offer some hints?
I've been trying and googling and forum-reading this for a couple of days, and ... am either missing something obvious, or am simply dumb. I'd prefer to simply be ignorant, and so I ask. 😄
I've got a personal, paid account. I've got some projects, and I've got some git repos. I'd like to allow some other people to check out a repo and then build the associated project. Only they can't, because the bundle identifier conflicts. The bundle identifier is, e.g., com.kithrup.filterTest. In my Xcode, the selected team is me. And that works, which isn't surprising because I did create it after all.
I've tried using App Store Connect to invite someone, and they do show up there. But they can't build either, again due to the bundle identifier conflict. (Also they can't find any provisioning profiles, which makes sense given everything else not working.)
This is a remarkably basic question for someone who's been developing on the Mac for... oh my, coming up on 20 years in a month. Of course, I managed to avoid Xcode for much of that time, by simply doing unixy stuff.
Help?
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags:
Developer Tools
Developer ID
Developer Program
I had assumed the answer was "copy or create a plist in /Library/LaunchDaemons," but after poking around here and google a bit, I'm more confused. (Which seems to be a normal thing for me, so I'll hold off deciding I'm stupid for a while.)
The options that I seem to see are:
Copy/create a plist in /Library/LaunchDaemons
Have Foo.app/Contents/Library/LaunchAgents, which will, I presume, run something as long as the app is running?
Use SMJobBless to install the daemon. This is the preferred way, and requires an embedded launchd plist, which I presume is what will be installedinto /Library/LaunchDaemons? And "embedded" means "pushed into the binary because MachO is infinitely versatile so we can do this if we want to"? This requires user interaction to get an authorization?
And... if the app is distributed via MDM, then that can install the launchd plist file without the app needing to run, just like it can install a system extension without the app needing to run?
We have a containing app for our network extension; it's set up as a faceless app and run as a LaunchAgent. It works rather well, we're happy with it.
Except sometimes, possibly only on M1's, on reboot, it'll show up twice. Our name in the plist is com.kithrup.appName -- simple enough. On reboot, launchctl list shows two com.kithrup jobs -- and the extra one is application.com.kithrup.appName.3238445.3238450.
Anyone have any idea about this?
We use CircleCI, so of course I've been spending the past week trying to get new secrets, profiles, certificates, and passwords in place.
In the process, I went to generate a new Developer ID Application certificate. In the process of that I screwed up multiple times. So now I have four of them (five, actually -- one using the older cert so it expires Feb 1, 2027).
They all have the same name. When I go to create a provisioning profile, there is no way to tell which one is which. No way to tell if they're being presented in the same order!
Apple has told me they will not delete or revoke them, since it's not a security issue for these ones.
I had dealt with this in cmake, and then forgotten about it -- now trying my Xcode-only test project, and it won't work, because the profile has -systemextension as a suffix, while the one Xcode generates doesn't.
Am I missing something in how to get Xcode to deal with this?
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags:
Xcode
Network Extension
Provisioning Profiles
I have something that looks like:
NavigationStack {
List(self.items, id: \.self, selection: self.$selectedItems) { item in
NavigationLink {
ItemView(item: item)
.environment(\.managedObjectContext, self.viewContext)
} label: {
LabelWithMenuView(object: item) { ptr in
self.labelHandler(item: item, newName: ptr)
}
}
}
if self.editMode?.wrappedValue == .active {
editButtons
} else {
TextField("Add Item", text: self.$newItem)
.onSubmit {
self.addItem()
self.newItem = ""
}
.padding()
}
}
#if os(iOS)
.toolbar {
EditButton()
}
.onChange(of: self.editMode?.wrappedValue) { old, new in
print("editMode \(old) -> \(new)")
}
#endif
With that layout, the edit button doesn't show up at all; if I put it as part of the List, it does show up, but the first click doesn't do anything; after that, it works, but the onChange handler doesn't show it getting changed, and the editButtons don't go away.
For login purposes, we may want to try automatically checking to see if an email address is set up in certain databases. It looks like the preferred way to do this is via ABAddressBook.shared().me(), then get the right key via in the properties? This, however, is treated as accessing the whole address book and brings up a confirmation dialogue.
However, as I thought about it, that might not be the real way we'd want -- we'd want to go through Active Directory, perhaps?
Am I making any sense, or just being incoherent? 😄
This is mainly caused by my having misread the documentation, but then the behaviour seemed to match my misreading, but then suddenly it didn't.
Specifically, I had thought that handleNewFlow could return false to indicate "I'm not interested in this particular connection," but it turns out to close it (killing some but not all? networking on the system) if I always return false. The specific thing I was trying to do was exclude certain apps from being proxied (without building a list of all apps, to filter them all).
So my question is two-fold: how dumb was I to misread the documentation, and is there a way to do what I was trying to do? (Short of, say, monitoring all new processes as they start, adding them to the NEAppRule set, and deliberately excluding the ones I wanted to whitelist.)
Since we've had a lot of problems with XPC (bad design on my part, I'm sure), I tried changing the data communications between the TPP and the userland proxy to use sockets -- in this case (I've so many, many cases), I am trying to do an http proxy (so the TPP connects to, say, port 12345, sends
CONNECT ${host}:${port} HTTP/1.0
X-Proxy-Host: ${host}:${port}
It then reads a response, looking for a 200.
So that part works -- once I added the networking client entitlement, I could connect and write that and read the response. Now we are cooking with gas, right?
The application doing the connection (eg, curl) then sends the normal HTTP request, the TPP gets it, it writes it to the socket it created, the write succeeds (that is, returns the number of bytes in the request), and...
it doesn't show up on the interface. (Using tcpdump -i lo0 -s 0 -vvvvvvvvvvvvvvvvvvv -A port 12345.) Since it doesn't show up on the interface, the user-land proxy doesn't get it, and things are very confused for everyone.
If the connect() failed, I'd say, ah yes, sandboxed to heck and back, even with the entitlement can't do it. Or if the first write() or read() failed. But they don't fail, and the first round works. If the second write() failed, I could see that.
But it both succeeds and doesn't succeed, and quantum confuses the heck out of me.
It tells me my certificate is bad (doesn't have a private key), and that it needs me to revoke it so it can generate a new one, and I do that, and it loops forever. Oh and I get email from Apple saying it's been revoked.
Not sure if it's related but I also can't use a Developer ID certificate. Also says it doesn't have a private key. I even generated a new certificate using openssl so I could make sure I had the private key and the .csr file and still no happiness.
I also managed to kill my login keychain at some point, because why not.
I've googled and stackoverflowed and nothing works.
This is on macOS 13.6.1, and Xcode Version 15.0.1 (15A507).
I am frustrated to the point of tears at this point.
A few hours ago, it took 3 minutes to get the notarization phase of our build done... now I've got one that's been running for 25 minutes and hasn't finished yet. The last time this happened, the waits got up to multiple hours, and the status page didn't get updated.