Realm 一 使用初步

在开发中尝试了使用Realm作为本地数据库,学习过程中算是一波三折。本次项目使用Swift 开发,过程还算顺畅。废话不说贴代码:

Realm其对代码侵入性很强,Realm要求类继承Object的基类。意味着不能再继承其他自定义的子类。在接入Realm之前整个项目已经基本成型,而主旨是在项目当中添加一个首页数据本地持久化的功能,因此拒绝改变原有模块;同时本着模块化的思想,尽量低耦合另起一个模块来实现此功能后期优点要多。
这是Model类(这里介绍两个界面共用一个Model的情况)
import SwiftyJSON
//这是 model
struct M_Attention {
    var code =  ""
    var id =  ""
    var isDelete =  false
    var name =  ""
    var proposedPrice =  "--"
    var quoteChange =  "--"
    var winery =  ""
    var last_price = "--"
    
    var isFollow = false
    var isSelect = false
    
    var ratio = ""
}
//遵循协议 SP_JsonModel 这在我的实战系列(网络层)中有提到
extension M_Attention:SP_JsonModel {
    init(_ json: JSON) {
        if json.isEmpty{
            return
        }
        code = json["code"].stringValue
        id = json["id"].stringValue
        isDelete = json["is_delete"].boolValue
        name = json["name"].stringValue
        proposedPrice = String(format:"%.2f",json["proposed_price"].doubleValue)
        proposedPrice = proposedPrice.isEmpty ? "--" : proposedPrice
        quoteChange = json["quote_change"].stringValue
        quoteChange = quoteChange.isEmpty ? "--" : quoteChange
        winery = json["winery"].stringValue
        isFollow = json["is_select"].boolValue
        last_price = json["last_price"].stringValue
        last_price = last_price.isEmpty ? "--" : last_price
        ratio = json["ratio"].stringValue
        isSelect = false
    }
}

//另一个页面
struct M_Market {
    var high_ratio = [M_Attention]()
    var low_ratio = [M_Attention]()
}

extension M_Market:SP_JsonModel {
    init(_ json: JSON) {
        if json.isEmpty{
            return
        }
        
        let high_ratioArr = json["high_ratio"].arrayValue
        for item in high_ratioArr {
            let value = M_Attention(item)
            high_ratio.append(value)
        }
        
        let low_ratioArr = json["low_ratio"].arrayValue
        for item in low_ratioArr {
            let value = M_Attention(item)
            low_ratio.append(value)
        }
    }
}

添加 Realm 功能
import RealmSwift
import Realm

/*
 因为已经建立好了模型,
 原则:不改变原有模型设计之上来添加功能,尽量将模块分离.
 */
//总表,这里涉及到不同页面共用同一个 M_Attention,因为使用的是默认表 Realm(),所以这样设计加以区分各页面数据。使用List实现一对多关系。
class M_AttentionRealmS: Object {
    var id = ""
    
    var attentions = List()
    
    var high_ratio = List()
    var low_ratio = List()
    
    override static func primaryKey() -> String? {
        return "id"
    }
}
// M_AttentionRealm 对应 M_Attention
class M_AttentionRealm: Object {
    dynamic var code =  ""
    dynamic var id =  ""
    dynamic var isDelete =  false
    dynamic var name =  ""
    dynamic var proposedPrice =  "--"
    dynamic var quoteChange =  "--"
    dynamic var winery =  ""
    dynamic var last_price = "--"
    
    dynamic var isFollow = false//是否已加自选
    dynamic var isSelect = false
    
    dynamic var ratio = ""
    
    override static func primaryKey() -> String? {
        return "code"
    }
    
    func write(_ model:M_Attention) {
        code = model.code
        id = model.id
        isDelete = model.isDelete
        name = model.name
        proposedPrice = model.proposedPrice
        quoteChange = model.quoteChange
        winery = model.winery
        last_price = model.last_price
        isFollow = model.isFollow
        isSelect = model.isSelect
        ratio = model.ratio
    }
    func read() -> M_Attention {
        return M_Attention(code: code,
                           id: id,
                           isDelete: isDelete,
                           name: name,
                           proposedPrice: proposedPrice,
                           quoteChange: quoteChange,
                           winery: winery,
                           last_price: last_price,
                           isFollow: isFollow,
                           isSelect: isSelect,
                           ratio: ratio)
        
    }
}
写入
fileprivate func t_获取自选列表() {
        
        My_API.t_获取自选列表(page:_pageIndex).post(M_Attention.self) { [weak self](isOk, data, error) in
            self?.sp_EndRefresh()
            if isOk {
                guard let datas = data as? [M_Attention] else{return}
                if self?._pageIndex == 1 {
                    DispatchQueue.global().async {
                        do {
                            let realm = try Realm()
                            let m_AttentionRealmS = M_AttentionRealmS()
                            m_AttentionRealmS.id = "m_AttentionRealm"
                            for item in datas {
                                let m_AttentionRealm = M_AttentionRealm()
                                m_AttentionRealm.write(item)
                                m_AttentionRealmS.attentions.append(m_AttentionRealm)
                            }
                            try realm.write {
                                //写入,根据主键更新
                                realm.add(m_AttentionRealmS, update: true)
                            }
                            //打印出数据库地址
                            //print(realm.configuration.fileURL)
                            DispatchQueue.main.async { _ in}
                        } catch let err {
                            print(err)
                        }
                    }
                }else{
            }else{
            }
        }
    }
另一个页面的数据
fileprivate func t_获取行情数据() {
        My_API.t_获取行情数据.post(M_Market.self) { [weak self](isOk, data, error) in
            self?.sp_EndRefresh()
            if isOk {
                guard let datas = data as? M_Market else{return}
                DispatchQueue.global().async {
                    do {
                        let realm = try Realm()
                        let m_MarketRealm = M_AttentionRealmS()
                        m_MarketRealm.id = "m_MarketRealm"
                        m_MarketRealm.high_ratio.removeAll()
                        m_MarketRealm.low_ratio.removeAll()
                        for item in datas.high_ratio {
                            let m_AttentionRealm = M_AttentionRealm()
                            m_AttentionRealm.write(item)
                            m_MarketRealm.high_ratio.append(m_AttentionRealm)
                        }
                        for item in datas.low_ratio {
                            let m_AttentionRealm = M_AttentionRealm()
                            m_AttentionRealm.write(item)
                            m_MarketRealm.low_ratio.append(m_AttentionRealm)
                        }
                        try realm.write {
                            //写入,根据主键更新
                            realm.add(m_MarketRealm, update: true)
                        }
                        //打印出数据库地址
                        //print(realm.configuration.fileURL)
                        DispatchQueue.main.async { _ in
                        }
                    } catch let err {
                        print(err)
                    }
                }
            }else{}
        }
    }
读取
fileprivate var _datas = [M_Attention]()

fileprivate func makeUI() {
        lab_range_W.constant = sp_fitSize((95,110,125))
        do {
            let realm = try Realm()
            if let theRealms:M_AttentionRealmS = realm.object(ofType: M_AttentionRealmS.self, forPrimaryKey: "m_AttentionRealm") {
                for item in theRealms.attentions {
                    _datas.append(item.read())
                }
            }
        } catch let err {
            print(err)
        }
        makeTableView()
    }
另一个页面的数据
var _datas = M_Market()

fileprivate func makeUI() {
        do {
            let realm = try Realm()
            if let theRealms:M_AttentionRealmS = realm.object(ofType: M_AttentionRealmS.self, forPrimaryKey: "m_MarketRealm") {
                for item in theRealms.high_ratio {
                    self._datas.high_ratio.append(item.read())
                }
                for item in theRealms.low_ratio {
                    self._datas.low_ratio.append(item.read())
                }
            }
        } catch let err {
            print(err)
        }
    }
附:新闻资讯页面
import SwiftyJSON
import RealmSwift
import Realm
//不存在多页面 共享 M_News 
class M_NewsRealm: Object {
// 自建 index ,目的:只保存最新第一页的数据
    dynamic var index = 0
    dynamic var article = ""
    dynamic var href =  ""
    dynamic var title =  ""
    dynamic var text = ""
    dynamic var news_time =  ""
    dynamic var thumb_img =  ""
    dynamic var author = ""
    dynamic var origin = ""
    
    override static func primaryKey() -> String? {
        return "index"
    }
    
    func write(_ model:M_News, _ index:Int) {
        index = index
        article = model.article
        href =  model.href
        title =  model.title
        text = model.text
        news_time =  model.news_time
        thumb_img =  model.thumb_img
        author = model.author
        origin = model.origin
    }
    func read() -> M_News {
        return M_News(article: article,
                      href: href,
                      title: title,
                      text: text,
                      news_time: news_time,
                      thumb_img: thumb_img,
                      author: author,
                      origin: origin)
        
    }
}


struct M_News {
    var article = ""
    var href =  ""
    var title =  ""
    var text = ""
    var news_time =  ""
    var thumb_img =  ""
    var author = ""
    var origin = ""
    var newsYY:String {
        let arr = news_time.components(separatedBy: " ")
        return arr.count > 0 ? arr.first! : "--"
    }
    var newsMM:String {
        let arr = news_time.components(separatedBy: " ")
        return arr.count > 0 ? arr.last! : "--"
    }
}

extension M_News:SP_JsonModel {
    init(_ json: JSON) {
        if json.isEmpty{
            return
        }
        author = json["author"].stringValue
        origin = json["origin"].stringValue
        article = json["article"].stringValue
        href = json["href"].stringValue
        title = json["title"].stringValue
        text = json["text"].stringValue
        news_time = json["news_time"].stringValue
        thumb_img = json["thumb_img"].stringValue
    }
}
//写入
                    DispatchQueue.global().async {
                        do {
                            let realm = try Realm()
                            for (index,item) in datas.enumerated() {
                                let m_AttentionRealm = M_NewsRealm()
                                m_AttentionRealm.write(item, index)
                                try realm.write {
                                    //写入,根据主键更新
                                    realm.add(m_AttentionRealm, update: true)
                                }
                            }
                            //打印出数据库地址
                            //print(realm.configuration.fileURL)
                            DispatchQueue.main.async { _ in }
                            
                        } catch let err {
                            print(err)
                        }
                    }
                 
//读取
        do {
            let realm = try Realm()
            let theRealms:Results = realm.objects(M_NewsRealm.self)
            for item in theRealms {
                _datas.append(item.read())
            }
        } catch let err {
            print(err)
        }

至此,就能正常使用了。当然后期数据当中的属性有变动的时候还需要做数据迁移。这是后话,待续。。。

你可能感兴趣的:(Realm 一 使用初步)