Looking at the path name for reasons, and ran into a thing: one of my coworkers was not getting /Applications/Safari.app as expected, but instead got /System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app. Which is annoying because I'm actually using spotlight to find the paths for applications, and that one doesn't show up.
Has anyone run into this? And know why?
(I figure I'll simply remove the prefix if it's there, and that should be fine, but I'm curious why it only seems to happen sometimes.)
Post
Replies
Boosts
Views
Activity
I asked a similar question last year, and got no responses. I've written a much simpler (no network extension!) case that seems to demonstrate what I'm confused about.
Simple app with an XPC service. I have an ObjectiveC class TestObject which has an NSString* and an NSData* (which I never actually use). I have a protocol defined in Swift:
@objc protocol XPCTestServiceProtocol {
func logData(entry: TestObject) -> Void
func logData(entry: TestObject, completion: ((String) -> Void))
}
In the Switt XPC service, the code is:
class XPCTestService: NSObject, XPCTestServiceProtocol {
var totalBytes = 0
var lastName = ""
@objc func logData(entry: TestObject) {
totalBytes += (entry.data?.count ?? 0)
}
@objc func logData(entry: TestObject, completion: ((String) -> Void)) {
totalBytes += (entry.data?.count ?? 0)
completion("Finished")
}
I've got this code in the ObjC app:
id<XPCTestServiceProtocol> proxy = [self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
self.stopRun = YES;
NSLog(@"Proxy got error %@", error);
}];
while (self.stopRun == NO) {
@synchronized (self) {
NSNumber *objNum = [NSNumber numberWithUnsignedLongLong:self.count++];
NSString *objName = [NSString stringWithFormat:@"Object %@", objNum];
TestObject __weak *toWeak = to;
#if USE_COMPLETION
[proxy logDataWithEntry:to completion:^(NSString *str) {
to = nil;
}];
#else
[proxy logDataWithEntry:to];
#endif
}
}
attached to a start button (and self.stopRun is set by a stop button, this is all super simple).
So I run that, start the test, and things start going (122k calls/second it says). According to Activity Monitor, my app is using about 1gbyte after 20 seconds or so.
However, if I run it under Instruments' Leaks template... Activity Monitor says it's used only about 60mbytes. (And at the end of the run, Instruments says it's used about 30mbytes.)
Now... if I use the completion and a synchronous proxy, then even without Instruments, Activity Monitor says it's 60mbytes or so.
Is the memory reported by Activity Monitor real? Or not real?
The code I have is
if (filterManager.providerConfiguration == nil)
{
NEFilterProviderConfiguration *providerConfiguration = [[NEFilterProviderConfiguration alloc] init];
providerConfiguration.filterPackets = YES;
providerConfiguration.filterPacketProviderBundleIdentifier = filterBundle.bundleIdentifier;
filterManager.providerConfiguration = providerConfiguration;
NSString *appName = [NSBundle mainBundle].infoDictionary[@"CFBundleName"];
if (appName != nil)
{
filterManager.localizedDescription = [NSString stringWithFormat:@"%@ (packet filter)", appName];
}
}
if (filterManager.enabled)
{
NSLog(@"Packet filter already enabled, not doing so again");
return;
}
filterManager.enabled = YES;
It's claiming the filter is already enabled. But System Settings > Network shows it there, with a yellow dot. My best guess is that it's showing up as already enabled in the preferences, even though it... isn't? I also log a message in the filter's init, and I don't see that showing up.
I've got sysdiagnose from it and a working system, and I'm going over soooooooo many log lines. I don't know what might be causing this, however.
Is there a way to find out when the set of keychains changes? ie, when a keychain is added or removed? I searched here and grepped through the headers in Security.framework but nothing leaped out at me -- which could just mean I missed something, as happens frequently. (This is on macOS.)
If there's another version of our app on the volume, it'll relocate the installed one there. This is particularly delightful, since nothing will work if it's not in /Applications.
We use pkgbuild and productbuild to create the .pkg file.
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.
Why doesn't this work? (Specifically, it crashes.)
struct Item: Identifiable, Hashable, Codable {
var id = UUID()
var name: String? = nil
}
private let defaults: [Item] = [
Item(name: "Bread"),
Item(),
Item(name: "Peanut Butter"),
Item(name: "Jelly")
]
struct ContentView: View {
@State var selectedItem = Set<Item>()
@State var showSheet = false
var body: some View {
VStack {
ForEach(defaults, id: \.self) { item in
Button(item.name ?? "<unnamed>") {
self.selectedItem.removeAll()
self.selectedItem.insert(item)
print("Selected item is now \(self.selectedItem)")
self.showSheet = true
}
}
}
.sheet(isPresented: self.$showSheet) {
let _ = print("selected item \(self.selectedItem)")
RenameSheet(name: self.selectedItem.first!.name ?? "<no name>") {
self.selectedItem.removeAll()
}
}
.padding()
}
}
Based on the output from the prints, it gets set when the button is clicked, but is then empty when the sheet is presented.
I've got a core data model, with a name, which I've cleverly called cdName. My view has:
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [
SortDescriptor(\Item.cdName),
])
private var items: FetchedResults<Item>
and then, later
ForEach(self.items, id: \.self) { item in
NavigationLink {
ItemView(item: item)
.environment(\.managedObjectContext, self.viewContext)
} label: {
LabelWithMenuView(label: item.cdName ?? "<no name>") { ptr in
if let newName = ptr {
let oldName = item.cdName!
item.cdName = newName
do {
try self.viewContext.save()
} catch {
print("Could not save rename of \(oldName) to \(newName)")
}
}
(LabelWithMenuView is a view that has an on-hover button which brings up a rename sheet and passes the new name off to the completion handler.)
When I do this (macOS)... it does change the name in Core Data, but it doesn't update the view. If I quit&restart my app, it shows up with the new name.
What am I doing wrong, please?
I got tried of the compiler telling me that .onChange(of:) was deprecated, so I thought, find, I'll simply stub it out for the older versions. Only... I can't seem to do that? I can use @available(macOS 14, *) to build for that and later, but is there any way to do the opposite? (I'd hoped there was a #if available support, but there isn't.)
I put this into a file:
#if DEBUG
#warning("Building with debug")
#endif
It always warns when I build in Xcode -- even when I'm (allegedly) using the Release configuration.
I created a new scheme called "Release", and changed the Run > Build Configuration to "Release". (And then I went and changed everything from "Debug" to "Release" in the scheme.)
But I always get the warning. (In Xcode. If I use xcodebuild -configuration Release I don't get the warning.)
Now that I can build again, I'm back to experimenting, this time using Firebase. To display my items, I set up a Table, and this mostly works, barring a couple of minor, crashy details.
I've got
@State var selectedItems = Set<Item.ID>()
private var tableData: [Item] {
return self.items.sorted(using: self.sortOrder)
}
var body: some View {
Table(self.tableData, selection: self.$selectedItems, sortOrder: self.$sortOrder) {
TableColumn("Item", value: \.name)
TableColumn("Count", value: \.count) { item in
Text("\(item.count)")
}
}
Edited down a bit but that's the basics.
The two problems I've got are:
When I select a row, it flashes but does not stay highlighted
If I select the same row again, it crashes with:
Fatal error: Duplicate elements of type 'Optional<String>' were found in a Set.
This usually means either that the type violates Hashable's requirements, or
that members of such a set were mutated after insertion.
I put in a willSet for the selectedItems which was not particularly helpful.
This doesn't happen with the CoreData version, so I assume it's something wonky about Firebase. Or my limited skills.
Searching for this crash doesn't seem to show anything useful.
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.
As mentioned before, we have to network extensions for our app -- a transparent proxy provider, and a packet filter. We just started testing with multiple users, and I'm seeing what seem to me to be very strange results, but they get less strange if the states aren't system-wide.
Easiest case: I install while I'm logged in, we install the agents and daemons, start everything up, and the app then goes to activate both extensions. This starts with an OSSystemExtensionRequest for each, and when the completion delegate is invoked, I go to "connect" them, which is where the does the load/save preferences. Barring the apparent timing issue I filed a feedback on, this works.
If i then fast-user-switch to a second user, the agent once again starts, and goes through the same process -- it creates an OSSystemExtensionRequest to load them both, the delegate gets invoked, and then it does the connection functions for each. The behaviour might change slightly if the second user is already logged in, but I lost my notes there.
At the end of this, I am left with things in a weird-to-me state:
For the second user (not an admin), I see three entries in prefs/settings > Network -- one packet filter, and two TPPs. The two TPPs either appear 100% identical, in that they both have the same connection time, or one is connected and the other isn't.
For the first user (an admin), I sometimes see 1, 2, or 3 entries -- and the VPNs are not always shown as connected.
This is new behaviour for us, so either it's something I'm doing in the connection code, or something in the OS changed. The latter seems unlikely since the machine in question is still running macOS 12.6, but I don't test multiple users very often.
If the packet filter is global, and the TPP network connection is per user, this kinda makes sense (but why did we not notice it before?).
I didn't think it was possible, but a coworker showed me a screenshot with the SentinelOne content filter having the enabled button greyed out in sysprefs:
So how are they doing that?
The crash is at
do {
retval = try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
When I first set it up, it complained (at run-time) about a lot of issues, mainly items not being optional and I apparently had a couple of @Attribute(.unique)s left. After I got rid of all of those, however, I get the crash there.
I assume this is an obvious thing that I am doing wrong, but I can't figure it out.