I'm seeing a strange and random crash with my combine networking after updating Xcode to version 14.3 (14E222b) a few days ago. The code below is crashing with EXC_BAD_ACCESS on .store(in:)
and wasn't on the previous version of Xcode.
private var cancellables = Set<AnyCancellable>()
func request() async {
URLSession.shared
.dataTaskPublisher(for: URL(string: "")!)
.map{$0.data}
.decode(type: Type.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {
print ("Received completion: \($0).")
}, receiveValue: { data in
print(data)
})
.store(in: &cancellables) // <- CRASHING HERE
}
Making request async
is the issue. This version works without issue in playgrounds:
import UIKit
import Combine
struct User: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
struct Download {
private var cancellables = Set<AnyCancellable>()
mutating func request() {
URLSession.shared
.dataTaskPublisher(for: URL(string: "https://jsonplaceholder.typicode.com/todos/1")!)
.map{$0.data}
.decode(type: User.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {
print ("Received completion: \($0).")
}, receiveValue: { data in
print(data)
})
.store(in: &cancellables)
}
}
var download = Download()
download.request()
or making request async
as follows in playgrounds:
import UIKit
import Combine
struct User: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
struct Download {
private var cancellables = Set<AnyCancellable>()
mutating func request() async -> User {
return await withCheckedContinuation { continuation in
URLSession.shared
.dataTaskPublisher(for: URL(string: "https://jsonplaceholder.typicode.com/todos/1")!)
.map{$0.data}
.decode(type: User.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {
print ("Received completion: \($0).")
}, receiveValue: { data in
continuation.resume(returning: data)
})
.store(in: &cancellables)
}
}
}
Task {
var download = Download()
let user = await download.request()
print(user)
}