Самозаверяющий сертификат Swift Combine

#swift #combine

#swift #объединить

Вопрос:

Я пытаюсь запросить конечную точку, которая включает HTTPS и самозаверяющий сертификат. Как бы я реализовал приведенный ниже код, чтобы включить сертификат, используя Combine в Swift.

 struct API {
    
    func getJSON() -> AnyPublisher<ResultList, Error> {
        let url = URL(string:urlString)!
        return URLSession.shared.dataTaskPublisher(for: url)
            .map({$0.data})
            .decode(type: ResultList.self, decoder: JSONDecoder())
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
    }
}
 

Например, без использования Combine я обычно делаю следующее:

 class SessionDelegate: NSObject, URLSessionDelegate {
    
    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        
        if challenge.protectionSpace.host == myCert {
            completion(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
        } else {
            completion(.performDefaultHandling, nil)
        }
    }
}
 

Ответ №1:

Вы не можете этого сделать URLSession.shared , потому что делегат сеанса должен принять самозаверяющий сертификат.

Ваш вопрос показывает, что вы уже знаете, как использовать делегат для этого. Поэтому измените getJSON , чтобы принять надлежащим образом делегированный сеанс в качестве аргумента:

     func getJSON(with session: URLSession) -> AnyPublisher<ResultList, Error> {
        let url = URL(string:urlString)!
        return session.dataTaskPublisher(for: url)
            .map({$0.data})
            .decode(type: ResultList.self, decoder: JSONDecoder())
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
    }