83 lines
2.3 KiB
Swift
83 lines
2.3 KiB
Swift
|
//
|
||
|
// GeminiDataTask.swift
|
||
|
// GeminiProtocol
|
||
|
//
|
||
|
// Created by Shadowfacts on 7/14/20.
|
||
|
//
|
||
|
|
||
|
import Foundation
|
||
|
import Network
|
||
|
|
||
|
public class GeminiDataTask {
|
||
|
public let request: GeminiRequest
|
||
|
private let completion: (Result<GeminiResponse, Error>) -> Void
|
||
|
|
||
|
private let connection: GeminiConnection
|
||
|
|
||
|
public private(set) var completed: Bool = false
|
||
|
|
||
|
public init(request: GeminiRequest, completion: @escaping (Result<GeminiResponse, Error>) -> Void) {
|
||
|
self.request = request
|
||
|
self.completion = completion
|
||
|
self.connection = GeminiConnection(endpoint: .url(request.url))
|
||
|
self.connection.delegate = self
|
||
|
|
||
|
}
|
||
|
|
||
|
public convenience init(url: URL, completion: @escaping (Result<GeminiResponse, Error>) -> Void) throws {
|
||
|
self.init(request: try GeminiRequest(url: url), completion: completion)
|
||
|
}
|
||
|
|
||
|
deinit {
|
||
|
self.cancel()
|
||
|
}
|
||
|
|
||
|
public func resume() {
|
||
|
self.connection.startConnection()
|
||
|
}
|
||
|
|
||
|
public func cancel() {
|
||
|
connection.cancelConnection()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public extension GeminiDataTask {
|
||
|
enum Error: Swift.Error {
|
||
|
case noData
|
||
|
case connectionError(NWError)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extension GeminiDataTask: GeminiConnectionDelegate {
|
||
|
public func connectionReady(_ connection: GeminiConnection) {
|
||
|
connection.sendRequest(self.request)
|
||
|
}
|
||
|
|
||
|
public func connection(_ connection: GeminiConnection, receivedData data: Data?, header: GeminiResponseHeader) {
|
||
|
guard !completed else {
|
||
|
print("GeminiRequestTask(\(self)) has already completed, shouldn't be receiving any data")
|
||
|
return
|
||
|
}
|
||
|
completed = true
|
||
|
if let data = data {
|
||
|
let response = GeminiResponse(header: header, body: data)
|
||
|
self.completion(.success(response))
|
||
|
} else {
|
||
|
self.completion(.failure(.noData))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public func connection(_ connection: GeminiConnection, handleError error: GeminiConnection.Error) {
|
||
|
guard !completed else {
|
||
|
print("GeminiRequestTask(\(self)) has already completed, shouldn't be receiving any data")
|
||
|
return
|
||
|
}
|
||
|
completed = true
|
||
|
self.completion(.failure(.connectionError(error)))
|
||
|
}
|
||
|
|
||
|
public func connectionCompleted(_ connection: GeminiConnection) {
|
||
|
}
|
||
|
|
||
|
}
|