Opendata を使用してアプリケーションを作成しようとしています。これは私の JSON データです: http://datatank.stad.gent/4/infrastructuur/publieksanitair
私が抱えている問題は、この JSON ファイルを解析する方法がわからないことです。「データにルート オブジェクトが含まれていません」というメッセージが常に表示されます。
したがって、 Service.swift ファイルで問題が発生します。デバッグ時にデータが返されるのを見るので、リクエストが機能すると確信していますが、それを処理する方法がわかりません。
私のプロジェクトはhttps://github.com/StijnPil/iOSProjectShared/tree/developから取得できます。
ただし、重要なコードも以下に示します。
Service.swift
import Foundation
class Service
{
enum Error: ErrorType
{
case InvalidJsonData(message: String?)
case MissingJsonProperty(name: String)
case MissingResponseData
case NetworkError(message: String?)
case UnexpectedStatusCode(code: Int)
}
static let sharedService = Service()
private let url: NSURL
private let session: NSURLSession
private init() {
let path = NSBundle.mainBundle().pathForResource("Properties", ofType: "plist")!
let properties = NSDictionary(contentsOfFile: path)!
url = NSURL(string: properties["baseUrl"] as! String)!
session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration())
}
func createFetchTask(completionHandler: Result<[PubliekSanitair]> -> Void) -> NSURLSessionTask {
return session.dataTaskWithURL(url) {
data, response, error in
let completionHandler: Result<[PubliekSanitair]> -> Void = {
result in
dispatch_async(dispatch_get_main_queue()) {
completionHandler(result)
}
}
guard let response = response as? NSHTTPURLResponse else {
completionHandler(.Failure(.NetworkError(message: error?.description)))
return
}
guard response.statusCode == 200 else {
completionHandler(.Failure(.UnexpectedStatusCode(code: response.statusCode)))
return
}
guard let data = data else {
completionHandler(.Failure(.MissingResponseData))
return
}
do {
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as? [NSDictionary] else {
completionHandler(.Failure(.InvalidJsonData(message: "Data does not contain a root object.")))
return
}
//old code
//let lots = try json.filter { $0["city"]?["name"] as? String == "Gent" }.map { try ParkingLot(json: $0) }
//new code
let lots = try json.map{ try PubliekSanitair(json: $0)}
completionHandler(.Success(lots))
} catch let error as Error {
completionHandler(.Failure(error))
} catch let error as NSError {
completionHandler(.Failure(.InvalidJsonData(message: error.description)))
}
}
}
}
結果.swift
enum Result<T>
{
case Success(T)
case Failure(Service.Error)
}
PubliekSanitair.swift
import Foundation
class PubliekSanitair
{
let type_sanit: String
init(type_sanit: String){
self.type_sanit = type_sanit
}
}
extension PubliekSanitair
{
convenience init(json: NSDictionary) throws {
guard let document = json["Document"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Document")
}
guard let folder = document["Folder"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Folder")
}
guard let placemark = folder["Placemark"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Placemark")
}
guard let extendedData = placemark["ExtendedData"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Placemark")
}
guard let schemaData = extendedData["SchemaData"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Placemark")
}
guard let simpleData = schemaData["SimpleData"] as? NSDictionary else{
throw Service.Error.MissingJsonProperty(name: "Placemark")
}
guard let type_sanit = simpleData[0]!["@text"] as? String else{
throw Service.Error.MissingJsonProperty(name: "@text in type_sanit")
}
self.init(type_sanit: type_sanit)
}
}