Hi,I'm using a dispatch source as a timer, I noticed that when the object that contains it is deallocated I get a crash:libdispatch.dylib`_dispatch_xref_dispose:
0x100134ac8 <+0>: ldr w8, [x0, #48]
0x100134acc <+4>: cmp w8, #2This happens only if the dispatch source had been suspended, according to the documentation (https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/GCDWorkQueues/GCDWorkQueues.html)You can suspend and resume the delivery of dispatch source events temporarily using the dispatch_suspend and dispatch_resume methods. These methods increment and decrement the suspend count for your dispatch object. As a result, you must balance each call to dispatch_suspend with a matching call to dispatch_resume before event delivery resumesSo I'm wondering if it's not possible to dispatch_source_cancel a suspended dispatch source. Actually the crash is when dealloc ends, the dispatch_source_cancel seems to always work.Here's my code:@interface DispatchTimer(){
dispatch_source_t dispatchSource;
NSString *uniqueId;
}
@end
@implementation DispatchTimer
- (void)dealloc {
NSLog(@"DEALLOCATED DispatchTimer");
if(dispatch_source_testcancel(dispatchSource) == 0){
dispatch_source_cancel(dispatchSource);
}
}
- (instancetype)init{
self = [super init];
if (self) {
uniqueId = [[NSUUID UUID] UUIDString];
dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t)(1 * NSEC_PER_SEC);
dispatch_source_set_timer(dispatchSource, startTime, intervalTime, 0);
__weak DispatchTimer *weakSelf = self;
dispatch_source_set_event_handler(dispatchSource, ^{
[weakSelf update];
});
dispatch_resume(dispatchSource);
}
return self;
}
- (void)stop{
dispatch_suspend(dispatchSource);
}
- (void)update{
NSLog(@"Update %@", uniqueId);
}If method 'stop' is called when the DispatchTimer is deallocated I get the crash, if stop is not called everything seems to be fine.In the docs they mention dispatch_release but I get an error when using it in ARC.Thanks for any help.
Short one:on macOS - is DispatchSource built on top of kevent? I suspect yes, but I can not find a direct mention.thx!
Hello,Is there a high-precision timer API in MacOS like that Windows Multimedia Timers provide? I need execute my callback exactly every 1 ms, so I need an API allowing to fire events with this resolution. I can't find appropriate API for this. Ideally I want to use C++.As far as I know timers with such small intervals are platform-specific, so I suppose MacOS has it.There are a lot of answers on the web regarding accurate time measurements. But I need accurate timer.
Post not yet marked as solved
I have received this report through firebase analytics(Crashlytics) and I have no idea what it is. Would you help me?
The problem is only in iOS 14. (iOS 14.0.0, 14.2.0)
There is no such case in versions below iOS 14
crash_info_entry_0
BUG IN CLIENT OF LIBDISPATCH: Unbalanced call to dispatch_group_leave()
Stack trace
Crashed: Thread #1
EXCBREAKPOINT 0x000000019836f7f4
Crashed: Thread
0 libdispatch.dylib 0x19836f7f4 <redacted> + 36
1 libdispatch.dylib 0x19833d8c4 dispatchgroupleave + 126
2 ??? 0x754b330102689c00 (Missing)
3 Life4MePlus 0x102682b8c -[AISynchronizationOperation main] + 38 (AISynchronizationOperation.m:38)
4 Foundation 0x199a9c0f0 <redacted> + 864
5 ??? 0x0 (Missing)
6 ??? 0x221c4e81dfc97800 (Missing)
com.apple.main-thread
com.apple.main-thread
0 libsystemkernel.dylib 0x1c4643dd0 machmsgtrap + 8
1 libsystemkernel.dylib 0x1c4643184 machmsg + 76
2 ??? 0x4b112781986bac00 (Missing)
3 ??? 0x31204581986b4e00 (Missing)
4 ??? 0x0 (Missing)
5 ??? 0x0 (Missing)
6 ??? 0x0 (Missing)
7 ??? 0x0 (Missing)
8 ??? 0x0 (Missing)
9 libdyld.dylib 0x19837be60 <redacted> + 4
Thread #2
Thread
0 libsystemkernel.dylib 0x1c46685bc workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x5d3bd101dfc97800 (Missing)
Thread #3
Thread
0 libsystemkernel.dylib 0x1c46685bc _workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x0 (Missing)
Thread #4
Thread
0 libsystemkernel.dylib 0x1c46685bc _workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x3453b581dfc97800 (Missing)
com.apple.uikit.eventfetch-thread
com.apple.uikit.eventfetch-thread
0 libsystemkernel.dylib 0x1c4643dd0 machmsgtrap + 8
1 libsystemkernel.dylib 0x1c4643184 machmsg + 76
2 ??? 0x0 (Missing)
3 ??? 0x61681c01986b5000 (Missing)
4 ??? 0x0 (Missing)
5 ??? 0x0 (Missing)
6 ??? 0x0 (Missing)
7 ??? 0x4a214b819b109000 (Missing)
8 ??? 0x15469a8199a9c100 (Missing)
9 ??? 0x0 (Missing)
10 ??? 0x0 (Missing)
Thread #5
Thread
0 libsystemkernel.dylib 0x1c46685bc workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x0 (Missing)
Thread #6
Thread
0 libsystemkernel.dylib 0x1c46685bc _workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x0 (Missing)
Thread #7
Thread
0 libsystemkernel.dylib 0x1c46685bc _workqkernreturn + 8
1 libsystempthread.dylib 0x1dfc90954 pthreadwqthread + 352
2 ??? 0x0 (Missing)
com.twitter.crashlytics.ios.MachExceptionServer
com.twitter.crashlytics.ios.MachExceptionServer
0 Life4MePlus 0x10277e5dc CLSProcessRecordAllThreads + 376 (CLSProcess.c:376)
1 Life4MePlus 0x10277e5dc CLSProcessRecordAllThreads + 376 (CLSProcess.c:376)
2 Life4MePlus 0x10277ea50 CLSProcessRecordAllThreads + 407 (CLSProcess.c:407)
3 Life4MePlus 0x10276ee60 CLSHandler + 26 (CLSHandler.m:26)
4 Life4MePlus 0x10276a204 CLSMachExceptionServer + 446 (CLSMachException.c:446)
5 libsystempthread.dylib 0x1dfc8eca8 pthreadstart + 320
6 ??? 0x7c25b581dfc97800 (Missing)
AFRKNetworking
AFRKNetworking
0 libsystemkernel.dylib 0x1c4643dd0 machmsgtrap + 8
1 libsystemkernel.dylib 0x1c4643184 machmsg + 76
2 ??? 0x3713a981986bac00 (Missing)
3 ??? 0x0 (Missing)
4 ??? 0x684cc081986b4400 (Missing)
5 ??? 0x7237968199932000 (Missing)
6 ??? 0x6813c40199964800 (Missing)
7 ??? 0x452e2b010368f800 (Missing)
8 Foundation 0x199a9c0f0 <redacted> + 864
9 ??? 0x0 (Missing)
10 ??? 0x710e8a81dfc97800 (Missing)
Thread #8
Thread
0 libsystempthread.dylib 0x1dfc97774 <redacted> + 6
com.apple.NSURLConnectionLoader
com.apple.NSURLConnectionLoader
0 libsystemkernel.dylib 0x1c4643dd0 machmsgtrap + 8
1 libsystemkernel.dylib 0x1c4643184 mach_msg + 76
2 ??? 0x0 (Missing)
3 ??? 0x0 (Missing)
4 ??? 0x60677381986b4400 (Missing)
5 ??? 0x386bc00198f6d000 (Missing)
6 ??? 0x552580199a9c100 (Missing)
7 ??? 0x47378301dfc8ec00 (Missing)
8 ??? 0x0 (Missing)
Post not yet marked as solved
For some simulation work-loads I have, I would like to use the system to its full potential and therefore use both P and E cores. Splitting the work-load into individual tasks is not easily possible (the threads communicate with each other and run in semi-lockstep). I can allocate smaller portions of the domain to the E cores (and iteratively adjust this so they take the same amount of time as the P cores).
But in order for this to work well, I need to ensure that a given thread (with its associated workload) is bound to the right type of core: *either* the performance (doing larger chunks of the domain) or the efficiency (doing smaller chunks of the domain) cores.
What's the best way to do this? So far, I don't think thread-to-core affinity has been something that was choosable in macOS.
The documentation mentioned the QoS classes, but which class(es) (or relative priorities) would I pick?
c
pthread_set_qos_class_self_np(QOS_CLASS_UTILITY, 0);
The existing classifications don't really map well, the work is user-initiated (i.e. they launched a console application), but not a GUI program. Would I use 4 threads with QOS_CLASS_UTILITY and 4 with QOS_CLASS_BACKGROUND? Would I just use UTILITY with relative priority for performance vs. efficiency cores?
Post not yet marked as solved
I'm testing the new concurrency (actor, await, group, etc) and I'm having a weird (for me) problem.
I have a method that executes 9 concurrent process using withThrowingTaskGroup. Each process starts fetching data from coredata, each in their own context.
I start the execution tapping a button.
The problem is that sometimes the execution get paused, usually in a very similar place (in an await context.perform{}). The code inside the perform executes well, but it's like the await doesn't return control to the next line of code.
The curious thing is that if I tap the button again, the old paused process continues and finishes, while the second process runs its own execution.
Is there any way to track what is happening?
class a {
b().download ({ data in
})
}
class b{
func download (downloadedData: @escaping (_ data: Data? ) -> Void ) {
c().download()
}
}
class c {
func download () -> Data {
let semaphore = DispatchSemaphore(value: 0)
NetworkManager().downloadRequest: { (result: Result<Data, Error>) in
switch result {
case .success(let success)
......
case .failure(let error):
.....
}
semaphore.signal()
}
)
semaphore.wait()
return data
}
}
Class a initiates the download and class c interacts with network manager to download the data. Class c issues semaphore wait as soon as it sends request to download the data and issues signal when download completes. Is there a way to issue signal from class a when download is in progress. Basically class a should be able to skip wait by issuing signal command
I'm trying to understand a design pattern for accessing the isolated state held in an actor type from within a SwiftUI view.
Take this naive code:
actor Model: ObservableObject {
@Published var num: Int = 0
func updateNumber(_ newNum: Int) {
self.num = newNum
}
}
struct ContentView: View {
@StateObject var model = Model()
var body: some View {
Text("\(model.num)") // <-- Compiler error: Actor-isolated property 'num' can not be referenced from the main actor
Button("Update number") {
Task.detached() {
await model.updateNumber(1)
}
}
}
}
Understandably I get the compiler error Actor-isolated property 'num' can not be referenced from the main actor when I try and access the isolated value. Yet I can't understand how to display this data in a view. I wonder if I need a ViewModel that observes the actor, and updates itself on the main thread, but get compile time error Actor-isolated property '$num' can not be referenced from a non-isolated context.
class ViewModel: ObservableObject {
let model: Model
@Published var num: Int
let cancellable: AnyCancellable
init() {
let model = Model()
self.model = model
self.num = 0
self.cancellable = model.$num // <-- compile time error `Actor-isolated property '$num' can not be referenced from a non-isolated context`
.receive(on: DispatchQueue.main)
.sink { self.num = $0 }
}
}
Secondly, imagine if this code did compile, then I would get another error when clicking the button that the interface is not being updated on the main thread...again I'm not sure how to effect this from within the actor?
Post not yet marked as solved
How does one add Codable conformance to a class that needs to be isolated to the MainActor?
For example, the following code gives compiler errors:
@MainActor final class MyClass: Codable {
var value: Int
enum CodingKeys: String, CodingKey {
case value
}
init(from decoder: Decoder) throws { // <-- Compiler error: Initializer 'init(from:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Decodable'
let data = try decoder.container(keyedBy: CodingKeys.self)
self.value = try data.decode(Int.self, forKey: .value)
}
func encode(to encoder: Encoder) throws { // <-- Compiler error: Instance method 'encode(to:)' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Encodable'
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(value, forKey: .value)
}
}
I'm definitely struggling to get my head around actors and @MainActor at the moment!
Post not yet marked as solved
How can one conform an actor to the Sequence protocol? The following code generates the compiler warning: Instance method 'makeIterator()' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'Sequence'.
@MainActor class Test: Sequence {
private var contents: [Int] = []
func makeIterator() -> Array<Int>.Iterator {
contents.makeIterator()
}
}
Post not yet marked as solved
I'm trying to figure out the correct structure for a macOS document app using SwiftUI and Swift 5.5 concurrency features.
I want to demonstrate updating a document's data asynchronously, in a thread safe manner, with the ability to read / write the data to a file, also thread-safe and in the background. Yet I am struggling to:
write clean code - some of it looks inelegant at best, more like clunky, compared to my prior apps which used DispatchQueues etc
implement Codeable conformance for an actor
I'm seeking ideas, corrections and advice on how to improve on this. I've posted the full code over at GitHub, as I will only highlight some particular elements here. This is a minimum viable app, just for proof-of-concept purposes.
The app
The app displays a list of Records with a button to add more. It should be able to save and reload the list from a file.
Current approach / design
I've chosen the ReferenceFileDocument protocol for the Document type, as this is what I would use in a future app which has a more complex data structure. (i.e. I'm not planning on using a pure set of structs to hold a documents' data)
Document has a property content of type RecordsModelView representing the top-level data structure.
RecordsModelView is annotated with @MainActor to ensure any updates it receives will be processed on the main thread.
RecordsModelView has a property of type RecordsModel. This is an actor ensuring read/write of its array of Records are thread safe, but not coordinated via the MainActor for efficiency.
The app assumes that the func to add an item takes a long time, and hence runs it from with a Task. Although not demonstrated here, I am also making the assumption that addRecord maybe called from multiple background threads, so needs to be thread safe, hence the use of an actor.
The code compiles and runs allowing new items to be added to the list but...
Issues
Firstly, I can't annotate Document with @MainActor - generates compiler errors I cannot resolve. If I could I think it might solve some of my issues...
Secondly, I therefore have a clunky way for Document to initialise its content property (which also has to be optional to make it work). This looks nasty, and has the knock on effect of needing to unwrap it everywhere it is referenced:
final class Document: ReferenceFileDocument {
@Published var content: RecordsViewModel?
init() {
Task { await MainActor.run { self.content = RecordsViewModel() } }
}
// Other code here
}
Finally, I can't get the RecordsModel to conform to Encodable. I've tried making encode(to encoder: Encoder) async, but this does not resolve the issue. At present, therefore RecordsModel is just conformed to Decodable.
func encode(to encoder: Encoder) async throws { // <-- Actor-isolated instance method 'encode(to:)' cannot be used to satisfy a protocol requirement
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(records, forKey: .records)
}
Post not yet marked as solved
Given that type UUID is a struct I thought it would be Sendable. But the compiler generates a warning:
struct S: Sendable {
var int: Int
var id: UUID // <-- Stored property 'id' of 'Sendable'-conforming struct 'S' has non-sendable type 'UUID'
}
Post not yet marked as solved
I'm trying to use the new structured concurrency features of Swift 5.5 to update some code in a larger App that has been written using GCD. One routine is loading parts of a dataset in a parallel loop and I would like to convert this code using withThrowingTaskGroup while keeping a progress counter. The code compiles, runs, but does not update the progress in a way I expected:
var progressCounter = 0
let count = 500
try await withThrowingTaskGroup(of: Void.self) { group in
for idx in 0..<count {
_ = group.addTaskUnlessCancelled {
// some IO
}
}
for try await _ in group {
progressCounter += 1
}
}
The for try await loop is executed after all 500 task have been run and finished (iOS 15 Beta 5). I was under the impression, the for try await loop would be run in parallel to the tasks, collecting results as they come in and thereby updating the progress counter. Clearly I'm missing something or is this expected? Is withThrowingTaskGroup not the right tool for this?
Any insight would be appreciated.
I have encountered an issue when trying to update the status of a detached task, by passing a closure to MainActor.run.
To illustrate the issue consider a function that counts the number of files in a folder and its sub-directories. It runs in a Task.detached closure, as I don't want it blocking the main thread. Every 10,000th file it updates a Published property fileCount, by passing a closure to MainThread.run.
However, the UI is failing to update and even giving me a spinning beach ball. The only way to stop this is by inserting await Task.sleep(1_000_000_000) before the call to MainThread.run. Here's the code:
final class NewFileCounter: ObservableObject {
@Published var fileCount = 0
func findImagesInFolder(_ folderURL: URL) {
let fileManager = FileManager.default
Task.detached {
var foundFileCount = 0
let options = FileManager.DirectoryEnumerationOptions(arrayLiteral: [.skipsHiddenFiles, .skipsPackageDescendants])
if let enumerator = fileManager.enumerator(at: folderURL, includingPropertiesForKeys: [], options: options) {
while let _ = enumerator.nextObject() as? URL {
foundFileCount += 1
if foundFileCount % 10_000 == 0 {
let fileCount = foundFileCount
await Task.sleep(1_000_000_000) // <-- Only works with this in...comment out to see failure
await MainActor.run { self.fileCount = fileCount }
}
}
let fileCount = foundFileCount
await MainActor.run { self.fileCount = fileCount }
}
}
}
}
The code works if I revert to the old way of achieving this:
final class OldFileCounter: ObservableObject {
@Published var fileCount = 0
func findImagesInFolder(_ folderURL: URL) {
let fileManager = FileManager.default
DispatchQueue.global(qos: .userInitiated).async {
let options = FileManager.DirectoryEnumerationOptions(arrayLiteral: [.skipsHiddenFiles, .skipsPackageDescendants])
var foundFileCount = 0
if let enumerator = fileManager.enumerator(at: folderURL, includingPropertiesForKeys: [], options: options) {
while let _ = enumerator.nextObject() as? URL {
foundFileCount += 1
if foundFileCount % 10_000 == 0 {
let fileCount = foundFileCount
DispatchQueue.main.async { self.fileCount = fileCount }
}
}
let fileCount = foundFileCount
DispatchQueue.main.async { self.fileCount = fileCount }
}
}
}
}
What am I doing wrong?
BTW - if you want to try out this code, here is a test harness. Be sure to pick a folder with lots of files in it and its sub-folders.
import SwiftUI
@main
struct TestFileCounterApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var showPickerOld = false
@StateObject private var fileListerOld = OldFileCounter()
@State private var showPickerNew = false
@StateObject private var fileListerNew = NewFileCounter()
var body: some View {
VStack {
Button("Select folder to count files using DispatchQueue...") { showPickerOld = true }
Text("\(fileListerOld.fileCount)").foregroundColor(.green)
.fileImporter(isPresented: $showPickerOld, allowedContentTypes: [.folder], onCompletion: processOldSelectedURL )
Divider()
Button("Select folder to count files using Swift 5.5 concurrency...") { showPickerNew = true }
Text("\(fileListerNew.fileCount)").foregroundColor(.green)
.fileImporter(isPresented: $showPickerNew, allowedContentTypes: [.folder], onCompletion: processNewSelectedURL )
}
.frame(width: 400, height: 130)
}
private func processOldSelectedURL(_ result: Result<URL, Error>) {
switch result {
case .success(let url): fileListerOld.findImagesInFolder(url)
case .failure: return
}
}
private func processNewSelectedURL(_ result: Result<URL, Error>) {
switch result {
case .success(let url): fileListerNew.findImagesInFolder(url)
case .failure: return
}
}
}```
Post not yet marked as solved
I am a bit confused about tasks being cancelled.
Overview:
checkCancellation function has 2 child tasks: computeA and computeB that run concurrently,
computeB throws an error.
Doubt:
I expected child task computeA to be cancelled because computeB threw an error, but computeA was never cancelled.
Is my understanding wrong or am I missing something?
Or is this a bug?
Note:
I am using a SwiftUI project (as Swift Playgrounds don't support async let)
macOS Big Sur 11.5.2 (20G95)
Xcode Version 13.0 beta 5 (13A5212g)
Output:
A - started
B - going to throw
A - going to return, Task.isCancelled = false
error: infinity
Concurrent Function Definitions:
import Foundation
import UIKit
enum ComputationError: Error {
case infinity
}
fileprivate func computeA() async throws -> Int {
print("A - started")
await Task.sleep(2 * 100_000_000)
print("A - going to return, Task.isCancelled = \(Task.isCancelled)") //I expected Task.isCancelled to be true
return 25
}
fileprivate func computeB() async throws -> Int {
print("B - going to throw")
throw ComputationError.infinity
}
func checkCancellation() async throws {
async let a = computeA()
async let b = computeB()
let c = try await a + b
print("c = \(c)")
}
Invoking Concurrent function
struct ContentView: View {
var body: some View {
Button("check cancellation") {
Task {
do {
try await checkCancellation()
print("normal exit")
} catch {
print("error: \(error)")
}
}
}
}
}
Post not yet marked as solved
Application runs fine in simulator but when running on an iPad I get the following error, first time I attempted to run on actual device. I have
Xcode 13 beta (Aug 10).
iOS 15.0 beta 7
Any ideas on how to work past this.
Referenced from: /private/var/containers/Bundle/Application/99D0B06B-2339-43C0-8D78-3C62D1E0C2AB/rtmpCameraWolf.app/rtmpCameraWolf
Expected in: /usr/lib/swift/libswift_Concurrency.dylib
Symbol not found: _$ss4TaskV8PriorityOMn
Referenced from: /private/var/containers/Bundle/Application/99D0B06B-2339-43C0-8D78-3C62D1E0C2AB/rtmpCameraWolf.app/rtmpCameraWolf
Expected in: /usr/lib/swift/libswift_Concurrency.dylib
(lldb)
dyld`__abort_with_payload:
0x1015569ac <+0>: mov x16, #0x209
0x1015569b0 <+4>: svc #0x80
-> 0x1015569b4 <+8>: b.lo 0x1015569d0 ; <+36>
0x1015569b8 <+12>: stp x29, x30, [sp, #-0x10]!
0x1015569bc <+16>: mov x29, sp
0x1015569c0 <+20>: bl 0x10151d568 ; cerror_nocancel
0x1015569c4 <+24>: mov sp, x29
0x1015569c8 <+28>: ldp x29, x30, [sp], #0x10
0x1015569cc <+32>: ret
0x1015569d0 <+36>: ret
Post not yet marked as solved
I have been getting a weird crash whenever I run my app and use my request utilities.
Here is the code:
Firstly, I have a button that submits the data when clicked
Button(action: { Task { await viewModel.submitData() } } ) {
Text("Log In")
}
This is the submitData function
func submitData() async -> Void {
state = .loading
do {
let result = try await AuthenticationAPI.login(user: user)
self.state = .success
self.authenticator.authenticate(token: result.value.token)
} catch let error as APIError {
self.handleAPIError(error)
} catch {
// TODO: Log Error
self.handleAPIError(.unexpectedError)
}
}
This is the AuthenticationAPI.login function
static func login(user: LoginUser) async throws -> APIService.Response<AuthenticatedUser> {
let endpoint = Endpoint.login
let data = try? encode(user.toDictionary())
return try await apiService.post(type: AuthenticatedUser.self,
url: endpoint.url, body: data)
}
Lastly this is the network call
func executeRequest<T: Decodable>(_ request: URLRequest) async throws -> Response<T> {
guard let (data, response) = try? await URLSession.shared.data(for: request) else {
throw APIError.networkError
}
if let response = response as? HTTPURLResponse {
if (200...299).contains(response.statusCode) {
guard let data = try? decoder.decode(T.self, from: data) else {
throw APIError.decodingError
}
return Response(value: data, response: response)
} else if (400...499).contains(response.statusCode) {
throw APIError.httpError(data, response)
} else if response.statusCode == 500 {
throw APIError.serverError
}
}
throw APIError.unexpectedError
}
func post<T: Decodable>(
type: T.Type,
url: URL,
headers: Headers = [:],
body: Data?
) async throws -> Response<T> {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = body
constructHeaders(request: &request, headers: headers)
return try await executeRequest(request) // This is where the compiler tells me the error occurs
}
The executeRequest function is never called because it never makes the request (I checked my local server).
These are the thread logs:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x00007fff30bb03f4 in swift::TargetMetadata<swift::InProcess>::isCanonicalStaticallySpecializedGenericMetadata() const ()
#1 0x00007fff30bbc7b1 in swift_checkMetadataState ()
#2 0x00007fff30b713d5 in type metadata completion function for ClosedRange<>.Index ()
#3 0x00007fff30bbf75d in swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization(swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) ()
#4 0x00007fff30bb1941 in _swift_getGenericMetadata(swift::MetadataRequest, void const* const*, swift::TargetTypeContextDescriptor<swift::InProcess> const*) ()
#5 0x00007fff30b8b440 in __swift_instantiateCanonicalPrespecializedGenericMetadata ()
#6 0x00000001017f9e00 in APIService.post<τ_0_0>(type:url:headers:body:) at /Users/jayaikendu/Documents/projects/Xcode - Swift/squizelstudents/Shared/Services/APIService.swift:124
#7 0x00000001017a0dd0 in static AuthenticationAPI.login(user:) at /Users/jayaikendu/Documents/projects/Xcode - Swift/squizelstudents/Shared/Networking/Authentication/AuthenticationAPI.swift:21
#8 0x000000010170b3c0 in LoginViewModel.submitData() at /Users/jayaikendu/Documents/projects/Xcode - Swift/squizelstudents/Shared/App/Login/ViewModels/LoginViewModel.swift:42
#9 0x00000001016317d0 in closure #1 in closure #1 in closure #2 in closure #1 in closure #1 in LoginView.body.getter at /Users/jayaikendu/Documents/projects/Xcode - Swift/squizelstudents/Shared/App/Login/Views/LoginView.swift:26
#10 0x0000000101637960 in partial apply for closure #1 in closure #1 in closure #2 in closure #1 in closure #1 in LoginView.body.getter ()
#11 0x0000000101631ae0 in thunk for @escaping @callee_guaranteed @Sendable @async () -> () ()
#12 0x0000000101637ac0 in partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> () ()
#13 0x00000001016353f0 in thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out τ_0_0) ()
#14 0x0000000101637d70 in partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out τ_0_0) ()
This is on XCode Beta 13.5
I should mention that I am using the Thread Sanitizer too. This error only appears with the Thread Sanitizer turned on.
Post not yet marked as solved
I have declared an NSMutableArray and the count should not exceed 100. If some one calls addObject method to add an item to that array when the count is 100 then that method call should not be executed until someone removes an item so that count will go down below 100. Can we use semaphore or group dispatch for signaling or mutex/NSLock is recommended.
Post not yet marked as solved
How to make one task(insert) wait for another to task(remove) in Objective C?
Post not yet marked as solved
Hello, I'm trying to perform simple async tasks wrapped in a Task struct but the compiler always says "error: cannot find 'Task' in scope" using XCode 13 with macOS 12's last beta
Even the simplier playground like this one, fails:
import Foundation
func foo() async -> String {
await withUnsafeContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
continuation.resume(returning: "Hello")
}
}
}
func bar() {
Task {
let text = await foo()
print(text)
}
}
Results in:
error: MyPlayground.playground:13:5: error: cannot find 'Task' in scope
Task {
^~~~
So... is this normal or am I missing something basic (and stupid)?
Thanks