![](/img/trans.png)
[英]MongoDB and NodeJS write array of objects from mongodb to a json file
[英]Read from JSON or XML file and write into array of Core Data Objects
并且我创建了一个看起来像下面的JSON结构(相同字段)的核心数据实体(“展示”),然后尝试从JSON文件中读取并写入到一组核心数据对象中。
我有一个本地(存储在Xcode中)JSON文件,其中包含如下所示的数据:
[{
"objectid": 13003,
"lat": 40.198539203831054,
"long": 20.294164128143816,
"adresse": "1 Random Street
"zeitraum": "v. 7-20h",
"stellplatzanzahl": 3
},
{
"objectid": 13004,
"lat": 50.25018761410509,
"long": 30.44382262875748,
"adresse": "2 Random Street",
"zeitraum": "",
"stellplatzanzahl": 6
}]
我在这里浏览了许多教程和文章,但是由于我要么打开一个远程文件和/或不尝试将其存储到Core Data中,但我终生无法使用它。
这是我到目前为止的代码,当我尝试将对象附加到数组时会崩溃。 当.append行被注释时,我可以在控制台中看到它实际上并没有将数据写入“ stand”。
class EventDetails: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var eventMap: MKMapView!
var annotation:MKAnnotation!
var Standarray: [Exstand] = []
var stand:Exstand? = nil
override func viewDidLoad() {
super.viewDidLoad()
do {
let data = NSData(contentsOf: url!)
let jsonData = try JSONDecoder().decode([Nstand].self, from: data! as Data)
for detail in jsonData {
self.stand?.adresse = detail.adresse as String
self.stand?.lat = detail.lat as Double
self.stand?.long = detail.long as Double
self.stand?.stellplatzanzahl = Int16(detail.stellplatzanzahl as Int)
self.stand?.zeitraum = detail.zeitraum as String
print(stand?.adresse)
print("adressen!")
//The line below crashes the app Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Standarray.append(stand!)
}
print("array!")
print(Standarray)
} catch {
print(error) // Handle Error
}
}
}
我还创建了该结构,因为在某些教程中,他们使用了该结构而不是Core Data实体,因此如果更好,我也可以使用它。
struct NStand : Codable{
var objectid: Int
var lat: Double
var long: Double
var adresse: String
var zeitraum: String
var stellplatzanzahl: Int
}
我还将JSON数据保存在XML文件中。 我不在乎从哪里读取它,我想要的只是我的应用程序实际读取和存储数据。
在此先感谢您提供任何有用的建议。
您的json在这里无效
“ adresse”:“随机街1号
至
“ adresse”:“随机街1号”,
应该
[{
"objectid": 13003,
"lat": 40.198539203831054,
"long": 20.294164128143816,
"adresse": "1 Random Street",
"zeitraum": "v. 7-20h",
"stellplatzanzahl": 3
},
{
"objectid": 13004,
"lat": 50.25018761410509,
"long": 30.44382262875748,
"adresse": "2 Random Street",
"zeitraum": "",
"stellplatzanzahl": 6
}
]
struct NStand : Codable{ // for core-data NSManagedObject
let objectid,stellplatzanzahl: Int
let lat,long: Double
let adresse,zeitraum: String
}
let str = """
[{
"objectid": 13003,
"lat": 40.198539203831054,
"long": 20.294164128143816,
"adresse": "1 Random Street",
"zeitraum": "v. 7-20h",
"stellplatzanzahl": 3
},
{
"objectid": 13004,
"lat": 50.25018761410509,
"long": 30.44382262875748,
"adresse": "2 Random Street",
"zeitraum": "",
"stellplatzanzahl": 6
}]
"""
do {
let res = try JSONDecoder().decode([NStand].self, from: Data(str.utf8))
print(res)
}
catch {
print(error)
}
发生错误是因为stand
nil
并且从未创建。
在NSManagedObject
子类中采用(De)codable
有点棘手,因为您必须调用需要托管对象上下文的指定初始化程序。
基于casademora的出色回答 ,首先创建CodingUserInfoKey
和JSONDecoder
的扩展,以便能够传递托管对象上下文。
extension CodingUserInfoKey {
static let context = CodingUserInfoKey(rawValue: "context")!
}
extension JSONDecoder {
convenience init(context: NSManagedObjectContext) {
self.init()
self.userInfo[.context] = context
}
}
然后将CodingKeys
和所需的初始化程序添加到您的NSManagedObject
子类中(在该类中,而不是在扩展名中)。
class Exstand: NSManagedObject, Decodable {
private enum CodingKeys: String, CodingKey { case objectid, lat, long, adresse, zeitraum, stellplatzanzahl }
public required convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("Exstand Error: no managed object context!") }
let entity = NSEntityDescription.entity(forEntityName: "Exstand", in: context)!
self.init(entity: entity, insertInto: context)
let values = try decoder.container(keyedBy: CodingKeys.self)
let objectid = try values.decode(String.self, forKey: .objectid) // do something with objectid
adresse = try values.decode(String.self, forKey: . adresse)
lat = try values.decode(Double.self, forKey: .lat)
long = try values.decode(Double.self, forKey: .long)
zeitraum = try values.decode(String.self, forKey: .zeitraum)
stellplatzanzahl = try values.decode(Int16.self, forKey: .stellplatzanzahl)
}
...
}
这就是您所需要的,现在您可以将JSON直接解码为Core Data
var standArray = [Exstand]()
override func viewDidLoad() {
super.viewDidLoad()
do {
let data = try Data(contentsOf: url!)
let context = // here add the reference to the managed object context
let decoder = JSONDecoder(context: context)
standArray = try decoder.decode([Exstand].self, from: data)
try context.save()
} catch {
print(error) // Handle Error
}
}
不需要其他结构/类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.