We are in the process of updating our legacy Spotlight MDImporter to the new macOS Spotlight App Extension.
The transition works well for standard attributes such as title, textContent, and keywords.
However, we encounter an issue when adding custom attributes to the CSSearchableItemAttributeSet.
These custom attributes are not being persisted, which means they cannot be queried using a Spotlight NSMetadataQuery.
Has anyone an idea on how to append custom attributes so that they are included in the indexed file status, as displayed by the shell command mdimport -t -d3 <path>
A sample project illustrating the problem is available here: https://www.dropbox.com/scl/fi/t8qg51cr1rpwouxdl900b/2024-09-04-Spotlight-extAttr.zip?rlkey=lg6n9060snw7mrz6jsxfdlnfa&dl=1
Overview
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Created
When displaying a view with a Button inside a ScrollView using the sheet modifier, if you try to close the sheet by swiping and your finger is touching the Button, the touch is not canceled.
This issue occurs when building with Xcode 16 but does not occur when building with Xcode 15.
Here is screen cast.
https://drive.google.com/file/d/1GaOjggWxvjDY38My4JEl-URyik928iBT/view?usp=sharing
Code
struct ContentView: View {
@State var isModalPresented: Bool = false
var body: some View {
ScrollView {
Button {
debugPrint("Hello")
isModalPresented.toggle()
} label: {
Text("Hello")
.frame(height: 44)
}
Button {
debugPrint("World")
} label: {
Text("World")
.frame(height: 44)
}
Text("Hoge")
.frame(height: 44)
.contentShape(Rectangle())
.onTapGesture {
debugPrint("Hoge")
}
}
.sheet(isPresented: $isModalPresented) {
ContentView()
}
}
}
I'm using NSTextTable to format panels of stand-out text within body text. Paragraphs within the panel are handled as individual NSTextTableBlocks within the table. Each block is added to the NSMutableParagraphStyle that is part of the attributed string within the block's attributes. That's all fine and it works.
But...
Occasionally I see undrawn lines within the panel. These disappear (or sometimes appear) when the parent window (and thus the NSTextView holding the rendered attributed string) is resized. Lines do not always appear, and when they do they are not always in the same place. The height of the gap varies.
I see this behaviour with these panels and with tables. What's common to both cases is not only the use of NSTextTable and NSTextTableBlock etc., but crucially (I think) the use of block margins. If I disable margins (which looks OK for the panels, but isn't right for tables), the problem disappears.
So, a bug or (more likely) I'm missing a key part of view rendering or margin set up. But what? Code here: https://github.com/smittytone/PreviewMarkdown/blob/930f5f32aa0b3b77ec3f4f53436a79e10bb26f18/Markdown%20Previewer/Styler.swift#L882
Running 14.6.1 on an M3. I'm using TextKit 1 because I'm using an NSLayoutManager subclass to override certain text underlines (not used in panels as outlined above, or tables).
Topic:
UI Frameworks
SubTopic:
AppKit
I am using GoogleMobileAds package dependencies and now when I want to archive and export an app I get this two warnings :
Upload Symbols Failed
The archive did not include a dSYM for the GoogleMobileAds.framework with the UUIDs [13B55A37-D103-36E1-8D7B-FA4EAB2C8146]. Ensure that the archive's dSYM folder includes a DWARF file for GoogleMobileAds.framework with the expected UUIDs.
Upload Symbols Failed
The archive did not include a dSYM for the UserMessagingPlatform.framework with the UUIDs [A3941120-02A1-30B5-8C28-BFC0F9496E16]. Ensure that the archive's dSYM folder includes a DWARF file for UserMessagingPlatform.framework with the expected UUIDs.
I have updated the packages to 11.9.0 (lasted) and Xcode 16 to 16 RC (lasted also) and I would like to know how to fix this... With Xcode 15 I have no problem !! I can export with no warnings ! But now with Xcode 16 no... Thanks for helping !
We are encountering an issue where the Safari extension we are developing stops working while in use on relatively new iOS versions (confirmed on 17.5.1, 17.6.1, and 18). Upon checking the Safari console, the content script is displayed in the extension script, so the background script or Service Worker must be stopping. The time until it stops is about 1 minute on 17.5.1 and about one day on 17.6.1 or 18.
When it stops, we would like to find a way to restart the Service Worker from the extension side, but we have not found a method to do so yet. To restart the extension, the user needs to turn off the corresponding extension in the iPhone settings and then turn it back on.
As mentioned in the following thread, it is written that the above bug was fixed in 17.6, but we recognize that it has not been fixed. https://forums.developer.apple.com/forums/thread/758346
On 17.5.1, adding the following process to the background script prevents it from stopping for about the same time as on 17.6 and above.
// Will be passed into runtime.onConnect for processes that are listening for the connection event
const INTERNAL_STAYALIVE_PORT = "port.connect";
// Try wake up every 9S
const INTERVAL_WAKE_UP = 9000;
// Alive port
var alivePort = null;
// Call the function at SW(service worker) start
StayAlive();
async function StayAlive() {
var wakeup = setInterval(() => {
if (alivePort == null) {
alivePort = browser.runtime.connect({ name: INTERNAL_STAYALIVE_PORT });
alivePort.onDisconnect.addListener((p) => {
alivePort = null;
});
}
if (alivePort) {
alivePort.postMessage({ content: "ping" });
}
}, INTERVAL_WAKE_UP);
}
Additionally, we considered methods to revive the Service Worker when it stops, which are listed below. None of the methods listed below resolved the issue.
①
Implemented a process to create a connection again if the return value of sendMessage is null. The determination of whether the Service Worker has stopped is made by sending a message from the content script to the background script and checking whether the message return value is null as follows.
sendMessageToBackground.js
let infoFromBackground = await browser.runtime.sendMessage(sendParam);
if (!infoFromBackground) {
// If infoFromBackground is null, Service Worker should have stopped.
browser.runtime.connect({name: 'reconnect'}); // ← reconnection process
// Sending message again
infoFromBackground = await browser.runtime.sendMessage(sendParam);
}
return infoFromBackground.message;
Background script
browser.runtime.onConnect.addListener((port) => {
if (port.name !== 'reconnect') return;
port.onMessage.addListener(async (request, sender, sendResponse) => {
sendResponse({
response: "response form background",
message: "reconnect.",
});
});
②
Verified whether the service worker could be restarted by regenerating Background.js and content.js.
sendMessageToBackground.js
export async function sendMessageToBackground(sendParam) {
let infoFromBackground = await browser.runtime.sendMessage(sendParam);
if (!infoFromBackground) {
executeContentScript(); // ← executeScript
infoFromBackground = await browser.runtime.sendMessage(sendParam);
}
return infoFromBackground.message;
}
async function executeContentScript() {
browser.webNavigation.onDOMContentLoaded.addListener((details) => {
browser.scripting.executeScript({
target: { tabId: details.tabId },
files: ["./content.js"]
});
});
}
However, browser.webNavigation.onDOMContentLoaded.addListener was not executed due to the following error.
@webkit-masked-url://hidden/:2:58295
@webkit-masked-url://hidden/:2:58539
@webkit-masked-url://hidden/:2:58539
③
Verify that ServiceWorker restarts by updating ContentScripts
async function updateContentScripts() {
try {
const scripts = await browser.scripting.getRegisteredContentScripts();
const scriptIds = scripts.map(script => script.id);
await browser.scripting.updateContentScripts(scriptIds);//update content
} catch (e) {
await errorLogger(e.stack);
}
}
However, scripting.getRegisteredContentScripts was not executed due to the same error as in 2.
@webkit-masked-url://hidden/:2:58359
@webkit-masked-url://hidden/:2:58456
@webkit-masked-url://hidden/:2:58456
@webkit-masked-url://hidden/:2:58549
@webkit-masked-url://hidden/:2:58549
These are the methods we have considered. If anyone knows a solution, please let us know.
Hey all!
in my personal quest to make future proof apps moving to Swift 6, one of my app has a problem when setting an artwork image in MPNowPlayingInfoCenter
Here's what I'm using to set the metadata
func setMetadata(title: String? = nil, artist: String? = nil, artwork: String? = nil) async throws {
let defaultArtwork = UIImage(named: "logo")!
var nowPlayingInfo = [
MPMediaItemPropertyTitle: title ?? "***",
MPMediaItemPropertyArtist: artist ?? "***",
MPMediaItemPropertyArtwork: MPMediaItemArtwork(boundsSize: defaultArtwork.size) { _ in
defaultArtwork
}
] as [String: Any]
if let artwork = artwork {
guard let url = URL(string: artwork) else { return }
let (data, response) = try await URLSession.shared.data(from: url)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { return }
guard let image = UIImage(data: data) else { return }
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in
image
}
}
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
the app crashes when hitting
MPMediaItemPropertyArtwork: MPMediaItemArtwork(boundsSize: defaultArtwork.size) { _ in
defaultArtwork
}
or
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in
image
}
commenting out these two make the app work again.
Again, no clue on why.
Thanks in advance
We're trying to implement a backup/restore data feature in our business productivity iPad app using UIDocumentPickerViewController and AppleArchive, but discovered odd behavior of [UIDocumentPickerViewController initForOpeningContentTypes: asCopy:YES] when reading large archive files from a USB drive.
We've duplicated this behavior with iPadOS 16.6.1 and 17.7 when building our app with Xcode 15.4 targeting minimum deployment of iPadOS 16. We haven't tested this with bleeding edge iPadOS 18.
Here's our Objective-C code which presents the picker:
NSArray* contentTypeArray = @[UTTypeAppleArchive];
UIDocumentPickerViewController* docPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypeArray asCopy:YES];
docPickerVC.delegate = self;
docPickerVC.allowsMultipleSelection = NO;
docPickerVC.shouldShowFileExtensions = YES;
docPickerVC.modalPresentationStyle = UIModalPresentationPopover;
docPickerVC.popoverPresentationController.sourceView = self.view;
[self presentViewController:docPickerVC animated:YES completion:nil];
The UIDocumentPickerViewController remains visible until the selected external archive file has been copied from the USB drive to the app's local tmp sandbox. This may take several seconds due to the slow access speed of the USB drive. During this time the UIDocumentPickerViewController does NOT disable its tableview rows displaying files found on the USB drive. Even the most patient user will tap the desired filename a second (or third or fourth) time since the user's initial tap appears to have been ignored by UIDocumentPickerViewController, which lacks sufficient UI feedback showing it's busy copying the selected file.
When the user taps the file a second time, UIDocumentPickerViewController apparently begins to copy the archive file once again. The end result is a truncated copy of the selected file based on the time between taps. For instance, a 788 MB source archive may be copied as a 56 MB file. Here, the UIDocumentPickerDelegate receives a 56 MB file instead of the original 788 MB of data.
Not surprisingly, AppleArchive fails to decrypt the local copy of the archive because it's missing data. Instead of failing gracefully, AppleArchive crashes in AAArchiveStreamClose() (see forums post 765102 for details).
Does anyone know if there's a workaround for this strange behavior of UIDocumentPickerViewController?
I've been using CGWindowListCreateImage which automatically creates an image with the size of the captured window.
But SCScreenshotManager.captureImage(contentFilter:configuration:) always creates images with the width and height specified in the provided SCStreamConfiguration. I could be setting the size explicitly by reading SCWindow.frame or SCContentFilter.contentRect and multiplying the width and height by SCContentFilter.pointPixelScale , but it won't work if I want to keep the window shadow with SCStreamConfiguration.ignoreShadowsSingleWindow = false.
Is there a way and what's the best way to take full-resolution screenshots of the correct size?
import Cocoa
import ScreenCaptureKit
class ViewController: NSViewController {
@IBOutlet weak var imageView: NSImageView!
override func viewDidAppear() {
imageView.imageScaling = .scaleProportionallyUpOrDown
view.wantsLayer = true
view.layer!.backgroundColor = .init(red: 1, green: 0, blue: 0, alpha: 1)
Task {
let windows = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true).windows
let window = windows[0]
let filter = SCContentFilter(desktopIndependentWindow: window)
let configuration = SCStreamConfiguration()
configuration.ignoreShadowsSingleWindow = false
configuration.showsCursor = false
configuration.width = Int(Float(filter.contentRect.width) * filter.pointPixelScale)
configuration.height = Int(Float(filter.contentRect.height) * filter.pointPixelScale)
print(filter.contentRect)
let windowImage = try await SCScreenshotManager.captureImage(contentFilter: filter, configuration: configuration)
imageView.image = NSImage(cgImage: windowImage, size: CGSize(width: windowImage.width, height: windowImage.height))
}
}
}
I’ve noticed a strange bug in Xcode 16 and Swift. When a preview is rendering and hasn’t finished yet and you run an app to debug, Xcode is launching two instances of the app. Has anyone else noticed this issue? If you let the preview finish rendering before running the app, this doesn’t happen. Very odd.
I'm seeing some odd behavior which may be a bug. I've broken it down to a least common denominator to reproduce it. But maybe I'm doing something wrong.
I am opening a file read-write. I'm then mapping the file read-only and private:
void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
I then unmap the memory and close the file. After the close, eslogger shows me this:
{"close":{"modified":false,[...],"was_mapped_writable":false}}
Which makes sense.
I then change the mmap statement to:
void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
I run the new code and and the close looks like:
{"close":{"modified":false, [....], "was_mapped_writable":true}}
Which also makes sense.
I then run the original again (ie, with MAP_PRIVATE vs. MAP_SHARED) and the close looks like:
{"close":{"modified":false,"was_mapped_writable":true,[...]}
Which doesn't appear to be correct.
Now if I just open and close the file (again, read-write) and don't mmap anything the close still shows:
{"close":{ [...], "was_mapped_writable":true,"modified":false}}
And the same is true if I open the file read-only.
It will remain that way until I delete the file. If I recreate the file and try again, everything is good until I map it MAP_SHARED.
I tried this with macOS 13.6.7 and macOS 15.0.1.
We are implementing a feature that uses PKPassLibrary.requestAutomaticPassPresentationSuppression to prevent the Wallet from appearing when unlocking a lock. We have already completed the approval process for the entitlement to enable Pass Presentation Suppression.
In most cases, our code snippet works as expected, and the result is .success. However, we are also encountering other results, such as .denied, .alreadyPresenting, and .cancelled or .notSupported, which cause the Wallet to appear for users.
Here's the code snippet we're using:
PKPassLibrary.requestAutomaticPassPresentationSuppression { result in
logger.log(
.info,
"PKPassLibrary suppression result: \(result.description)",
LogContext.homeFeature
)
}
I would appreciate clarification on the following points:
What's the meaning of each result type (.denied, .alreadyPresenting, .cancelled, .notSupported) beyond what is mentioned in the documentation? The documentation here does not provide additional details.
What is the recommended handling for these specific result states? Should we be taking different actions or retries based on each case?
Thank you very much for your help.
Best, Ramiro.
https://developer.apple.com/forums/thread/768776
Swift concurrency is an important part of my day-to-day job. I created the following document for an internal presentation, and I figured that it might be helpful for others.
If you have questions or comments, put them in a new thread here on DevForums. Use the App & System Services > Processes & Concurrency topic area and tag it with both Swift and Concurrency.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Swift Concurrency Proposal Index
This post summarises the Swift Evolution proposals that went into the Swift concurrency design. It covers the proposal that are implemented in Swift 6.2, plus a few additional ones that aren’t currently available.
The focus is here is the Swift Evolution proposals. For general information about Swift concurrency, see the documentation referenced by Concurrency Resources.
Swift 6.0
The following Swift Evolution proposals form the basis of the Swift 6.0 concurrency design.
SE-0176 Enforce Exclusive Access to Memory
link: SE-0176
notes: This defines the “Law of Exclusivity”, a critical foundation for both serial and concurrent code.
SE-0282 Clarify the Swift memory consistency model ⚛︎
link: SE-0282
notes: This defines Swift’s memory model, that is, the rules about what is and isn’t allowed when it comes to concurrent memory access.
SE-0296 Async/await
link: SE-0296
introduces: async functions, async, await
SE-0297 Concurrency Interoperability with Objective-C
link: SE-0297
notes: Specifies how Swift imports an Objective-C method with a completion handler as an async method. Explicitly allows @objc actors.
SE-0298 Async/Await: Sequences
link: SE-0298
introduces: AsyncSequence, for await syntax
notes: This just defines the AsyncSequence protocol. For one concrete implementation of that protocol, see SE-0314.
SE-0300 Continuations for interfacing async tasks with synchronous code
link: SE-0300
introduces: CheckedContinuation, UnsafeContinuation
notes: Use these to create an async function that wraps a legacy request-reply concurrency construct.
SE-0302 Sendable and @Sendable closures
link: SE-0302
introduces: Sendable, @Sendable closures, marker protocols
SE-0304 Structured concurrency
link: SE-0304
introduces: unstructured and structured concurrency, Task, cancellation, CancellationError, withTaskCancellationHandler(…), sleep(…), withTaskGroup(…), withThrowingTaskGroup(…)
notes: For the async let syntax, see SE-0317. For more ways to sleep, see SE-0329 and SE-0374. For discarding task groups, see SE-0381.
SE-0306 Actors
link: SE-0306
introduces: actor syntax
notes: For actor-isolated parameters and the nonisolated keyword, see SE-0313. For global actors, see SE-0316. For custom executors and the Actor protocol, see SE-0392.
SE-0311 Task Local Values
link: SE-0311
introduces: TaskLocal
SE-0313 Improved control over actor isolation
link: SE-0313
introduces: isolated parameters, nonisolated
SE-0314 AsyncStream and AsyncThrowingStream
link: SE-0314
introduces: AsyncStream, AsyncThrowingStream, onTermination
notes: These are super helpful when you need to publish a legacy notification construct as an async stream. For a simpler API to create a stream, see SE-0388.
SE-0316 Global actors
link: SE-0316
introduces: GlobalActor, MainActor
notes: This includes the @MainActor syntax for closures.
SE-0317 async let bindings
link: SE-0317
introduces: async let syntax
SE-0323 Asynchronous Main Semantics
link: SE-0323
SE-0327 On Actors and Initialization
link: SE-0327
notes: For a proposal to allow access to non-sendable isolated state in a deinitialiser, see SE-0371.
SE-0329 Clock, Instant, and Duration
link: SE-0329
introduces: Clock, InstantProtocol, DurationProtocol, Duration, ContinuousClock, SuspendingClock
notes: For another way to sleep, see SE-0374.
SE-0331 Remove Sendable conformance from unsafe pointer types
link: SE-0331
SE-0337 Incremental migration to concurrency checking
link: SE-0337
introduces: @preconcurrency, explicit unavailability of Sendable
notes: This introduces @preconcurrency on declarations, on imports, and on Sendable protocols. For @preconcurrency conformances, see SE-0423.
SE-0338 Clarify the Execution of Non-Actor-Isolated Async Functions
link: SE-0338
note: This change has caught a bunch of folks by surprise and there’s a discussion underway as to whether to adjust it.
SE-0340 Unavailable From Async Attribute
link: SE-0340
introduces: noasync availability kind
SE-0343 Concurrency in Top-level Code
link: SE-0343
notes: For how strict concurrency applies to global variables, see SE-0412.
SE-0374 Add sleep(for:) to Clock
link: SE-0374
notes: This builds on SE-0329.
SE-0381 DiscardingTaskGroups
link: SE-0381
introduces: DiscardingTaskGroup, ThrowingDiscardingTaskGroup
notes: Use this for task groups that can run indefinitely, for example, a network server.
SE-0388 Convenience Async[Throwing]Stream.makeStream methods
link: SE-0388
notes: This builds on SE-0314.
SE-0392 Custom Actor Executors
link: SE-0392
introduces: Actor protocol, Executor, SerialExecutor, ExecutorJob, assumeIsolated(…)
notes: For task executors, a closely related concept, see SE-0417. For custom isolation checking, see SE-0424.
SE-0395 Observation
link: SE-0395
introduces: Observation module, Observable
notes: While this isn’t directly related to concurrency, it’s relationship to Combine, which is an important exising concurrency construct, means I’ve included it in this list.
SE-0401 Remove Actor Isolation Inference caused by Property Wrappers
link: SE-0401, commentary
availability: upcoming feature flag: DisableOutwardActorInference
SE-0410 Low-Level Atomic Operations ⚛︎
link: SE-0410
introduces: Synchronization module, Atomic, AtomicLazyReference, WordPair
SE-0411 Isolated default value expressions
link: SE-0411, commentary
SE-0412 Strict concurrency for global variables
link: SE-0412
introduces: nonisolated(unsafe)
notes: While this is a proposal about globals, the introduction of nonisolated(unsafe) applies to “any form of storage”.
SE-0414 Region based Isolation
link: SE-0414, commentary
notes: To send parameters and results across isolation regions, see SE-0430.
SE-0417 Task Executor Preference
link: SE-0417, commentary
introduces: withTaskExecutorPreference(…), TaskExecutor, globalConcurrentExecutor
notes: This is closely related to the custom actor executors defined in SE-0392.
SE-0418 Inferring Sendable for methods and key path literals
link: SE-0418, commentary
availability: upcoming feature flag: InferSendableFromCaptures
notes: The methods part of this is for “partial and unapplied methods”.
SE-0420 Inheritance of actor isolation
link: SE-0420, commentary
introduces: #isolation, optional isolated parameters
notes: This is what makes it possible to iterate over an async stream in an isolated async function.
SE-0421 Generalize effect polymorphism for AsyncSequence and AsyncIteratorProtocol
link: SE-0421, commentary
notes: Previously AsyncSequence used an experimental mechanism to support throwing and non-throwing sequences. This moves it off that. Instead, it uses an extra Failure generic parameter and typed throws to achieve the same result. This allows it to finally support a primary associated type. Yay!
SE-0423 Dynamic actor isolation enforcement from non-strict-concurrency contexts
link: SE-0423, commentary
introduces: @preconcurrency conformance
notes: This adds a number of dynamic actor isolation checks (think assumeIsolated(…)) to close strict concurrency holes that arise when you interact with legacy code.
SE-0424 Custom isolation checking for SerialExecutor
link: SE-0424, commentary
introduces: checkIsolation()
notes: This extends the custom actor executors introduced in SE-0392 to support isolation checking.
SE-0430 sending parameter and result values
link: SE-0430, commentary
introduces: sending
notes: Adds the ability to send parameters and results between the isolation regions introduced by SE-0414.
SE-0431 @isolated(any) Function Types
link: SE-0431, commentary, commentary
introduces: @isolated(any) attribute on function types, isolation property of functions values
notes: This is laying the groundwork for SE-NNNN Closure isolation control. That, in turn, aims to bring the currently experimental @_inheritActorContext attribute into the language officially.
SE-0433 Synchronous Mutual Exclusion Lock 🔒
link: SE-0433
introduces: Mutex
SE-0434 Usability of global-actor-isolated types
link: SE-0434, commentary
availability: upcoming feature flag: GlobalActorIsolatedTypesUsability
notes: This loosen strict concurrency checking in a number of subtle ways.
Swift 6.1
Swift 6.1 has the following additions.
Vision: Improving the approachability of data-race safety
link: vision
SE-0442 Allow TaskGroup’s ChildTaskResult Type To Be Inferred
link: SE-0442, commentary
notes: This represents a small quality of life improvement for withTaskGroup(…) and withThrowingTaskGroup(…).
SE-0449 Allow nonisolated to prevent global actor inference
link: SE-0449, commentary
notes: This is a straightforward extension to the number of places you can apply nonisolated.
Swift 6.2
Xcode 26 beta has two new build settings:
Approachable Concurrency enables the following feature flags: DisableOutwardActorInference, GlobalActorIsolatedTypesUsability, InferIsolatedConformances, InferSendableFromCaptures, and NonisolatedNonsendingByDefault.
Default Actor Isolation controls SE-0466
Swift 6.2, still in beta, has the following additions.
SE-0371 Isolated synchronous deinit
link: SE-0371, commentary
introduces: isolated deinit
notes: Allows a deinitialiser to access non-sendable isolated state, lifting a restriction imposed by SE-0327.
SE-0457 Expose attosecond representation of Duration
link: SE-0457
introduces: attoseconds, init(attoseconds:)
SE-0461 Run nonisolated async functions on the caller’s actor by default
link: SE-0461
availability: upcoming feature flag: NonisolatedNonsendingByDefault
introduces: nonisolated(nonsending), @concurrent
notes: This represents a significant change to how Swift handles actor isolation by default, and introduces syntax to override that default.
SE-0462 Task Priority Escalation APIs
link: SE-0462
introduces: withTaskPriorityEscalationHandler(…)
notes: Code that uses structured concurrency benefits from priority boosts automatically. This proposal exposes APIs so that code using unstructured concurrency can do the same.
SE-0463 Import Objective-C completion handler parameters as @Sendable
link: SE-0463
notes: This is a welcome resolution to a source of much confusion.
SE-0466 Control default actor isolation inference
link: SE-0466, commentary
availability: not officially approved, but a de facto part of Swift 6.2
introduces: -default-isolation compiler flag
notes: This is a major component of the above-mentioned vision document.
SE-0468 Hashable conformance for Async(Throwing)Stream.Continuation
link: SE-0468
notes: This is an obvious benefit when you’re juggling a bunch of different async streams.
SE-0469 Task Naming
link: SE-0469
introduces: name, init(name:…)
SE-0470 Global-actor isolated conformances
link: SE-0470
availability: upcoming feature flag: InferIsolatedConformances
introduces: @SomeActor protocol conformance
notes: This is particularly useful when you want to conform an @MainActor type to Equatable, Hashable, and so on.
SE-0471 Improved Custom SerialExecutor isolation checking for Concurrency Runtime
link: SE-0471
notes: This is a welcome extension to SE-0424.
SE-0472 Starting tasks synchronously from caller context
link: SE-0472
introduces: immediate[Detached](…), addImmediateTask[UnlessCancelled](…),
notes: This introduces the concept of an immediate task, one that initially uses the calling execution context. This is one of those things where, when you need it, you really need it. But it’s hard to summary when you might need it, so you’ll just have to read the proposal (-:
In Progress
The proposals in this section didn’t make Swift 6.2.
SE-0406 Backpressure support for AsyncStream
link: SE-0406
availability: returned for revision
notes: Currently AsyncStream has very limited buffering options. This was a proposal to improve that. This feature is still very much needed, but the outlook for this proposal is hazy. My best guess is that something like this will land first in the Swift Async Algorithms package. See this thread.
SE-NNNN Closure isolation control
link: SE-NNNN
introduces: @inheritsIsolation
availability: not yet approved
notes: This aims to bring the currently experimental @_inheritActorContext attribute into the language officially. It’s not clear how this will play out given the changes in SE-0461.
Revision History
2025-09-02 Updated for the upcoming release Swift 6.2.
2025-04-07 Updated for the release of Swift 6.1, including a number of things that are still in progress.
2024-11-09 First post.
I'm looking into a newer XPC API available starting with macOS 14. Although it's declared as a low-level API I can't figure it how to specify code signing requirement using XPCListener and XPCSession. How do I connect it with xpc_listener_set_peer_code_signing_requirement and xpc_connection_set_peer_code_signing_requirement which require xpc_listener_t and xpc_connection_t respectively?
Foundation XPC is declared as a high-level API and provides easy ways to specify code signing requirements on both ends of xpc.
I'm confused with all these XPC APIs and their future:
Newer really high-level XPCListener and XPCSession API (in low-level framework???)
Low-level xpc_listener_t & xpc_connection_t -like API. Is it being replaced by newer XPCListener and XPCSession?
How is it related to High-level Foundation XPC? Are NSXPCListener and NSXPCConnection going to be deprecated and replaced by XPCListener and XPCSession??
Hey everyone,
Is it possible and how to get Managed Apple ID (email) programmatically for user signed in to ipad through shared IPad feature ?
It would be good to have MDM independent solution, I mean API call to MDM service is not acceptable for us.
Maybe API call to ASM or ABM, or get that somehow on iOS device end... any advice ?
Thanks in advance,
Dima
Topic:
Business & Education
SubTopic:
General
Hello!
I have a problem installing the iPad version of the application on a Mac.
I can't install the application - Testflight says that an OS update is required. See screenshot.
Mac on the latest OS version - 15.2.
Testflight application version - 3.7.0
Moreover, I installed the same application from Testflight on the previous version of the OS and the previous version of the Testflight application. Therefore, I can't say exactly after what this appeared, since I updated the OS version and the Testflight application at the same time
Perhaps this is a bug in the Testflight application version 3.7.0.
I'm implementing Apple Pay in my Flutter web app and I'm following the guidelines for domain verification using the apple-developer-merchantid-domain-association file.
When I access the file at https://mydomain.com/.well-known/apple-developer-merchantid-domain-association through my web app, the browser silently downloads the file instead of displaying its content on the webpage.
My question is:
Is this the expected behavior for the apple-developer-merchantid-domain-association file? Should the browser download the file silently, or is there another step required, such as displaying the content on the webpage for verification purposes?
I've consulted some resources and they indicate that the file download is the correct behavior. However, I'd appreciate confirmation from the community to ensure I'm implementing the verification process correctly.
Summary is how do we know if apple has verified it?
I want to render a 3d/stereoscopic video in an Apple Vision Pro window using RealityKit/RealityView. The video is a left-right stereo. The straight forward approach would be to spawn a quad, and give it a custom Shader Graph material, which has a CameraIndexSwitch. The CameraIndexSwitch chooses between the right texture vs the left texture.
https://i.sstatic.net/XawqjNcg.png
The issue I have here is that I have to extract the video frames from my AVSampleBufferVideoRenderer. This should work ok, but not if I'm playing FairPlay content.
So, my question is, how to render stereo FairPlay videos in a SwiftUI RealityView?
Topic:
Spatial Computing
SubTopic:
Reality Composer Pro
Tags:
Metal
MetalKit
RealityKit
AVFoundation
Hello.
When testing with the Endpoint Security Framework for the AUTH_OPEN event, I found that the deadline was 15 seconds, but the actual process termination occurred at 5 or 6 seconds. Is this intended?
I am currently working on creating a digital wallet for Apple. While I am able to successfully generate the .pkpass file and verify its contents by changing the extension to .zip, I encounter an issue when attempting to open the .pkpass file on an iPhone—it displays the error "File format is not supported."
I validated the .pkpass file using https://pkpassvalidator.azurewebsites.net/, and the validation results indicate that everything is correct. Additionally, I manually verified the contents by extracting the zip file, and all the information appears to be in order.
I am unable to identify the root cause of this issue. Could you please provide guidance on what might be going wrong?
Topic:
App & System Services
SubTopic:
Wallet
For important background information, read Extra-ordinary Networking before reading this.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Broadcasts and Multicasts, Hints and Tips
I regularly see folks struggle with broadcasts and multicasts on Apple platforms. This post is my attempt to clear up some of the confusion.
This post covers both IPv4 and IPv6. There is, however, a key difference. In IPv4, broadcasts and multicasts are distinct concepts. In contrast, IPv6 doesn’t support broadcast as such; rather, it treats broadcasts as a special case of multicasts. IPv6 does have an all nodes multicast address, but it’s rarely used.
Before reading this post, I suggest you familiarise yourself with IP addresses in general. A good place to start is The Fount of All Knowledge™.
Service Discovery
A lot of broadcast and multicast questions come from folks implementing their own service discovery protocol. I generally recommend against doing that, for the reasons outlined in the Service Discovery section of Don’t Try to Get the Device’s IP Address.
There are, however, some good reasons to implement a custom service discovery protocol. For example, you might be working with an accessory that only supports this custom protocol [1]. If you must implement your own service discovery protocol, read this post and also read the advice in Don’t Try to Get the Device’s IP Address.
IMPORTANT Sometimes I see folks implementing their own version of mDNS. This is almost always a mistake:
If you’re using third-party tooling that includes its own mDNS implementation, it’s likely that this tooling allows you to disable that implementation and instead rely on the Bonjour support that’s built-in to all Apple platforms.
If you’re doing some weird low-level thing with mDNS or DNS-SD, it’s likely that you can do that with the low-level DNS-SD API.
[1] And whose firmware you can’t change! I talk more about this in Working with a Wi-Fi Accessory.
API Choice
Broadcasts and multicasts typically use UDP [1]. TN3151 Choosing the right networking API describes two recommended UDP APIs:
Network framework
BSD Sockets
Our general advice is to prefer Network framework over BSD Sockets, but UDP broadcasts and multicasts are an exception to that rule. Network framework has very limited UDP broadcast support. And while it’s support for UDP multicasts is less limited, it’s still not sufficient for all UDP applications. In cases where Network framework is not sufficient, BSD Sockets is your only option.
[1] It is possible to broadcast and multicast at the Ethernet level, but I almost never see questions about that.
UDP Broadcasts in Network Framework
Historically I’ve claimed that Network framework was useful for UDP broadcasts is very limited circumstances (for example, in the footnote on this post). I’ve since learnt that this isn’t the case. Or, more accurately, this support is so limited (r. 122924701) as to be useless in practice.
For the moment, if you want to work with UDP broadcasts, your only option is BSD Sockets.
UDP Multicasts in Network Framework
Network framework supports UDP multicast using the NWConnectionGroup class with the NWMulticastGroup group descriptor. This support has limits. The most significant limit is that it doesn’t support broadcasts; it’s for multicasts only.
Note This only relevant to IPv4. Remember that IPv6 doesn’t support broadcasts as a separate concept.
There are other limitations, but I don’t have a good feel for them. I’ll update this post as I encounter issues.
Local Network Privacy
Some Apple platforms support local network privacy. This impacts broadcasts and multicasts in two ways:
Broadcasts and multicasts require local network access, something that’s typically granted by the user.
Broadcasts and multicasts are limited by a managed entitlement (except on macOS).
TN3179 Understanding local network privacy has lots of additional info on this topic, including the list of platforms to which it applies.
Send, Receive, and Interfaces
When you broadcast or multicast, there’s a fundamental asymmetry between send and receive:
You can reasonable receive datagrams on all broadcast-capable interfaces.
But when you send a datagram, it has to target a specific interface.
The sending behaviour is the source of many weird problems. Consider the IPv4 case. If you send a directed broadcast, you can reasonably assume it’ll be routed to the correct interface based on the network prefix. But folks commonly send an all-hosts broadcast (255.255.255.255), and it’s not obvious what happens in that case.
Note If you’re unfamiliar with the terms directed broadcast and all-hosts broadcast, see IP address.
The exact rules for this are complex, vary by platform, and can change over time. For that reason, it’s best to write your broadcast code to be interface specific. That is:
Identify the interfaces on which you want to work.
Create a socket per interface.
Bind that socket to that interface.
Note Use the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options rather than binding to the interface address, because the interface address can change over time.
Extra-ordinary Networking has links to other posts which discuss these concepts and the specific APIs in more detail.
Miscellaneous Gotchas
A common cause of mysterious broadcast and multicast problems is folks who hard code BSD interface names, like en0. Doing that might work for the vast majority of users but then fail in some obscure scenarios.
BSD interface names are not considered API and you must not hard code them. Extra-ordinary Networking has links to posts that describe how to enumerate the interface list and identify interfaces of a specific type.
Don’t assume that there’ll be only one interface of a given type. This might seem obviously true, but it’s not. For example, our platforms support peer-to-peer Wi-Fi, so each device has multiple Wi-Fi interfaces.
When sending a broadcast, don’t forget to enable the SO_BROADCAST socket option.
If you’re building a sandboxed app on the Mac, working with UDP requires both the com.apple.security.network.client and com.apple.security.network.server entitlements.
Some folks reach for broadcasts or multicasts because they’re sending the same content to multiple devices and they believe that it’ll be faster than unicasts. That’s not true in many cases, especially on Wi-Fi. For more on this, see the Broadcasts section of Wi-Fi Fundamentals.
Snippets
To send a UDP broadcast:
func broadcast(message: Data, to interfaceName: String) throws {
let fd = try FileDescriptor.socket(AF_INET, SOCK_DGRAM, 0)
defer { try! fd.close() }
try fd.setSocketOption(SOL_SOCKET, SO_BROADCAST, 1 as CInt)
let interfaceIndex = if_nametoindex(interfaceName)
guard interfaceIndex > 0 else { throw … }
try fd.setSocketOption(IPPROTO_IP, IP_BOUND_IF, interfaceIndex)
try fd.send(data: message, to: ("255.255.255.255", 2222))
}
Note These snippet uses the helpers from Calling BSD Sockets from Swift.
To receive UDP broadcasts:
func receiveBroadcasts(from interfaceName: String) throws {
let fd = try FileDescriptor.socket(AF_INET, SOCK_DGRAM, 0)
defer { try! fd.close() }
let interfaceIndex = if_nametoindex(interfaceName)
guard interfaceIndex > 0 else { fatalError() }
try fd.setSocketOption(IPPROTO_IP, IP_BOUND_IF, interfaceIndex)
try fd.setSocketOption(SOL_SOCKET, SO_REUSEADDR, 1 as CInt)
try fd.setSocketOption(SOL_SOCKET, SO_REUSEPORT, 1 as CInt)
try fd.bind("0.0.0.0", 2222)
while true {
let (data, (sender, port)) = try fd.receiveFrom()
…
}
}
IMPORTANT This code runs synchronously, which is less than ideal. In a real app you’d run the receive asynchronously, for example, using a Dispatch read source. For an example of how to do that, see this post.
If you need similar snippets for multicast, lemme know. I’ve got them lurking on my hard disk somewhere (-:
Other Resources
Apple’s official documentation for BSD Sockets is in the man pages. See Reading UNIX Manual Pages. Of particular interest are:
setsockopt man page
ip man page
ip6 man page
If you’re not familiar with BSD Sockets, I strongly recommend that you consult third-party documentation for it. BSD Sockets is one of those APIs that looks simple but, in reality, is ridiculously complicated. That’s especially true if you’re trying to write code that works on BSD-based platforms, like all of Apple’s platforms, and non-BSD-based platforms, like Linux.
I specifically recommend UNIX Network Programming, by Stevens et al, but there are lots of good alternatives.
https://unpbook.com
Revision History
2025-09-01 Fixed a broken link.
2025-01-16 First posted.