Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/danbrooker/data
Data Framework for Swift; Uses YapDatabase not CoreData
https://github.com/danbrooker/data
Last synced: about 1 month ago
JSON representation
Data Framework for Swift; Uses YapDatabase not CoreData
- Host: GitHub
- URL: https://github.com/danbrooker/data
- Owner: DanBrooker
- License: mit
- Created: 2015-03-30T21:37:07.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2016-09-15T11:37:18.000Z (over 8 years ago)
- Last Synced: 2023-03-22T16:49:42.433Z (almost 2 years ago)
- Language: Swift
- Size: 79.1 KB
- Stars: 8
- Watchers: 5
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Data.swift
[![Build Status](https://travis-ci.org/DanBrooker/Data.svg?branch=master)](https://travis-ci.org/DanBrooker/Data)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
![Cocoapods Compatible](https://img.shields.io/cocoapods/v/Data.swift.svg)
![License](https://img.shields.io/badge/license-MIT-000000.svg)
![Platform](https://img.shields.io/badge/platform-iOS-lightgrey.svg)Data.swift is a Swift (2.0) framework for working with data models.
> Data.swift is built on the fantastic YapDatabase which is built on Sqlite3`Swift 1.2 can be found on branch swift1.2`
It aims to have the following attributes:
* Threadsafe
* Typesafe
* Tested
* Protocols not Inheritance# Getting started
## Cocoapods
```ruby
platform :ios, '8.0'
use_frameworks!pod 'Data', git: 'https://github.com/DanBrooker/Data'
```## Carthage
YapDatabase now has a framework, I just need to add it :D
## Setup
Import Data module
``` swift
import Data
```> Data.Model is simple protocol which requires a uid:String property and a means to archive and unarchive an object
``` swift
class YourModel : Data.Model {
let uid: String // Required propertyinit() {
self.uid = "A UID OF YOUR CHOOSING"
}// Required init
required init(archive: Archive) {
uid = archive["uid"] as! String
}// Required archive property, [String: AnyObject]
var archive : Archive {
return ["uid": uid]
}
}struct YourStruct : Data.Model {
let uid: String // Required propertyinit() {
self.uid = "A UID OF YOUR CHOOSING"
}// Required init
init(archive: Archive) {
uid = archive["uid"] as! String
}// Required archive property, [String: AnyObject]
var archive : Archive {
return ["uid": uid]
}
}
```# Basics
Created a data store
``` swift
let store = YapStore()
```## Add
``` swift
let model = YourModel()
store.append(model)
```## Find
``` swift
let model: YourModel = store.find(modelsUID)
```## Filter
``` swift
let models: [YourModel] = store.filter({ $0.someProperty > 0 })
```## All
``` swift
let models: [YourModel] = store.all()
```
## Count
``` swift
let count = store.count(YourModel.self)
```## Update
> Update is important because your object is not being observed for changes and therefore once your done changing a object you will need to save it
``` swift
store.update(model)
```## Delete
``` swift
store.remove(model)
```## Delete all
``` swift
store.truncate(YourModel.self)
```# Next step
Now that you've got the basics
## Querying
```swift
public struct Query {
let filter: ( (element: T) -> Bool )?
let window: Range?
let order: ( (a: T, b: T) -> Bool )?
}
```A simple query for all YourModel objects
```swift
let query = Query()
```A more complex query
> Filter models based on enabled being true, limited to the first 20 elements and ordered by property```swift
let query = Query(
filter: { $0.enabled == true },
window: 0..<20,
order: { $0.property > $1.property }
)
```## Notifications
Options:a) You can observe the following notifications for changes
* "dataStoreAdded"
> Not actually called yet, cannot distinguish between modified and added currently* "dataStoreModified"
* "dataStoreRemoved"b) And this is the best option use `Collection` collections
## Collections
`Collection` is a drop in replacement for Array with the added benefit of being persistent and automatically updating when someone changes an object in the underlying data store
```swift
let query = Query()
let data: Collection = Data(query: query, store: store)
```See querying above for more information about populating `Collection` with a query
### Tableview helpers
`Collection` has a delegate `DataDelegate` and it generates some very useful callbacks for `UITableView`s
```swift
extension ViewController: DataDelegate {func beginUpdates() {
tableView.beginUpdates()
}func endUpdates() {
tableView.endUpdates()
}func objectAdded(indexPaths: [NSIndexPath]) {
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
}func objectRemoved(indexPaths: [NSIndexPath]) {
tableView.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
}func objectUpdated(indexPaths: [NSIndexPath]) {
tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
}}
```## Key-Value Store
YapDatabase is actually a key-value store, or more correctly a hash of hashes.
You can therefore just store arbitrary key-values if you need to
```swift
// Set
store.setObjectForKey(object, forKey:"key")
// Get
let object : ObjectType = store.objectForKey("key")
```## Indexes - WIP
> Basic indexes are working but the API is not solidified yet
> Aggregate index `filter`ing not yet supportedSetup Indexes, once per model
```swift
struct TestModel: Data.Model {let text: String
//.. init and archive functions removed for this example
// function used to index properties
func indexes() -> [Index] {
return [
Index(key: "text", value: text)
]
}
}let example = TestModel(uid: "doesn't matter")
store.index(example)
```
> Indexable types String, Int Double, Float, Bool### Find
```swift
var unique: TestModel? = store.find("enabled", value: true)
```### Filter
```swift
var enabled: [TestModel] = store.filter("enabled", value: true)
```### Search
sqlite full text search. [reference](http://www.sqlite.org/fts3.html#section_1_4)
> You need to setup indexes to use search. Only searches **TEXT** columns
```swift
struct Tweet: Data.Model {let text: String
let authorName: String//.. init and archive functions removed for this example
// function used to index properties
func indexes() -> [Index] {
return [
Index(key: "text", value: text),
Index(key: "authorName", value: authorName)
]
}
}let example = Tweet(uid: "doesn't matter", text: "also doesn't matter", authorName: "anon")
store.index(example)
```Search using various methods
```swift
var results : [Tweet] = store.search(string: "yapdatabase") // Basic Keyword Search
results = store.search(phrase: "yapdatabase is good") // Exact Phrase
results = store.search(string: "authorName:draconisNZ") // Only Search Property
results = store.search(string: "^yap") // Starts with
results = store.search(string: "yap*" // Wildcard
results = store.search(string: "'yapdatabase OR yapdatabse'") // OR
results = store.search(string: "'tweet NOT storm'") // NOT
results = store.search(string: "'tweet NEAR/2 storm'") // Keywords are within '2' tokens of each other
```# TODO
* Transactions and mutiple model reads/writes
* Secondary index aggregation i.e. OR and AND
* iOS9 Core Spotlight
* Query should use indexes
* Relationships (Delete rules), Implicit and Explict* Search snippets and return results across models if required
* Metadata helpers for things like caching table row height
* Tableview sections with Collection<>, also CollectionView
* Data syncing - CloudKit, Dropbox ...# License
Data.swift is released under an MIT license. See LICENSE for more information.