首页 > 解决方案 > URLSession 不调用 API。虽然在操场上它有效

问题描述

所以这段代码在操场上对我有用,但由于某种原因URLSession.shared.dataTask(...没有调用我当前在本地运行的烧瓶 api。知道出了什么问题吗?到目前为止,我只关心为什么它没有进入do{我的项目但它在操场上正常工作。

    func getWords() -> [Word]{
    var words = [Word]()
    let url = URL(string: self.url)
    let request = URLRequest(url: url!)
    
    let group = DispatchGroup()
    
    print("XD")
    URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
            do {
                print("A")
                if let data = data{
                    print("B")
                    if let decodedResponse = try? JSONDecoder().decode([Word].self, from: data){
                        group.enter()
                        DispatchQueue.main.async(){
                            words = decodedResponse
                            print("C")
                            print(words)
                            group.leave()
                        }
                    }
                }
                print("DD")
            } catch {
                print("Words.swift Error in try catch")
            }
    group.enter()
    }).resume()
    group.leave()

    group.notify(queue: DispatchQueue.main, execute: {
           print(words)
         })
    print("ASDASD WORDS: \(words)")
    
    for _ in 1 ... 4 {
        // - to make sure there aren't duplicates -
        
        var wordId:Int = Int.random(in: 0..<words.count)
        while randomIds.contains(wordId){
            wordId = Int.random(in: 0..<words.count)
        }
        randomIds.append(wordId)
    }
    //returns 4 words
    return words
}

标签: iosswiftxcodeapiurlsession

解决方案


你没有DispatchGroup正确使用;您应该enter在开始异步工作之前和leave完成后调用。然后您可以使用它notify来执行一些操作。

DispatchGroup但是,在这种情况下,您实际上并不需要 a ;您之所以拥有它,是因为您正试图将异步操作转换为同步操作;

正确的方法是接受该操作是异步的,并且此函数不可能return [Word]。您将需要重构函数以接受完成处理程序闭包并使用结果调用它。

像这样的东西:

func getWords(completionHandler:@escaping (Result<[Word], Error>) -> Void)  -> Void{
    var words = [Word]()
    let url = URL(string: self.url)
    let request = URLRequest(url: url!)  // Note you should use a guard and call the completion handler with an error if url is `nil`
    
    URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
        if let error = error {
            completionHandler(.failure(error))
        } else {
            do {
                if let data = data {
                   let words = try JSONDecoder().decode([Word].self, from: data)
                   completionHandler(.success(words))
                } else {
                   // TODO call completionHander with a .failure(SomeError)
                }
            } catch {
                completionHandler(.failure(error))
            }
        }
    }).resume() 
}

然后你可以调用它:

getWords() { result in 
    switch result {
    case .success(let words):
        print(words)
    case .failure(let error):
        print(error.localizedDescription)
    }
}

推荐阅读