在各种移动App开发炙手可热的今天,移动数据库即使运用已十分广泛,但其发展却与之形成鲜明对比。数据显示,在过往十年的时间里,数据库创新层出不穷,服务器端数据库数量更是爆发式增长,刨除MySQL、PostgreSQL等老牌数据库,自2007年iPhone面世以来,已有包括Redis、Neo4J、TokuDB等超过30种服务器端数据库技术诞生,然而颇让人诧异的是,其中却无一是专门针对移动平台而设计的,移动端数据库发展呈现出踌躇不前的状态。
为此,由YCombinator孵化的创业团队Realm历时几年开发出了一款能够直接在手机、平板电脑及可穿戴设备上运行的开源移动数据库。不同于常规的服务器端数据库,Realm不仅能让开发者更为快捷地构建应用,还将赋予其极佳的用户体验。而开发者可以直接在自己所开发的iOS应用中使用Realm,存储和查询本地数据。
目前,Realm仅支持iOS平台,并支持Android。现在,开发者可以在Objective-C和Swift中使用它。Realm最大的特点之一就是其易用性极强,数据可以直接作为对象使用,并通过代码查询,而无需再头疼ORM众多坑爹的性能和维护问题。
由于我比较喜欢 swift,所以这个教程就用 swfit 作为主要语言。Real 版本是的Realm Swift 0.93.2
准备工作
第一步当然是到 Github
下载。
配置要求
- APP 系统要求: iOS >= 8, OS X >= 10.9 或者 WatchKit.
- Xcode >= 6.3
- 现在Realm Swift的发行版是服务于Swift 1.2。同时也提供 Swfit 2.0版本,但是在苹果发布最新版本前,需要手动更新。
安装(Swift 1.2)
安装主要有三种方式
动态 Framework
- 下载最先版本的 Realm,并解压压缩包。
- 点击 Xcode 工程“General”设定,拖拽 RealmSwift.framework 和 Realm.framework到“Embedded Binaries”。选择 Copy items if needed并点击确定。
- 在你test target 的“Build Settings”,添加 RealmSwift.framework的上级目录到“Framework Search Paths”中。(目测自动有)。
- 如果你想把Realm用于 IOS 工程,你还要需要在“Build Phases” 中创建“Run Script Phase”。并将
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh"
粘贴到 input 里。(不这样做,会在archive 时引起 bug)。
同时,动态 frameworks只支持 ios8以上。
CocoaPods(我在用的方法)
1.安装CocoaPods 0.37.1 或者更高版本,考虑到有人不知道如何安装。。。
[sudo] gem install cocoapods
2.在你的Podfile中,添加use_frameworks!,并 pod ‘RealmSwift’ 到你的工程中。
3.到控制台中,运行
pod install
4.使用CocoaPods的.xcworkspace 到你的工程中。
Carthage
- 添加github “realm/realm-cocoa” 到你的 Cartfile。
- 运行carthage update。
- iOS:从Carthage/Build/iOS/ 中,拖动RealmSwift.framework和Realm.framework到工程“General”的“Linked Frameworks and Libraries”中。
Mac :从Carthage/Build/Mac/ 中,拖动RealmSwift.framework和Realm.framework到工程“General”的“Embedded Binaries”中。 - iOS: 如果你想把Realm用于 IOS 工程,你还要需要在“Build Phases” 中创建“Run Script Phase”。内容填写:
/usr/local/bin/carthage copy-frameworks
添加frameworks的路径
(SRCROOT)/Carthage/Build/iOS/Realm.framework (SRCROOT)/Carthage/Build/iOS/RealmSwift.framework
(不这样做,会在archive 时引起 bug)。
安装(Swift 2.0)
这个版本一直会更新到年底。
主要有三种安装方式:源码安装,CocoaPods 和 Carthage
源码安转
1.下载源码。
2.在克隆的目录运行,sh build.sh build
3.移除工程已经存在的RealmSwift.framework 和Realm.framework。
4.点击 Xcode 工程“General”设定,拖拽 RealmSwift.framework 和 Realm.framework到“Embedded Binaries”。选择 Copy items if needed并点击确定。
5. 在你test target 的“Build Settings”,添加 RealmSwift.framework的上级目录到“Framework Search Paths”中。
CocoaPods
在 Podfile 中添加
# You need to add both “Realm” & “RealmSwift”
use_frameworks!
pod 'Realm', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'swift-2.0'
pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'swift-2.0'
Carthage
coming soon(官网还没有)。
Realm Browser
在release版本的browser/我们能发现一个数据浏览器,用于查看数据库数据。
测试版本你可以在Tools > Generate demo database中查看例子。
集成Xcode
集成 Xcode 后,可以轻松建立 Realm 的数据对象。
最简单集成方法是通过RealmPlugin下的Alcatraz 实现。
你也可以手动安装,打开 plugin/RealmPlugin.xcodeproj并编译,然后重启Xcode,在新建中查看是否如上图所示。
API 手册
例子
在 Release 包里有,有空我给大家逐个解释一下。
获取帮助
- Attend our monthly Online Office Hours to ask questions or show us your app.
- Reproducible Bugs & Feature Requests should be filed directly against our GitHub repo.
- Discussions & Support: realm-cocoa@googlegroups.com.
- StackOverflow: look for previous questions under the tag #realm — or open a new one.
Sign up for our Community Newsletter to get regular tips, learn about other use-cases and get alerted of blogposts and tutorials about Realm.
模型(model)
Realm 支持Bool, Int8, Int16, Int32, Int64, Double, Float, String, NSDate(精确到秒), and NSData.
关系类型:Object(多对一) 和 List(一对多)。
Realm 的数据模型与 swift 的类很类似。
import RealmSwift
// Dog model
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person? // 可以有可选形
}
// Person model
class Person: Object {
dynamic var name = ""
dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
let dogs = List<Dog>()
}
数据属性
大多数是dynamic var,除了 list 类型。
定制 Models
设置索引键值Object.indexedProperties()
class Book: Object {
dynamic var price = 0
dynamic var title = ""
override static func indexedProperties() -> [String] {
return ["title"]
}
}
设定主键Object.primaryKey()
确保数据唯一,也是更新更有效率
class Person: Object {
dynamic var id = 0
dynamic var name = ""
override static func primaryKey() -> String? {
return "id"
}
}
Object.ignoredProperties() (隐藏属性?)
class Person: Object {
dynamic var tmpID = 0
var name: String { // computed properties are automatically ignored
return "\(firstName) \(lastName)"
}
dynamic var firstName = ""
dynamic var lastName = ""
override static func ignoredProperties() -> [String] {
return ["tmpID"]
}
}