chenzhao

  • java
  • iOS
  • IT
知识积累
不积跬步无以至千里
  1. 首页
  2. iOS
  3. 正文

realm使用笔记

2016年 11月 17日 87点热度 0人点赞 0条评论

准备换数据库realm
环境xcode8.1 swift oc 混编 官方没有太多这样的说明 ,就是用oc 的库导入一个swift文件然后调用吧

文档页面:
https://realm.io/docs/objc/latest/

####1 创建数据库文件,

    /// 创建数据库文件
    ///
    /// - Parameter dataName: dataName 数据库文件名称
    func createRleam(dataName:String){
       let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
        if  FileManager.default.fileExists(atPath: "\(path!)/realm") == false{
          try! FileManager.default.createDirectory(atPath: "\(path!)/realm", withIntermediateDirectories: true, attributes: nil)
        }
        let filePath = path! + "/realm/\(dataName)"
        let config = RLMRealmConfiguration.default()
        config.fileURL = URL(string: filePath)
        config.readOnly = false
        let currentVersion:UInt64 = 1
        config.schemaVersion = currentVersion
        config.migrationBlock = {  (migration,oldSchemaVersion) in
           
            // 数据迁移的block
            if oldSchemaVersion < currentVersion{
             
            }
        }
        
        RLMRealmConfiguration.setDefault(config)
        //获取父级路径, 更改文件保护模式
        let folderPath = RLMRealm.default().configuration.fileURL?.deletingLastPathComponent().path
        Getdevice.println("父级路径\(folderPath)")
        if let folderPath = folderPath{
           try? FileManager.default.setAttributes([FileAttributeKey.protectionKey:FileProtectionType.none], ofItemAtPath: folderPath)
        }

    }

####2 创建 一个数据模型

class RLMHome: RLMObject {
    override init() {
        super.init()
    }
    override init(value: Any) {
         super.init(value: value)
    }
    /// 索引值 一直用0 来创建
    dynamic var index = ""
    dynamic var homedata:Data?
    //设置忽略属性,即不存到realm数据库中
    
    override class func primaryKey()->String{
       return "index"
    }
    //一般来说,属性为nil的话realm会抛出异常,但是如果实现了这个方法的话,就只有name为nil会抛出异常,也就是说现在cover属性可以为空了
    override class func requiredProperties()->Array<String>{
      return ["index"]
    }
    //设置索引,可以加快检索的速度
    override class func indexedProperties()->Array<String>{
        return ["index"]
    }
    //设置属性默认值
//    override class func defaultPropertyValues()->[AnyHashable : Any]?{
//        return ["index":"0","homedata":Data()]
//    }
}

####3 数据的增 或者更新

     let home = RLMHome()
                    home.index = "0"
                    let data = try? json.rawData()
                    home.homedata = data                   let realm = RLMRealm.default()
                        realm.beginWriteTransaction()

// 或者独立的增加add 就好有提示 add 的话 主键肯定不能相同,大家都懂得 
// 这个是更新 根据主键的   
                RLMHome.createOrUpdate(in: realm,withValue: home)
try? realm.commitWriteTransaction()

####4 数据的查询

//查询所有 这个数据查询是没有分页的,因为懒加载,用得时候在读取,所以分页自己分楼
 let homes = RLMHome.allObjects()
                if homes.count>0 && (homes[0] as! RLMHome).homedata != nil{
                    let data = (homes[0] as! RLMHome).homedata
                    let json = JSON(data: data!)
                    if json["code"].intValue == CompleteCode{
                        complete(json)
                        
                        return
                    }

查询遇到的坑, "id == 123" ,id为主键, 查询失败 得id == '123' , 在另外一个地方非主键查询得不嫁单引号,

数据更新和结构问题

self.downDataCompleteArray = RLMDownloads.objects(where: "downStatus == 1") as! RLMResults<RLMDownloads>

结构 RLMResults<自定义>
类似数组但是不是数组, 如果用他来更新ui 或者说realm数据库更新ui 都得用他们的消息机制,接收到更改刷新ui
比如我的

self.RLMNotificationTokenReadun =  self.downDataUnderwayArray.addNotificationBlock { [weak self] (results:RLMResults<RLMDownloads>?, change:RLMCollectionChange? , error) in
            if change != nil{
               self?.underwayTableView.reloadData()
            }
        }

deinit 的时候self.RLMNotificationTokenReadun.stop()一下

可以说方便了,但是和原有项目数据结构相差还是比较大得

遇到的小问题 1:
数据更新问题, 开始整体更新

    home = RLMHome()
                    home.index = "0"
                   // home.adData = nil
                     home.homedata = data
                     DispatchQueue(label: "rleam").async {
                         let realm = RLMRealm.default()
                         realm.beginWriteTransaction()
                         //realm.addOrUpdate(home)
                         RLMHome.createOrUpdate(in: realm,withValue: home)
                         try? realm.commitWriteTransaction()
                     }
                 }

没问题 ,后来准备局部更新 , 发现这样方式失败 , 就算查询出来更改同样崩溃 后来发现api 上有个更新

let realm = RLMRealm.default()
                     try? realm.transaction{ () in
                         home.homedata = data
                     }
标签: 暂无
最后更新:2022年 11月 11日

陈昭

IT 程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2022 chenzhao. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang