You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI代码无报错却不显示卫星分类文本,求解决方案

SwiftUI项目无法显示卫星分类文本的问题排查

使用Xcode 14.3(14E222b)开发SwiftUI项目,代码运行无报错,但无法显示卫星分类文本,目标是展示卫星分类信息,怀疑问题出在Text组件写法上,相关代码如下:

import SwiftUI
import Foundation

struct Datamodel: Decodable {
    var category: String
    var transactionscount: Int
    var satcount: Int
    var above: [Data]
}

struct Data: Decodable {
    var satid: Int
    var satname: String
    var intDesignator: String
    var launchDate: String
    var satlat: Double
    var satlng: Double
    var satalt: Double
}

struct TestView :  View
{ /// start
    @ObservedObject var fetcher = VerseFetcher()

    var body: some View{ ///  start body
        Text(self.fetcher.verse?.category ?? "")
            .foregroundColor(.black)
            .fixedSize(horizontal: false, vertical: true)
    } /// end body

    public class VerseFetcher : ObservableObject{ /// start verse fetcher
        @Published var verse: Datamodel?

        init(){ /// start init
            load()
        } /// end init

        func load(){ /// start load
            let url = URL(string: "https://api.n2yo.com/rest/v1/satellite/above/41.702/-76.014/0/70/18/&apiKey=<api-key>")!

            URLSession.shared.dataTask(with: url) {(data,response,error) in/// start url session
                do  { /// start do
                    if let d = data { /// start if
                        let webdata = try JSONDecoder().decode(Datamodel.self, from: d)

                        DispatchQueue.main.async { /// start dispatch
                            self.verse = webdata
                        } ///  end dispatch que
                    }   else { /// end if /  start else
                        print("No data")
                    }/// end else
                } catch { ///  end do /  start catch
                    print("Error here")
                } /// end catch
            }.resume()/// end url session
        } /// end load
    } /// end Verse Fetcher
} /// end

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

问题根源分析

  1. JSON结构不匹配:n2yo的above接口返回的JSON中,category字段嵌套在info对象内,而非根节点,原Datamodel结构错误导致解码失败,verse始终为nil,Text组件只能显示空字符串。
  2. 结构体命名冲突:自定义的Data结构体与系统自带的Data类型重名,存在潜在的编译或运行时冲突。
  3. URL格式错误:原URL末尾多了一个斜杠,导致API请求无效,无法获取有效数据。
  4. 错误处理模糊:仅打印"Error here"无法定位解码失败的具体原因,不利于排查问题。

修复方案

  1. 修正数据模型结构
    调整结构体以匹配API返回的JSON格式,同时避免命名冲突:

    struct APIResponse: Decodable {
        var info: Datamodel
        var above: [SatelliteData]
    }
    
    struct Datamodel: Decodable {
        var category: String
        var transactionscount: Int
        var satcount: Int
    }
    
    struct SatelliteData: Decodable {
        var satid: Int
        var satname: String
        var intDesignator: String
        var launchDate: String
        var satlat: Double
        var satlng: Double
        var satalt: Double
    }
    
  2. 更新解码逻辑
    在VerseFetcher的load方法中,解码APIResponse而非原Datamodel:

    let webdata = try JSONDecoder().decode(APIResponse.self, from: d)
    DispatchQueue.main.async {
        self.verse = webdata.info
    }
    
  3. 修正URL格式
    去掉URL末尾多余的斜杠,确保API请求有效:

    let url = URL(string: "https://api.n2yo.com/rest/v1/satellite/above/41.702/-76.014/0/70/18&apiKey=<api-key>")!
    
  4. 优化错误处理
    打印具体错误信息,方便定位问题:

    catch {
        print("解码失败:\(error)")
    }
    
  5. 分类ID转文本(可选)
    n2yo API返回的category是数字ID,可添加映射函数转为对应分类名称:

    func categoryName(for categoryID: String) -> String {
        switch categoryID {
        case "18":
            return "气象卫星"
        // 可根据需求补充其他分类ID的映射
        default:
            return "未知分类"
        }
    }
    

    然后修改Text组件:

    Text(categoryName(for: self.fetcher.verse?.category ?? ""))
        .foregroundColor(.black)
        .fixedSize(horizontal: false, vertical: true)
    

内容的提问来源于stack exchange,提问作者A.Moeex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:07:03