我有一个由许多json文件组成的文件夹。例如:
a.json
b.json
c.json
c.json2
c.json3
每个文件都包含我需要插入领域数据库的数据。 a =一种类型的对象,b =另一种类型的对象,c.json1,c.json2和c.json3都是相同类型的对象,但由于内容的数量,它们被分成3个文件。
我没有单独为每种类型的对象创建一个for循环,而是试图创建一个字典,我可以为我的第二个for循环迭代。
var filesToProcess : [String: Object] =
["a.json" : A(), "b.json" : B(), "c.json" : C()]
for (str, obj) in filesToProcess {
let numFiles = FileCounter().getNumFilesStartingWith(filename : str, url : unzippedDestinationUrl)
for i in 0...numFiles {
var append : String = ""
i == 0 ? (append = "") : (append = String(i))
if let jsonData = try? Data(contentsOf: unzippedDestinationUrl.appendingPathComponent(str+append)){
if let array = (try? JSONSerialization.jsonObject(with: jsonData, options: [])) as? [[String: Any]] {
for item in array{
let itemJsonStr = item["data"] as! String
let item = obj(jsonStr : itemJsonStr)
DispatchQueue(label: "background").async {
let realm = try! Realm()
try! realm.write {
realm.add(item)
}
}
}
}
}
}
}
其中A,B和C是这样的对象:
import Foundation
import RealmSwift
import Realm
open class A : Object {
open dynamic var _id : String = ""
open dynamic var prop1 : Int = 0
open dynamic var prop2 : String = ""
open override class func primaryKey() -> String? {
return "_id"
}
required public init() {
super.init()
}
public init(jsonStr: String)
{
if let dataDict = try? JSONSerializer.toDictionary(jsonStr){
self._id = dataDict ["id"] as! String
self.prop1 = dataDict ["prop1"] as! Int
self.prop2 = dataDict ["prop2"] as! String
}
super.init()
}
required public init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
}
然而,在我的for循环中:
let item = obj(jsonStr : itemJsonStr)
我收到错误:
Cannot call value of Non-function type 'Object'
这周围有吗?我试图做的是什么,或者我应该坚持我已经做过的事情,即为每种类型的对象创建重复代码的单独循环?注意A,B和C具有不同的属性,但都是使用json
类型的输入字符串初始化的答案 0 :(得分:1)
obj
是一个对象的实例,你不能这样称呼它。
实现所需内容的一种方法是创建对象的公共超类(例如MyObject
),在那里声明init(jsonStr: String)
并使您的字典成为这样:
var filesToProcess : [String: MyObject] = ["a.json" : A.self, "b.json" : B.self, "c.json" : C.self]
然后你就可以打电话了
obj.init(jsonStr: ...)
创建一个对象。
您可以使用协议实现相同目的。
另一种方法是使用闭包实现它:
var filesToProcess: [(String, (String) -> Object)] = [
("a.json", {json in A(jsonStr: json)}),
("b.json", {json in B(jsonStr: json)}),
("c.json", {json in C(jsonStr: json)})
]
然后obj(jsonStr : itemJsonStr)
实际上会有效。
(注意我使用了一个2元组的数组而不是字典)。
答案 1 :(得分:0)
您可以制作新功能
func parse(jsonStr: String) {
if let dataDict = try? JSONSerializer.toDictionary(jsonStr){
self._id = dataDict ["id"] as! String
self.prop1 = dataDict ["prop1"] as! Int
self.prop2 = dataDict ["prop2"] as! String
}
}
而不是这一行
//let item = obj(jsonStr : itemJsonStr)
你可以这样做
obj.parse(jsonStr: str)
let item = obj