带协议的动态初始化程序

时间:2017-04-06 07:56:14

标签: ios swift alamofire swifty-json

我正在使用AlamofireSwiftyJSON。我想为常见情况构建一般请求和解析模型。首先,我制定了一个名为JSONConvertible的协议。

protocol JSONConvertible {
    init?(json: JSON)
}

其次,我在Request中扩展了Alamofire类。

extension Request {

    func getResult(format: [String: AnyClass]) {
        self.responseJSON { (response) in
            guard let statusCode = response.response?.statusCode else {
                return
            }
            switch statusCode {
            case 200:
                var result = [String: AnyObject]()
                let json = JSON(rawValue: response.result.value!)!
                for (key, className) in format {
                    if className.self is JSONConvertible {
                        let value = className.self(json: json[key]) // get error in this line
                    }
                }
            case 201..<400:
                break
            case 400...Int.max:
                break
            default:
                break
            }

        }
    }   
}

但是我收到编译器的错误。因为AnyObject只是协议而且没有这个初始化程序。我不想只获得字典或数组。我想获得具体类的实例。请帮我。非常感谢!

2 个答案:

答案 0 :(得分:1)

那是因为在if内,className.self的类型仍为AnyObject。您需要将其强制转换为JSONConvertible,然后才能使用初始化程序。

if let concreteClass = className.self as? JSONConvertible.Type 
{
   let value = concreteClass.init(json: json[key])
}

如果您熟悉kotlin,则在测试if子句中的类型时,swift不会自动进行强制转换。

答案 1 :(得分:0)

我找到了解决这个问题的另一种方法。定义新协议。

protocol JSONConvertibleObject: AnyObject, JSONConvertible {

}

而是使用它。

extension Request {

    func getResult(format: [String: JSONConvertibleObject]) {
        self.responseJSON { (response) in
            guard let statusCode = response.response?.statusCode else {
                return
            }
            switch statusCode {
            case 200:
                var result = [String: AnyObject]()
                let json = JSON(rawValue: response.result.value!)!
                for (key, className) in format {
                    let value = className.self.dynamicType.init(json: json[key])
                }
            case 201..<400:
                break
            case 400...Int.max:
                break
            default:
                break
            }

        }
    }   
}