我在python中创建了一个可以正常工作的http服务器(将json作为字符串响应),并在Swift中创建了一个URLSession
,该服务器应该可以检索该json。我的问题是苹果需要HTTP连接才能使用HTTPS。
应用传输安全性(ATS)
从iOS 9.0和OS X 10.11开始,默认情况下为使用URLSession建立的所有HTTP连接启用一个称为“应用程序传输安全性”(App Transport Security,ATS)的新安全性功能。 ATS要求HTTP连接使用HTTPS(RFC 2818)。 有关更多信息,请参见《信息属性列表键参考》中的NSAppTransportSecurity。
请参阅:https://developer.apple.com/documentation/foundation/urlsession
这是我的python服务器的代码:
import http.server
import ssl
import json
class RequestHandler(http.server.BaseHTTPRequestHandler):
def set_headers(self):
self.send_response(200)
self.end_headers()
def do_GET(self):
self.set_headers()
self.wfile.write(json.dumps({
'title': 'title'
}).encode())
port = 8888
host = ''
with http.server.HTTPServer((host, port), RequestHandler) as httpd:
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='key.pem', certfile='cert.pem', server_side=True)
print('server serves on {}:{}'.format(host, port))
httpd.serve_forever()
这就是我用来生成证书和密钥文件的命令:openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
。当我启动python服务器文件时,它要求我输入PEM密码,因此我认为这是可行的。
这是我的URLSession
的Swift代码:
let url = URL(string: "http://localhost:8888")!
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let dataTask = session.dataTask(with: url) { (data, response, error) in
guard error != nil else {
print("\(error!.localizedDescription)")
return
}
guard data != nil else {
print("no data")
return
}
print(String(data: data!, encoding: .utf8)!)
}
dataTask.resume()
当我先运行Python代码然后运行Swift代码时,Xcode给我一个错误,并显示无数据。错误:无法启动任务... <1>,因为它不符合ATS策略
请注意,我希望我的python服务器遵守ATS策略,并且不要在我的info.plist中添加任何域异常或NSAllowsLocalNetworking
键。
PS:ssl
模块和ssl.wrap_socket(...
是试图使我的HTTP服务器符合ATS策略。
答案 0 :(得分:0)
我实际上很喜欢为此使用Ngrok,它非常简单和免费(尽管有付费版本)。在他们的网站上
ngrok将本地服务器公开在NAT和防火墙之后 通过安全的隧道上网。
例如,我在localhost:8000上运行django项目,然后运行ngrok创建iOS应用程序要连接的https / http URL,而不是尝试直接连接到localhost:8000。设置和开始大约需要两秒钟。