swift语言怎么样Swift字典模型互转总结
现在很多iOS项⽬的开发开始转向Swift语⾔。相信 Swift语⾔很快会成为iOS⼯程师必备技能。字典转模型,模型转转字典在开发过程中扮演⾮常重要的⾓⾊。今天就和⼤家分享⼀下使⽤Swift,如何进⾏字典模型互转。为了让⼯作做到极致,这⾥先提供⼀个⼯具。该⼯具能够使⽤json数据⽣成对应的模型类⽂件,⽀持oc和Swift,⾮常不错。
功能:
1,字典-->模型:最简单的形式
class User: NSObject {  //模型类
var name:String?
var icon:String?
// print时会调⽤。相当于java中的 toString()。为了代码整洁下⾯的模型去了这个计算属性。
override internal var description: String {
return "name: \(name) \n icon:\(icon) \n"
}
}
func func1(){
let dict = ["name":"Jack","icon":"lufy.png"]
if let user = User.objectWithKeyValues(dict) as? User{
print("\(user)")
}
}
输出: name: Optional("Jack")
icon: Optional("lufy.png")
2,字典-->模型:模型中包裹模型
//模型类
class Status :NSObject {
var text:String?
var user:User?        //与 1 中的模型相同
var retweetedStatus:Status?
}
func func2(){
let dict = ["text":"Agree!Nice weather!",
"user":["name":"Jack","icon":"lufy.png"],
"retweetedStatus":["text":"Nice weather!",
"user":["name":"Rose","icon":"nami.png"]]
]
if let status = Status.objectWithKeyValues(dict) as? Status{
print("\(status)")
}
}
输出:
text:Optional("Agree!Nice weather!")
user:Optional(name: Optional("Jack")  icon:Optional("lufy.png"))
retweetedStatus:Optional(text:Optional("Nice weather!")
user:Optional(name: Optional("Rose")icon:Optional("nami.png"))
retweetedStatus:nil)
3,字典-->模型:字典中包裹数组,数组中的元素是⼀个模型对应的字典
//模型类,必须遵守DictModelProtocol协议,并实现customClassMapping⽅法。
class UserGroup: NSObject,DictModelProtocol {
var groupName:String?;            //团队名称
var numbers:NSArray?              //成员,保存User实例
static func customClassMapping() -> [String: String]?{
return ["numbers":"User"];  //指定numbers数组中的元素类型是User
}
}
func func3(){
let dict = ["groupName":"Dream Team",
"numbers":[["name":"Jack","icon":"lufy.png"],
["name":"Rose","icon":"nami.png"]]
]
if let group = UserGroup.objectWithKeyValues(dict){
print("\(group)")
}
}
输出: groupName:Optional("Dream Team")
numbers:Optional((
"name: Optional(\"Jack\") \n icon:Optional(\"lufy.png\") \n",
"name: Optional(\"Rose\") \n icon:Optional(\"nami.png\") \n"
))
4,字典-->模型:将⼀个字典数组转成模型数组func func4(){
let arrayOfStatus = [["text":"Agree!Nice weather!",
"user":["name":"Jack",
"icon":"lufy.png"
],
"retweetedStatus":["text":"Nice weather!",
"user":["name":"Rose",
"icon":"nami.png"
]
]
],
["text":"2___Agree!Nice weather!",
"user":["name":"2___Jack",
"icon":"2___lufy.png"
],
"retweetedStatus":["text":"2___Nice weather!",
"user":["name":"2___Rose",
"icon":"2___nami.png"
]
]
]]
if let status = Status.objectArrayWithKeyValuesArray(arrayOfStatus){
for item in status{ //打印出数组的元素
print(item)
}
}
}
输出:
text:Optional("Agree!Nice weather!")
user:Optional(name: Optional("Jack")icon:Optional("lufy.png"))
retweetedStatus:Optional(text:Optional("Nice weather!")
user:Optional(name: Optional("Rose") icon:Optional("nami.png"))
retweetedStatus:nil
)
text:Optional("2___Agree!Nice weather!")
user:Optional(name: Optional("2___Jack")icon:Optional("2___lufy.png"))
retweetedStatus:Optional(text:Optional("2___Nice weather!")
user:Optional(name: Optional("2___Rose")icon:Optional("2___nami.png"))
retweetedStatus:nil
)
5 模型-->字典:最简单形式
func func5(){
let user = User()
user.name = "hejunm"
user.icon = "my.png"
if let dict = user.keyValues{
do{ //转化为JSON 字符串,打印出来更直观
let data = try NSJSONSerialization.dataWithJSONObject(dict, options: .PrettyPrinted)                print(NSString(data: data, encoding: NSUTF8StringEncoding))
}catch{}
}
}
输出:
Optional({
"icon" : "my.png",
"name" : "hejunm"
})
6 模型-->字典:模型中还有模型
func func6(){
let user = User()
user.name = "retweeted user hejunm"
user.icon = "my.png"
let retweetedStatus = Status();  //转发微博
< = "this is retweeted status";
retweetedStatus.user = user
let oriUser = User()
oriUser.name = "original user"
oriUser.icon = "my.png"
let oriStatus = Status(); //原微博
< = "this is original status"
oriStatus.user = oriUser
let dict =  oriStatus.keyValues
do{ //转化为JSON 字符串
var data = try NSJSONSerialization.dataWithJSONObject(dict!, options: .PrettyPrinted)
print(NSString(data: data, encoding: NSUTF8StringEncoding))
}catch{
}
}
输出:
Optional({
"text" : "this is original status",
"user" : {
"icon" : "my.png",
"name" : "original user"
},
"retweetedStatus" : {
"text" : "this is retweeted status",
"user" : {
"icon" : "my.png",
"name" : "retweeted user hejunm"
}
}
})
7,模型-->字典:模型数组转字典数组
func func7(){
let user1 = User()
user1.name = "hejunm_1"
user1.icon = "my.png_1"
let user2 = User()
user2.name = "hejunm_2"
user2.icon = "my.png_2"
let userArray = [user1,user2] as NSArray
if let dicts = userArray.keyValuesArray{
do{
let data = try NSJSONSerialization.dataWithJSONObject(dicts, options: .PrettyPrinted) //转成json字符串                print(NSString(data: data, encoding: NSUTF8StringEncoding))
}catch{
}
}
}
输出:
Optional([
{
"icon" : "my.png_1",
"name" : "hejunm_1"
},
{
"icon" : "my.png_2",
"name" : "hejunm_2"
}
])
源码
字典-->模型
//
//  HE_Dict2Model.swift
//  HEExtention
//
//  Created by 贺俊孟 on 16/4/27.
//  Copyright © 2016年贺俊孟. All rights reserved.
//  字典传模型
import Foundation
/** 当字典中存在数组,并且数组中保存的值得类型是字典,那么就需要指定数组中的字典对应的类类型。
这⾥以键值对的形式保存
eg 字典如下:
key: [[key1:value1, key2:value2],[key1:value3, key2:value4],[key1:value5, key2:value6]]
key:  key值
value: 字典[key1:value1, key2:value2] 对应的模型
*/
@objc public protocol DictModelProtocol{
static func customClassMapping() -> [String: String]?
}
extension NSObject{
//dict: 要进⾏转换的字典
class func objectWithKeyValues(dict: NSDictionary)->AnyObject?{
if HEFoundation.isClassFromFoundation(self) {
print("只有⾃定义模型类才可以字典转模型")
assert(true)
return nil
}
let obj:AnyObject = self.init()
var cls:AnyClass = self.classForCoder()                                          //当前类的类型
while("NSObject" !=  "\(cls)"){
var count:UInt32 = 0
let properties =  class_copyPropertyList(cls, &count)                        //获取属性列表
for i in 0..<count{
let property = properties[Int(i)]                                        //获取模型中的某⼀个属性
let propertyType = String.fromCString(property_getAttributes(property))!  //属性类型
let propertyKey = String.fromCString(property_getName(property))!        //属性名称
if propertyKey == "description"{ continue  }                              //description是Foundation中的计算型属性,是实例的描述信息
var value:AnyObject! = dict[propertyKey]      //取得字典中的值
if value == nil {continue}
let valueType =  "\(value.classForCoder)"    //字典中保存的值得类型
if valueType == "NSDictionary"{              //1,值是字典。这个字典要对应⼀个⾃定义的模型类并且这个类不是Foundation中定义的类型。                    let subModelStr:String! = Type(propertyType)
if subModelStr == nil{
print("你定义的模型与字典不匹配。字典中的键\(propertyKey)  对应⼀个⾃定义的模型")
assert(true)
}
if let subModelClass = NSClassFromString(subModelStr){
value = subModelClass.objectWithKeyValues(value as! NSDictionary) //递归
}
}else if valueType == "NSArray"{              //值是数组。数组中存放字典。将字典转换成模型。如果协议中没有定义映射关系,就不做处理                    spondsToSelector("customClassMapping") {
if var subModelClassName = cls.customClassMapping()?[propertyKey]{  //⼦模型的类名称
subModelClassName =  HEFoundation.bundlePath+"."+subModelClassName
if let subModelClass = NSClassFromString(subModelClassName){
value = subModelClass.objectArrayWithKeyValuesArray(value as! NSArray);
}
}
}
}
obj.setValue(value, forKey: propertyKey)
}
free(properties)                            //释放内存
cls = cls.superclass()!                    //处理⽗类
}
return obj
}
/**
将字典数组转换成模型数组
array: 要转换的数组, 数组中包含的字典所对应的模型类就是调⽤这个类⽅法的类当数组中嵌套数组,内部的数组包含字典,cls就是内部数组中的字典对应的模型
*/
class func objectArrayWithKeyValuesArray(array: NSArray)->NSArray?{
unt == 0{
return nil
}
var result = [AnyObject]()
for item in array{
let type = "\(item.classForCoder)"
if type == "NSDictionary"{
if let model = objectWithKeyValues(item as! NSDictionary){
result.append(model)
}
}else if type == "NSArray"{
if let model =  objectArrayWithKeyValuesArray(item as! NSArray){
result.append(model)
}
}else{
result.append(item)
}
}
unt==0{
return nil
}else{
return result
}
}
}
模型-->字典
//
/
/  HE_Model2Dict.swift
//  HEExtention
//
//  Created by 贺俊孟 on 16/4/27.
//  Copyright © 2016年贺俊孟. All rights reserved.
//  模型传字典
import Foundation
extension NSObject{
var keyValues:[String:AnyObject]?{                  //获取⼀个模型对应的字典
get{
var result = [String: AnyObject]()          //保存结果
var classType:AnyClass = self.classForCoder
while("NSObject" !=  "\(classType)" ){
var count:UInt32 = 0
let properties = class_copyPropertyList(classType, &count)
for i in 0..<count{
let property = properties[Int(i)]
let propertyKey = String.fromCString(property_getName(property))!        //模型中属性名称                    let propertyType = String.fromCString(property_getAttributes(property))!  //模型中属性类型                    if "description" == propertyKey{ continue }  //描述,不是属性
let tempValue:AnyObject!  = self.valueForKey(propertyKey)
if  tempValue == nil { continue }
if let _ =  Type(propertyType) {        //1,⾃定义的类
result[propertyKey] = tempValue.keyValues
}else if (ainsString("NSArray")){      //2, 数组, 将数组中的模型转成字典                        result[propertyKey] = tempValue.keyValuesArray      //3,基本数据
}else{
result[propertyKey] = tempValue
}
}
free(properties)
classType = classType.superclass()!
}
unt == 0{

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。