Ios Swift 4和xB7;数据转换
我正在iOS中创建一个模拟时钟显示器,它还显示太阳正午和时钟正午之间的差异,因此我需要知道太阳正午的时间,以便计算该差异 此api调用:Ios Swift 4和xB7;数据转换,ios,json,swift,Ios,Json,Swift,我正在iOS中创建一个模拟时钟显示器,它还显示太阳正午和时钟正午之间的差异,因此我需要知道太阳正午的时间,以便计算该差异 此api调用:http://api.usno.navy.mil/rstt/oneday?date=today&coords=51.1,-1.0&tz=1产生以下结果(一些不相关的字段被丢弃): { “年份”:2018年, “月”:6, “天”:18, “lon”:-1.000000, “lat”:51.100000, "tz":1,, “圣代”:[ {“phen”:“BC”,
http://api.usno.navy.mil/rstt/oneday?date=today&coords=51.1,-1.0&tz=1
产生以下结果(一些不相关的字段被丢弃):
{
“年份”:2018年,
“月”:6,
“天”:18,
“lon”:-1.000000,
“lat”:51.100000,
"tz":1,,
“圣代”:[
{“phen”:“BC”,“time”:“04:02”},
{“phen”:“R”,“time”:“04:49”},
{“phen”:“U”,“time”:“13:05”},这方面的东西应该是可行的。基本上,您希望为phen
项创建一个类。您甚至可以对现象类型使用枚举来提高可读性
我相信您还可以做其他事情来提高可读性,比如定义自己的CodingKeys
enum来为属性提供更好的名称,但这取决于您自己。这应该让您开始
struct SolarData: Decodable {
struct Phenomenon: Decodable {
enum Kind: String, Decodable {
case
beginCivilTwilight = "BC",
rise = "R",
upperTransit = "U",
set = "S",
endCivilTwilight = "EC",
lowerTransit = "L"
}
var phen: Kind
var time: String
}
let year: Int
let month: Int
let day: Int
let lon: Double
let lat: Double
let tz: Double
let sundata: [Phenomenon]
/// The number of minutes past clock noon at which solar noon occurs.
public var solarNoonOffset: Int {
let noon = sundata
.first { $0.phen == .upperTransit }
.map { $0.time }
let solarNoonHour = Int(noon!.prefix(2))
let solarNoonMins = Int(noon!.suffix(2))
let offset = (solarNoonHour! - 12) * 60 + solarNoonMins!
return offset
}
}
let testJson = """
{
"year":2018,
"month":6,
"day":18,
"lon":-1.000000,
"lat":51.100000,
"tz":1,
"sundata":[
{"phen":"BC", "time":"04:02"},
{"phen":"R", "time":"04:49"},
{"phen":"U", "time":"13:05"},
{"phen":"S", "time":"21:22"},
{"phen":"EC", "time":"22:09"}]
}
"""
let solarData = try JSONDecoder().decode(SolarData.self, from: testJson.data(using: .utf8)!)
print("Solar Noon Offset: \(solarData.solarNoonOffset)")
您必须将NSDateFormatter与“HH:mm”一起使用模板,据我所知,它声明另一个具有属性phen
和time
的结构。使该结构符合Codable
,然后将sundata
声明为该结构的数组。同意@Paulw11-如果您将sundata
结构声明为phen
(您可以将其定义为enum Phen:String、Decodable
和time
,然后您将能够使用类似let noon=sundata.first(其中:{$0.Phen==.U})!.time
而不是您的多行声明。我同意@Paulw11更好地使用另一个结构,替代方法是sundata.lazy.first{$0[“Phen]==“U”}?[“time”]
。另外,请使用日期格式化程序提取日期,并让其返回可选值,因为服务器总是会返回错误数据,这只是一个字符串。使用日期格式化程序处理“HH:MM”当然是显而易见的事情(一旦有人提到它)!谢谢。我觉得SunData本身应该是一个结构,但被数组抛出。但它是一个SunData属性数组,正在等待提取。在被指出后也很明显。再次感谢。谢谢。这个“现象”“struct正是我为简化数据提取而寻找的指针类型。
struct SolarData: Decodable {
let year: Int
let month: Int
let day: Int
let lon: Double
let lat: Double
let tz: Double
let sundata: Array<[String: String]>
/// The number of minutes past clock noon at which solar noon occurs.
public var solarNoonOffset: Int {
let noon = sundata
.filter { $0["phen"] == "U" }
.flatMap { $0 }
.filter { $0.0 == "time" }[0]
.value
let solarNoonHour = Int(noon.prefix(2))
let solarNoonMins = Int(noon.suffix(2))
let offset = (solarNoonHour! - 12) * 60 + solarNoonMins!
return offset
}
}
struct SolarData: Decodable {
struct Phenomenon: Decodable {
enum Kind: String, Decodable {
case
beginCivilTwilight = "BC",
rise = "R",
upperTransit = "U",
set = "S",
endCivilTwilight = "EC",
lowerTransit = "L"
}
var phen: Kind
var time: String
}
let year: Int
let month: Int
let day: Int
let lon: Double
let lat: Double
let tz: Double
let sundata: [Phenomenon]
/// The number of minutes past clock noon at which solar noon occurs.
public var solarNoonOffset: Int {
let noon = sundata
.first { $0.phen == .upperTransit }
.map { $0.time }
let solarNoonHour = Int(noon!.prefix(2))
let solarNoonMins = Int(noon!.suffix(2))
let offset = (solarNoonHour! - 12) * 60 + solarNoonMins!
return offset
}
}
let testJson = """
{
"year":2018,
"month":6,
"day":18,
"lon":-1.000000,
"lat":51.100000,
"tz":1,
"sundata":[
{"phen":"BC", "time":"04:02"},
{"phen":"R", "time":"04:49"},
{"phen":"U", "time":"13:05"},
{"phen":"S", "time":"21:22"},
{"phen":"EC", "time":"22:09"}]
}
"""
let solarData = try JSONDecoder().decode(SolarData.self, from: testJson.data(using: .utf8)!)
print("Solar Noon Offset: \(solarData.solarNoonOffset)")