A Swift wrapper around the JSONbin.io API

Overview

Cubby

Release License Issues Downloads

Bitrise Codecov Codacy

Tweet Follow Github

Cubby is a Swift wrapper around the JSONBin API that provides a simple interface for storing, categorizing, and fetching Swift structs in the cloud.

API Support

Cubby provides full support for both v2 and v3 of the JSONBin API.

Version 2.0

  • Bin
    • Create
    • Read
    • Update
    • Delete
  • Collection
    • Create
    • Read
  • Schema Doc
    • Create
    • Read
    • Update
  • Geolocation
    • Lookup
  • Experimental
    • Request Count

Version 3.0

  • Bin
    • Create
    • Read
    • Version Count
    • Update
    • Update Name
    • Update Privacy
    • Delete
    • Delete Versions
  • Collection
    • Create
    • Fetch in Collection
    • Fetch Uncategorized
    • Update Name
    • Add Schema Doc
    • Remove Schema Doc
  • Schema Doc
    • Create
    • Read
    • Update
    • Update Name
  • Other
    • List Usage Logs
    • Download Usage Log

Usage

Cubby uses specification protocols to indicate which endpoints each API version supports. Use an appropriate instantiation of JSONBin.V2.API or JSONBin.V3.API depending on the endpoint you want to call. (Note that version 2 of the JSONBin API is planned for deprecation on January 1, 2022.)

Bin

Create, read, update, or delete bins that represent Swift structs. Each bin represents a single Swift struct and has a privacy setting, an optional name, and an optional collection it belongs to.

public protocol JSONBinV2APIBinSpec: JSONBinV2APISpec {
    func createBin<Resource: Encodable>(named name: String?, with resource: Resource, inCollectionWith id: Collection.ID?, private: Bool?) -> Request
   
    >
    
    func 
    readBin<
    Resource: 
    Decodable>(
    with 
    id: ID, 
    of 
    type: Resource.
    Type, 
    at 
    version: Version
    ?) 
    -> Request
    
    
     func 
     updateBin<
     Resource: 
     Encodable>(
     with 
     id: ID, 
     using 
     resource: Resource, 
     versioning: 
     Bool
     ?) 
     -> Request
     
      
       >
    
       func 
       deleteBin(
       with 
       id: ID) 
       -> Request
       
         } 
        public 
        protocol 
        JSONBinV3APIBinSpec: 
        JSONBinV3APISpec { 
        func 
        createBin<
        Resource: 
        Encodable>(
        named 
        name: 
        String
        ?, 
        with 
        resource: Resource, 
        inCollectionWith 
        id: 
        Collection.ID
        ?, 
        private: 
        Bool
        ?) 
        -> Request
        
         
          > 
          func 
          readBin<
          Resource: 
          Decodable>(
          with 
          id: ID, 
          of 
          type: Resource.
          Type, 
          at 
          version: Version
          ?, 
          includingMetadata: 
          Bool
          ?, 
          usingDotPath 
          dotPath: 
          String
          ?) 
          -> Request
          
           
            > 
            func 
            versionCount(
            ofBinWith 
            id: ID) 
            -> Request
             
             func 
             updateBin<
             Resource: 
             Encodable>(
             with 
             id: ID, 
             using 
             resource: Resource, 
             versioning: 
             Bool
             ?) 
             -> Request
             
              
               > 
               func 
               updateName(
               ofBinWith 
               id: ID, 
               toName 
               name: 
               String) 
               -> Request
                
                func 
                updatePrivacy(
                ofBinWith 
                id: ID, 
                toPrivate 
                private: 
                Bool) 
                -> Request
                 
                 func 
                 deleteBin(
                 with 
                 id: ID) 
                 -> Request
                  
                  func 
                  deleteVersions(
                  ofBinWith 
                  id: ID, 
                  preservingLatest: 
                  Bool
                  ?) 
                  -> Request
                  
                    }
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
Creation Example
var apple = Company(name: "Apple", remoteWorkPolicy: .hybrid)

let request = api.createBin(named: "Apple Computer", with: company)
let creation = try await request.returnedResource
let id = creation.metadata.id

print(creation.resource) // Company(name: "Apple", remoteWorkPolicy: .hybrid)
Read Example
let request = api.readBin(with: id, of type: Company.self, at: .number(1), includingMetadata: false)
let company = try await request.returnedResource

print(company) // Company(name: "Apple Computer", remoteWorkPolicy: .hybrid)
Update Example
apple.remoteWorkPolicy = .disallowed

let request = api.updateBin(with: id, using: apple)
let update = try await request.returnedResource

print(update.resource) // Company(name: "Apple", remoteWorkPolicy: .disallowed)
Update Name Example
let request = api.updateName(ofBinWith: id, toName: "Apple Inc.")
let update = try await request.returnedResource

print(update.resource) // Company(name: "Apple", remoteWorkPolicy: .disallowed)
Version Count Example
let request = api.versionCount(ofBinWith: id)
let versionCount = try await request.returnedResource.metadata.versionCount

print(versionCount) // 1
Deletion Versions Example
let request = api.deleteVersions(ofBinWithID: id, preservingLatest: true)
let deletion = try await request.returnedResource

print(deletion.message) // "Versions for the Bin are deleted successfully and latest version preserved on the base record."
Deletion Example
let request = api.deleteBin(with: id)
let deletion = try await request.returnedResource

print(deletion.message) // "Bin deleted successfully"

Collection

Create, fetch from, or update collections that contain your Swift structs. To ensure a collection only contains structs of the same type, attach a schema document (see below) representing that type to the collection. Once attached, attempting to create a bin in a collection of a different type (i.e., one that cannot be validated by the schema) will fail.

public protocol JSONBinV2APICollectionSpec: JSONBinV2APISpec {
    func createCollection(named name: String) -> Request
    
   func 
   updateCollection(
   with 
   id: ID, 
   using 
   action: Action) 
   -> Request
   
    
}


    public 
    protocol 
    JSONBinV3APICollectionSpec: 
    JSONBinV3APISpec {
    
    func 
    createCollection(
    named 
    name: 
    String) 
    -> Request
    
    
     func 
     fetchBins(
     inCollectionWith 
     id: ID, 
     sortedBy 
     sortOrder: Fetch.SortOrder
     ?) 
     -> Request<[Fetch.Result]>
    
     func 
     fetchUncategorizedBins(
     sortedBy 
     sortOrder: Fetch.SortOrder
     ?) 
     -> Request<[Fetch.Result]>
    
     func 
     updateName(
     ofCollectionWith 
     id: ID, 
     toName 
     name: 
     String) 
     -> Request
     
    
      func 
      addSchemaDoc(
      with 
      id: SchemaDoc.ID, 
      toCollectionWith 
      collectionID: ID) 
      -> Request
      
    
       func 
       removeSchemaDoc(
       fromCollectionWith 
       id: ID) 
       -> Request
       
         }
       
      
     
    
   
  
Creation Example
let request = api.createCollection(named: "WFH Companies")
let creation = try await request.returnedResource
let id = creation.metadata.id

print(creation.metadata.name) // "WFH Companies"
Fetch Example
let request = api.fetchBins(inCollectionWith: id)
let companies = try await request.returnedResource

print(companies) // [Company(name: "Twitter", remoteWorkPolicy: .allowed), Company(name: "GitHub", remoteWorkPolicy: .distributed)]
Update Name Example
let request = api.updateName(ofCollectionWith: id, toName: "Remote Companies")
let update = try await request.returnedResource

print(update.metadata.name) // "Remote Companies"
Add Schema Doc Example
let request = api.addSchemaDoc(with: schemaDocID, toCollectionWith: id)
request() // Adds a schema doc to the collection
Remove Schema Doc Example
let request = api.removeSchemaDoc(fromCollectionWith: id)
request() // Removes the schema doc from the collection

Schema Doc

Create, read, or update schema documents that can be attached to collections.

public protocol JSONBinV2APISchemaDocSpec: JSONBinV2APISpec {
    func createSchemaDoc<Resource>(for type: Resource.Type, named name: String) -> Request
   
    >
    
    func 
    readSchemaDoc<
    Resource>(
    with 
    id: ID, 
    for 
    type: Resource.
    Type) 
    -> Request
    
     
      >
    
      func 
      updateSchemaDoc<
      Resource>(
      with 
      id: ID, 
      toSchemaFor 
      type: Resource.
      Type) 
      -> Request
      
       
        > } 
        public 
        protocol 
        JSONBinV3APISchemaDocSpec: 
        JSONBinV3APISpec { 
        func 
        createSchemaDoc<
        Resource>(
        for 
        type: Resource.
        Type, 
        named 
        name: 
        String) 
        -> Request
        
         
          > 
          func 
          readSchemaDoc<
          Resource>(
          with 
          id: ID, 
          for 
          type: Resource.
          Type) 
          -> Request
          
           
            > 
            func 
            updateSchemaDoc<
            Resource>(
            with 
            id: ID, 
            toSchemaFor 
            type: Resource.
            Type) 
            -> Request
            
             
              > 
              func 
              updateName(
              ofSchemaDocWith 
              id: ID, 
              toName 
              name: 
              String) 
              -> Request
              
                }
              
             
            
           
          
         
        
       
      
     
    
   
  
Creation Example
extension Company: SchemaAdhering {
    static var description: String? {
        "A company has both a name and a remote work policy."
    }

    static var properties: [CodingKeys: SchemaType] {
        [
            .name: .string,
            .remoteWorkPolicy: .string
        ]
    }
}

let request = api.createSchemaDoc(for: Company.self, named: "Company Schema Doc")
let creation = try await request.returnedResource
let id = creation.metadata.id

print(creation.metadata.name) // "Company Schema Doc"
print(creation.schema.title) // "Company"
print(creation.schema.description) // "A company has both a name and a remote work policy."
print(creation.schema.properties) // [.name: .string, .remoteWorkPolicy: .string]
Read Example
let request = api.readSchemaDoc(with: id)
let read = try await request.returnedResource

print(read.metadata.name) // "Company Schema Doc"
print(read.schema.title) // "Company"
print(read.schema.description) // "A company has both a name and a remote work policy."
print(read.schema.properties) // [.name: .string, .remoteWorkPolicy: .string]
Update Example
extension Company: SchemaAdhering {
    static var description: String? {
        "A company has both a name, a remote work policy, and a number of employees."
    }

    static var properties: [CodingKeys: SchemaType] {
        [
            .name: .string,
            .remoteWorkPolicy: .string,
            .employeeCount: .integer
        ]
    }
}

let request = api.updateSchemaDoc(with: id, toSchemaFor: Company.self)
let update = request.returnedResource

print(update.metadata.name) // "Company Schema Doc"
print(update.schema.title) // "Company"
print(update.schema.description) // "A company has, a name, a remote work policy, and a number of employees."
print(update.schema.properties) // [.name: .string, .remoteWorkPolicy: .string, .employeeCount: .integer]
Update Name Example
let request = api.updateName(ofSchemaDocWith: id, toName: "Company Schema Document")
let update = try await request.returnedResource

print(update.metadata.name) // "Company Schema Document"

Geolocation

Look up geolocation data for an IP address.

public protocol JSONBinV2APIGeoIPSpec: JSONBinV2APISpec {
    func lookUpGeolocation(for ipAddress: IPAddress) -> Request
   
}
  
Look Up Geolocation Example
let ipAddress = IPAddress("141.158.45.225")
let request = api.lookUpGeolocation(for: ipAddress)
let lookupData = await request.returnedResource.data

print(lookupData.range) // 2375953408..<2375953919
print(lookupData.countryCode) // "US"
print(lookupData.regiounCode) // "PA"
print(lookupData.timeZone) // "America/New_York"
print(lookupData.city) // "Philadelphia"
print(lookupData.coordinates.latitude) // 39.934
print(lookupData.coordinates.longitude) // -75.16
print(lookupData.metroCode) // 504
print(lookupData.accuracyRadius) // 1

Experimental

Get the number of requests remaining for this account.

public protocol JSONBinV2APIExperimentalSpec: JSONBinV2APISpec {
    func requestCount() -> Request
   
}
  
Request Count Example
let request = api.requestCount()
let count = try await request.returnedResource

print(count.value) // 1000000

Other

List the usage logs for this account, or download a specific usage log.

public protocol JSONBinV3APIOtherSpec: JSONBinV3APISpec {
    func listUsageLogs() -> Request
    
   func 
   downloadUsageLog(
   named 
   name: 
   String) 
   -> Request
   
    
}
   
  
List Usage Logs Example
let ipAddress = IPAddress("141.158.45.225")
let request = api.listUsageLogs
let list = await request.returnedResource

print(list.logNames) // ["12-31-2022", "01-01-2022", "01-02-2022"]
Download Usage Log Example
let ipAddress = IPAddress("141.158.45.225")
let request = api.downloadUsageLog(named: "01-01-2022")
let usageLog = await request.returnedResource

print(usageLog.compressed) // ZIP data of log contents

Installation

Cubby is distributed using the Swift Package Manager. To install it into a project, simply add it as a dependency within your Package.swift manifest:

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/Fleuronic/Cubby", from: "1.0.0")
    ],
    ...
)

Then import Cubby wherever you’d like to use it:

import Cubby

For more information on how to use the Swift Package Manager, check out this article, or its official documentation.

You might also like...
An IPFS client/api Swift Package, with the ability to add and pin any data on iOS/iPadOS/macOS

An IPFS client/api Swift Package, with the ability to add and pin any data on iOS/iPadOS/macOS. Originally bundled with GraniteUI, pulled out for independant use by any party.

Pexels API client library for the Swift programming language.
Pexels API client library for the Swift programming language.

Pexels-Swift Pexels.com API client library for the Swift programming language. Overview This Swift Package is a wrapper for Pexels API to get access t

A Swift library for Discord REST/Gateway API in all platforms.

swift-discord main develop A Swift library for Discord API. Package Products Discord, alias library that contains DiscordREST, DiscordGateway. Discord

Cross-platform Swift library for accessing the public GitHub API.

GoatHerb GoatHerb is a cross-platform Swift library for accessing the GitHub API. Features General Compatible with swift-log. Full concurrency (async/

iOS 15 share play API in react-native

react-native-shareplay iOS 15 share play API in react-native Installation yarn add react-native-shareplay And go to Xcode Capabilities and enable "Gro

This is a simple mobile app which is connect to the Twitter API
This is a simple mobile app which is connect to the Twitter API

Project 3 - My Twitter My Twitter is a basic twitter app to read your tweets. Time spent on two parts: 8.5 hours spent in total Twitter - Part II This

A movie api created using Vapor, Fluent (ORM) and Postgres

A movie api created using Vapor, Fluent (ORM) and Postgres

Test application that gets its data from the themoviedb api

SWorld app Aplicacion de prueba que obtiene sus datos de la api themoviedb, se permite listar, buscar por titulos y acceder al detalle Prerquisitos pa

A simple, reliable and scalable delivery API for transactional push notifications for websites and applications
A simple, reliable and scalable delivery API for transactional push notifications for websites and applications

Catapush is a simple, reliable and scalable delivery API for transactional push notifications for websites and applications. Ideal for sending data-dr

Owner
Fleuronic
Fleuronic
A Swift Playground to play around Combine

CombinePlayground A Swift Playground to play around Combine Why made this playground To help myself learn Combine, I re-implemented the same features

Jake Lin 5 Apr 17, 2022
A repository to experiment around the use and generation of tokens for the JLL/T Design System

Basic Style Dictionary This example code is bare-bones to show you what this framework can do. If you have the style-dictionary module installed globa

null 0 Dec 7, 2021
React Native utility library around image and video files for getting metadata like MIME type, timestamp, duration, and dimensions. Works on iOS and Android using Java and Obj-C, instead of Node 🚀.

Qeepsake React Native File Utils Extracts information from image and video files including MIME type, duration (video), dimensions, and timestamp. The

Qeepsake 12 Oct 19, 2022
Github iOS Client based on Github REST V3 API and GraphQL V4 API

ZLGithubClient Github iOS 客户端 by Existorlive Objective-c 2.0 Swift 5 Cocoapods 1.9.1 iOS >= 11.0 基于 Github REST V3 API 和 Github GraphQL V4 API 开发的iOS客

朱猛 55 Dec 29, 2022
SwiftyXPC - a wrapper for Apple’s XPC interprocess communication library that gives it an easy-to-use, idiomatic Swift interface.

SwiftyXPC is a wrapper for Apple’s XPC interprocess communication library that gives it an easy-to-use, idiomatic Swift interface.

null 36 Jan 1, 2023
Powerful property wrapper to back codable properties.

BackedCodable Powerful property wrapper to back codable properties. Why Swift's Codable is a great language feature but easily becomes verbose and req

Jérôme Alves 472 Dec 18, 2022
A property wrapper to enforce that closures are called exactly once!

A property wrapper that allows you to enforce that a closure is called exactly once. This is especially useful after the introduction of SE-0293 which makes it legal to place property wrappers on function and closure parameters.

Suyash Srijan 11 Nov 13, 2022
ExtraLottie is a SwiftUI wrapper of Lottie-iOS

?? What is ExtraLottie? ExtraLottie is a SwiftUI wrapper of Lottie-iOS. ℹ️ Info Currently ExtraLottie supports custom loop mode, LottieLoopMode, start

null 3 May 9, 2022
A Swift playground that comes pre-loaded with Plot, that can be used to explore the new component API.

PlotPlayground A Swift playground that comes pre-loaded with Plot, so that you can quickly try out the library and its new, SwiftUI-like API for build

John Sundell 48 Jan 5, 2023
A web API client in Swift built using Async/Await

Web API Client A modern web API client in Swift built using Async/Await and Actors. let client = APIClient(host: "api.github.com") // Using the clien

Alexander Grebenyuk 741 Dec 30, 2022