Realm Swift

Realm Swift

version 0.98.7

官方文档

参考文献

Realm支持类型

  • String,NSString
  • Int
  • Int8,Int16,Int32,Int64
  • Float
  • Double
  • Bool
  • NSData
  • NSDate
  • RealmOptional
  • Object
  • List

Realm Object

Model Properties

属性声明方式

Class => T:Object

Type Non-optional Optional
声明类型 非可选类型声明方式 可选类型声明方式
Bool dynamic var value = false let value = RealmOptional()
Int dynamic var value = 0 let value = RealmOptional()
Float dynamic var value:Float = 0.0 let value = RealmOptional()
Double dynamic var value:Double = 0 let value = RealmOptional()
String dynamic var value = “” dynamic var value: String? = nil
Data dynamic var value = Data() dynamic var value: NSData? = nil
Date dynamic var value = Date() dynamic var value: Date? = nil
Object n/a: must be optional dynamic var value: Class?
List let value = List n/a: must be non-optional
注意事项:
  • Object只能声明成可选类型.
  • List和RealmOptional只能声明成非可选类型.
  • 使用var修饰变量,必须要使用dynamic.具体原因请查照)

Relationships

一对一(To-One Relationships)

class Dog: Object {
    // ... other property declarations
    dynamic var owner: Person? // to-one relationships must be optional
}

一对多(To-Many Relationships)

class Person: Object {
    // ... other property declarations
    let dogs = List<Dog>()
}

反向链接(Inverse Relationships / backlink)

class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0
    var owners: [Person] {
        // Realm 并不会存储这个属性,因为这个属性只定义了 getter
        // 定义“owners”,和 Person.dogs 建立反向关系
        return linkingObjects(Person.self, forProperty: "dogs")
    }
}

Indexed Properties

添加索引属性,加快查询速度.

class Book: Object {
  dynamic var price = 0
  dynamic var title = ""

  override static func indexedProperties() -> [String] {
    return ["title"]
  }
}

索引支持类型

  • strings
  • integers
  • booleans
  • NSDate
注意事项

Indexing a property will greatly speed up queries where the property is compared for equality (i.e. the = and IN operators), at the cost of slower insertions.

使用索引增加查询速度的代价是插入数据时速度会降低

Auto-Updating Objects

顾名思义当一个数据的内容改变时,它会自动更新该数据的所有实例化对象

let myDog = Dog()
myDog.name = "Fido"
myDog.age = 1

try! realm.write {
  realm.add(myDog)
}

let myPuppy = realm.objects(Dog).filter("age == 1").first
try! realm.write {
  myPuppy!.age = 2
}

print("age of my dog: \(myDog.age)") // => 2

当数据变化,需要更新界面时,需要配合 [Realm notifications](#Realm notifications) 或 [key-value observation](#key-value observation)实现,后续会详细描述这2个功能

Primary Keys

声明主键之后,对象将被允许查询,更新速度更加高效,并且要求每个对象保持唯一性。

一旦带有主键的对象被添加到 Realm 之后,该对象的主键将不可修改。

class Person: Object {
  dynamic var id = 0
  dynamic var name = ""

  override static func primaryKey() -> String? {
    return "id"
  }
}

Ignored Properties

重写 Object.ignoredProperties() 可以防止 Realm 存储数据模型的某个属性。Realm 将不会干涉这些属性的常规操作,它们将由成员变量(ivar)提供支持,并且您能够轻易重写它们的 setter 和 getter。

class Person: Object {
  dynamic var tmpID = 0
  var name: String { // read-only properties are automatically ignored
    return "\(firstName) \(lastName)"
  }
  dynamic var firstName = ""
  dynamic var lastName = ""

  override static func ignoredProperties() -> [String] {
    return ["tmpID"]
  }
}

Writes

所有写入操作(添加,修改,删除)都必须依托一个write transaction.

由于write transaction会占用一定的资源,所以尽量精简write transaction的个数.当队列写入时,只需要一个就write transaction

Creating Objects

数据赋值方式:

// (1) Create a Dog object and then set its properties
var myDog = Dog()
myDog.name = "Rex"
myDog.age = 10

// (2) Create a Dog object from a dictionary
let myOtherDog = Dog(value: ["name" : "Pluto", "age": 3])

// (3) Create a Dog object from an array
let myThirdDog = Dog(value: ["Fido", 5])

Nested Objects

嵌套赋值方式:

// Instead of using already existing dogs...
let aPerson = Person(value: ["Jane", 30, [aDog, anotherDog]])

// ...we can create them inline
let anotherPerson = Person(value: ["Jane", 30, [["Buster", 5], ["Buddy", 6]]])

Adding Objects

write操作是阻塞操作,如果有一个写操作,那么其他线程的write操作都会被阻塞.

最好是将write操作放在一个单独的线程中.

// Create a Person object
let author = Person()
author.name = "David Foster Wallace"

// Get the default Realm
let realm = try! Realm()
// You only need to do this once (per thread)

// Add to the Realm inside a transaction
try! realm.write {
  realm.add(author)
}

Updating Objects

Typed Updates

// Update an object with a transaction
try! realm.write {
  author.name = "Thomas Pynchon"
}

Creating and Updating Objects With Primary Keys

update:true Object必须具有PrimaryKeys.否则会报错.

// Creating a book with the same primary key as a previously saved book
let cheeseBook = Book()
cheeseBook.title = "Cheese recipes"
cheeseBook.price = 9000
cheeseBook.id = 1

// Updating book with id = 1
try! realm.write {
  realm.add(cheeseBook, update: true)
}

// Assuming a "Book" with a primary key of `1` already exists.
try! realm.write {
  realm.create(Book.self, value: ["id": 1, "price": 9000.0], update: true)
  // the book‘s `title` property will remain unchanged.
}

Key-Value Coding

let persons = realm.objects(Person)
try! realm.write {
  persons.first?.setValue(true, forKeyPath: "isFirst")
  // set each person‘s planet property to "Earth"
  persons.setValue("Earth", forKeyPath: "planet")
}

Deleting Objects

// let cheeseBook = ... Book stored in Realm
try! realm.write {
// Delete an object with a transaction
  realm.delete(cheeseBook)

  realm.delete(List<T:Object>)

  realm.delete(Results<T:Object>)

  // Delete all objects from the realm
  realm.deleteAll()
}

Queries

通过查询操作,Realm 将会返回包含 Object 集合的Results实例。Results 的表现和 Array 十分相似,并且包含在 Results 中的对象能够通过索引下标进行访问。

所有的查询(包括查询和属性访问)在 Realm 中都是延迟加载的,只有当属性被访问时,才能够读取相应的数据。也就是说当没有使用数据前,进行多次排序或者过滤都是不需要额外cpu时间的

查询结构不是Copy对象,而是引用对象.所以在Write操作中修改查询数据,是直接修改数据库中的数据.

基本查询语句

let dogs = realm.objects(Dog) // retrieves all Dogs from the default Realm

Filtering

条件查询

类似NSPredicate,同时支持NSPredicate.

// Query using a predicate string
var tanDogs = realm.objects(Dog).filter("color = ‘tan‘ AND name BEGINSWITH ‘B‘")

// Query using an NSPredicate
let predicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "tan", "B")
tanDogs = realm.objects(Dog).filter(predicate)

var tanDogs = realm.objects(Dog).filter("color = ‘tan‘").filter("name BEGINSWITH ‘B‘")

支持的断言类型

  • 比较操作数(comparison operand)可以是属性名称或者某个常量,但至少有一个操作数必须是属性名称;
  • 比较操作符 ==、<=、<、>=、>、!=, 以及 BETWEEN 支持 int、long、long long、float、double 以及 NSDate 属性类型的比较,比如说 age == 45
  • 相等比较 ==以及!=,比如说Results().filter(“company == %@”, company)
  • 比较操作符 == and != 支持布尔属性
  • 对于 NSString 和 NSData 属性来说,我们支持 ==、!=、BEGINSWITH、CONTAINS 以及 ENDSWITH 操作符,比如说 name CONTAINS ‘Ja’
  • 字符串支持忽略大小写的比较方式,比如说 name CONTAINS[c] ‘Ja’ ,注意到其中字符的大小写将被忽略
  • **Realm 支持以下复合操作符:“AND”、“OR” 以及 “NOT”。比如说 name BEGINSWITH ‘J’ AND age >= 32;

    包含操作符 IN,比如说 name IN {‘Lisa’, ‘Spike’, ‘Hachi’}**

  • ==、!=支持与 nil 比较,比如说 Results().filter(“ceo == nil”)。注意到这只适用于有关系的对象,这里 ceo 是 Company 模型的一个属性
  • ANY 比较,比如说 ANY student.age < 21
  • 支持复合表达式类型@count, @min, @max, @sum and @avg.例如realm.objects(Company).filter(“[email protected] > 5”)
  • 子查询有如下限制
    • @count is the only operator that may be applied to the SUBQUERY expression
    • The SUBQUERY(…)[email protected] expression must be compared with a constant
    • Correlated subqueries are not yet supported

Sorting

// Sort tan dogs with names starting with "B" by name
let sortedDogs = realm.objects(Dog).filter("color = ‘tan‘ AND name BEGINSWITH ‘B‘").sorted("name")

//倒序
let sortedDogs = realm.objects(Dog).filter("color = ‘tan‘ AND name BEGINSWITH ‘B‘").sorted("name" , ascending:false)

Auto-Updating Results

结果会自动更新

let puppies = realm.objects(Dog).filter("age < 2")
puppies.count // => 0
try! realm.write {
  realm.create(Dog.self, value: ["name": "Fido", "age": 1])
}
puppies.count // => 1

Limiting Results

// Loop through the first 5 Dog objects
// restricting the number of objects read from disk
let dogs = try! Realm().objects(Dog)
for i in 0..<5 {
  let dog = dogs[i]
  // ...
}

Realms

Realm Configuration

Realm.Configuration.defaultConfiguration = config.直接设置默认配置

假设需要快速切换账户,可以使用一下代码

func setDefaultRealmForUser(username: String) {
  var config = Realm.Configuration()

  // Use the default directory, but replace the filename with the username
  config.path = NSURL.fileURLWithPath(config.path!)
                  .URLByDeletingLastPathComponent?
                  .URLByAppendingPathComponent("\(username).realm")
                  .path

  // Set this as the configuration used for the default Realm
  Realm.Configuration.defaultConfiguration = config
}

Other Realms

指定BundleData中的Realm

let config = Realm.Configuration(
    // Get the path to the bundled file
    path: NSBundle.mainBundle().pathForResource("MyBundledData", ofType:"realm"),
    // Open the file in read-only mode as application bundles are not writeable
    readOnly: true)

// Open the Realm with the configuration
let realm = try! Realm(configuration: config)

// Read some data from the bundled Realm
let results = realm.objects(Dog).filter("age > 5")

注意

如果是初始化一个Realm,指定的路径必须是可写的

In-Memory Realms

内存中的Realms,没有保存在磁盘上.

优点:可以快速的访问数据,而不需要考虑数据持久化的性能开销.内存Realms只会在temp路径里存放几个文件,用来进行线程间数据同步,不会将Realms中任何数据写入磁盘中

注意

由于ARC的原因,内存Realms创建的数据必须要有一个强引用,否则会被回收

Error Handling

错误只会发生在第一次创建Realms.如果Realms已经创建,以后不会发生错误.

do {
  let realm = try Realm()
} catch let error as NSError {
  // handle error
}

Copying Objects Between Realms

数据拷贝只能是不同Realms都在同一线程中创建的,否则无法实现数据拷贝

realm.create(MyObjectSubclass.self, value: originalObjectInstance)

Auxiliary Realm Files

Realms内部处理的辅助文件,对于使用者来说,就是汇报bug的时候,需要一并提交这些文件

  • .realm.lock - A lock file for resource locks.
  • .realm.log_a, .realm.log_b - Log files for transaction logs.
  • .realm.note - A named pipe for notifications.

Class Subsets

Realms可以配置只保存特定的Class,除指定的Class外,其他Class一律不存储.

let config = Realm.Configuration(objectTypes: [MyClass.self, MyOtherClass.self])
let realm = try! Realm(configuration: config)

Deleting Realm Files

删除本地Realm

Realm在使用的时候,都是强引用,如果需要的话,就用autoreleasepool来包含

如果使用强引用,直接删除也不会有什么影响

autoreleasepool {
  // all Realm usage here
}
let manager = NSFileManager.defaultManager()
let realmPath = Realm.Configuration.defaultConfiguration.path as! NSString
let realmPaths = [
  realmPath as String,
  realmPath.stringByAppendingPathExtension("lock")!,
  realmPath.stringByAppendingPathExtension("log_a")!,
  realmPath.stringByAppendingPathExtension("log_b")!,
  realmPath.stringByAppendingPathExtension("note")!
]
for path in realmPaths {
  do {
    try manager.removeItemAtPath(path)
  } catch {
    // handle error
  }
}

Using Realm with Background App Refresh

这章主要是说如何使用IOS本地加密,详情查看官方文档.

Threading

这一章主要是讲多线程开发,大量写入事务最好是放在其他线程中,以防止UI线程被阻塞

只在一个线程中处理所有事情,不需要担心并发和多线程.(然并卵的话)

Realm在多线程处理上不需要使用线程锁,只需要注意写入操作需要在Write事件中.

Realm为了更好的支持多线程处理,它为每个线程都创建了一个视图(SQL中的视图概念??).由于每个线程都有自己的snapshots,导致线程之间同步问题.

唯一需要记住的是:你不能在多个线程之间共享同一个Realm对象.如果这样的话,就会导致一个线程上修改了数据,其他线程无法同步数据.

Seeing Changes From Other Threads

在UI线程或者其他添加Runloop的线程上,Realm都会自动更新其他线程Runloop的操作结果.(这里是说其他线程有更新,UI线程或Runloop线程都不会更新数据)

在其他类型的线程上操作,都是基于Snapshots.

所以最好的处理方法是,保存唯一的一个视图,这样就不用担心多线程并发的问题.

UI线程或者其他添加Runloop的线程上,数据都会自动刷新,除非将Realm.autorefresh设置为NO

其他类型的线程,都是以最后一次修改成功的Realm为snapshot,除非是手动refresh

Realm.commitWrite后,Realm会刷新一次

最好是不要经常性的手动调用refresh(),当你正在刷新,其他线程有其他事务进行处理时,会导致数据”pinned”,进而增大Realm在磁盘上的空间

```

###Passing Instances Across Threads
继承于NSObject的类,是可以在线程之间传递的.<BR>
继承于Realm, Object, Results, or List的类,是无法在线程之间传递的.否则会引起崩溃.<BR>
多线程之间传递数据的解决方案:<BR>

* Object:可以通过primary key来实现.
* Results:可以filter或者NSPredicate来实现.

**Realm一些可以多线程操作的属性和方法,如下**

* Realm: all properties, class methods, and initializers.
* Object: invalidated, objectSchema, realm, class methods, and initializers.
* Results: objectClassName and realm.
* List: invalidated, objectClassName, and realm.

###Using a Realm Across Threads
**想要在不同线程中,访问同一个Realm文件,就必须要在各自线程中获取相同配置的Realm实例.就是重新调用Realm.realm().**<BR>

let queue = dispatch_queue_create(“test”, DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue) {

autoreleasepool {

// Get realm and table instances for this thread

let realm = try! Realm()

// Break up the writing blocks into smaller portions
// by starting a new transaction
for idx1 in 0..<1000 {
  realm.beginWrite()

  // Add row via dictionary. Property order is ignored.
  for idx2 in 0..<1000 {
    realm.create(Person.self, value: [
      "name": "\(idx1)",
      "birthdate": NSDate(timeIntervalSince1970: NSTimeInterval(idx2))
    ])
  }

  // Commit the write transaction
  // to make this data available to other threads
  try! realm.commitWrite()
}

}

}


##JSON
不支持json数据直接导入,但是支持 NSJSONSerialization.JSONObjectWithData(_:options:)转换的导入.<BR>

// A Realm Object that represents a city

class City: Object {

dynamic var city = “”

dynamic var id = 0

// other properties left out …

}

// Insert from NSData containing JSON

try! realm.write {

let json = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())

realm.create(City.self, value: json, update: true)

}


######注意事项
* float properties should be initialized with float-backed NSNumbers(float类型需要使用NSNumber来声明)* * * * * * * *
* NSDate and NSData properties cannot be automatically inferred from strings, but should be converted to the appropriate type before passing to Realm().create(_:value:update:).(**没理解**)
* If a JSON null (i.e. NSNull) is supplied for a required property, an exception will be thrown.(如果一个json对象为null,会抛出异常)
* If no property is supplied on insert for a required property, an exception will be thrown.(如果一个声明属性,没有对应的值,会抛出异常)
* Realm will ignore any properties in the JSON not defined by the Object.(当Json对象中有Object没有声明变量,会忽略)

##Notifications
多线程中对特定数据有修改时,会发送Notifications.<BR>
**需要注意的是,addNotificationBlock返回的Token是必须要被强引用的,否则无法回调**<BR>
支持的调用方式:

* Realm.addNotificationBlock(_:)
* AnyRealmCollection.addNotificationBlock(_:)
* Results.addNotificationBlock(_:)
* List.addNotificationBlock(_:)
* NotificationToken.stop()

// Observe Realm Notifications

let token = realm.addNotificationBlock { notification, realm in

viewController.updateUI()

}

// later

token.stop()

// Observe Results Notifications

let token = realm.objects(Person).filter(“age > 5”).addNotificationBlock { results, error in

// results is identical to ‘realm.objects(Person).filter(“age > 5”)’

viewController.updateUI()

}

// later

token.stop()


##Key-Value Observation
**这章略过,由于不熟悉KVO,所以先不学习这章**<BR>
Realm objects are Key-Value Observing compliant for most properties. All persisted (non-ignored) properties on your Object subclasses are KVO-compliant, along with the invalidated property on Object and List.

Observing properties of standalone instances of Object subclasses works just like with any other dynamic property, but note that you cannot add an object to a Realm (with realm.add(obj) or other similar methods) while it has any registered observers.

Observing properties of persisted objects works a little differently. With persisted objects, there are three times when the value of a property may change: when you directly assign to it; when you call realm.refresh() or the Realm is automatically refreshed after a write transaction is committed on a different thread; and when you call realm.beginWrite() after changes on a different thread which have not been picked up by a refresh on the current thread.

In the latter two cases, all of the changes made in the write transaction(s) on another thread will be applied at once, and KVO notifications will all be sent at once. Any intermediate steps are discarded, so if in the write transaction you incremented a property from one to ten, on the main thread you’ll get a single notification of a change directly from one to ten. Because properties can change in value when not in a write transaction or even as part of beginning a write transaction, trying to modify persisted Realm objects from within observeValueForKeyPath(_:ofObject:change:context:) is not recommended.

Unlike NSMutableArray properties, observing changes made to List properties does not require using mutableArrayValueForKey(_:), although that is supported for compatiblity with things not written for Realm. Instead, you can simply call the modification methods on List directly, and anyone observing the property it is stored in will be notified. List properties do not need to be marked as dynamic to be observable, unlike normal properties.

In our example apps you can find a short example of using Realm with ReactiveCocoa from Objective?C, and ReactKit from Swift.

##Migrations
**数据迁移,版本迭代时,数据库常用**<BR>

###为什么要进行数据库迁移

class Person: Object {

dynamic var firstName = “”

dynamic var lastName = “”

dynamic var age = 0

}

在某个版本更新中,变成了下边这样

class Person: Object {

dynamic var fullName = “”

dynamic var age = 0

}

那么就需要用到数据迁移了.

###Performing a Migration

Realm.Configuration.defaultConfiguration.schemaVersion = 2;

Realm.Configuration.defaultConfiguration.migrationBlock = {migration, oldSchemaVersion in

if oldSchemaVersion < 1 {

migration.enumerate(Person.className(), { (oldObject, newObject) in

let firstName = oldObject![“firstName”] as! String

let lastName = oldObject![“lastName”] as! String

newObject![“fullName”] = “(firstName) (lastName)”

})

}

    };

###Adding more versions

Realm.Configuration.defaultConfiguration.schemaVersion = 2;

Realm.Configuration.defaultConfiguration.migrationBlock = {migration, oldSchemaVersion in

if oldSchemaVersion < 10 {

migration.enumerate(Person.className(), { (oldObject, newObject) in

if oldSchemaVersion < 1 {

let firstName = oldObject![“firstName”] as! String

let lastName = oldObject![“lastName”] as! String

newObject![“fullName”] = “(firstName) (lastName)”

}

            // Add the `email` property to Realms with a schema version of 0 or 1
                        if oldSchemaVersion < 2 {
                            newObject!["email"] = ""
                        }
            })
        }

    };

###Linear Migrations
需要考虑跨版本的数据库迁移,例如v0直接升级到v3版本,而不是只考虑v2升级到v3.

##Encryption
**Realm的加密只支持OS X , IOS , WatchKit.但是不支持watchOS**<BR>
Realm的加密方式为:**key为64字节,AES-256+SHA2**<BR>
**加密过的 Realm 只会带来很少的额外资源占用(通常最多只会比平常慢10%)**<BR>
**注:如果数据库加密后,由于不知道加密方式,即使有原始key,也无法获取解密key,所以无法用Realm Browser查看.**
**注:如果数据库加密,每次获取Realm实例时,必须使用encryptionKey.**
func getKey() -> NSData {
    // Identifier for our keychain entry - should be unique for your application
    let keychainIdentifier = "io.Realm.Test"
    let keychainIdentifierData = keychainIdentifier.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!

    // First check in the keychain for an existing key
    var query: [NSString: AnyObject] = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: keychainIdentifierData,
        kSecAttrKeySizeInBits: 512,
        kSecReturnData: true
    ]

    // To avoid Swift optimization bug, should use withUnsafeMutablePointer() function to retrieve the keychain item
    // See also: http://stackoverflow.com/questions/24145838/querying-ios-keychain-using-swift/27721328#27721328
    var dataTypeRef: AnyObject?
    var status = withUnsafeMutablePointer(&dataTypeRef) { SecItemCopyMatching(query, UnsafeMutablePointer($0)) }
    if status == errSecSuccess {
        return dataTypeRef as! NSData
    }

    // No pre-existing key from this application, so generate a new one
    let keyData = NSMutableData(length: 64)!
    let result = SecRandomCopyBytes(kSecRandomDefault, 64, UnsafeMutablePointer<UInt8>(keyData.mutableBytes))
    assert(result == 0, "Failed to get random bytes")

    // Store the key in the keychain
    query = [
        kSecClass: kSecClassKey,
        kSecAttrApplicationTag: keychainIdentifierData,
        kSecAttrKeySizeInBits: 512,
        kSecValueData: keyData
    ]

    status = SecItemAdd(query, nil)
    assert(status == errSecSuccess, "Failed to insert the new key in the keychain")

    return keyData
}

“`

时间: 2024-08-28 12:18:14

Realm Swift的相关文章

iOS中 Realm的学习与使用 韩俊强的博客

每日更新关注:http://weibo.com/hanjunqiang  新浪微博! iOS开发者交流QQ群:446310206  有问题或技术交流可以咨询!欢迎加入! 这篇直接搬了一份官方文档过来看的 由于之前没用markdown搞的乱七八糟的 所以重新做了一份 后面看到官网的中文文档更新不及时看着英文翻译了一点 搞的更乱了 :( 英文好的直接点右边->官方OC文档 Realm是一个移动端的数据库,Realm是SQLite和CoreData的替代者.它可以节省你成千上万行代码和数周的工作,并且

用 Swift、Foursquare API 和 Realm 創建一個咖啡屋 App

原文链接 : Building a Coffee Shop App with Swift, Foursquare API and Realm 原文作者 : De Vries Reinder 译文出自 : APPCODA 译者 : kmyhy 人們常說,程序員能將咖啡變成電腦程式.接下來,我們將編寫一個 App,列出距離你最近的咖啡屋! 在本教程中,你將使用到如下技能: Swift.Xcode 和 Interface Builder (自動佈局.約束和故事板) Realm,一個輕量級的 Core

Android &amp;Swift iOS开发:语言与框架对比

转载自:http://www.infoq.com/cn/articles/from-android-to-swift-ios?utm_campaign=rightbar_v2&utm_source=infoq&utm_medium=articles_link&utm_content=link_text 从Android到Swift iOS开发:语言与框架对比 我从2009年开始做Android开发,开始接触Swift是在2014年底,当时组里曾经做过一个Demo App,感觉技术还

Realm数据库的简单介绍和使用

给大家介绍一个数据库操作的框架Realm,本文主要以iOS 平台的使用场景为例. realm是一个跨平台移动数据库引擎,支持iOS.OS X(Objective-C和Swift)以及Android: 核心数据引擎由C++打造,并不是建立在SQLite之上的ORM, 拥有独立的数据库存储引擎: 据官方称性能上比sqlite, coredata牛逼,而且使用起来更加简单, 更易入门. 下载地址:https://realm.io/cn/ 使用教程:https://realm.io/docs/objc/

SwiftLint——Swift代码检查及自动格式化工具

某软不给力,正在做的UWP项目停工了.官方说法是要等到RS2发布新的VOIP架构,再看看是不是给某软面子.虽然Beta用户中发出了几点愤怒的声音,但是木有用.有用的只能是某软的Skype for business UWP版拿下几个大订单,才有说服力.像现在这样鶸的表现,真是让人心寒…… 当然UWP开发入门还会继续写下去,本篇只是偷个懒,把工作中整理的资料放上来.蜀黍我可不是叛徒,我没发过誓不给水果开发APP,某软现在就是最大的果蛆.无奈混口饭吃,让写Swift就写呗,水果一套加上Xcode,咋用

移动端数据库新王者:realm

介绍 realm是一个跨平台移动数据库引擎,支持iOS.OS X(Objective-C和Swift)以及Android. 2014年7月发布.由YCombinator孵化的创业团队历时几年打造,是第一个专门针对移动平台设计的数据库.目标是取代SQLite. 为了彻底解决性能问题,核心数据引擎C++打造,并不是建立在SQLite之上的ORM.如果对数据引擎实现想深入了解可以查看:Realm 核心数据库引擎探秘.因此得到的收益就是比普通的ORM要快很多,甚至比单独无封装的SQLite还要快. 因为

汇集了很多swift 学习指南

https://github.com/ipader/SwiftGuide 1,059   Unstar7,294 Fork1,966 ipader/SwiftGuide CodeIssues 0Pull requests 0WikiPulseGraphs 这份指南汇集了Swift语言主流学习资源,并以开发者的视角整理编排.http://dev.swiftguide.cn 376 commits 3 branches 0 releases 12 contributors Swift 100.0%

Awesome Swift

Awesome Swift A collaborative list of awesome Swift resources,inspired by awesome-python and listed on awesome-awesomeness. Feel free to contribute! Awesome Swift Demo Apps iOS Apple Watch OS X Dependency Managers Guides Editor Support Vim Libs Anima

iOS开发——网络编程Swift篇&amp;Alamofire详解

Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AFNetworking非常稳定,在Mac OSX与iOS中也能像其他Objective-C代码一样用Swift编写.不过Alamofire更适合Swift语言风格习惯(Alamofire与AFNetworking可以共存一个项目中,互不影响). Alamofire 取名来源于Alamo Fire fl