Swift concurrency seems to be random when using MainActor?

I’ve been trying to figure out a way to call corelocation’s requestLocation on the main thread (which apparently is required).

Consider this MRE

import CoreLocation
import MapKit
import SwiftUI

struct ContentView: View {
    var locationManager = LocationManager()

    var body: some View {
        Button {
            Task {
                let location = try await locationManager.currentLocation // works
                print(location)
                let location2 = try await locationManager.work() // works, no mainactor needed
                print(location2)
                 let location3 = try await APIService.shared.test() // doesnt work
                print(location3)
                let location4 = try await APIService.shared.test2() // works, mainactor needed
                print(location4)
                let location5 = try await APIService.shared.test3() // doesnt work even with mainactor
                print(location5)
            }
        } label: {
            Text("Get Location")
        }.task {
            // 1. Check if the app is authorized to access the location services of the device
            locationManager.checkAuthorization()
        }
    }
}

class LocationManager: NSObject, CLLocationManagerDelegate {
    // MARK: Object to Access Location Services

    private let locationManager = CLLocationManager()

    // MARK: Set up the Location Manager Delegate

    override init() {
        super.init()
        locationManager.delegate = self
    }

    // MARK: Request Authorization to access the User Location

    func checkAuthorization() {
        switch locationManager.authorizationStatus {
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        default:
            return
        }
    }

    // MARK: Continuation Object for the User Location

    private var continuation: CheckedContinuation<CLLocation, Error>?

    // MARK: Async Request the Current Location

    var currentLocation: CLLocation {
        get async throws {
            return try await withCheckedThrowingContinuation { continuation in
                // 1. Set up the continuation object
                self.continuation = continuation
                // 2. Triggers the update of the current location
                locationManager.requestLocation()
            }
        }
    }

    @MainActor
    var currentLocation2: CLLocation {
        get async throws {
            return try await withCheckedThrowingContinuation { continuation in
                // 1. Set up the continuation object
                self.continuation = continuation
                // 2. Triggers the update of the current location
                locationManager.requestLocation()
            }
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // 4. If there is a location available
        if let lastLocation = locations.last {
            // 5. Resumes the continuation object with the user location as result
            continuation?.resume(returning: lastLocation)
            // Resets the continuation object
            continuation = nil
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        // 6. If not possible to retrieve a location, resumes with an error
        continuation?.resume(throwing: error)
        // Resets the continuation object
        continuation = nil
    }

    func work() async throws -> CLLocation {
        return try await currentLocation
    }
}

class APIService {
    static let shared = APIService()

    // Private initializer to prevent the creation of additional instances
    private init() {
    }

    func test() async throws -> String {
        return try await String(describing: LocationManager().currentLocation)
    }

    @MainActor
    func test2() async throws -> String {
        return try await String(describing: LocationManager().currentLocation)
    }

    func test3() async throws -> String {
        return try await String(describing: LocationManager().currentLocation2)
    }
}

Test1 works as expected because Task from the view is inherited as mainactor

Test2 works for the same reason I assume

Test3 doesnt work not sure why when test2 worked? I guess if it goes to another class, you lose the actor?

Test4 works as expected because you force it to be mainactor

Test5 doesnt work mysteriously even though you force it to be mainactor again
So what is the rule for main thread in swift concurrency?

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật