I filed the following issue on swiftlang/swift on GitHub (Aug 8th), and a followup the swift.org forums, but not getting any replies. As we near the release of Swift 6.2, I want to know if what I'm seeing below is expected, or if it's another case where the compiler needs a fix.
protocol P1: Equatable { }
struct S1: P1 { }
// Error: Conformance of 'S1' to protocol 'P1' crosses into main actor-isolated code an can cause data races
struct S1Workaround: @MainActor P1 { } // OK
// Another potential workaround if `Equatable` conformance can be moved to the conforming type.
protocol P2 { }
struct S2: Equatable, P2 { } // OK
There was a prior compiler bug fix which addressed inhereted protocols regarding @MainActor. For Equatable, one still has to use @MainActoreven when the default actor isolation is MainActor.
Also affects Hashable and any other protocol inheriting from Equatable.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello
I'm using this sdk DeclaredAgeRange to get the user age range
When I'm doing in debug mode using sandbox account it is working as expected and I can get the user age range
But when I tried in TestFlight build using sandbox account it is not working and it is always return the age range 18+ and also isEligibleForAgeFeatures API is always returning false
Any advise on this?
Topic:
Programming Languages
SubTopic:
Swift
I'm trying to fix some Swift6 warnings, this one seems too strict, I'm not sure how to fix it. The variable path is a String, which should be immutable, it's a local variable and never used again inside of the function, but still Swift6 complains about it being a race condition, passing it to the task
What should I do here to fix the warning?
I am encountering a strange issue. I have a class that manages a selection of generic items T in an Array. It's a work in progress, but I'l try to give a gist of the setup.
class FileManagerItemModel: NSObject, Identifiable, Codable, NSCopying, Transferable, NSItemProviderReading, NSItemProviderWriting {
var id: URL
static func == (lhs: FileManagerItemModel, rhs: FileManagerItemModel) -> Bool {
lhs.fileURL == rhs.fileURL
}
var fileURL: URL {
FileManagerItemModel.normalizedFileURL(type: type,
rootURL: rootURL,
filePath: filePath)
}
init(type: FileManagerItemType, rootURL: URL, fileURL: URL) {
self.type = type
self.rootURL = rootURL
self.filePath = FileManagerItemModel.filePathRelativeToRootURL(fileURL: fileURL, rootURL: rootURL) ?? "[unknown]"
self.id = FileManagerItemModel.normalizedFileURL(type: type,
rootURL: rootURL,
filePath: filePath)
}
}
The class that manages the selection of these FileManagerItemModels is like so:
@Observable
class MultiSelectDragDropCoordinator<T: Hashable>: ObservableObject, CustomDebugStringConvertible {
private(set) var multiSelectedItems: [T] = []
func addToSelection(_ item: T) {
if !multiSelectedItems.contains(where: { $0 == item }) {
multiSelectedItems.append(item)
}
}
...
}
My issue is that the check if !multiSelectedItems.contains(where: { $0 == item }) in func addToSelection fails. The if is always executed, even if multiSelectedItems contains the given item.
Now, my first thought would be to suspect the static func == check. But that check works fine and does what it should do. Equality is defined by the whole fileURL.
So, the if should have worked. And If I put a breakpoint in func addToSelection on the if, and type po multiSelectedItems.contains(where: { $0 == item }) in the debug console, it actually returns true if the item is in multiSelectedItems. And it properly return false if the item is not in multiSelectedItems.
Still, if I then continue stepping through the app after the breakpoint was hit and I confirmed that the contains should return true, the app still goes into the if, and adds a duplicate item.
I tried assigning to a variable, I tried using a function and returning the true/false. Nothing helps.
Does anyone have an idea on why the debugger shows one (the correct and expected) thing but the actual code still does something different?
Topic:
Programming Languages
SubTopic:
Swift
Is there a way to achieve the following using C++/Swift interoperability:
class MyCppClass
{
public:
...
...
private:
bool member1;
ACppClass member2;
ASwiftClass member3;
}
I'm aware of the recent C++/Objective-C interoperability compiler setting, but can't find any information on whether this is possible.
I've watched the Apple video:
https://developer.apple.com/videos/play/wwdc2023/10172/
and seen this post from Quinn:
https://developer.apple.com/forums/thread/768928
but I don't see anyone discussing this kind of situation.
Thanks in advance.
Topic:
Programming Languages
SubTopic:
Swift
Hi all,
I'm running into a Swift Concurrency issue and would appreciate some help understanding what's going on.
I have a protocol and an actor set up like this:
protocol PersistenceListener: AnyObject {
func persistenceDidUpdate(key: String, newValue: Any?)
}
actor Persistence {
func addListener(_ listener: PersistenceListener) {
listeners.add(listener)
}
/// Removes a listener.
func removeListener(_ listener: PersistenceListener) {
listeners.remove(listener)
}
// MARK: - Private Properties
private var listeners = NSHashTable<AnyObject>.weakObjects()
// MARK: - Private Methods
/// Notifies all registered listeners on the main actor.
private func notifyListeners(key: String, value: Any?) async {
let currentListeners = listeners.allObjects.compactMap { $0 as? PersistenceListener }
for listener in currentListeners {
await MainActor.run {
listener.persistenceDidUpdate(key: key, newValue: value)
}
}
}
}
When I compile this code, I get a concurrency error:
"Sending 'listener' risks causing data races"
I get many warnings like this when I build an old project.
I asked AI chatbot which gave me several solutions, the recommended one is:
var hashBag = [String: Int]()
func updateHashBag() async {
var tempHashBag = hashBag // make copy
await withTaskGroup(of: Void.self) { group in
group.addTask {
tempHashBag["key1"] = 1
}
group.addTask {
tempHashBag["key2"] = 2
}
}
hashBag = tempHashBag // copy back?
}
My understanding is that in the task group, the concurrency engine ensures synchronized modifications on the temp copy in multiple tasks. I should not worry about this.
My question is about performance.
What if I want to put a lot of data into the bag? Does the compiler do some kind of magics to optimize low level memory allocations? For example, the temp copy actually is not a real copy, it is a special reference to the original hash bag; it is only grammar glue that I am modifying the copy.
Is there a swift6 manual that will teach me how to code in swift?
I am trying to use initialize a Decimal type using its generic binary integer exactly initializer but it keeps crashing with a fatal error regardless of the value used:
Code to reproduce the issue:
let binaryInteger = -10
let decimal = Decimal(exactly: binaryInteger) // error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
Is it a known bug?
Why Ternary operator in not called a binary Operator or ternary Operands ?
question ? answer1 : answer2
When it takes 2 operators ?
I have a transformation function that takes in data, executes some instructions, and returns an output. This function is dynamic and not shipped with the binary. Currently, I’m executing it using JavaScriptCore.JSContext, which works well, but the function itself is written in JavaScript.
Is there a way to achieve something similar using Swift – such as executing a dynamic Swift script, either directly or through other means? I know this is possible on macOS, but I’m not sure about iOS. I’ve also heard that extensions might open up some possibilities here. Any insights or alternative approaches would be appreciated.
I came across a code
let myFruitBasket = ["apple":"red", "banana": "yellow", "budbeeri": "dark voilet", "chikoo": "brown"]
Can we have range for keys and values of dictionary, it will be convenient
for keys
print(myFruitBasket.keys[1...3])
// banana, budbeeri, chikoo
same for values
print(myFruitsBasket.values[1...3])
// yellow, voilet, brown
In my code I use a binding that use 2 methods to get and get a value. There is no problem with swift 5 but when I swift to swift 6 the compiler fails :
Here a sample example of code to reproduce the problem :
`import SwiftUI
struct ContentView: View {
@State private var isOn = false
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Toggle("change it", isOn: Binding(get: getValue, set: setValue(_:)))
}
.padding()
}
private func getValue() -> Bool {
isOn
}
private func setValue(_ value: Bool) {
isOn = value
}
}`
Xcode compiler log error :
1. Apple Swift version 6.1.2 (swiftlang-6.1.2.1.2 clang-1700.0.13.5) 2. Compiling with the current language version 3. While evaluating request IRGenRequest(IR Generation for file "/Users/xavierrouet/Developer/TestCompilBindingSwift6/TestCompilBindingSwift6/ContentView.swift") 4. While emitting IR SIL function "@$sSbScA_pSgIeAghyg_SbIeAghn_TR". for <<debugloc at "<compiler-generated>":0:0>>Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var LLVM_SYMBOLIZER_PATH` to point to it):
0 swift-frontend 0x000000010910ae24 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 swift-frontend 0x0000000109108c5c llvm::sys::RunSignalHandlers() + 112
2 swift-frontend 0x000000010910b460 SignalHandler(int) + 360
3 libsystem_platform.dylib 0x0000000188e60624 _sigtramp + 56
4 libsystem_pthread.dylib 0x0000000188e2688c pthread_kill + 296
5 libsystem_c.dylib 0x0000000188d2fc60 abort + 124
6 swift-frontend 0x00000001032ff9a8 swift::DiagnosticHelper::~DiagnosticHelper() + 0
7 swift-frontend 0x000000010907a878 llvm::report_fatal_error(llvm::Twine const&, bool) + 280
8 swift-frontend 0x00000001090aef6c report_at_maximum_capacity(unsigned long) + 0
9 swift-frontend 0x00000001090aec7c llvm::SmallVectorBase::grow_pod(void*, unsigned long, unsigned long) + 384
10 swift-frontend 0x000000010339c418 (anonymous namespace)::SyncCallEmission::setArgs(swift::irgen::Explosion&, bool, swift::irgen::WitnessMetadata*) + 892
11 swift-frontend 0x00000001035f8104 (anonymous namespace)::IRGenSILFunction::visitFullApplySite(swift::FullApplySite) + 4792
12 swift-frontend 0x00000001035c876c (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 2636
13 swift-frontend 0x00000001035c6614 (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 15860
14 swift-frontend 0x00000001035c2368 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 2788
15 swift-frontend 0x00000001033e7c1c swift::irgen::IRGenerator::emitLazyDefinitions() + 5288
16 swift-frontend 0x0000000103573d6c swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 4528
17 swift-frontend 0x00000001035c15c4 swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)17>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 180
18 swift-frontend 0x000000010357d1b0 swift::IRGenRequest::OutputType swift::Evaluator::getResultUncached<swift::IRGenRequest, swift::IRGenRequest::OutputType swift::evaluateOrFatalswift::IRGenRequest(swift::Evaluator&, swift::IRGenRequest)::'lambda'()>(swift::IRGenRequest const&, swift::IRGenRequest::OutputType swift::evaluateOrFatalswift::IRGenRequest(swift::Evaluator&, swift::IRGenRequest)::'lambda'()) + 812
19 swift-frontend 0x0000000103576910 swift::performIRGeneration(swift::FileUnit*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_deleteswift::SILModule>, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::GlobalVariable**) + 176
20 swift-frontend 0x0000000102f61af0 generateIR(swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_deleteswift::SILModule>, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, llvm::GlobalVariable*&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator>>) + 156
21 swift-frontend 0x0000000102f5d07c performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_deleteswift::SILModule>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 2108
22 swift-frontend 0x0000000102f5c0a8 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1036
23 swift-frontend 0x0000000102f5f654 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1764
24 swift-frontend 0x0000000102f5dfd8 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3716
25 swift-frontend 0x0000000102ee20bc swift::mainEntry(int, char const**) + 5428
26 dyld 0x0000000188a86b98 start + 6076
Using Xcode 16.4 / Mac OS 16.4
Getting this error several times when presenting a modal window over my splitview window when running it on my Mac using Swift/Mac Catalyst in XCode 14.2. When I click the Cancel button in the window then I get Scene destruction request failed with error: (null) right after an unwind segue.
2023-07-04 16:50:45.488538-0500 Recipes[27836:1295134] [WindowHosting] UIScene property of UINSSceneViewController was accessed before it was set.
2023-07-04 16:50:45.488972-0500 Recipes[27836:1295134] [WindowHosting] UIScene property of UINSSceneViewController was accessed before it was set.
2023-07-04 16:50:45.496702-0500 Recipes[27836:1295134] [WindowHosting] UIScene property of UINSSceneViewController was accessed before it was set.
2023-07-04 16:50:45.496800-0500 Recipes[27836:1295134] [WindowHosting] UIScene property of UINSSceneViewController was accessed before it was set.
2023-07-04 16:50:45.994147-0500 Recipes[27836:1295134] Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x7f7fdf068a00>.
bleep
2023-07-04 16:51:00.655233-0500 Recipes[27836:1297298] Scene destruction request failed with error: (null)
I don't quite understand what all all this means. (The "bleep" was a debugging print code I put in the unwind segue). I'm working through Apple's Mac Catalyst tutorial but it seems to be riddled with bugs and coding issues, even in the final part of the completed app which I dowmloaded and ran. I don't see these problems on IPad simulator.
I don't know if it's because Catalyst has problems itself or there's something else going on that I can fix myself. Any insight into these errors would be very much appreciated!
PS: The app seems to run ok on Mac without crashing despite the muliple issues
Hey everyone,
I’m learning async/await and trying to fetch an image from a URL off the main thread to avoid overloading it, while updating the UI afterward. Before starting the fetch, I want to show a loading indicator (UI-related work). I’ve implemented this in two different ways using Task and Task.detached, and I have some doubts:
Is using Task { @MainActor the better approach?
I added @MainActor because, after await, the resumed execution might not return to the Task's original actor. Is this the right way to ensure UI updates are done safely?
Does calling fetchImage() on @MainActor force it to run entirely on the main thread?
I used an async data fetch function (not explicitly marked with any actor). If I were to use a completion handler instead, would the function run on the main thread?
Is using Task.detached overkill here?
I tried Task.detached to ensure the fetch runs on a non-main actor. However, it seems to involve unnecessary actor hopping since I still need to hop back to the main actor for UI updates. Is there any scenario where Task.detached would be a better fit?
class ViewController : UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
//MARK: First approch
Task{@MainActor in
showLoading()
let image = try? await fetchImage() //Will the image fetch happen on main thread?
updateImageView(image:image)
hideLoading()
}
//MARK: 2nd approch
Task{@MainActor in
showLoading()
let detachedTask = Task.detached{
try await self.fetchImage()
}
updateImageView(image:try? await detachedTask.value)
hideLoading()
}
}
func fetchImage() async throws -> UIImage {
let url = URL(string: "https://via.placeholder.com/600x400.png?text=Example+Image")!
//Async data function call
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
guard let image = UIImage(data: data) else {
throw URLError(.cannotDecodeContentData)
}
return image
}
func showLoading(){
//Show Loader handling
}
func hideLoading(){
//Hides the loader
}
func updateImageView(image:UIImage?){
//Image view updated
}
}
The speaker mentions there is "less risk of creating a retain cycle in when capturing self in a closure within a value type", such as a SwiftUI view struct.
Can you elaborate on when this could actually occur?
Thanks!
I am using Xcode 15 and working on a localised app. I use the new String Catalogs feature which works great for my app. In my app I created some local package like Apple has done it in the Backyard Birds example. However the translations I did in the package's String Catalog won’t be used in the app. What am I doing wrong?
I'm using Network Framework to transfer files between 2 devices. The "secondary" device sends file requests to the "primary" device, and the primary sends the files back.
When the primary gets the request, it responds like this:
do {
let data = try Data(contentsOf: filePath)
let priSecDataFilePacket = PriSecDataFilePacket(fileName: filename, dataBlob: data)
let jsonData = try JSONEncoder().encode(priSecDataFilePacket)
let message = NWProtocolFramer.Message(priSecMessageType: PriSecMessageType.priToSecDataFile)
let context = NWConnection.ContentContext(identifier: "TransferUtility", metadata: [message])
connection.send(content: encodedJsonToSend, contentContext: context, isComplete: true, completion: .idempotent)
} catch {
print("\(error)")
}
It works great, even for hundreds of file requests. The problem arises if some files being requested are extremely large, like 600MB. You can see the memory speedometer on the primary quickly ramp up to the yellow zone, at which point iOS kills the app for high memory use, and you see the Jetsam log.
I changed the code to skip JSON encoding the binary file as a test, and that helped a bit, but it still goes too high; the real offender is the step where it loads the 600MB file into the data var:
let data = try Data(contentsOf: filePath)
If I remark out everything else and just leave that one line, I can still see the memory use spike.
As a fix, I'm rewriting this so the secondary requests the file in 5MB chunks by telling the primary a byte range such as "0-5242880" or "5242881-10485760", and then reassembling the chunks on the secondary once they all come in. So far this seems promising, but it's a fair amount of work.
My question: Does Network Framework have a built-in way to stream those bytes straight from disk as it sends them? So that I could send all the data in one single request without having to load the bytes into memory?
I'm continuing with the migration towards Swift 6. Within one of our libraries, I want to check whether a parameter object: Any? confirms to Sendable.
I tried the most obvious one:
if let sendable = object as? Sendable {
}
But that results into the compiler error "Marker protocol 'Sendable' cannot be used in a conditional cast".
Is there an other way to do this?
I have a macro that converts expression into a string literal, e.g.:
#toString(variable) -> "variable"
#toString(TypeName) -> "TypeName"
#toString(\TypeName.property) -> "property"
In Xcode 16.3 #toString(TypeName) stopped to work, compilation throws 'Expected member name or initializer call after type name' error.
Everything works fine in Xcode 16.2. I tried to compare build settings between 16.2 and 16.3 but haven't noticed differences that may cause this new error.
The following works in both Xcode versions:
#toString(variable) -> "variable"
#toString(\TypeName.property) -> "property"
Seems like Xcode tries to compile code that shouldn't be compiled because of macro expansion.
Does anybody know what new has appeared in 16.3 and, perhaps, how to fix the problem?