Swift 遍历字符串字典、customObject并调用customObject初始化器

Swift 遍历字符串字典、customObject并调用customObject初始化器,swift,string,loops,object,dictionary,Swift,String,Loops,Object,Dictionary,我有一个由许多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.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类型的输入字符串初始化的。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元组数组而不是字典)。

您可以创建一个新函数

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