我正在使用 Xcode 9.2 和 Swift 4。如何检查返回的 json 数据是否为空?
现在它给我错误 Type 'Any' has no subscript members
at line if json[0]["data"]
var json: NSMutableArray = []
var newsArray: NSMutableArray = []
let url = URLFactory()
var data = try! NSData(contentsOf: url.getURL()) as Data
do {
json = try JSONSerialization.jsonObject(with: data, options: []) as! NSMutableArray
if json[0]["data"] {
// data is not null
}
} catch let error as NSError {
// handle error
}
我的 JSON 返回如下内容:
{
"data":
[
{
"news_id":123,
"title":"title",
"news_date":"2017-02-08 21:46:06",
"news_url":"url",
"short_description":"description",
"category_id":4,
"category_name":"Health",
"latlng":
[
{
"lat":"43.003429",
"lng":"-78.696335"
}
]
}
{ ....
}
最佳答案
如果你使用的是 Swift 4,我可能会建议 JSONDecoder
:
首先,定义保存解析数据的类型:
struct ResponseObject: Codable {
let data: [NewsItem]
}
struct NewsItem: Codable {
let newsId: Int
let title: String
let newsDate: Date
let newsURL: URL
let shortDescription: String
let categoryID: Int
let categoryName: String
let coordinates: [Coordinate]
// because your json keys don't follow normal Swift naming convention, use CodingKeys to map these property names to JSON keys
enum CodingKeys: String, CodingKey {
case newsId = "news_id"
case title
case newsDate = "news_date"
case newsURL = "news_url"
case shortDescription = "short_description"
case categoryID = "category_id"
case categoryName = "category_name"
case coordinates = "latlng"
}
}
struct Coordinate: Codable {
let lat: String
let lng: String
}
然后你可以解析它:
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
do {
let responseObject = try decoder.decode(ResponseObject.self, from: data)
print(responseObject.data)
} catch {
print(error)
}
显然,如果您的 JSON 不同,您可能需要相应地更改您的对象(例如,令我感到奇怪的是 latlng
是一个坐标数组)。此外,如果您想将其中一些字符串转换为数字,您可以定义自定义 init(from:)
方法,但我宁愿修复 JSON,而不是(为什么 latlng
返回字符串值而不是数值)。
有关详细信息,请参阅 Encoding and Decoding Custom Types .
顺便说一句,我建议不要使用这种模式(请注意,这是您的网络请求逻辑,但已删除 NSData
):
let data = try! Data(contentsOf: url.getURL())
这将同步检索数据,这可能会有问题,因为
- 在检索数据时应用程序将被卡住,从而导致糟糕的用户体验;
- 您的应用可能会被寻找卡住应用的看门狗进程杀死;和
- 你没有强大的错误处理,如果网络请求失败,这将崩溃。
我建议使用 URLSession
:
let task = URLSession.shared.dataTask(with: url.getURL()) { data, _, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
// now parse `data` like shown above
// if you then need to update UI or model objects, dispatch that back
// to the main queue:
DispatchQueue.main.async {
// use `responseObject.data` to update model objects and/or UI here
}
}
task.resume()
关于json - Swift 4 JSONSerialization.jsonObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48130993/