swift 字典轉(zhuǎn)模型框架

import Foundation

@objc protocol DictModelProtocol{

///自定義映射
///
/// :returns: 返回可選映射關(guān)系字典 [屬性名: 自定義對象名稱]
/// :class 替換成 static 是 swift 1.2 修改的
static func customClassMapping() -> [String: String]?

}
///字典轉(zhuǎn)模型工具
class SwiftDictModel {

//單例录粱,全局訪問入口

static let sharedManger = SwiftDictModel()



///  將字典轉(zhuǎn)換成模型對象
///
///  :param: dict 數(shù)據(jù)字典
///  :param: cls  模型類
///
///  :returns: 實(shí)例化的類對象
func objectWithDictionary(dict:NSDictionary,cls:AnyClass) -> AnyObject?{

    //1. 取出模型類的字典
    let dictInfo = fullModelinfo(cls)
    
    //實(shí)例化對象
    var obj:AnyObject = cls.alloc()
    
    //遍歷模型字典房交,有什么屬性就設(shè)置什么屬性
    // k 應(yīng)該 和 dict 中的 key 是一致的
    for (k,v) in dictInfo {
  
        //取出字典中的內(nèi)容
        if let value: AnyObject? = dict[k]{
            
            println("要設(shè)置數(shù)值的 \(value) + key \(k)")
            //判斷是否是自定義類
            //json 反序列化的時(shí)候撒顿,如果是null 值,保存在字典中的事NSNull()
            if v.isEmpty && !(value === NSNull()){
               obj.setValue(value, forKey: k)
                
            }else{
                
                let type = "\(value!.classForCoder)"
                     println("\t自定義對象 \(value) \(k) \(v) ---- type \(type)")
                
                //兩種可能虐急,字典/數(shù)組
                if type == "NSDictionary"{
                    // value 是字典-> 將 value 的字典轉(zhuǎn)換成 Info 的對象
                    if let subObj: AnyObject? = objectWithDictionary(value as! NSDictionary, cls: NSClassFromString(v)){
                    
                        //使用kvc設(shè)置數(shù)值
                        obj.setValue(subObj, forKey: k)
                        
                    }
                    
                    }else if type == "NSArray" {
                    
                        //value 是數(shù)組
                        //如果是數(shù)組如何處理? 遍歷數(shù)組虽风,繼續(xù)處理數(shù)組中的字典
                        if let subObj:AnyObject? = objectWithArray(value as! NSArray, cls: NSClassFromString(v)){
                        obj.setValue(subObj, forKey: k)
                        }
                    
                    }
                
                }
                
            }
            
        
        }
    

    println(dictInfo)
    
    return obj

}

///將數(shù)組轉(zhuǎn)換成模型字典
///
/// :parm: array 數(shù)組的描述
/// : param: cls 模型類
///
/// :returns: 模型數(shù)組

func objectWithArray(array: NSArray, cls: AnyClass) -> [AnyObject]? {

    //創(chuàng)建一個(gè)數(shù)組
    var result = [AnyObject]()
    
    //1.遍歷數(shù)組
    //可能存在什么類型温鸽? 字典/數(shù)組
    for value in array{
    
        let type = "\(value.classForCoder)"
        
        if  type == "NSDictionary"{
        
            if let subObj:AnyObject = objectWithDictionary(value as! NSDictionary, cls: cls){
            
                result.append(subObj)
            
            }
        }else if type == "NSArray"{
         
            if let subObj: AnyObject = objectWithArray(value as! NSArray, cls: cls){
            
                result.append(subObj)
            }
            
        }
    
    }
    
return result

}

/// 緩存字典 格式[類名:模型字典瓤鼻, 類名2:模型字典]
var modelCache = [String:[String:String]]()

/// 獲取模型類的完整信息
/// 
///: parm:cls  模型類
func fullModelinfo(cls:AnyClass)-> [String: String] {

    // 判斷類信息是否已經(jīng)被緩存
    if let cache = modelCache["\(cls)"] {
        println("\(cls)已經(jīng)被緩存")
        return cache
    }
    var currentCls: AnyClass = cls
    
    //模型字典
    var dictInfo = [String:String]()
    
    while let parent:AnyClass = currentCls.superclass(){
    
        //取出并且拼接 currentCls 的模型字典
        dictInfo.merge(modelInfo(currentCls))
        
        currentCls = parent
        println(parent)
    
    }
    // 將模型信息寫入緩存
   modelCache["\(cls)"] = dictInfo
    
    println(dictInfo)
   return dictInfo

}
//獲取給定類的信息
func modelInfo(cls:AnyClass) -> [String: String]{

    // 判斷類信息是否已經(jīng)被緩存
    if let cache = modelCache["\(cls)"] {
        println("\(cls)已經(jīng)被緩存")
        return cache
    }
    
    var mapping: [String:String]?
    if cls.respondsToSelector("customClassMapping"){
    
        println("實(shí)現(xiàn)了協(xié)議")
        
        //調(diào)用協(xié)議方法秉版,獲取自定義對象映射關(guān)系字典
        
        mapping = cls.customClassMapping()
        
        println(mapping)
    }
    //獲取累的屬性
    var count: UInt32 = 0
    
    let ivars = class_copyIvarList(cls, &count)
    
    println("有\(zhòng)(count)屬性")

// // 定義一個(gè)類屬性的字典:[屬性的名字,自定對象的名稱/“”]

    var dictInfo = [String: String]()
    for i in 0..<count {
    
        //檢索數(shù)組下標(biāo)只能茬祷,用Int 
        let ivar = ivars[Int(i)]
        
        //UInt8 = char, c語言的字符串
        let cname = ivar_getName(ivar)
        //將c 語言字符串轉(zhuǎn)換成 swift 的String
        let name = String.fromCString(cname)!
         //println(name)
        let type = mapping?[name] ?? ""
        
        //設(shè)置字典
        dictInfo[name] = type
        
    
    }
    
    free(ivars)
    
    // 將模型信息寫入緩存
    modelCache["\(cls)"] = dictInfo
    return dictInfo
}

}

extension Dictionary{

mutating func merge<K, V>(dict:[K:V]){

    for (k,v) in dict{
    
        //字典的分類法清焕, 如果要使用 updateValue 需要明確的指定類型
        self.updateValue(v as! Value, forKey: k as! Key)
    
    }

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市祭犯,隨后出現(xiàn)的幾起案子秸妥,更是在濱河造成了極大的恐慌,老刑警劉巖沃粗,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粥惧,死亡現(xiàn)場離奇詭異,居然都是意外死亡最盅,警方通過查閱死者的電腦和手機(jī)突雪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涡贱,“玉大人咏删,你說我怎么就攤上這事∥蚀剩” “怎么了督函?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長激挪。 經(jīng)常有香客問我辰狡,道長,這世上最難降的妖魔是什么垄分? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任搓译,我火速辦了婚禮,結(jié)果婚禮上锋喜,老公的妹妹穿的比我還像新娘些己。我一直安慰自己豌鸡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布段标。 她就那樣靜靜地躺著涯冠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逼庞。 梳的紋絲不亂的頭發(fā)上蛇更,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音赛糟,去河邊找鬼派任。 笑死,一個(gè)胖子當(dāng)著我的面吹牛璧南,可吹牛的內(nèi)容都是我干的掌逛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼司倚,長吁一口氣:“原來是場噩夢啊……” “哼豆混!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起动知,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤皿伺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盒粮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸵鸥,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年丹皱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脂男。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡种呐,死狀恐怖宰翅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爽室,我是刑警寧澤汁讼,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站阔墩,受9級特大地震影響嘿架,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啸箫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一耸彪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忘苛,春花似錦蝉娜、人聲如沸唱较。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽南缓。三九已至,卻和暖如春荧呐,著一層夾襖步出監(jiān)牢的瞬間汉形,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工倍阐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留概疆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓峰搪,卻偏偏與公主長得像岔冀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子罢艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,686評論 0 9
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫尽纽、插件咐蚯、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,058評論 4 62
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)弄贿,斷路器春锋,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 1. genuine adj. 真的,真正的差凹;真誠的 2. emergency n. 緊急情況期奔,突發(fā)事件 ...
    單單單單單閱讀 314評論 2 2
  • 精力湯食材:(3人份) 生菜4片 小番茄3個(gè) 芒果1個(gè) 地瓜4片 銀耳1朵(熟)黃豆60克(熟)枸杞10克 葡萄干...
    素之味閱讀 352評論 0 0