Giter Site home page Giter Site logo

siam-biswas / storage Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 0.0 48 KB

Elegant way to store data in Swift

License: MIT License

Swift 96.56% Objective-C 2.56% Ruby 0.87%
swift data-store generic-programming storage userdefaults keychain plist filemanager propertywrapper data-persistence

storage's Introduction

Storage

Platform UserDefault Keychain FileManager Plist

Elegant way to store data in Swift

Storage is a generic solution for data persistency in swift. As there are multiple ways to store data locally in iOS apps, Storage made it easier for you to use them with one single tool. Currently storage has support to work with UserDefaults, Keychain, FileManager & Plist.

Version 1.0.2

Usage

Lets start by creating some Buckets in Store

extension Store{
    
    var username:Bucket<String?> { .init() }
    var phones:Bucket<[String]?> { .init() }
    var age:Bucket<Int?> { .init() }
    var isValid:Bucket<Bool?> { .init() }
}

And just use it anywhere with Subscript , KeyPath & DynamicMemberLookup

Storage[\.username] = "jhon.doe"
let username = Storage[\.username]

Storage[\.phones] = ["01711223344","93456789"]

Storage.age = 28
Storage.isValid = true

Bucket

Bucket is basically a generic data type holder. You can intialize a bucket with a key, a data container, expiration date & default value. If you are using optinal value then all this parameters are not mandatory. But if you want to have a non-optional value, then providing a default value is mandatory. If you just use .init() to initialize a bucket than the variable name will be used as a key to store the value.

extension Store{
    var username:Bucket<String?> { .init() }
    var phones:Bucket<[String]?> { .init(key: "phones") }
    var age:Bucket<Int?> { .init(key: "age", expire: Date()) }
    var isValid:Bucket<Bool?> { .init(key: "username", expire: Date(), container: UserDefaults.standard) }
    var email:Bucket<String> { .init(key: "email", expire: Date(), container: UserDefaults.standard, value: "[email protected]") }
}

Container

Container is a gateway between storage and different data storing protocols. Currently storage has container support for UserDefault, Keychain, FileManager & Plist. By default Storage use UserDefault as container. You can set your preferred container while creating Bucket.

extension Store{
    var phone:Bucket<String?> { .init(container: UserDefaults.standard)}
    var email:Bucket<String?> { .init(container: UserDefaults(suiteName: "com.storage.example"))}
}
extension Store{
    var name:Bucket<String?> { .init(container: Keychain.default)}
    var phone:Bucket<String?> { .init(container: Keychain(service: "storage"))}
    var email:Bucket<String?> { .init(container: Keychain(service: "storage",accessGroup: "com.storage"))}
}
extension Store{
    var name:Bucket<String?> { .init(container: FileManager.default)}
}
extension Store{
    var name:Bucket<String?> { .init(container: Plist.default)}
    var phone:Bucket<String?> { .init(container: Plist(.existing(name: "Info")))}
    var email:Bucket<String?> { .init(container: Plist(.new(name: "Credentials")))}
    
}

You can also change the default container by set the value for StorageContainer.default

 StorageContainer.default = FileManager.default

Store

Store is where you put all your Buckets from different Containers. Stoarge has a default store with name Store. As mentioned before you can just use its extension for bucket storing purpose.

extension Store{
    var username:Bucket<String?> { .init() }
    var phone:Bucket<String?> { .init(container: Keychain.default)}
    var email:Bucket<String?> { .init(container: Plist.default)}
}

You can also create your custom Store by conform to Storable in your custom class or struct.

public struct DataStore:Storable{
    var username:Bucket<String?> { .init() }
    var phone:Bucket<String?> { .init(container: Keychain.default)}
    var email:Bucket<String?> { .init(container: Plist.default)}
}

Then define a custom global Adapter variable with StorageAdapter.

public var DataStorage = StorageAdapter<DataStore>(store: .init())

And the usage is as before

DataStorage[\.username] = "jhon.doe"
let username = DataStorage[\.username]

DataStorage[\.phones] = ["01711223344","93456789"]

DataStorage.email = "[email protected]"

Codable, NSCoding & RawRepresentable

Storage support Codable ,NSCoding & RawRepresentable with all the Containers ! Just conform to Storagable in your custom type or enum. It also works with array of your custom types.

struct Name:Codable,Storagable{
    
    var firstName:String
    var lastName:String
    
}
struct Name:NSObject, NSCoding, Storagable{ ... }
enum NameType: String, Storagable {
    case former
    case family
    case official
}

Supported types

Here's a full table of supported types with Storage:

Single value Array
String [String]
Int [Int]
Double [Double]
Float [Float]
CGFloat [CGFloat]
NSNumber [NSNumber]
Bool [Bool]
Data [Data]
Date [Date]
URL [URL]
UIImage [UIImage]
[String: Any] [[String: Any]]
Codable [Codable]
NSCoding [NSCoding]
RawRepresentable [RawRepresentable]

Property Wrapper

You can use the property wrapper @StorageWrapper to attach storage behaviors and logic directly to your custom properties. @StorageWrapper can be used with a previously created buckets KeyPath and Adapter or you can initalize it with a new Bucket .

extension Store {
    var username: Bucket<String> { .init() }
}
class CustomClass {
    @StorageWrapper(keyPath: \.username)
    var username: String?
    
    @StorageWrapper(keyPath: \.address, adapter: Storage) 
    var address:String?

    @StorageWrapper(bucket: Bucket(key: "email", expire: Date(), container: UserDefaults.standard, value: "[email protected]"))
    var email: String?
}

Debug

We have added a debugger for your convenience to check the current Storage session.

For enable the debugger

StorageDebug.set(true)

Get the debug report

let report = StorageDebug.report

Installation

CocoaPods

You can use CocoaPods to install Storage by adding it to your Podfile:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
    pod 'Storage', :git => 'https://github.com/siam-biswas/Storage.git'
end

Manually

To use this library in your project manually you may:

  1. for Projects, just drag all the (.swift) files from (Source\Storage) to the project tree
  2. for Workspaces, include the whole Storage.xcodeproj

Reference & Inspiration

The design of the Storage architecture gets huge inspiration from SwiftyUserDefaults, and we invite the reader to take a look at its repo & documentation. Also check out this awesome articles and repos which were really helpfull while creating Storage.

storage's People

Contributors

siam-biswas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.