ios - SwiftUI : API URL fetch failed

标签 ios json swift xcode url

我正在尝试从 API url 检索数据
这是实现指南的内容,因此 URL 应与以下格式匹配:

The request for information in JSON format is submitted as a GET operation to the endpoint: http://digit-eyes.com/gtin/v2_0/?upc_code=x&app_key=x&signature=x&language=x&field_names=x


这是我从 JSON 中获取数据并从 JSON 中解码的函数。
我已经用 x 替换了签名和 API key 。
签名是通过组合 app_key 和形成散列值的条形码生成的。
func loadData() {
    guard let url = URL(string: "https://www.digit-eyes.com/gtin/v2_0/?upcCode=5901905880016&language=en&app_key=x&signature=x&language=en&field_names=description,brand,ingredients,image,upc_code") else {
        print("Invalid URL")
        return
    }
    let request = URLRequest(url: url)
    URLSession.shared.dataTask(with: request) { data, responce, error in
        if let data = data {
            if let decodedRepsonce = try? JSONDecoder().decode(Response.self, from: data) {
                DispatchQueue.main.async{
                    self.results = decodedRepsonce.results
                }
                return
            }
        }
        print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") //This is the error I get
    }.resume()
}
这是我将 URL 粘贴到 Safari 时得到的结果

我已经用“https://itunes.apple.com/search?term=radiohead&entity=song”测试了这个 URL,它可以工作。一个明显的区别是这个链接下载一个 JSON 文件,我的 URL 没有。
我将 JSON 存储到数组结果中:
struct Result: Codable {
    var description: String
    var brand: String
    var ingredients: String
    var image: String
    var upc_code: Int
}
然后显示在正文中:
var body: some View {
    GeometryReader { geometry in
        VStack(spacing: 0) {
        self.indicator.padding()
        List(self.results, id: \.upc_code) { item in
            VStack(alignment: .leading) {
                Text(item.brand)
                     .font(.headline)
                Text(item.description)
            }
        }
        
  }
编辑
处理来自 JSON 数据的空值
要调用 loadData,我在正文的 VStack 上有一个 .onAppear。
    .onAppear {
            //let signiture = self.scannedCode.barcode.hashedValue("Ls75O8z1q9Ep9Kz0")
            self.loadData(url: "https://www.digit-eyes.com/gtin/v2_0/?upcCode=5901905880016&language=en&app_key=/9nOS+obsRF5&signature=DiKl4lURenoNe53I0a/i3kiAkQQ=&language=en&field_names=description,ingredients,brand,image") { error, result  in
                if let err = error {
                    print(err)
                }
            }
    }
}
这是在 body 外部的结构中
    func loadData(url: String, completion: @escaping (Error?, Result?) -> Void) {
        if let url = URL(string: url) {
            let task = URLSession.shared.dataTask(with: url) { data, response, error in
                guard let data = data, error == nil else {return}
                
                do {
                    let decoder = JSONDecoder()
                    let result: Result = try decoder.decode(Result.self, from: data)
                    completion(nil, result)
                }
                catch let e {
                    print(e)
                    completion(e, nil)
                }
            }

            task.resume()
        }
    }
}
我现在得到:

valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "brand", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))


在 JSON 对象中,品牌名称并不总是可以找到,因此它有时为空。如果找到空值,我不知道如何恢复解码器。

最佳答案

试试这段代码在正文中调用:

func loadData(url: String, completion: @escaping (Error?, Result?) -> Void) {
    if let url = URL(string: url) {
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else {return}
            
            do {
                let decoder = JSONDecoder()
                let result: Result = try decoder.decode(Result.self, from: data)
                completion(nil, result)
            }
            catch let e {
                print(e)
                completion(e, nil)
            }
        }

        task.resume()
    }
}

loadData(url: "https://google.com") { error, result  in
    if let err = error {
        print(err)
    }
}
尝试如下修改结构并添加其他变量。我还注意到 upc_code 是一个字符串。
struct Result: Codable {
    var description: String?
    var brand: String?
    var ingredients: String?
    var image: String?
    var upc_code: String?
    var return_message: String?
    var return_code: String?
}

关于ios - SwiftUI : API URL fetch failed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62739895/

相关文章:

json - Swift 解析 json 读为 nil

ios - 当在 UITableViewController 上推回时,UITabBar 会被移除,但在 ViewController 上不会被移除

json - 使用 FOR JSON 和 CTE 并将其存储在变量中

PHP 从数据库中提取数据时将所有非英文字符替换为 null

ios - UIWebView 不显示我的网页

ios - 取消 UISwitch 的自动触发值改变事件

ios - Swift 绘图应用程序很慢

iOS - 如何计算特定 View 内的点击次数?

ios - 单击以将图像添加到核心数据

java - 将字符串转换为 javax.json.JsonString 时出现问题