三篇参考文章:http://stackoverflow.com/questions/24310324/deserialize-json-nsdictionary-to-swift-objects,
http://swift.oz-apps.com/2015/04/creating-a-class-from-a-string-in-swift/
https://ijoshsmith.com/2014/06/05/instantiating-classes-by-name-in-swift/
swift不支持动态类初始化,这样就不能将获取到的JSON或字典转为对象。没有了对象,我们队数据的操作就只能通过valueForKey,no,这是绝对不行的。
要想对类进行动态初始化,
最简单的方式,在类中加入关键字:@(类名)
@objc(Level)
class Level: NSObject {
var backGroundMusic:String?
var backGroundImageUrl:String?
var level:NSNumber?
var numberOfBalls:NSNumber?
var numberOfDrops:NSNumber?
var fallingSpeed:NSNumber?
var scoreGoal:NSNumber?
}
//
// LevelResponse.swift
// DropProjectsGame
//
// Created by lin kang on 17/1/23.
// Copyright © 2017年 lin kang. All rights reserved.
//
import UIKit
@objc(LevelResponse)
class LevelResponse: NSObject {
var results:[Level]?
}
这样就可以使用 NSClassFromString(),方法获得类,并初始化。不然其值为空。
这是我的读取字典,并转换为对象的方法:
这里上一次我忽略了类中包含类属性,类中包含数组等可能性,这个需要用递归的方法将其全部迭代找完。
今天重新修改了一下
//
// Dictionary Extention.swift
// DropProjectsGame
//
// Created by lin kang on 17/1/22.
// Copyright © 2017年 lin kang. All rights reserved.
//
import UIKit
let classNameKey = "className"
extension NSDictionary{
static func decodeDic(dicOrigin:[String:AnyObject])->AnyObject?{
if let className:String = (dicOrigin[classNameKey] as? String){
// print("xx:\(NSClassFromString(className) as? NSObject.Type)")
if let classType = (NSClassFromString(className) as? NSObject.Type){
//获取类实例
let instance = classType.init()
let keys = dicOrigin.keys;
for var key in keys
{
if key != classNameKey {
var value = dicOrigin[key];
//是数组,那么进行数组处理
if (value is NSArray) {
value = handleArray(originArray: value as! NSArray)
//是字典,那么是类,进行类处理
}else if (value is NSDictionary ){
value = decodeDic(dicOrigin: value as! [String : AnyObject]) as AnyObject?
}
//类属性赋值
if instance.responds(to: NSSelectorFromString(key)) {
instance.setValue(value, forKey: key )
}
}
}
return instance ;
}else{
print("\(className)没有此类型")
}
}
return nil
}
static func handleArray(originArray:NSArray)->NSArray{
var arrayResult = [AnyObject]()
for item in originArray{
var value = item
//是数组继续迭代
if item is NSArray {
value = handleArray(originArray: item as! NSArray)
}else if item is [String:AnyObject] {
//是字典转为类的处理
value = NSDictionary.decodeDic(dicOrigin: item as! [String:AnyObject]) as AnyObject!
}
//其他类型则加入数组
arrayResult.append(value as AnyObject)
}
return arrayResult as NSArray
}
}
规则前提,字典代表类,必须传入className字符串,缺点是每个字典都要传入类名。
只需调用方法 decodeDic()即可转为className中的类实例,以后有更好的转换方法,我将继续优化。这是我本地Plist种的数据:
在写这个代码时,真是被?optional 和 !给整烦了,
一点点经验:如果报错:unwrap optional,那说明你在使用一个optional的值,要将它加上!不能为空。