<commit_before><h3 align="center">
  <img src="" alt="StorageKit" width="600" height="214" />

  Your Data Storage Troubleshooter 🛠
</h3>

<div align="center">
<img src="https://cocoapod-badges.herokuapp.com/p/storagekit/badge.png">
<img src="https://cocoapod-badges.herokuapp.com/v/storagekit/0.1.0/badge.png">
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat">
<img src="https://cocoapod-badges.herokuapp.com/l/StorageKit/badge.png">
<img src="(https://img.shields.io/badge/Swift-3.0.x-orange.svg)">
</div>

<br />

StorageKit is a framework which reduces the complexity of managing a persistent layer. You can easily manage your favorite persistent framework (*Core Data* / *Realm* at the moment), accessing them through a high-level interface.

Our mission is keeping the persistence layer isolated as much as possible from the client codebase. In this way, you can just focus on developing your app. Moreover, you can migrate to another persistent framework easily, keeping the same interface: StorageKit will do almost everything for you.

* Hassle free setup 👍
* Easy to use 🤖
* Extensible 🚀
* Support for background queries 🙌🏼
* Fully tested ( well, almost, ... ☺️ )

*StorageKit* is a **Swift 3** and **XCode 8** compatible project.

# Table of Contents
1. [How it works](#how-it-works)
2. [Define entities](#define-entities)
3. [CRUD](#crud)
3. [Background operations](#background-operations)
4. [Installation](#installation)
5. [Core Mantainers](#core-mantainers)
6. [Known issues](#known-issues)
7. [TODO](#todo)
8. [License](#license)
9. [Credits](#credits)

## How it works
The first step is creating a new `Storage` object with a specific type (either `.CoreData` or `.Realm`) which is the entry-point object to setup `StorageKit`:

```
    let storage = StorageKit.addStorage(type: .Realm)
```
or
```
    let storage = StorageKit.addStorage(type: .CoreData(dataModelName: "Example")
```

The storage exposes a `context` which is the object you will use to perform the common *CRUD operations*, for instance:

```
    storage.mainContext?.fetch(predicate: NSPredicate(format: "done == false"), sortDescriptors: nil, completion: { (fetchedTasks: [RTodoTask]?) in
        self.tasks = fetchedTasks
            // do whatever you want
        }
    )
```

or 

```
    let task = functionThatRetrieveASpecificTaskFromDatabase()

    do {
        try storage.mainContext?.delete(task)
    } catch {
        // manage the error specific for CoreData or Realm
    }
```

That's it! 🎉

In just few lines of code you are able to use your favorite database (`Storage`) and perform any CRUD operations through the `StorageContext`.

## Define Entities
Both [Core Data](https://developer.apple.com/documentation/coredata/nsmanagedobject) and [Realm](https://realm.io/docs/swift/latest/#models) relies on two base
 objects to define the entities:

![Code Data Entity]()

```
import RealmSwift

class RTodoTask: Object {
    dynamic var name = ""
    dynamic var done = false
    
    override static func primaryKey() -> String? {
        return "taskID"
    }
}
```

*StorageKit is not able to define your entity class. It means that you must define all your entities manually. It's the only thing you have to do by yourself, please bear with us.*

You can create a new entity using in this way:
```
    do {
        try let entity: MyEntity = context.create()<commit_msg>Add image links to README<commit_after><h3 align="center">
  <img src="https://raw.githubusercontent.com/StorageKit/StorageKit/master/Resources/logo.jpg" alt="StorageKit" width="600" height="214" />

  Your Data Storage Troubleshooter 🛠
</h3>

<div align="center">
<img src="https://cocoapod-badges.herokuapp.com/p/storagekit/badge.png">
<img src="https://cocoapod-badges.herokuapp.com/v/storagekit/0.1.0/badge.png">
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat">
<img src="https://cocoapod-badges.herokuapp.com/l/StorageKit/badge.png">
<img src="(https://img.shields.io/badge/Swift-3.0.x-orange.svg)">
</div>

<br />

StorageKit is a framework which reduces the complexity of managing a persistent layer. You can easily manage your favorite persistent framework (*Core Data* / *Realm* at the moment), accessing them through a high-level interface.

Our mission is keeping the persistence layer isolated as much as possible from the client codebase. In this way, you can just focus on developing your app. Moreover, you can migrate to another persistent framework easily, keeping the same interface: StorageKit will do almost everything for you.

* Hassle free setup 👍
* Easy to use 🤖
* Extensible 🚀
* Support for background queries 🙌🏼
* Fully tested ( well, almost, ... ☺️ )

*StorageKit* is a **Swift 3** and **XCode 8** compatible project.

# Table of Contents
1. [How it works](#how-it-works)
2. [Define entities](#define-entities)
3. [CRUD](#crud)
3. [Background operations](#background-operations)
4. [Installation](#installation)
5. [Core Mantainers](#core-mantainers)
6. [Known issues](#known-issues)
7. [TODO](#todo)
8. [License](#license)
9. [Credits](#credits)

## How it works
The first step is creating a new `Storage` object with a specific type (either `.CoreData` or `.Realm`) which is the entry-point object to setup `StorageKit`:

```
    let storage = StorageKit.addStorage(type: .Realm)
```
or
```
    let storage = StorageKit.addStorage(type: .CoreData(dataModelName: "Example")
```

The storage exposes a `context` which is the object you will use to perform the common *CRUD operations*, for instance:

```
    storage.mainContext?.fetch(predicate: NSPredicate(format: "done == false"), sortDescriptors: nil, completion: { (fetchedTasks: [RTodoTask]?) in
        self.tasks = fetchedTasks
            // do whatever you want
        }
    )
```

or 

```
    let task = functionThatRetrieveASpecificTaskFromDatabase()

    do {
        try storage.mainContext?.delete(task)
    } catch {
        // manage the error specific for CoreData or Realm
    }
```

That's it! 🎉

In just few lines of code you are able to use your favorite database (`Storage`) and perform any CRUD operations through the `StorageContext`.

## Define Entities
Both [Core Data](https://developer.apple.com/documentation/coredata/nsmanagedobject) and [Realm](https://realm.io/docs/swift/latest/#models) relies on two base
 objects to define the entities:

![Code Data Entity](https://raw.githubusercontent.com/StorageKit/StorageKit/master/Resources/entity_dog.png)

```
import RealmSwift

class RTodoTask: Object {
    dynamic var name = ""
    dynamic var done = false
    
    override static func primaryKey() -> String? {
        return "taskID"
    }
}
```

*StorageKit is not able to define your entity class. It means that you must define all your entities manually. It's the only thing you have to do by yourself, please bear with us.*

You can create a new entity using in this way:
```
    do {
        try let entity: MyEntity = context.create()
{'fraction_non_alphanumeric': 0.12435677530017153, 'fraction_numerical': 0.008004574042309892, 'mean_word_length': 4.051985559566787, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 16, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7159691', 'n_tokens_mistral': 2223, 'n_tokens_neox': 2116, 'n_words': 741}