URLSession 不调用 API。虽然在游乐场它有效
URLSession does not call API. Though in Playground it works
所以这段代码在操场上对我有用,但出于某种原因 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
}
您没有正确使用 DispatchGroup
;您应该在开始异步工作之前调用 enter
并在完成后调用 leave
。然后,您可以使用 notify
执行一些操作。
但是,在这种情况下您并不需要 DispatchGroup
;您拥有它是因为您正试图将异步操作转变为同步操作;
正确的做法是接受操作是异步的,并且此函数不可能 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)
}
}
所以这段代码在操场上对我有用,但出于某种原因 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
}
您没有正确使用 DispatchGroup
;您应该在开始异步工作之前调用 enter
并在完成后调用 leave
。然后,您可以使用 notify
执行一些操作。
但是,在这种情况下您并不需要 DispatchGroup
;您拥有它是因为您正试图将异步操作转变为同步操作;
正确的做法是接受操作是异步的,并且此函数不可能 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)
}
}