Sending actions in the completion closure inside Effect.run

Hi guys, I came across the warning about avoid sending actions after Effect.run completed. Before I have used Effect.Future, and there was no issue at all. But right now, it keep showing this warning every time I try to use it inside completion. I couldnt' find any info on docs.

 private func startNFC() -> Effect<Action> {
    Effect.run { @MainActor [weak self] subscriber in
      guard let self = self else {
        subscriber(.none)
        return
      }
      
      self.interactor.performAction(action: .read, completion: { result in
        switch result {
        case .success(let response):
          guard let response = response else {
            subscriber(.none)
            return
          }
          subscriber(.NFCReadResult(NFC.dictionary(with: response)))
        case .failure:
          subscriber(.showNFCError)
        }
      })
    }
  }

This is the error I get every time I am trying to return Effect.run with completions.

Avoid sending actions using the 'send' argument from 'Effect.run' after the effect has completed. This can happen if you escape the 'send' argument in an unstructured context.

To fix this, make sure that your 'run' closure does not return until you're done calling 'send'.

Hi @hbayramov, the problem is that you are using the Effect.run that takes an async closure. The lifetime of that effect is tied to the lifetime of the async work. But you aren't actually performing any async work, so the effect completes immediately.

You either need to change performAction to be async instead of callback based (you can use withUnsafeContinuation to do that), or you need to go back to using Combine's Future:

return .publisher {
  Future { callback in 
    // Do callback-based work and feed data to 'callback'
  }
}
1 Like

Thanks for reply, I will try to use with Future.