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
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am a Chinese student beginner ,do you have any advice for me to learn swift?I don't know how to start it.Please!🙏
Topic:
Programming Languages
SubTopic:
Swift
As a fun project, I'm wanting to model an electronic circuit.
Components inherit from a superclass (ElectronicComponent). Each subclass (e.g. Resistor) has certain methods to return properties (e.g. resistance), but may vary by the number of outlets (leads) they have, and what they are named.
Each outlet connects to a Junction.
In my code to assemble a circuit, while I'm able to manually hook up the outlets to the junctions, I'd like to be able to use code similar to the following…
class Lead: Hashable // implementation omitted
{
let id = UUID()
unowned let component: ElectronicComponent
weak var connection: Junction?
init(component: ElectronicComponent, to connection: Junction? = nil)
{
self.component = component
self.connection = connection
}
}
@dynamicMemberLookup
class ElectronicComponent
{
let id = UUID()
var connections: Set<Lead> = []
let label: String?
init(label: String)
{
self.label = label
}
subscript<T>(dynamicMember keyPath: KeyPath<ElectronicComponent, T>) -> T
{
self[keyPath: keyPath]
}
func connect(lead: KeyPath<ElectronicComponent, Lead>, to junction: Junction)
{
let lead = self[keyPath: lead]
lead.connection = junction
connections.insert(lead)
}
}
class Resistor: ElectronicComponent
{
var input, output: Lead?
let resistance: Measurement<UnitElectricResistance>
init(_ label: String, resistance: Measurement<UnitElectricResistance>)
{
self.resistance = resistance
super.init(label: label)
}
}
let resistorA = Resistor("R1", resistance: .init(value: 100, unit: .ohms))
let junctionA = Junction(name: "A")
resistorA.connect(lead: \.outlet2, to: junctionA)
While I'm able to do this by implementing @dynamicMemberLookup in each subclass, I'd like to be able to do this in the superclass to save repeating the code.
subscript<T>(dynamicMember keyPath: KeyPath<ElectronicComponent, T>) -> T
{
self[keyPath: keyPath]
}
Unfortunately, the compiler is not allowing me to do this as the superclass doesn't know about the subclass properties, and at the call site, the subclass isn't seen as ElectronicComponent.
I've been doing trial and error with protocol conformance and other things, but hitting walls each time.
One possibility is replacing the set of outlets with a dictionary, and using Strings instead of key paths, but would prefer not to.
Another thing I haven't tried is creating and adopting a protocol with the method implemented in there. Another considered approach is using macros in the subclasses, but I'd like to see if there is a possibility of achieving the goal using my current approach, for learning as much as anything.
Is there a swift6 manual that will teach me how to code in swift?
Hi there, this is my first time posting here. I've heard that some of the apple developers are usually active on these forums, so I've decided to shoot my shot, because this question was driving me crazy for a few days now and nobody could yet give me a clear view on what's actually happening.
Here is the first snippet of the code
class Animal {
var name = "Fischer"
var command: () -> Void = { }
deinit {
print(#function, #line)
}
}
do {
var pet: Animal? = Animal()
pet?.command = { print(pet?.name ?? "Bobby") }
}
This code causes a memory leak, because
Reference 'pet' is created.
Independent copy of the reference 'pet' is created inside the closure. now there are two references to the same object, which are 'pet' outside the closure and 'pet' inside the closure.
As we exit the 'do' scope, the 'pet' reference is deleted, but ARC does not deallocate the object due to the strong reference 'pet', that is still referencing to the same object.
And all of that causes a memory leak.
Now here is the code, that is pretty similar, except for the fact, that we assign a nil to the 'pet' reference
class Animal {
var name = "Fischer"
var command: () -> Void = { }
deinit {
print(#function, #line)
}
}
do {
var pet: Animal? = Animal()
pet?.command = { print(pet?.name ?? "Bobby") }
pet = nil
}
And boom! deinit is called, meaning that the object was deallocated, but how? Why was the object deallocated? If we are deleting the exact same reference, that was deleted by the end of the 'do' scope in the first snippet? Am I misunderstanding something? I really hope this post will find the right people, since I could not even find appropriate tags for that.
Topic:
Programming Languages
SubTopic:
Swift
I am porting an old app from ObjC. The app uses many defined constants such as:
#define COM_OFFSET 12.5
and many variables that are read and/or written throughout the App, such as:
PCDate* Dates[367];
@class PCMainView;
PCMainView* MainView;
in one file called "PCCommon.h"
How do I duplicate this function in Swift? I have looked around and have found no help.
Thanks in advance.
I am currently encountering two deprecated errors in my code. Could someone please identify the issues with the code?
Errors:
'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:annotationItems:annotationContent:)' was deprecated in iOS 17.0: Use Map initializers that take a MapContentBuilder instead.
'MapAnnotation' was deprecated in iOS 17.0: Use Annotation along with Map initializers that take a MapContentBuilder instead.
Code:
// MARK: - Stores Map (Dynamic)
struct StoresMapView: View {
@State private var storeLocations: [StoreLocation] = []
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: -31.95, longitude: 115.86),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)
var body: some View {
Map(coordinateRegion: $region, interactionModes: .all, annotationItems: storeLocations) { store in
MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: store.latitude, longitude: store.longitude)) {
VStack(spacing: 4) {
Image(systemName: "leaf.circle.fill")
.font(.title)
.foregroundColor(.green)
Text(store.name)
.font(.caption)
.fixedSize()
}
}
}
.onAppear(perform: loadStoreData)
.navigationTitle("Store Locator")
}
private func loadStoreData() {
guard let url = URL(string: "https://example.com/cop092/StoreLocations.json") else { return }
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data, let decoded = try? JSONDecoder().decode([StoreLocation].self, from: data) {
DispatchQueue.main.async {
self.storeLocations = decoded
if let first = decoded.first {
self.region.center = CLLocationCoordinate2D(latitude: first.latitude, longitude: first.longitude)
}
}
}
}.resume()
}
}
I have a Settings class that conform to the TestProtocol. From the function of the protocol I need to call the setString function and this function needs to be on the MainActor. Is there a way of make this work in Swift6, without making the protocol functions running on @MainActor
The calls are as follows:
class Settings: TestProtocol{
var value:String = ""
@MainActor func setString( _ string:String ){
value = string
}
func passString(string: String) {
Task{
await setString(string)
}
}
}
protocol TestProtocol{
func passString( string:String )
}
Here is my code:
`
// A 3rd-party class I must use.
class MySession{
init() async throws {
// ..
}
}
actor SessionManager{
private var mySession: MySession? // The MySession is not Sendable
func createSession() async {
do {
mySession = try await MySession()
log("getOrCreateSession() End, success.")
} catch {
log("getOrCreateSession() End, failure.")
}
}
}`
I get this warning: "Non-sendable type 'MySession' returned by implicitly asynchronous call to a nonisolated function cannot cross the actor boundary."
How can this be fixed?
i am trying to build my code and have ran into this error.
"Trailing closure passed to parameter of type 'DispatchWorkItem' that does not accept a closure"
i have been trying to figure it out for so long, and even ai cant figure it out. is this a bug, or am i missing some obvious way to fix this ?
func loadUser(uid: String, completion: (() -> Void)? = nil) {
db.collection("users").document(uid).getDocument { [weak self] snapshot, error in
guard let data = snapshot?.data(), error == nil else { completion?(); return }
DispatchQueue.main.async {
self?.currentUser = User(
username: data["username"] as? String ?? "Learner",
email: data["email"] as? String ?? "",
profileImageName: "person.circle.fill",
totalXP: data["totalXP"] as? Int ?? 0,
currentStreak: data["currentStreak"] as? Int ?? 0,
longestStreak: data["longestStreak"] as? Int ?? 0,
level: data["level"] as? Int ?? 1,
levelProgress: data["levelProgress"] as? Double ?? 0.0,
xpToNextLevel: data["xpToNextLevel"] as? Int ?? 100,
completedLessons: data["completedLessons"] as? [String] ?? []
)
self?.saveUser()
completion?()
}
}
}
Last night my iPhone game crashed while running in debug mode on my iPhone. I just plugged it into my Mac, and was able to find the ips file. The stack trace shows the function in my app where it crashed, and then a couple of frames in libswiftCore.dylib before an assertion failure.
My question is - I've got absolutely no idea what the assertion failure actually was, all I have is...
0 libswiftCore.dylib 0x1921412a0 closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 228
1 libswiftCore.dylib 0x192141178 closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 327
2 libswiftCore.dylib 0x192140b4c _assertionFailure(_:_:file:line:flags:) + 183
3 MyGame.debug.dylib 0x104e52818 SentryBrain.takeTurn(actor:) + 1240
...
How do I figure out what the assertion failure was that triggered the crash? How do I figure out what line of code in takeTurn(...) triggered the failing assertion failure?
I've been searching all over the web trying to find the proper way to get all records created by a specific user in CloudKit.
I am able to get the correct id using:
guard let userRecordID = try? await container.userRecordID() else { return }
I can see that the id returned is associated with records in my CloudKit dashboard. So I would expect that the following would get those records:
let predicate = NSPredicate(format: "%K == %@", #keyPath(CKRecord.creatorUserRecordID), userRecordID)
let query = CKQuery(recordType: "CKUser", predicate: predicate)
But instead when I use that query it returns nothing. It is successful but with nothing returned...
Any ideas why this would be happening?
P.S. I have also tried constructing the predicate using the reference, but I get the same result - success with no results.
P.S.2 Also worth mentioning that I am trying to get the results from the public database and I have set my CKContainer to the correct container id.
With Swift being brought to new places, is anyone working on interoperability with PHP? I'd love to replace much of my PHP and Javascript web code with Swift (and ideally SwiftUI for UI design). Are there any projects/people working in this space?
Hey everyone,
I have a problem with an app im creating. The code doesn't have any errors but the console has this that pops up:
Snapshot request 0x1054191d0 complete with error: <NSError: 0x10541a970; domain: FBSSceneSnapshotErrorDomain; code: 4; "an unrelated condition or state was not satisfied"> {
NSLocalizedDescription = an error occurred during a scene snapshotting operation;
}
I'm developing an audio unit for use on iOS. The AUv3 worked fine with xcode 15.X and swift 5.X. I recently tried to submit an update to my plug-in but Apple refused submission because my Xcode was not the latest. Now that I'm on Xcode 16.4 I can't get my project to compile, even when following all of the same previous steps.
As one example of a change, Xcode doesn't appear to include the “C++ and Objective-C interoperability” build setting that it used to. This setting is noted in the Swift documentation and I used to need it, https://www.swift.org/documentation/cxx-interop/project-build-setup/#mixing-swift-and-c-using-xcode
Currently my C++ code can't see anything from Swift, and I get a "Use of undeclared identifier 'project_name'". I've selected Switch support for version 5.0 in an attempt to minimize changes from Apple.
My process is I generate an Xcode project file from my audio plugin support, JUCE. Then I add in the swift files, click yes to create bridging headers, but c++ doesn't see swift anymore. I'd greatly appreciate any suggestions.
Topic:
Programming Languages
SubTopic:
Swift
Hey team I'm facing an issue where startDate is 1 January 2025 and endDate is 31 March 2025 between this 2 dates is 90 days, but on my code is being taken as 89 days
I've seen the math of the code excludes the first partial day (from midnight to 06:00) on 2025-01-01, which results in 89 full days instead of 90 days.
startDate: 2025-01-01 06:00:00 +0000
endDate: 2025-03-31 06:00:00 +0000
this is my function
func daysBetweenDates() -> Int? {
guard let selectedStartDate = selectedStartDate?.date else { return nil }
guard let selectedEndDate = selectedEndDate?.date else { return 0 }
let calendar = Calendar.current
let dateComponents = calendar.dateComponents([.day], from: selectedStartDate, to: selectedEndDate)
return dateComponents.day
}
what I've tried is reset the hours to 0 so it can take the full day and return 90 days
like this
func daysBetweenDates() -> Int? {
guard let selectedStartDate = selectedStartDate?.date else { return nil }
guard let selectedEndDate = selectedEndDate?.date else { return 0 }
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0) ?? .current
let cleanMidNightStartDate = calendar.startOfDay(for: selectedStartDate)
let cleanMidNightEndDate = calendar.startOfDay(for: selectedEndDate.addingTimeInterval(24 * 60 * 60))
let dateComponents = calendar.dateComponents([.day], from: cleanMidNightStartDate, to: cleanMidNightEndDate)
let daysCount = dateComponents.day ?? 0
return daysCount
}
this worked for that date specifically but when I tried to change the date for example
startDate: 18 December 2024.
endDate: 18 March 2025.
between those dates we have 90 days but this function now reads 91.
what I'm looking is a cleaver solution for this problem so I can have the best posible quality code, thanks in advance!
Topic:
Programming Languages
SubTopic:
Swift
I have my project running perfectly fine on Xcode 16. However, in Xcode 26 it doesn't build due to an error that I do not understand. I have three files that pertain to this error:
// FriendListResponse.swift
import Foundation
struct FriendListResponse: Decodable {
var friendships: [Friendship]
var collections: [FriendCollection]
}
// Friendship.swift
import Foundation
struct Friendship: Decodable {
var createdAt: String
var friendId: Int
var friendUserId: Int // user ID of the friend
var friendUsername: String
var id: Int
var tagNames: [String]
}
// FriendCollection.swift
struct FriendCollection: Decodable {
var id: Int
var permalink: String
var tagNames: [String]
var title: String
}
On the first file, FriendListResponse.swift, I am the simple error message "circular reference." I do not understand how these self-contained structs could create a circular reference. Although I have other data types in my project, none of them are even referenced in these files except for Friendship and FriendCollection.
The FriendListResponse is a struct that is created from JSON values that are fetched from an API. This is the function that fetches the JSON:
public static func listFriends(username: String) async throws -> [Friendship] {
let data = try await sendGETRequest(
url: "people/\(username)/friends/list.json"
)
print(String(data: data, encoding: .utf8)!)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let wrapper = try decoder.decode(FriendListResponse.self, from: data)
return wrapper.friendships
}
// Note: the function sendGETRequest is just
// a function that I have created that takes a set
// of parameters and returns a data object
// using the HTTP GET protocol. I don't think
// that it is related to this issue. However, if you
// think that it is, I can share the code for that.
This error has also happened in a few other cases within contained networks of my data structure.
I do not know why this error is only appearing once I launch Xcode 26 beta with my project files. I would think that this error also would appear in Xcode 16.4.
Any help would be greatly appreciated in my process to compile my project on Xcode 26!
I noticed that when I enter the fully immersive view and then click the X button below the window, the immersive space remains active, and the only way to dismiss it is to click the digital crown. On other apps (Disney+ for example), closing out of the main window while in immersive mode also closes out the immersive space. I tried applying an onDisappear modifier to the the Modules view with a dismissImmersiveSpace, but that doesn't appear to do anything.
Any help would be appreciated.
Greetings,
func stepForward(_ input: Int) -> Int {
return input + 1
}
func stepBackward(_ input: Int) -> Int {
return input - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
return backward ? stepBackward : stepForward /* Error
type of expression is ambiguous without a type annotation */
}
Why am I getting this error. If I change the function to
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
if backward {
return stepBackward
else {
return stepForward
}
}
Why is the previous chooseStepFunction giving me an error ?
Thx in advance
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