我知道NSCache是线程安全的,但我找不到任何提到NSURLCache的线程安全的文件.
在我的项目中,我们使用的是一个封闭的源代码框架(Backbase,如果你想知道的话).这是一个混合应用程序框架,提供了许多"开箱即用"的安全选项.其中一个是证书固定,我对其实现非常感兴趣.
我们只需要在配置文件中设置一个属性即可.URLSession.shared通过框架处理完成的每个请求,并且钉扎是有效的.但是,如果我实例化我自己的URLSession,那么钉扎效果不佳.但是我也可以URLSession通过用框架实例化它来使pinning对新的有效NSURLSessionConfiguration.
对于那些只阅读代码的人:
// Pinning effective
URLSession.shared.dataTask(with: request, completionHandler: completion)
// Pinning not effective
URLSession(configuration: .default).dataTask(with: request, completionHandler: completion)
// Pinning effective
URLSession(configuration: ShinnyFramework.getConfiguration()).dataTask(with: request, completionHandler: completion)
Run Code Online (Sandbox Code Playgroud)
对我来说,URLSession.shared是不可改变的,所以不可能改变它的工作.要实现固定,唯一的方法是URLSession使用自定义创建新的URLSessionDelegate.
我的问题是:他们做了什么才能得到这种行为?方法调整,Isa调酒,还有其他什么?
编辑:我不是在寻找有关如何实现证书锁定的详细说明.我更感兴趣的是如何编辑所谓的不可变静态属性以及如何在URLSession不使用委托的情况下配置对象的行为.
我的网络逻辑中有以下代码:
let task = urlSession.dataTask(with: request) { [weak self] (data, response, error) in
if let error = error {
if error.localizedDescription.contains("The request timed out") {
// request timeout stuff ...
} else {
// other errors
}
}
}
Run Code Online (Sandbox Code Playgroud)
字符串匹配localizedDescription不是好的代码实践。如何像 in 子句一样获取错误的类型catch?
使用XCode-8.2.1,Swift-3.0.2和iOS-10.2.1,
我正在尝试调用两个不同的URLSession.shared.dataTasks(第一个是简单的URL请求,第二个是POST请求)。
由于我的第一个dataTask提供了第二个dataTask的httpBody中所需的结果,因此两个URLSession.shared.dataTasks应该依次运行,一个接一个地运行!(并且准备代码也应连续运行)。
到目前为止,我尝试使用两个连续的serialQueue.sync{}队列。但是我必须意识到代码无法按照我想要的顺序执行。
日志中的打印语句如下:
Hmmmmmm 2
Hmmmmmm 1
Hmmmmmm 3
Run Code Online (Sandbox Code Playgroud)
(而不是根据需要的1、2、3)!
您如何获得订单1、2、3?
(即,如何确保第二个dataTask的httpBody可以填充来自第一个dataTask的结果?)
这是我的代码:(由于URL已被删除,因此无法执行-但您明白了)!
import UIKit
class ViewController: UIViewController {
let serialQueue = DispatchQueue(label: "myResourceQueue")
var stationID: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.serialQueue.sync {
let myResourceURL = URL(string: "myQueryString1")
let task = URLSession.shared.dataTask(with: myResourceURL!) { (data, response, error) in
if (error != nil) {
// print(error.debugDescription)
} else {
if …Run Code Online (Sandbox Code Playgroud) synchronization grand-central-dispatch nsurlsessiondatatask urlsession
设置此参数不会影响
到主机的同时连接数。我在苹果开发者论坛上发现了同样的问题。看起来像是iOS 10中的错误,iOS 9正常工作。
let sessionConfiguration = URLSessionConfiguration.background(withIdentifier: <identifier>)
sessionConfiguration.httpMaximumConnectionsPerHost = 4
sessionConfiguration.allowsCellularAccess = AppDelegate.shared.userDefaults.allowsCellularAccess
sessionConfiguration.timeoutIntervalForRequest = 7*60
sessionConfiguration.timeoutIntervalForResource = 24*60*60
let session = URLSession(configuration: sessionConfiguration, delegate:self, delegateQueue: operationQueue)
Run Code Online (Sandbox Code Playgroud)
有人有同样的问题吗?是否有另一种稳定的方法可以在后台管理许多上载/下载的队列?
我想充分利用iOS上网络通话的优先级。
到目前为止,我正在使用URLSessionTask.priority。我创建如下网络呼叫:
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data, let response = response {
// Handle response
} else {
// Handle error
}
}
task.priority = priority
Run Code Online (Sandbox Code Playgroud)
问题是,我仍然看到优先级为0.0的下载任务一开始就从优先级为1.0的任务中占用了大量负载(最多〜60%)。有时,只有当大量低优先级请求完成时才开始优先级为1.0的呼叫。Apple的(文档)确认:
要向主机提供有关如何确定应用中URL会话任务优先级的提示,请为每个任务指定优先级。指定优先级仅提供提示,并不保证性能。[...]没有API可让您从主机的角度确定任务的有效优先级。
我想实现假定的下载和缓存,而又不降低用户发起的请求的性能。这对于连接不良的设备尤其重要。
我考虑过的解决方案:
n并行下载,具有优先级队列,并在高优先级请求进入时中止/暂停非常低优先级的请求。但是,对我来说,这听起来像已经必须存在,并且有点像如果实施不当,这是一种绝佳的射击方式。我考虑过的替代方法:
我支持iOS 9和更高版本,但也会考虑在iOS 9上不起作用的解决方案。
我一直在按照本教程进行讲解URLSession。通过创建协议并扩展现有协议来完成该示例URLSession。
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol
}
extension URLSession: URLSessionProtocol {
func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {
return dataTask(with: request, completionHandler: completionHandler) as URLSessionDataTaskProtocol
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试按预期工作。但是,当我尝试运行真实对象时,URLSession-> datatask()陷入无限循环并崩溃。似乎datatask()正在调用自身。
请问我在俯视什么?
更新:
protocol URLSessionDataTaskProtocol {
var originalRequest: URLRequest? { get }
func resume()
}
extension URLSessionDataTask: URLSessionDataTaskProtocol {}
Run Code Online (Sandbox Code Playgroud) 按照/sf/answers/1939869921/的建议,我可以执行异步下载,如下所示,并在viewDidLoad.
func loadItems(tuple : (name : String, imageURL : URL)) {
print("Download Started")
URLSession.shared.dataTask(with: tuple.imageURL, completionHandler :
{ data, response, error in
guard let data = data, error == nil else { return }
print(response?.suggestedFilename ?? tuple.imageURL.lastPathComponent)
print("Download Finished")
DispatchQueue.main.async() { [weak self] in
self?.displayFlag(data: data, title: tuple.name)
}
}).resume()
}
Run Code Online (Sandbox Code Playgroud)
这一切都运作良好。我的问题是,如果下载缓慢,并且我退出页面,如何以及在哪里(viewDidUnload?看起来已经不推荐使用)可以取消获取(图像下载)任务?
我使用 URLSession 进行 POST 请求并获取玩家列表,但有时我会获取错误“Error Domain=NSURLErrorDomain Code=-1001”,我该如何处理?
我如何在“完成”中出现错误?
func addPlayer(playerCode: String, completion: @escaping (Error?) -> ()) {
guard let url = URL(string: "\(url)") else { return }
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let playerCode = [playerCode]
let params = ["players": playerCode]
do {
let data = try JSONSerialization.data(withJSONObject: params, options: .init())
urlRequest.httpBody = data
urlRequest.setValue("application/json", forHTTPHeaderField: "content-type")
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 5.0
DispatchQueue.global(qos: .background).async {
URLSession(configuration: sessionConfig).dataTask(with: urlRequest) { (data, resp, err) in
guard let …Run Code Online (Sandbox Code Playgroud) 当我使用 URLSession 收到非常大的响应时,我收到此警告:
[quic] quic_crypto_session_state_serialize [C3.1.1:2] [-4b5609327fb472a4] TLS ticket does not fit (6817 > 6144)
Run Code Online (Sandbox Code Playgroud)
最大 TLS 记录大小为 16 KB,但这里我们只能看到 6 KB。也许有办法增加 TLS 票证大小?
urlsession ×10
ios ×7
swift ×7
nsurlsession ×2
backbase ×1
caching ×1
ios10 ×1
nsurlcache ×1
ssl ×1
swift4 ×1
timeout ×1
unit-testing ×1