Cubby 是一个 Swift 封装,用于 JSONBin API,它提供了一个简单的接口,用于在云端存储、分类和获取 Swift 结构体。
Cubby 提供对 JSONBin API v2 和 v3 的完整支持。
Cubby 使用规范协议来指示每个 API 版本支持哪些端点。 根据您要调用的端点,使用 JSONBin.V2.API
或 JSONBin.V3.API
的适当实例化。(请注意,JSONBin API 的版本 2 计划于 2022 年 2 月 28 日弃用。)
创建、读取、更新或删除代表 Swift 结构体的容器 (bins)。 每个容器代表一个单独的 Swift 结构体,并具有隐私设置、可选名称以及其所属的可选集合。
public protocol JSONBinV2APIBinSpec: JSONBinV2APISpec {
func createBin<Resource: Encodable>(named name: String?, with resource: Resource, inCollectionWith id: Collection.ID?, private: Bool?) -> Request<Creation<Resource>>
func readBin<Resource: Decodable>(with id: ID, of type: Resource.Type, at version: Version?) -> Request<Resource>
func updateBin<Resource: Encodable>(with id: ID, using resource: Resource, versioning: Bool?) -> Request<Update<Resource>>
func deleteBin(with id: ID) -> Request<Deletion>
}
public protocol JSONBinV3APIBinSpec: JSONBinV3APISpec {
func createBin<Resource: Encodable>(named name: String?, with resource: Resource, inCollectionWith id: Collection.ID?, private: Bool?) -> Request<Creation<Resource>>
func readBin<Resource: Decodable>(with id: ID, of type: Resource.Type, at version: Version?, includingMetadata: Bool?, usingDotPath dotPath: String?) -> Request<Read<Resource>>
func versionCount(ofBinWith id: ID) -> Request<VersionCount>
func updateBin<Resource: Encodable>(with id: ID, using resource: Resource, versioning: Bool?) -> Request<Update<Resource>>
func updateName(ofBinWith id: ID, toName name: String) -> Request<NameUpdate>
func updatePrivacy(ofBinWith id: ID, toPrivate private: Bool) -> Request<PrivacyUpdate>
func deleteBin(with id: ID) -> Request<Deletion>
func deleteVersions(ofBinWith id: ID, preservingLatest: Bool?) -> Request<Deletion>
}
var apple = Company(name: "Apple", remoteWorkPolicy: .hybrid)
let request = api.createBin(named: "Apple Computer", with: apple)
let creation = try await request.returnedResource
let id = creation.metadata.id
print(creation.resource) // Company(name: "Apple", remoteWorkPolicy: .hybrid)
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)
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)
let request = api.updateName(ofBinWith: id, toName: "Apple Inc.")
let update = try await request.returnedResource
print(update.resource) // Company(name: "Apple", remoteWorkPolicy: .disallowed)
let request = api.versionCount(ofBinWith: id)
let versionCount = try await request.returnedResource.metadata.versionCount
print(versionCount) // 1
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."
let request = api.deleteBin(with: id)
let deletion = try await request.returnedResource
print(deletion.message) // "Bin deleted successfully"
创建、从其中获取或更新包含 Swift 结构体的集合。 为了确保集合仅包含相同类型的结构体,请将代表该类型的架构文档(参见下文)附加到集合。 一旦附加,尝试在不同类型的集合中创建容器(即,无法通过架构验证的容器)将会失败。
public protocol JSONBinV2APICollectionSpec: JSONBinV2APISpec {
func createCollection(named name: String) -> Request<Creation>
func updateCollection(with id: ID, using action: Action) -> Request<Update>
}
public protocol JSONBinV3APICollectionSpec: JSONBinV3APISpec {
func createCollection(named name: String) -> Request<Creation>
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<NameUpdate>
func addSchemaDoc(with id: SchemaDoc.ID, toCollectionWith collectionID: ID) -> Request<Addition>
func removeSchemaDoc(fromCollectionWith id: ID) -> Request<Removal>
}
let request = api.createCollection(named: "WFH Companies")
let creation = try await request.returnedResource
let id = creation.metadata.id
print(creation.metadata.name) // "WFH Companies"
let request = api.fetchBins(inCollectionWith: id)
let companies = try await request.returnedResource
print(companies) // [Company(name: "Twitter", remoteWorkPolicy: .allowed), Company(name: "GitHub", remoteWorkPolicy: .distributed)]
let request = api.updateName(ofCollectionWith: id, toName: "Remote Companies")
let update = try await request.returnedResource
print(update.metadata.name) // "Remote Companies"
let request = api.addSchemaDoc(with: schemaDocID, toCollectionWith: id)
request() // Adds a schema doc to the collection
let request = api.removeSchemaDoc(fromCollectionWith: id)
request() // Removes the schema doc from the collection
创建、读取或更新可以附加到集合的架构文档。
public protocol JSONBinV2APISchemaDocSpec: JSONBinV2APISpec {
func createSchemaDoc<Resource>(for type: Resource.Type, named name: String) -> Request<Response<Resource>>
func readSchemaDoc<Resource>(with id: ID, for type: Resource.Type) -> Request<Schema<Resource>>
func updateSchemaDoc<Resource>(with id: ID, toSchemaFor type: Resource.Type) -> Request<Response<Resource>>
}
public protocol JSONBinV3APISchemaDocSpec: JSONBinV3APISpec {
func createSchemaDoc<Resource>(for type: Resource.Type, named name: String) -> Request<Response<Resource>>
func readSchemaDoc<Resource>(with id: ID, for type: Resource.Type) -> Request<Response<Resource>>
func updateSchemaDoc<Resource>(with id: ID, toSchemaFor type: Resource.Type) -> Request<Update<Resource>>
func updateName(ofSchemaDocWith id: ID, toName name: String) -> Request<NameUpdate>
}
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]
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]
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]
let request = api.updateName(ofSchemaDocWith: id, toName: "Company Schema Document")
let update = try await request.returnedResource
print(update.metadata.name) // "Company Schema Document"
查找 IP 地址的地理位置数据。
public protocol JSONBinV2APIGeoIPSpec: JSONBinV2APISpec {
func lookUpGeolocation(for ipAddress: IPAddress) -> Request<Lookup>
}
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
获取此帐户剩余的请求数。
public protocol JSONBinV2APIExperimentalSpec: JSONBinV2APISpec {
func requestCount() -> Request<Count>
}
let request = api.requestCount()
let count = try await request.returnedResource
print(count.value) // 1000000
列出此帐户的使用日志,或下载特定的使用日志。
public protocol JSONBinV3APIOtherSpec: JSONBinV3APISpec {
func listUsageLogs() -> Request<UsageLog.List>
func downloadUsageLog(named name: String) -> Request<UsageLog>
}
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"]
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
Cubby 使用 Swift Package Manager 分发。 要将其安装到项目中,只需将其作为依赖项添加到您的 Package.swift
清单中
let package = Package(
...
dependencies: [
.package(url: "https://github.com/Fleuronic/Cubby", from: "1.0.0")
],
...
)
然后在您想要使用它的任何地方导入 Cubby
import Cubby