Given the below code with Swift 6 language mode, Xcode 16.2
If running with iOS 18+: the app crashes due to _dispatch_assert_queue_fail
If running with iOS 17 and below: there is a warning: warning: data race detected: @MainActor function at Swift6Playground/PublishedValuesView.swift:12 was not called on the main thread
Could anyone please help explain what's wrong here?
import SwiftUI
import Combine
@MainActor
class PublishedValuesViewModel: ObservableObject {
@Published var count = 0
@Published var content: String = "NA"
private var cancellables: Set<AnyCancellable> = []
func start() async {
let publisher = $count
.map { String(describing: $0) }
.removeDuplicates()
for await value in publisher.values {
content = value
}
}
}
struct PublishedValuesView: View {
@ObservedObject var viewModel: PublishedValuesViewModel
var body: some View {
Text("Published Values: \(viewModel.content)")
.task {
await viewModel.start()
}
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi guys,
I've been struggling for a few days with this really weird behaviour.
We made an app for our e-commerce website and found out that a part of the product page is missing.
For any reason, the header and first blocks of the page and footer are displayed, but then a massive part of the content is missing. This content is not loaded through ajax; that's why I don't understand why it's not displayed.
You can see here 2 screenshots of what the page should look like and what the page looks like with WKWebView.
I've been inspecting this with Safari; there isn't any blocking error in the console, and html elements are just empty. There is the div with class row and nothing in it.
The same website is working perfectly with native Android Webview.
If anyone has any clue to find out what's going wrong
Topic:
Programming Languages
SubTopic:
Swift
My application crash on iOS 16 randomly, stack trace like this:
libswiftCore.dylib __swift_release_dealloc + 32
libswiftNetwork.dylib outlined consume of (@escaping @callee_guaranteed (@in_guaranteed Network.NWConnection.State) -> ())? + 52
libswiftNetwork.dylib outlined consume of (@escaping @callee_guaranteed (@in_guaranteed Network.NWConnection.State) -> ())? + 52
libswiftCore.dylib __swift_release_dealloc + 56
libsystem_blocks.dylib __call_dispose_helpers_excp + 48
libsystem_blocks.dylib __Block_release + 252
libsystem_blocks.dylib bool HelperBase::disposeCapture<(HelperBase::BlockCaptureKind)4>(unsigned int, unsigned char*) + 68
libsystem_blocks.dylib HelperBase::destroyBlock(Block_layout*, bool, unsigned char*) + 180
libsystem_blocks.dylib __call_dispose_helpers_excp + 72
libsystem_blocks.dylib __Block_release + 252
libdispatch.dylib ___destroy_helper_block_8_32c35typeinfo name for dispatch_block_private_data_s + 96
libsystem_blocks.dylib __call_dispose_helpers_excp + 48
libsystem_blocks.dylib __Block_release + 252
libdispatch.dylib __dispatch_client_callout + 20
libdispatch.dylib __dispatch_root_queue_drain + 684
libdispatch.dylib __dispatch_worker_thread2 + 164
libsystem_pthread.dylib __pthread_wqthread + 228
From buly(a tool to report crash) we notice that this crash only happens on iOS 16
Topic:
Programming Languages
SubTopic:
Swift
Issue:
During app execution, the intended method is not being called; instead, the method preceding (written above the intended method) is being executed.
For Example:
//In my case the ViewController class is at 3rd level of inheritance.
class ViewController: UIViewController {
func methodA() {
print("methodA")
}
func methodB() {
print("methodB")
}
}
let vc = ViewController()
vc.methodB()
Output: //"methodA"
Expected: //"methodB"
Observations:
Recent code changes have revealed that enabling the below Swift-6 flag leads to this linking issue. When this flag is commented out, the problem disappears.
.enableUpcomingFeature("InternalImportsByDefault")
Additionally, moving the intended method into an extension of the same class resolves the issue when the flag is enabled.
Conclusion:
To resolve the issue:
Comment out the Swift-6 flag.
Alternatively, move the method into an extension of the same class, which addresses the issue for this specific case.
I had similar issue in other class where it crashes with message "method not found", but actually the method is there. When moving the method into an extension of same class resolve this issue.
Any help is much appreciated.
Thanking you..
I generate images with command line apps in Swift on MacOS. Under the prior Xcode/MacOS my code had been running at the same performance for years. Converting to Swift 6 (no code changes) and running on Sequoia, I noticed a massive slowdown. Running Profile, I tracked it down to allow single line:
var values = ContiguousArray<Double>(repeating: 0.0, count: localData.options.count)
count for my current test case is 4, so its allocating 4 doubles at a time, around 40,000 times in this test. This one line takes 42 seconds out of a run time of 52 seconds. With the profile shown as:
26 41.62 s 4.8% 26.00 ms specialized ContiguousArray.init(_uninitializedCount:)
42 41.57 s 4.8% 42.00 ms _ContiguousArrayBuffer.init(_uninitializedCount:minimumCapacity:)
40730 40.93 s 4.7% 40.73 s _swift_allocObject_
68 68.00 ms 0.0% 68.00 ms std::__1::pair<MallocTypeCacheEntry*, unsigned int> swift::ConcurrentReadableHashMap<MallocTypeCacheEntry, swift::LazyMutex>::find<unsigned int>(unsigned int const&, swift::ConcurrentReadableHashMap<MallocTypeCacheEntry, swift::LazyMutex>::IndexStorage, unsigned long, MallocTypeCacheEntry*)
7 130.00 ms 0.0% 7.00 ms swift::swift_slowAllocTyped(unsigned long, unsigned long, unsigned long long)
which is clearly inside the OS allocator somewhere. What happened? Previously this would have taken closer to 8 seconds or so for the entire run.
underlying Objective-C module 'FirebaseSharedSwift' not found
aymodazhnyneylcscdggrsgjocui/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/FirebaseSharedSwift.build/Objects-normal/x86_64/FirebaseSharedSwift.private.swiftinterface:5:19: underlying Objective-C module 'FirebaseSharedSwift' not found
Command SwiftCompile failed with a nonzero exit code
I have the following TaskExecutor code in Swift 6 and is getting the following error:
//Error
Passing closure as a sending parameter risks causing data races between main actor-isolated code and concurrent execution of the closure.
May I know what is the best way to approach this?
This is the default code generated by Xcode when creating a Vision Pro App using Metal as the Immersive Renderer.
Renderer
@MainActor
static func startRenderLoop(_ layerRenderer: LayerRenderer, appModel: AppModel) {
Task(executorPreference: RendererTaskExecutor.shared) { //Error
let renderer = Renderer(layerRenderer, appModel: appModel)
await renderer.startARSession()
await renderer.renderLoop()
}
}
final class RendererTaskExecutor: TaskExecutor {
private let queue = DispatchQueue(label: "RenderThreadQueue", qos: .userInteractive)
func enqueue(_ job: UnownedJob) {
queue.async {
job.runSynchronously(on: self.asUnownedSerialExecutor())
}
}
func asUnownedSerialExecutor() -> UnownedTaskExecutor {
return UnownedTaskExecutor(ordinary: self)
}
static let shared: RendererTaskExecutor = RendererTaskExecutor()
}
I’m experiencing a crash at runtime when trying to extract audio from a video. This issue occurs on both iOS 18 and earlier versions. The crash is caused by the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[AVAssetExportSession exportAsynchronouslyWithCompletionHandler:] Cannot call exportAsynchronouslyWithCompletionHandler: more than once.
(0x1851435ec 0x1826dd244 0x1970c09c0 0x214d8f358 0x214d95899 0x190a1c8b9 0x214d8efd9 0x30204cef5 0x302053ab9 0x190a5ae39)
libc++abi: terminating due to uncaught exception of type NSException
My previous code worked fine, but it's crashing with Swift 6.
Does anyone know a solution for this?
Previous code:
func extractAudioFromVideo(from videoURL: URL, exportHandler: ((AVAssetExportSession, CurrentValueSubject<Float, Never>?) -> Void)? = nil, completion: @escaping (Swift.Result<URL, Error>) -> Void) {
let asset = AVAsset(url: videoURL)
// Create an AVAssetExportSession to export the audio track
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetExportSession"])))
return
}
// Set the output file type and path
guard let filename = videoURL.lastPathComponent.components(separatedBy: ["."]).first else { return }
let outputURL = VideoUtils.getTempAudioExportUrl(filename)
VideoUtils.deleteFileIfExists(outputURL.path)
exportSession.outputFileType = .m4a
exportSession.outputURL = outputURL
let audioExportProgressPublisher = CurrentValueSubject<Float, Never>(0.0)
if let exportHandler = exportHandler {
exportHandler(exportSession, audioExportProgressPublisher)
}
// Periodically check the progress of the export session
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
audioExportProgressPublisher.send(exportSession.progress)
}
// Export the audio track asynchronously
exportSession.exportAsynchronously {
switch exportSession.status {
case .completed:
completion(.success(outputURL))
case .failed:
completion(.failure(exportSession.error ?? NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown error occurred while exporting audio"])))
case .cancelled:
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Export session was cancelled"])))
default:
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown export session status"])))
}
// Invalidate the timer when the export session completes or is cancelled
timer.invalidate()
}
}
## New Code:
func extractAudioFromVideo(from videoURL: URL, exportHandler: ((AVAssetExportSession, CurrentValueSubject<Float, Never>?) -> Void)? = nil, completion: @escaping (Swift.Result<URL, Error>) -> Void)
{
let asset = AVAsset(url: videoURL)
// Create an AVAssetExportSession to export the audio track
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetExportSession"])))
return
}
// Set the output file type and path
guard let filename = videoURL.lastPathComponent.components(separatedBy: ["."]).first else { return }
let outputURL = VideoUtils.getTempAudioExportUrl(filename)
VideoUtils.deleteFileIfExists(outputURL.path)
exportSession.outputFileType = .m4a
exportSession.outputURL = outputURL
let audioExportProgressPublisher = CurrentValueSubject<Float, Never>(0.0)
if let exportHandler {
exportHandler(exportSession, audioExportProgressPublisher)
}
let task = Task {
if #available(iOS 18.0, *) {
// Handle export for iOS 18 and later
let states = exportSession.states(updateInterval: 0.1)
for await state in states {
switch state {
case .pending, .waiting:
break
case .exporting(progress: let progress):
print("Exporting: \(progress.fractionCompleted)")
if progress.isFinished {
completion(.success(outputURL))
} else if progress.isCancelled {
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Export session was cancelled"])))
} else {
audioExportProgressPublisher.send(Float(progress.fractionCompleted))
}
}
}
try await exportSession.export(to: outputURL, as: .m4a) // Only call export once
} else {
// Handle export for iOS versions below 18
let publishTimer = Timer.publish(every: 0.1, on: .main, in: .common)
.autoconnect()
.sink { [weak exportSession] _ in
guard let exportSession = exportSession else { return }
audioExportProgressPublisher.send(exportSession.progress)
}
// Only call export once
await exportSession.export()
// Handle the export session's status
switch exportSession.status {
case .completed:
completion(.success(outputURL))
case .failed:
completion(.failure(exportSession.error ?? NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown error occurred while exporting audio"])))
case .cancelled:
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Export session was cancelled"])))
default:
completion(.failure(NSError(domain: "com.example.app", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown export session status"])))
}
// Invalidate the timer when the export session completes or is cancelled
publishTimer.cancel()
}
}
task.cancel()
}
Topic:
Programming Languages
SubTopic:
Swift
I'm primarily an AppleScript writer and only a novice programmer, using ChatGPT to help me with the legwork. It has helped me to write a functioning app that builds a menu structure based on the scripts I have in the Scripts directory used in the script menu and then runs the applescripts. When I distribute the app to my desktop and run it, the scripts that access other apps, like InDesign will cause it to launch, but not actually do anything. I included the ids for each app in the entitlements dictionary and have given the app full disk access in system settings, but it's not functioning as I'd expect.
I know there are apps like Alfred that allow you to run scripts from a keystroke, but I'm building this for others I work with so they can also access info about each script, what it does, and how to use it from the menu, as well as key commands to run them.
Not sure what else to say, but if this sounds like a simple fix to anyone, please let me know.
Can i use c++ library with c library in swift app project
Hello. I want to use a C++ library in my Swift app project.
First, our company has an internal solution library.
When built, it generates a Static Library in '.a' format, and we use it by connecting the library's Header to the App_Bridging_Header.
There's no problem with this part.
However, the new feature now includes C++. It also generates a Static Library in '.a' format.
So, I tried to use the same method and created an App_Bridging_Header. But an error occurs, and I can't proceed.
The first error occurs in the library file:
'iostream' file not found
The second error occurs in the App_Bridging_Header:
failed to emit precompiled header '/Users/kimjitae/Library/Developer/Xcode/DerivedData/ddddd-glmnoqrwdrgarrhjulxjmalpyikr/Build/Intermediates.noindex/PrecompiledHeaders/ddddd-Bridging-Header-swift_3O89L0OXZ0CPD-clang_188AW1HK8F0Q3.pch' for bridging header '/Users/kimjitae/Desktop/enf4/ddddd/ddddd/ddddd-Bridging-Header.h'
Our library is developed in C++ using Xcode, and there's no problem when we run and build just the library project.
The build succeeds, and the '.a' file is generated correctly. However, when we try to connect it with the app, the above problems occur.
Could there be a problem because we also need to use the existing C library alongside this?
The build is successful in an app project created with Objective-C.
I have been trying to integrate a UIKit view into SwiftUI, specifically a WKWebView. However, I keep encountering a does not conform to protocol error.
Here's my code:
import SwiftUI
import WebKit
struct SimpleWebView: View {
var body: some View {
WebViewContainerRepresentable()
.edgesIgnoringSafeArea(.all)
}
}
struct WebViewContainerRepresentable: UIViewRepresentable {
typealias UIViewType = WKWebView
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
// Updates not required for this use case
}
}
I tried this with other views as well, and it turns out this is not WKWebView-specific.
The minimum deployment version is iOS 15.
Any help would be much appreciated. Let me know if I need to add any more information.
A few years ago [1] Xcode added new warnings that help detect a nasty gotcha related to the lifetime of unsafe pointers. For example:
Initialization of 'UnsafeMutablePointer<timeval>' results in a dangling pointer
Inout expression creates a temporary pointer, but argument 'iov_base' should be a pointer that outlives the call to 'init(iov_base:iov_len:)'
I’ve seen a lot of folks confused by these warnings, and by the lifetime of unsafe pointers in general, and this post is my attempt to clarify the topic.
If you have questions about any of this, please put them in a new thread in the Programming Languages > Swift topic.
Finally, I encourage you to watch the following WWDC presentations:
WWDC 2020 Session 10648 Unsafe Swift
WWDC 2020 Session 10167 Safely manage pointers in Swift
These cover some of the same ground I’ve covered here, and a lot of other cool stuff as well.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
[1] Swift 5.2.2, as shipped in Xcode 11.4. See the discussion of SR-2790 in Xcode 11.4 Release Notes.
Basics
In Swift, the ampersand (&) indicates that a parameter is being passed inout. Consider this example:
func addVarnish(_ product: inout String) {
product += " varnish"
}
var waffle = "waffle"
addVarnish(&waffle) // line A
print(waffle)
// printed: waffle varnish
On line A, the ampersand tells you that waffle could be modified by addVarnish(_:).
However, there is another use of ampersand that was designed to help with C interoperability. Consider this code:
var tv = timeval()
gettimeofday(&tv, nil)
print(tv)
// printed: timeval(tv_sec: 1590743104, tv_usec: 77027)
The first parameter to gettimeofday is an UnsafeMutablePointer<timeval>. Here the ampersand denotes a conversion from a timeval to an UnsafeMutablePointer<timeval>. This conversion makes it much easier to call common C APIs from Swift.
This also works for array values. For example:
var hostName = [CChar](repeating: 0, count: 256)
gethostname(&hostName, hostName.count)
print(String(cString: hostName))
// printed: slimey.local.
In this code the ampersand denotes a conversion from [CChar] to an UnsafeMutablePointer<CChar> that points to the base of the array.
While this is convenient, it’s potentially misleading, especially if you come from a C background. In C-based languages, using ampersand in this way yields a pointer to the value that’s valid until the value gets deallocated. That’s not the case in Swift. Rather, the pointer generated by the ampersand syntax is only valid for the duration of that function call.
To understand why that’s the case, consider this code:
struct TimeInTwoParts {
var sec: time_t = 0
var usec: Int32 = 0
var combined: timeval {
get { timeval(tv_sec: sec, tv_usec: usec) }
set {
sec = newValue.tv_sec
usec = newValue.tv_usec
}
}
}
var time = TimeInTwoParts()
gettimeofday(&time.combined, nil) // line A
print(time.combined)
// printed: timeval(tv_sec: 1590743484, tv_usec: 89118)
print(time.sec)
// printed: 1590743484
print(time.usec)
// printed: 89118
Here combined is a computed property that has no independent existence in memory. Thus, it simply makes no sense to take the address of it.
So, how does ampersand deal with this? Under the covers the Swift compiler expands line A to something like this:
var tmp = time.combined
gettimeofday(&tmp, nil)
time.combined = tmp
Once you understand this it’s clear why the resulting pointer is only valid for the duration of the call: As soon as Swift cleans up tmp, the pointer becomes invalid.
A Gotcha
This automatic conversion can be a nasty gotcha. Consider this code:
var tv = timeval()
let tvPtr = UnsafeMutablePointer(&tv) // line A
// ^~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization of 'UnsafeMutablePointer<timeval>' results in a dangling pointer
gettimeofday(tvPtr, nil) // line B
This results in undefined behaviour because the pointer generated by the ampersand on line A is no longer valid when it’s used on line B. In some cases, like this one, the later Swift compiler is able to detect this problem and warn you about it. In other cases you’re not so lucky. Consider this code:
guard let f = fopen("tmp.txt", "w") else { … }
var buf = [CChar](repeating: 0, count: 1024)
setvbuf(f, &buf, _IOFBF, buf.count) // line A
let message = [UInt8]("Hello Crueld World!".utf8)
fwrite(message, message.count, 1, f) // line B
fclose(f) // line C
This uses setvbuf to apply a custom buffer to the file handle. The file handle uses this buffer until after the close on line C. However, the pointer created by the ampersand on line A only exists for the duration of the setvbuf call. When the code calls fwrite on line B the buffer pointer is no longer valid and things end badly.
Unfortunately the compiler isn’t able to detect this problem. Worse yet, the code might actually work initially, and then stop working as you change optimisation settings, update the compiler, change unrelated code, and so on.
Another Gotcha
There is another gotcha associated with the ampersand syntax. Consider this code:
class AtomicCounter {
var count: Int32 = 0
func increment() {
OSAtomicAdd32(1, &count)
}
}
This looks like it’ll implement an atomic counter but there’s no guarantee that the counter will be atomic. To understand why, apply the tmp transform from earlier:
class AtomicCounter {
var count: Int32 = 0
func increment() {
var tmp = count
OSAtomicAdd32(1, &tmp)
count = tmp
}
}
So each call to OSAtomicAdd32 could potentially be operating on a separate copy of the counter that’s then assigned back to count. This undermines the whole notion of atomicity.
Again, this might work in some builds of your product and then fail in other builds.
Note The above discussion is now theoretical because Swift 6 added a Synchronization module that includes comprehensive support for atomics. That module also has a Mutex type (if you need a mutex on older platforms, check out OSAllocatedUnfairLock). These constructs use various different mechanisms to ensure that the underlying value has a stable address.
Summary
So, to summarise:
Swift’s ampersand syntax has very different semantics from the equivalent syntax in C.
When you use an ampersand to convert from a value to a pointer as part of a function call, make sure that the called function doesn’t use the pointer after it’s returned.
It is not safe to use the ampersand syntax for functions where the exact pointer matters.
It’s Not Just Ampersands
There’s one further gotcha related to arrays. The gethostname example above shows that you can use an ampersand to pass the base address of an array to a function that takes a mutable pointer. Swift supports two other implicit conversions like this:
From String to UnsafePointer<CChar> — This allows you to pass a Swift string to an API that takes a C string. For example:
let greeting = "Hello Cruel World!"
let greetingLength = strlen(greeting)
print(greetingLength)
// printed: 18
From Array<Element> to UnsafePointer<Element> — This allows you to pass a Swift array to a C API that takes an array (in C, arrays are typically represented as a base pointer and a length). For example:
let charsUTF16: [UniChar] = [72, 101, 108, 108, 111, 32, 67, 114, 117, 101, 108, 32, 87, 111, 114, 108, 100, 33]
print(charsUTF16)
let str = CFStringCreateWithCharacters(nil, charsUTF16, charsUTF16.count)!
print(str)
// prints: Hello Cruel World!
Note that there’s no ampersand in either of these examples. This technique only works for UnsafePointer parameters (as opposed to UnsafeMutablePointer parameters), so the called function can’t modify its buffer. As the ampersand is there to indicate that the value might be modified, it’s not used in this immutable case.
However, the same pointer lifetime restriction applies: The pointer passed to the function is only valid for the duration of that function call. If the function keeps a copy of that pointer and then uses it later on, Bad Things™ will happen.
Consider this code:
func printAfterDelay(_ str: UnsafePointer<CChar>) {
print(strlen(str))
// printed: 18
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
print(strlen(str))
// printed: 0
}
}
let greeting = ["Hello", "Cruel", "World!"].joined(separator: " ")
printAfterDelay(greeting)
dispatchMain()
The second call to strlen yields undefined behaviour because the pointer passed to printAfterDelay(_:) becomes invalid once printAfterDelay(_:) returns. In this specific example the memory pointed to by str happened to contain a zero, and hence strlen returned 0 but that’s not guaranteed. The str pointer is dangling, so you might get any result from strlen, including a crash.
Advice
So, what can you do about this? There’s two basic strategies here:
Extend the lifetime of the pointer
Manual memory management
Extending the Pointer’s Lifetime
The first strategy makes sense when you have a limited number of pointers and their lifespan is limited. For example, you can fix the setvbuf code from above by changing it to:
let message = [UInt8]("Hello Crueld World!".utf8)
guard let f = fopen("tmp.txt", "w") else { … }
var buf = [CChar](repeating: 0, count: 1024)
buf.withUnsafeMutableBufferPointer { buf in
setvbuf(f, buf.baseAddress!, _IOFBF, buf.count)
fwrite(message, message.count, 1, f)
fclose(f)
}
This version of the code uses withUnsafeMutableBufferPointer(_:). That calls the supplied closure and passes it a pointer (actually an UnsafeMutableBufferPointer) that’s valid for the duration of that closure. As long as you only use that pointer inside the closure, you’re safe!
There are a variety of other routines like withUnsafeMutableBufferPointer(_:), including:
The withUnsafeMutablePointer(to:_:) function
The withUnsafeBufferPointer(_:), withUnsafeMutableBufferPointer(_:), withUnsafeBytes(_:), and withUnsafeMutableBytes(_:) methods on Array
The withUnsafeBytes(_:) and withUnsafeMutableBytes(_:) methods on Data
The withCString(_:) and withUTF8(_:) methods on String.
Manual Memory Management
If you have to wrangle an unbounded number of pointers — or the lifetime of your pointer isn’t simple, for example when calling an asynchronous call — you must revert to manual memory management. Consider the following code, which is a Swift-friendly wrapper around posix_spawn:
func spawn(arguments: [String]) throws -> pid_t {
var argv = arguments.map { arg -> UnsafeMutablePointer<CChar>? in
strdup(arg)
}
argv.append(nil)
defer {
argv.forEach { free($0) }
}
var pid: pid_t = 0
let success = posix_spawn(&pid, argv[0], nil, nil, argv, environ) == 0
guard success else { throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil) }
return pid
}
This code can’t use the withCString(_:) method on String because it has to deal with an arbitrary number of strings. Instead, it uses strdup to copy each string to its own manually managed buffer. And, as these buffers are manually managed, is has to remember to free them.
Change History
2024-12-11 Added a note about the Synchronization module. Made various editorial changes.
2021-02-24 Fixed the formatting. Added links to the WWDC 2021 sessions. Fixed the feedback advice. Minor editorial changes.
2020-06-01 Initial version.
My framework has private Objective-C API that is only used within the framework. It should not be exposed in the public interface (so it shouldn't be imported in the umbrella header).
To expose this API to Swift that's within the framework only the documentation seems to indicate that this needs to be imported in the umbrella header?
Import Code Within a Framework Target
To use the Objective-C declarations in files in the same framework target as your Swift code, configure an umbrella header as follows:
1.Under Build Settings, in Packaging, make sure the Defines Module setting for the framework target is set to Yes.
2.In the umbrella header, import every Objective-C header you want to expose to Swift.
Swift sees every header you expose publicly in your umbrella header. The contents of the Objective-C files in that framework are automatically available from any Swift file within that framework target, with no import statements. Use classes and other declarations from your Objective-C code with the same Swift syntax you use for system classes.
I would imagine that there must be a way to do this?
func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
if
let delegate = delegate,
let shouldChangeCharactersIn = delegate.textField {
return shouldChangeCharactersIn(textField, range, string)
}
return true
}
This is from an extension
extension TextInput: UITextFieldDelegate, ObservableTextFieldDelegateProtocol {
The delegate is already a UITextFieldDelegate, but when you click on the error, it returns 7 instances of:
"Found this candidate in module 'UIKit' (UIKit.UITextFieldDelegate.textField)"
This doesn't give an error in Xcode 16. Is this an Xcode 26 bug?
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.
Hello, I have an issue with importing some .mp3 files into a swift playground project (in Xcode, not in the Playground app). They worked fine in the Xcode project, but for some reason playgrounds isn't able to find them. I imported them the exact same way as I did in the Xcode project.
I'm encountering an issue where certain images are not displaying on some iOS devices, while the same code works perfectly on others. There’s no error or crash — just some images fail to load or display. I've confirmed the image URLs and formats are correct.
Has anyone faced a similar issue or could suggest what might be causing this inconsistent behavior?
Thanks in advance!
Topic:
Programming Languages
SubTopic:
Swift
I can't find a viable path to call StoreKit from C++ right now and would love some ideas.
I'm implementing the code exactly as shown at 4:09 in
https://developer.apple.com/videos/play/wwdc2023/10172/
However when I add any StoreKit functionality in I immediately get
"Actor isolated structure cannot be exposed in C++"
This makes me think I can't create a StoreKit view and call it from C++? Am I missing a better way? I don't think I can have another structure that holds the storeChooser in it because it will have the same problem (I assume, although I will check). Part of the issue seems to be that my app is C++ so there is no main function called in the swift for me to open this view with either, I was going to use the present function Zoe described (as below).
I've tried a lot of alternative approaches but it seems to be blocking async functions from showing in C++ as well. So I'm not sure how to access the basic product(for:) and purchase(product) functions.
import Foundation
import StoreKit
import SwiftUI
public struct storeChooser: View {
public var productIDs: [String]
public var fetchError: String
//@State //Note this is from the UI
@State public var products: [Product] = []
// @State private var isPresented = true
// weak private var host: UIViewController? = nil
public init() {
productIDs = ["20_super_crystals_v1"]
products = []
self.fetchError = "untried"
}
public var body: some View {
VStack(spacing: 20) {
Text( "Products")
ForEach(self.products) { product in
Button {
//dont do anything yet
} label: {
Text("\(product.displayPrice) - \(product.displayName)")
}
}
}.task {
do {
try await self.loadProducts()
} catch {
print(error)
}
}
}
public func queryProducts() {
Task {
do {
try await self.loadProducts()
} catch {
print(error)
}
}
}
public func getProduct1Name() -> String {
if self.products.count > 0 {
return self.products[0].displayName
} else {
return "empty"
}
}
private func loadProducts() async throws {
self.products = try await Product.products(for: self.productIDs)
}
/* public mutating func present(_ viewController: UIViewController) {
isPresented = true;
let host = UIHostingController(rootView: self)
host.rootView.host = host
viewController.present(host, animated: true)
} */
}
I've narrowed down my question after many rabbit holes - how can C++ code open any view in Swift. I can call functions in swift from C++ (works great), but not async or main actor (or actor at all) functions. And if I'm not mistaken all views are actors if not main actors? When calling from C+ I think its necessary that the first view be the main actor?
I've implemented the code from the WWDC23 C++ interop video (Zoe's image picker) where I made a view in a struct, and just want to call it and let the view do the work.
The compiler immediately gives me 'cannot expose main actors to C++'. If I'm not mistaken, doesn't this block the opening of any kind of swift view from C++? Hopefully I'm missing something obvious, which is likely :)
In Zoe's code was his entry point into the program still Swift and not actually C++ app?
Thanks!
Thanks!
Topic:
Programming Languages
SubTopic:
Swift
decidePolicyFor delegate method:
import WebKit
@objc extension DocumentationVC
{
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
Being called just alright in swift 5 minimal concurrency.
Raising concurrency to complete with swift 5 or swift 6. Changing the code to avoid warnings:
@preconcurrency import WebKit
@objc extension DocumentationVC
{
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
The delegate method is not being called. Changing back to swift 5 concurrency minimal - it is called.
Looking at WKNavigationDelegate:
WK_SWIFT_UI_ACTOR
@protocol WKNavigationDelegate <NSObject>
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(WK_SWIFT_UI_ACTOR void (^)(WKNavigationActionPolicy))decisionHandler WK_SWIFT_ASYNC(3);
Changing the delegate method to:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping @MainActor (WKNavigationActionPolicy) -> Void) {
And it is called across swift 5 concurrency minimal to complete to swift 6.
I thought, the meaning of @preconcurrency import WebKit was to keep the delegate without @MainActor before the (WKNavigationActionPolicy) still matching regardless the swift concurrency mode?
My point is - this can introduce hidden breaking changes? I didn't see this documented anyhow at: https://www.swift.org/migration/documentation/migrationguide/.
decidePolicyFor is an optional method - so if signature 'mismatches' - there will be no warning on not-implementing the delegate method.
How do we catch or diagnose irregularities like this? Is it something @preconcurrency import WebKit should be ensuring and it is not?
Is this delegate mismatch a bug on swift side or something we should be taking care of while migrating? If it is on us, how do we diagnose these potential mismatches?