openai-kit
openai-kit copied to clipboard
There's no way to use a background session to make Chat requests
Using a background session prevents Chat requests from failing if the app goes to background. The extension on URLSession uses dataTask with completionHandler, creating an exception:
func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
dataTask(with: request, completionHandler: completionHandler) as URLSessionDataTask
}
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
One way to fix this issue is to save an array of continuations, use downloadTask and expose a way to send the URLSession configuration so we can set a delegate an control downloads:
extension OpenAIService: URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
guard let data = try? Data(contentsOf: location) else {
continuations[downloadTask]?.resume(throwing: OpenAIServiceError.errorRequestingPrompt)
return
}
continuations[downloadTask]?.resume(returning: data)
continuations[downloadTask] = nil
}
}
private lazy var backgrounUrlSession: URLSession = {
let config = URLSessionConfiguration.background(withIdentifier: "com.mumme.fanart.openai")
config.sessionSendsLaunchEvents = true
config.shouldUseExtendedBackgroundIdleMode = true
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
var continuations = [URLSessionTask: CheckedContinuation<Data, Error>]()
func task(for request: URLRequest) async throws -> Data {
try await withCheckedThrowingContinuation { continuation in
let downloadTask = backgroundSession.downloadTask(with: request)
continuations[downloadTask] = continuation
downloadTask.resume()
}
}