Deserialize JSON / NSDictionary to Swift objects 将JSON 或Dic转为类对象

三篇参考文章: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的值,要将它加上!不能为空。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值