简体   繁体   English

Swift:URLSession.shared.downloadTask 仅在模拟器中工作

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM