So you are basically saying:Without a NEMachServiceName entry in the Info.plist, a System Network Extension cannot work at all?This is all a bit confusing, as a normal Network Extension didn't require such a key and a System Extension that is not a Network Extension apparently neither. There is no documentation on the differences between a Network Extension and a System Network Extension, so it's currently even unclear which entitlements or capabilities a System Network Extension or its hosting app really require or which Info.plist keys must be set.It turns out our validation problem was related to the App Group missing in the entitlements of the System Extension, despite the fact that Xcode itself manages these entitlements and in the UI everything looked correct. Making Xcode re-create everything solved the problem so far.
Post
Replies
Boosts
Views
Activity
I have to diagree.In Swift, Array, String, and Dictionary are all value types. They behave much like a simple int value in C, acting as a unique instance of that data. You don’t need to do anything special — such as making an explicit copy — to prevent other code from modifying that data behind your back. Importantly, you can safely pass copies of values across threads without synchronization. In the spirit of improving safety, this model will help you write more predictable code in Swift.- Source: https://developer.apple.com/swift/blog/?id=10The following code is thread-safe:import Foundation
class SomeClass {
let lock = NSLock()
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
func getNumbers ( ) -> [Int] {
lock.lock()
let result = self.numbers
lock.unlock()
return result
}
func modifyNumbers ( ) {
lock.lock()
let first = self.numbers.removeFirst()
self.numbers.append(first)
lock.unlock()
}
}
let numberContainer = SomeClass()
let thread1 = Thread() {
while true {
var numbers = numberContainer.getNumbers()
// Numbers is now copy on write!
// Modifying it will copy it.
let first = numbers.removeFirst()
numbers.append(first)
}
}
thread1.start()
let thread2 = Thread() {
while true {
var numbers = numberContainer.getNumbers()
// Numbers is now copy on write!
// Modifying it will copy it.
let first = numbers.removeFirst()
numbers.append(first)
}
}
thread2.start()
while true {
numberContainer.modifyNumbers()
}Three threads are constantly modifying a copy-on-write array and this causes no issues at all. Try it. Copy the code to test.swift:swiftc -sanitize=thread test.swift && ./testIf this wasn't thread-safe, then Swift would not treat arrays as values types and they would not "behave much like a simple int value in C" since for int values in C the code above would also be thread-safe.And in case you may think "Okay, then they must have changed that recently, this was definitely not the case when I wrote my reply", please note that the first blog post I linked is from Aug 15, 2014 and your reply is from Apr 14, 2017
Sorry, but this is incorrect. The code found at the documentation of isKnownUniquelyReferenced(_:) is not how copy-on-write is implemented for Swift standard types. And how to do it corretly to become thread-safe is even hinted below the code sample:If the instance passed as object is being accessed by multiple threads simultaneously, this function may still return true. Therefore, you must only call this function from mutating methods with appropriate thread synchronization.And that's how Swift standard types have implemented their copy-on-write. As otherwise the promise that Array, String, and Dictionary are value types in Swift would not hold true. Value types are are always thread-safe. See last paragraph of https://developer.apple.com/swift/blog/?id=10
Copy-on-write is thread-safe for all Swift standard types, like Strings, Arrays, or Dictionaries (and also sets, even not mentioned in the blog post linked below), as these are considered value types in Swift: https://developer.apple.com/swift/blog/?id=10And value types are thread-safe by definition, so when you implement them as copy-on-write, this copy must be thread-safe, too, anything else would break the promisse that they are value types.If you imlepment your own copy-on-write type, it's in your responsebility to ensure that the copy is thread safe:If the instance passed as object is being accessed by multiple threads simultaneously, this function may still return true. Therefore, you must only call this function from mutating methods with appropriate thread synchronization.- Source: isKnownUniquelyReferenced(_:)
It wasn't clear to us that one has to use different entitlements when developing a system extension and when releasing one. Is that documented anywhere? It seems a bit odd to develop a system extension, yet using the entitlement only intended for network extensions that are no system extensions. It does work that way and I already confirmed in my initial post that it does but we would never have expected this to be the official way. Thanks for letting us know but that should actually be written in bold letters at the documentations of that entitlement.
As for Xcode having no support for system extensions entitlements, we created FB7745789
Okay, we figured it out today. The problem was that while the main application was calling stopVPNTunnel(), another event from a helper process that took place at the same time (a bit of a race condition) caused the system extension itself to call [self cancelTunnelWithError:nil] right before it would process the stop call. Despite not reporting an error, this also stops the system extension and that way stopTunnelWithReason:completionHandler: was never called, as cancel will not trigger it and apparently once canceled, an external stop will just do nothing as the extension is already stopping.
The comments for the cancel method say "Subclasses should not override this method", but would that really be an issue? It just seems pratical to override it, so we can run the same clean up code we would otherwise run if the stop method is called and we will make sure, that in any case the super implementation is called as well. Also we will only call this method to report critical errors in the future, as for stopping gracefully, we think it is better practice to always wait for an external request either by our app or by the system preferences, even if the system extension knows that such a stop is going to occur very soon. It simply leads to clearer responsibilities that way.
If there was at least a way to see with what build settings unit tests are built in the editor. I can only see it, when running tests but when running tests, everything is okay and builds fine. The errors are only there when editing unit test files.
I added a headers phase to the build phases of the unit test target and added the not found headers there, even as public headers but the editor still cannot find them, unless their directories are listed under USER_HEADER_SEARCH_PATHS or unless I add the test files to the main target of the project, where they definitely don't belong.
The header files don't belong to the main target, the belong to a framework target that is built along with the main target and then added to the main targets bundle and they are project headers to the framework but that usually plays no role anywhere else in the project. The project has over a dozen targets and in every file from every target this header can just be included with #import "header.h", it will work in the editor and it will work when building. It only fails for unit test targets.
And yes, there are multiple unit test targets but the other ones either just test a frameworks public functionality (so they don't import headers at all, they import the framework as a whole with @import framework;, which is not possible in that case) or they require no headers as they test Swift code. I tried whether that import would work in any other test target and it fails the same, so this is nothing specific to the test target either.
I also discovered it won't just affect headers. When I want to use code from frameworks in the unit test and do a @import framework, I get error "Module framework not found` in the editor. Despite the fact that the framework is listed under "Link Binary With Libraries" and even as explicitly under "Dependencies". Again, it is built correctly when running the tests and it can be used correctly when running the tests, just the editor fails to find them. I also have no autocompletion for any symbols in the frameworks or headers.
I agree with chrsgrf, documentation says
You use the kSecClass key with a suitable value to tell keychain services whether the data you want to store represents a password, a certificate, a cryptographic key, or something else.
But if you have that in your query dictionary, nothing is added at all! The call indicates success (returns 0) but it doesn't add anything to keychain. Only if you leave it out, something gets added - Bug. I didn't know it was already reported, so I reported it as well FB9048257
Also Quinn said:
In general I prefer to get the persistent ref to the identity as I import it.
That is the only option that works at all on iOS. If you use kSecReturnAttributes, kSecReturnData, or kSecReturnRef, even when successfully added, the result is NULL. Only if you use kSecReturnPersistentRef it will not be NULL - Bug. I filed the bug as FB9048313. This was already reported in 2017 for iOS 9 as radar 22228229 and closed as duplicate of 21810530
The keychain API is a horrible mess, especially on iOS. And its really sad that Apple completely lost interest in fixing any bugs reported by developers several year ago. I remember a time (around macOS 10.3/10.4) where we developer would report a bug, quite often even got feedback/questions there and with the next minor release it was fixed and the bug report was even correctly closed. Meanwhile reporting bugs is like talking to my cat. I have over 50 open bug reports on different accounts, all easily reproducible, some even critical and they are all entirely ignored for years. In some of them I even showed where in the source code the bug is and it's a one line change to fix it but it is not happening. And the biggest joke is, the Feedback interface itself is full of bugs and not even those get fixed.
The only solution we found was the same one that also jdv85 shared on StackOverflow. When the app is calling a method of the XPC service for processing, the priority of that XPC service is raised so that the request can quickly be performed as the main app may have to wait for the result of that call. Once processing is over, which is indicated by calling the callback block of the request, the priority level will drop again after a while. By never "answering" the request, the system believes that the XPC service is still processing it and that way the priority stays up. This also keeps sudden termination disabled automatically for the XPC service as the system will not terminate an XPC process while it believes it is still actively processing data, so we don't need to disable it manually anymore.
While this solution works, it's still just a workaround that may break one day in the future, e.g. when Apple decides that there is a time limit for XPC requests and in case an XPC request receives no answer within a given time frame, the priority of the XPC process is limited nonetheless as apparently that task is very long running. It's not a permanent fix you can surly rely upon forever.
I have several USB hubs and docks (USB hubs with things like card readers, HDMI output, Ethernet ports, USB-PD (Power Delivery) pass-through, etc.) All of these hubs and docks work fine on an Intel MacBook Pro running Big Sur, never had any issues with any of them. Yet all of them are failing in one way or another on an M1 MacBook Pro running Monterey (12.3.1).
What usually doesn't work is USB-3, no matter if USB 3.0 (5 Gbit/s, aka 3.1 Gen 1, aka 3.2 Gen 1) or USB 3.1 Gen 2 (10 Gbit/s aka USB 3.2 Gen 2). These ports do have power but no device is working plugged into them. If they do have USB 2 ports (480 Mbit/s), these do work most of the time (a bit unreliable but I can always get these to work). What sometimes does work are USB-C ports, yet it's kinda random if they will support USB 3.x speeds or just USB 2 speeds. HDMI output seems to always work for me, card readers and Ethernet usually works but I found both to be unreliable (e.g. sometimes Ethernet seems to work but cannot ever obtain an IP address using DHCP and when assigning one from hand, nothing is ping-able).
It makes no difference if these are active or passive hubs/docks. If they are active, they fail, no matter if powered by an external power supply or not. It also makes no difference if the PD pass-through is being used or not to pass power to the MacBook.
When plugging an USB 2 stick into an USB 3 port and then un- and re-plugging the hub/dock to the MacBook multiple times, sometimes it starts to work as expected, as the port correctly works at USB 2 port in that case but even that is random. It always works well for real USB 2 only ports.
So my conclusion is, that the USB 3.x implementation in Monterey is somehow seriously broken and cannot correctly support USB 3 hubs. It explains why USB 2 only ports are working correctly as an USB 3 hub must include an USB 2 hub for USB 2 functionality (these two USB versions are strictly separated Hub-wise, see USB 3 standard). It explains why HDMI works, as it's not transported via USB protocol at all (it's transported via USB-C cable but uses dedicated lines on that cable just for that purpose). It explains why sometimes card readers work (as they are internally connected via USB 2 in some cases) and why Ethernet is unreliable (it is using USB 3 but may be able to fallback to 2, yet this can be an issue if you have a Gbit-link but the port is only connected via 480 Mbit/s). And it explains why plugging devices directly into the USB port with any hub in between does work just fine, as in that case no hub support is required.
As the MacBook has internal hubs, apparently the implementation can handle some hubs correctly and if you are lucky and your external one behaves exactly like the internal one, it seems to work, so very few hubs seems to work okay but the majority of hubs does not. And again, these hubs work perfectly fine on older MacBooks, often even on newer ones if the still run Big Sur, as well as on all PCs with Linux and Windows I've tested them with.
Yet 3 major Monterey updates later and almost a year after the first Monterey Beta that already showed this problem, Apple has still been unable to fix this serious issue. Note that this is the second time in the history of macOS where Apple totally messed up the USB stack of the system. There has already been an update (I don't remember which macOS it was) that broke USB 2 functionality in such a way, that many devices completely failed after the update, especially multimedia devices (sound cards, video sticks, and so on). I remember that incident as I was developing USB device drivers myself at that time.
The problem is definitely caused by live issues. After your build failed, Xcode does correctly highlight the compiler errors, that's why the often appear for a brief moment. But then live issues triggers builds of the current file in the background to update issues constantly while you are editing it and this kind of background builds fail for some reason and they fail in a way that no compiler errors are available, so all errors disappear as the live issues override the issues from the last build. That's why disabling live issues causes the errors of the last build to be shown but then build errors will only update every time you trigger a build and not while editing a file.
As for why live issues fail, there seem to be a couple of reason:
As one user here pointed out, this can happen if Xcode and filesystem disagree about capitalization (Xcode thinks the folder is named "folder" while in fact it is named "Folder"). HFS/AFS by default don't care for capitalization, to them "folder" and "Folder" are in fact the same folder, yet code and certain APIs sometimes do care, so if there is mismatch, strange things can happen.
Another user reported that this can happen if the dev tools don't have the special access rights that they usually do. Usually they get these rights when you start Xcode first time and install the backend components but apparently these permission can get lost. To restore them you can run
sudo DevToolsSecurity -enable
in Terminal.
The post right above this one suggests, that the issue also happens if live build cannot find frameworks, which would certainly also cause this issue.
Most people experience live build failures because of some issue that only affects the ARM code of Xcode, so running Xcode in Rosetta fixes this issue for them. So far nobody has an idea what the real problem is it that causes ARM code to fail.
So the reasons are very individual but in all cases it is live build is failing in background and Apple does not provide a way to see why it is failing and what might be the problem, which makes it guesswork to fix anything.
Okay, I figured out what the problem was. Finally!
The key to figuring that out was to see how Xcode is actually calling clang/swiftc in the background, so you can call it yourself with exactly the same arguments and get the actual error message.
To get that information, you start Xcode in Terminal with sourcekit logging enabled
SOURCEKIT_LOGGING=3 /<path-to-xcode>/Xcode.app/Contents/MacOS/Xcode 2>xcode.txt
After you edited a source file, you can quit Xcode again and now the file xcode.txt contains the sourcekit log. When you search for the file you just edited, you will stumble upon an entry that shows how the compiler was called in the background
key.compilerargs: [
"-x",
"objective-c",
"-ivfsoverlay",
:
All you need to do is converting that into a command line call by removing the comas and making all arguments a single line, then you can call the compiler yourself with the exact same arguments and it will tell you what the issue is.
More details about all this can be found here: https://stackoverflow.com/a/75605312/15809
In my case it turned out that a module has not been found by the compiler because the "Supported Destinations" (General tab for a framework target) were not correct. During a full build that played no role as the framework was still built for all the destinations and the linker would then find the module file in the build target location which is added to the search paths. But when creating the command line arguments for live issues, Xcode relies on this information correctly reflecting platform dependencies and if the current platform is not listed there, the module map of the framework is not added to the arguments and then the module is not found.
I think it's really a pity that Xcode is not showing these kind of errors by default somewhere in the UI. If you use Visual Studio Code, which uses the same mechanism as Xcode to lint source code and it runs into a similar problem, it will show you the actual error message in its error console and you will know at once what needs to be done to fix that.
I got this warning for every target I build in Xcode 15 that isn't the main executable target, e.g. for all framework targets. Note that I haven't set anything in the build settings. For all targets, frameworks or binary, the setting GCC_DYNAMIC_NO_PIC is default (not listed under customized, shows "No" when hovered, also for "Resolved"), still Xcode would add -Wl,-pie to every linker call it made and this produced the warning when being added to liker calls for frameworks.
The fix: Overriding the default once to YES, then deleting it again, clean build and no more warnings anymore, as this argument is no longer added to liker calls.
Give it a try, maybe works for you, too. And yes, we are also using podfiles but the don't produce this warning either anymore, yet I'm not sure if they actually did before.
We still observe that issue with Xcode 15.
We run for actions in parallel: Building the app for macOS, building the app for iOS, running tests for macOS, running tests for iOS. Running tests for iOS alone takes longer than the entire rest together, despite the fact that we have 50 times more macOS than iOS tests.