[英]Swift: URLSession.shared.downloadTask working only in Simulator
I have been struggling with this bug for a few days... So I've got a function which should download some data from an online txt file and then return it.几天来我一直在为这个错误而苦苦挣扎......所以我有一个功能应该从在线txt文件下载一些数据然后返回它。 The strange thing is, this works fully when I try it out in Simulator or if I connect my iPhone and download it there.
奇怪的是,当我在模拟器中试用它或者连接我的 iPhone 并在那里下载它时,这完全有效。 But once I start testing it out in TestFlight, this feature does not work at all there.
但是一旦我开始在 TestFlight 中对其进行测试,此功能在那里根本不起作用。
This is the function code:这是函数代码:
public static func loadSomeData() -> String {
let url = URL(string: "https://myurl.com/file.txt")!
var input = ""
let task = URLSession.shared.downloadTask(with: url) { localURL, urlResponse, error in
if let localURL = localURL {
if let string = try? String(contentsOf: localURL) {
input = string
}
}
}
task.resume()
while !input.isEmpty {
// Waits until the data is loaded
}
return input
}
Also, while the address is HTTPS, I have still allowed Arbitrary Loads in the plist file.此外,虽然地址是 HTTPS,但我仍然允许在 plist 文件中进行任意加载。
Thanks so much for your time and possible answers in forehand!非常感谢您的时间和可能的正手答案!
As David S said, you don't want to do a busy loop like that.正如大卫 S 所说,你不想做这样的繁忙循环。 What you need to do is pass in a completion handler and let the network request run asynchronously.
您需要做的是传入一个完成处理程序并让网络请求异步运行。 Something like this should do the trick.
像这样的事情应该可以解决问题。
class Loader {
enum Error: Swift.Error {
case badURL
case badData
case other(Swift.Error)
}
public func loadSomeData(then block: @escaping(Result<String, Error>) -> Void) {
let url = URL(string: "https://www.w3.org/TR/PNG/iso_8859-1.txt")!
let task = URLSession.shared.downloadTask(with: url) { localURL, urlResponse, error in
guard error == nil else {
block(.failure(.other(error!)))
return
}
guard let localURL = localURL else {
block(.failure(.badURL))
return
}
guard let string = try? String(contentsOf: localURL) else {
block(.failure(.badData))
return
}
block(.success(string))
}
task.resume()
}
}
Then you can just do this to fetch whatever data you need.然后你可以这样做来获取你需要的任何数据。
let loader = Loader()
loader.loadSomeData { result in
switch result {
case .success(let string):
print("SUCCESS: \(string)")
case .failure(let error):
print("ERROR: \(error)")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.