Xcode 9.2とSwift 4.を使用しています。返されたjsonデータがnullかどうかを確認するにはどうすればよいですか?エラーType 'Any' has no subscript members
行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
が文字列値を返すのではなく、数値)。
詳細については、「 カスタムタイプのエンコードとデコード 」を参照してください。
余談ですが、私はこのパターンに反対することをお勧めします(これはネットワークリクエストロジックですが、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()
_