Swift 调度队列块未运行 [英] Swift dispatch queue block not running

查看:16
本文介绍了Swift 调度队列块未运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在编写一个 Alamofire HTTP 请求并且遇到了我的视图未加载的问题 - 可能是因为没有数据.令人困惑的部分是这在昨天有效.在请求中,我能够执行 print(data) 并且结果是 506 字节,如果我的计算是正确的,那么给定返回的 JSON 有效负载的大小大约是正确的从下面的端点.

@State var recipes = [Recipe]()AF.request("http://localhost:3000/recipes").responseJSON { response in守卫让数据 = response.data else { return }如果让响应 = 尝试?JSONDecoder().decode([Recipe].self, from: data) {DispatchQueue.main.async {self.recipes = 回复}返回}}

我可以确认被命中的端点返回以下数据...

<预><代码>[{名称":曼哈顿","图像":"https://images.unsplash.com/photo-1536935338788-846bb9981813?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&1autolib=2&amp;8&8&8&ix2cro=&amp;8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&amp;8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&8&amp;8&8&8&8&8;,精神":波旁威士忌",冰":粉碎",玻璃":轿跑车",产量":3.75",描述":这是一种很好的饮料.你应该成功.",成分":[{瓶子":高西布耶之子",数量":2.5"},{瓶子":Cocchi Vermouth Di Torino",金额":0.75"},{瓶子":简单糖浆",金额":0.083"}]}]

我这里也有我的配方和成分模型,它应该能够根据上述 JSON 进行解码.

struct Recipe:可解码,可识别{var id = UUID()变量名:字符串var 图像:字符串var精神:字符串变冰:字符串var glass:字符串var 产量:字符串变量描述:字符串var成分:[成分]}struct Ingredient:可解码,可识别{var id = UUID()var 瓶子:字符串变量数量:字符串}

有人能发现问题吗?我试图在 DispatchQueue 中放置一个调试打印,但它没有打印,对我来说,这听起来像是一个错误.但是,我是 Swift/XCode/iOS 的新手,不确定最佳调试实践.

解决方案

如果你不能调试自己,永远不要使用 try?.有了更多的经验,我会说我们倾向于不使用 try?,但有时我们会这样做.但是当我们编写try?时,我们能够找到一个可能的问题,即如果需要进行调试.

然后让我们用 do/catch 做一个适当的尝试:

做{让响应 = 尝试 JSONDecoder().decode([Recipe].self, from: dataDispatchQueue.main.async {self.recipes = 回复}} 抓住 {print("糟糕,解码时出现错误:(error)")//而不是 error.localizedDescription 因为它更适合用户而不是开发人员,因此您将跳过所有有用的信息}

并读取输出.

更进一步?
不要相信 API 应该返回什么.
我见过很多问题,其中返回的值是错误消息、XML 错误消息、JSON 错误消息、HTML 错误消息和 JSON 值丢失或类型错误等.JSONDecoder 没想到...
原因可能多种多样,包括参数错误/丢失、APIKey 错误/丢失、服务器停机、标头错误/丢失等.
但是,然后,打印返回的值.

print(String(data: data, encoding: .utf8) ?? "No data found")

所以当你得到它时直接打印它,或者至少在捕获时打印:

} catch {print("糟糕,解码时出现错误:(error)")//而不是 error.localizedDescription 因为它更适合用户而不是开发人员,因此您将跳过所有有用的信息打印(在获取响应字符串化时:(字符串(数据:数据,编码:.utf8)??未找到数据")")}

如果你不理解错误信息输出,没关系,没有什么可耻的.但是您的首要任务是获取该错误消息.如果你不理解它,你可以在 SO 上分享它,你可能会得到帮助.但目前,我们无法猜测您的代码有什么问题.

I am currently writing an Alamofire HTTP request and am running into an issue where my view is not loading - likely because there is no data. The confusing part is that this was working yesterday. In the request I was able to do print(data) and the result was 506 bytes which, if my calculation is correct, is about the correct size given the JSON payload returned from the endpoint below.

@State var recipes = [Recipe]()

AF.request("http://localhost:3000/recipes").responseJSON { response in
    guard let data = response.data else { return }
    if let response = try? JSONDecoder().decode([Recipe].self, from: data) {
        DispatchQueue.main.async {
            self.recipes = response
        }
        return
    }
}

I can confirm that the endpoint that is being hit returns the following data...

[
   {
      "name":"Manhattan",
      "image":"https://images.unsplash.com/photo-1536935338788-846bb9981813?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2486&q=80",
      "spirit":"Bourbon",
      "ice":"Crushed",
      "glass":"Coupe",
      "yield":"3.75",
      "description":"This is a good drink. You should make it.",
      "ingredients":[
         {
            "bottle":"High West Son Of Bourye",
            "amount":"2.5"
         },
         {
            "bottle":"Cocchi Vermouth Di Torino",
            "amount":"0.75"
         },
         {
            "bottle":"Simple Syrup",
            "amount":"0.083"
         }
      ]
   }
]

I also have my Recipe and Ingredient model here which should be able to decode based on the above JSON.

struct Recipe: Decodable, Identifiable {
    var id = UUID()
    var name: String
    var image: String
    var spirit: String
    var ice: String
    var glass: String
    var yield: String
    var description: String
    var ingredients: [Ingredient]
}

struct Ingredient: Decodable, Identifiable {
    var id = UUID()
    var bottle: String
    var amount: String
}

Is anybody able to spot an issue? I was trying to put a debugging print in the DispatchQueue but it is not printing which, to me, sounds like an error. However I am new to Swift/XCode/iOS and am not sure the best debugging practices for this.

解决方案

If you can't debug yourself, NEVER USE try?. With more experience, I'd say that we tend to not use try?, but sometimes we do. But when we write try?, we are able to find an possible issue, ie debug if needed.

Let's do a proper try then, with a do/catch:

do { 
    let response = try JSONDecoder().decode([Recipe].self, from: data
    DispatchQueue.main.async {
        self.recipes = response
    }
} catch {
    print("Oops, there was en error while decoding: (error)") // and not error.localizedDescription as it's more for users than developpers, so you'll skip all the useful informations
}

And read the output.

Going further?
Don't believe what's the API is supposed to return.
I've seen plenty and plenty of questions where the returned values was an error message, a XML Error message, a JSON Error message, an HTML Error message, and a JSON value missing, or of bad type, etc. And that, your JSONDecoder wasn't expecting it...
Reasons could be various, from bad/missing parameters, bad/missing APIKey, server down, bad/missing header, etc.
But, then, print the returned value.

print(String(data: data, encoding: .utf8) ?? "No data found")

So print it directly when you get it, or at least in the catch:

} catch {
    print("Oops, there was en error while decoding: (error)") // and not error.localizedDescription as it's more for users than developpers, so you'll skip all the useful informations
    print("While getting response stringified: (String(data: data, encoding: .utf8) ?? "No data found")")
}

If you don't understand the error message output, it's okay, there is no shame about it. But your first job is to get that error message. You can share it on SO if you don't understand it, you might get help with that. But currently, we can't guess what's wrong with your code.

这篇关于Swift 调度队列块未运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆