#ios #swift #alamofire #urlrequest
#iOS #swift #alamofire #urlrequest
Вопрос:
У меня возникла проблема с одним запросом, который я выполняю.
При использовании Postman этот запрос работает с одним предупреждением «Самозаверяющий сертификат в цепочке сертификатов»
Вот завиток, если вы хотите попробовать:
curl --location --request GET 'https://app-server.iot.i.tplinknbu.com/v1/server-info'
--header 'Content-Type: application/json'
--header 'app-cid: app:TP-Link_Tapo_Android:98-3B-16-96-48-EB'
--data-raw ''
Но при использовании Almofire или системы запросов по умолчанию из iOS он завершается с ошибкой:
2020-11-22 23:47:50.192188 0000 App [4483:1574605] Task <E6235AC9-2246-4F32-BB17-CB969F244030>.<2> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
2020-11-22 23:47:50.195117 0000 App[4483:1574592] Task <E6235AC9-2246-4F32-BB17-CB969F244030>.<2> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x151093800) s: *.tplinknbu.com i: TP-LINK CA P1>",
"<cert(0x151094000) s: TP-LINK CA P1 i: tp-link-CA>",
"<cert(0x15106e200) s: tp-link-CA i: tp-link-CA>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://app-server.iot.i.tplinknbu.com/v1/server-info, NSErrorFailingURLStringKey=https://app-server.iot.i.tplinknbu.com/v1/server-info, NSUnderlyingError=0x282b23e10 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x281760f30>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x151093800) s: *.tplinknbu.com i: TP-LINK CA P1>",
"<cert(0x151094000) s: TP-LINK CA P1 i: tp-link-CA>",
"<cert(0x15106e200) s: tp-link-CA i: tp-link-CA>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <E6235AC9-2246-4F32-BB17-CB969F244030>.<2>"
), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <E6235AC9-2246-4F32-BB17-CB969F244030>.<2>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x281760f30>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}
Это код, который я использую:
info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Код:
let defaultManager: ServerTrustManager = {
let serverTrustPolicies: [String: ServerTrustEvaluating] = [
"tplinknbu.com": DisabledTrustEvaluator(),
"tplinknbu.com:443": DisabledTrustEvaluator()
]
return Alamofire.ServerTrustManager(evaluators: serverTrustPolicies)
}()
let pathURL = URL(string: "https://app-server.iot.i.tplinknbu.com/v1/server-info")
var request = URLRequest(url: pathURL!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = HTTPMethod.get.rawValue
let dataRequest = Session(serverTrustManager: defaultManager, eventMonitors: [AlamofireLogger()]).request(request).responseJSON {
(response) in
switch response.result {
case .failure(let error):
print(error)
default: break
}
}
Что я делаю не так?
PS если я использую прокси-инструмент Proxyman и активирую сертификат Proxyman, который у них есть на iPhone, все хорошо работает в приложении iOS
Комментарии:
1. проблема может быть в вашем объекте сеанса, он выделяется dell перед обработкой запроса, попробуйте присвоить его переменной вне функции, а затем проверьте, была ли такая же проблема,.
2. @ShivamGaur спасибо, и вы были правы, я терял сеанс!!!
Ответ №1:
Вы должны точно соответствовать хостам, которые вы используете. Это tplinknbu.com
НЕ соответствует app-server.iot.i.tplinknbu.com
. Вы также должны исследовать ошибки, которые вы видите напрямую, поскольку они могут содержать полезную информацию.
И, как сказал @Shivam Gaur, вы не должны создавать Session
встроенные экземпляры подобным образом. Вам нужно сохранить их ссылку в чем-то вроде одноэлементного, чтобы запросы могли завершаться.
Комментарии:
1. owww Я не понял, что это должен быть полный URL. Итак, исправление заключалось в том, что сохранение сеанса plist просто установлено в <key>NSAllowsArbitraryLoads</key> <true/>