Home / IOS Development / javascript – ‘Cannot set headers after they are sent to the client’ NodeJS error when sending the iOS Swift app to the background

javascript – ‘Cannot set headers after they are sent to the client’ NodeJS error when sending the iOS Swift app to the background



I have an app with Swift / SwiftUI. I use ObservableObject and JSONDecoder to get values ​​from the Node.JS Express API to be displayed in my app:

struct DevicesList: Decodable {
    var data: [PhilipsHueDevicesListEntry]
}

struct DevicesListEntry: Decodable {
    var ID: String
    var Name: String
    var State: Bool
    var Reachable: Bool
}

Class that gets the values ​​from the API and enters in the object above:

class GetDevices: ObservableObject {

var didChange = PassthroughSubject()

var DevicesList = DevicesList(data: []){
    didSet {
        didChange.send(self)
    }
}

init(){
    let keychain = KeychainSwift()
    let authToken = keychain.get("authToken")!
    let bridgeID = keychain.get("hubID")!
    var request = URLRequest(url: URL(string: GlobalVariables.HUEGetDevices)!)
    request.httpMethod = HTTPMethod.get.rawValue
    let headers = [
        "auth-token": authToken,
        "bridgeID": bridgeID,
        "Content-Type": "application/json"]
    request.allHTTPHeaderFields = headers
    URLSession.shared.dataTask(with: request) { (data, _, _) in
        guard let data = data else {return}
        let devices = try! JSONDecoder().decode(DevicesList.self, from: data)
        DispatchQueue.main.async {
            self.DevicesList = devices
        }
    }.resume()
}

So to show on the main screen of my app:

@State var devices = GetDevices()

ForEach(devices.DevicesList.data, id: .ID) { device in
                        ZStack{
                            Rectangle()
                                .cornerRadius(5)
                                .frame(width: 1
00, height: 100) .foregroundColor(Color.orange) VStack(alignment: .leading){ Text(device.Name) .multilineTextAlignment(.center) .frame(width: 100, height: 100) } } ....

Everything works just fine, until I swipe up to send the app to the background (which I assume is running init() function again to update the observable object). I get this error:

_http_outgoing.js:503
throw new errors.Error('ERR_HTTP_HEADERS_SENT', 'set');
^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at validateHeader (_http_outgoing.js:503:11)
    at ServerResponse.setHeader (_http_outgoing.js:510:3)
    at ServerResponse.header (/app-c/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/app-c/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/app-c/node_modules/express/lib/response.js:267:15)
    at ServerResponse.send (/app-c/node_modules/express/lib/response.js:158:21)
    at lightDataCallbackFunction (/app-c/app.js:185:32). // <----- This is where the error occurs in my js file
    at Socket.socket.on (/app-c/app.js:121:7)
    at Socket.emit (events.js:180:13)
    at /app-c/node_modules/socket.io/lib/socket.js:528:12
    at process._tickCallback (internal/process/next_tick.js:176:11) 

My JS file as the error occurs:

lightDataCallbackFunction = function(data){
    if(data['socketID'] == socketID){
      if(data['code'] == '208'){
        return res.status(200).send(data) // <--- OCCURS HERE
      }else{
        return res.status(400).send({"data": "", "code": "209", "message": data['message']})
      }
    }
  }

I really have no idea why this is the case and what is happening. My best guess would be that when I send the app to the background, the observable object instance is run again, and somehow the same code on the server side tries to send a different (same) response to my app? I even return the answer to end the function, so I can not see why this happens?

EDIT:

I have tried the MwcsMac comment from below, he mentioned that he usually just does not use init() function at all, instead he moves the code that should go inside init() function and puts it in a new function, and then calls that function when the current section is loaded via .onAppear().

I've tried it, but it either does not run the feature at all for some reason - or it just does not update my view (fills ForEach loop in my SwiftUI code.


Source link