Skip to content

Instantly share code, notes, and snippets.

@loudmouth
Last active July 24, 2019 19:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loudmouth/7b93f15ca0e34caa259c712b6845b5ed to your computer and use it in GitHub Desktop.
Save loudmouth/7b93f15ca0e34caa259c712b6845b5ed to your computer and use it in GitHub Desktop.
extension Client {
/**
Fetch a collection of Entries from Contentful matching the specified query. This method does not
specify the content_type in the query parameters, so the entries returned in the results can be
of any type.
- Parameter query: The Query object to match results againts.
- Parameter completion: A handler being called on completion of the request.
- Returns: The data task being used, enables cancellation of requests.
*/
public func fetchEntries(with query: Query, completion: ResultsHandler<[Entry]>) -> URLSessionDataTask?
/**
Fetch a collection of Entries from Contentful matching the specified query. This method does not
specify the content_type in the query parameters, so the entries returned in the results can be
of any type.
- Parameter query: The Query object to match results againts.
- Returns: A tuple of data task and an observable for the resulting array of Entry's.
*/
public func fetchEntries(with query: Query) -> TaskObservable<[Entry]>
/**
Fetch a collection of Entries of a specified content type matching the query. The content_type
parameter is specified by passing in a generic parameter: a model class conforming to `EntryModel`.
- Parameter query: A QueryOn object to match results of the specified EntryModel against.
- Parameter completion: A handler being called on completion of the request.
- Returns: The data task being used, enables cancellation of requests.
*/
public func fetchEntries<EntryType>(with query: QueryOn<EntryType>, completion: ResultsHandler<[EntryType]>) -> URLSessionDataTask?
/**
Fetch a collection of Entries of a specified content type matching the query. The content_type
parameter is specified by passing in a generic parameter: a model class conforming to `EntryModel`.
- Parameter query: A QueryOn object to match results of the specified EntryModel against.
- Returns: A tuple of data task and an observable for the resulting array of EntryModel types.
*/
public func fetchEntries<EntryType>(with query: QueryOn<EntryType>) -> TaskObservable<[EntryType]>
/**
Fetch a collection of Assets from Contentful matching the specified query.
- Parameter query: The Query object to match results againts.
- Parameter completion: A handler being called on completion of the request.
- Returns: The data task being used, enables cancellation of requests.
*/
public func fetchAssets(with query: AssetQuery, completion: ResultsHandler<[Asset]>) -> URLSessionDataTask?
/**
Fetch a collection of Assets from Contentful matching the specified query.
- Parameter query: The Query object to match results againts.
- Returns: A tuple of data task and an observable for the resulting array of Assets.
*/
public func fetchAssets(query: AssetQuery) -> (task: URLSessionDataTask?, result: Observable<Result<[Asset]>>)
}
/// The available URL parameter names for queries; used internally by the various `Contentful.Query` types.
/// If you are constructing Dictionary's to pass into `Client` "fetch" methods, instead of taking advantage of "fetch" methods
/// that take `Query` types, use these static variables to avoid typos in query construction.
public struct QueryParameter {
static internal let contentType: String
static internal let select: String
static internal let order: String
static internal let limit: String
static internal let skip: String
static internal let include: String
static internal let locale: String
static internal let mimetypeGroup: String
static internal let fullTextSearch: String
}
/// Use types that conform to QueryableRange to perform queries with the four Range operators
/// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/ranges>
public protocol QueryableRange {
public var stringValue: String { get }
}
extension Int : QueryableRange {
public var stringValue: String { get }
}
extension String : QueryableRange {
public var stringValue: String { get }
}
extension Date : QueryableRange {
public var stringValue: String { get }
}
/// Use bounding boxes or bounding circles to perform queries on location-enabled content.
/// See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/locations-in-a-bounding-object>
public enum Bounds {
case box(bottomLeft: CLLocationCoordinate2D, topRight: CLLocationCoordinate2D)
case circle(center: CLLocationCoordinate2D, radius: Double)
}
public enum MimetypeGroup : String {
case attachment
case plaintext
case image
case audio
case video
case richtext
case presentation
case spreadsheet
case pdfdocument
case archive
case code
case markup
}
/**
Property-value query operations used for matching patterns on either "sys" or "fields" properties of `Asset`s and `Entry`s.
Each operation specifies a property name on the left-hand side, with a value to match on the right.
For instance, using the doesNotEqual operation in an a concrete Query like:
```
Query(where:"fields.name", .doesNotEqual("Happy Cat"))
```
would append the following to the http URL:
```
"fields.name[ne]=Happy%20Cat"
```
Refer to the documentation for the various Query classes for more information.
*/
public enum QueryOperation {
case equals(String)
case doesNotEqual(String)
case hasAll([String])
case includes([String])
case excludes([String])
case exists(Bool)
/// Full text search on a field.
case matches(String)
/// MARK: Ranges
case isLessThan(QueryableRange)
case isLessThanOrEqualTo(QueryableRange)
case isGreaterThan(QueryableRange)
case isGreaterThanOrEqualTo(QueryableRange)
/// Proximity searches.
case isNear(CLLocationCoordinate2D)
case isWithin(Query.Bounds)
}
public protocol AbstractQuery : class {
public init()
/// The parameters dictionary that are converted to `URLComponents` on the HTTP URL. Useful for debugging.
public var parameters: [String : String] { get set }
}
public extension AbstractQuery {
/**
Convenience intializer for creating a Query with a QueryOperation. See concrete types Query, FilterQuery, AssetQuery, and QueryOn
for more information and example usage.
- Parameter name: The name of the property you are performing the QueryOperation against. For instance,
`"sys.id"` or `"fields.yourFieldName"`
- Parameter operation: the QueryOperation
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public convenience init(where name: String, _ operation: QueryOperation, for locale: String? = default)
}
/// Protocol which enables concrete query implementations to be 'chained' together so that results
/// can be filtered by more than one QueryOperation or other query. Protocol extensions give default implementation
/// so that all concrete types, `Query`, `AssetQuery`, `FilterQuery`, and `QueryOn<EntryType>`, can use the same implementation.
public protocol ChainableQuery : AbstractQuery {
}
public extension ChainableQuery {
/**
Convenience initializer for a select operation query in which only the fields specified in the fieldNames property will be returned in the JSON response.
The `"sys"` dictionary is always requested by the SDK.
Note that if you are using the select operator with an instance `QueryOn<EntryType>`
that you must make properties that you are ommitting in the response (by not including them in your selections array) optional properties.
Example usage:
```
let query = try! QueryOn<Cat>(selectingFieldsNamed: ["fields.bestFriend", "fields.color", "fields.name"])
client.fetchEntries(with: query).observable.then { cats in
// Do stuff with cats.
}
```
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/select-operator>
- Parameter fieldNames: An array of field names to include in the JSON response.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
- Throws: Will throw an error if property names are not prefixed with `"fields."`, if selections go more than 2 levels deep
("fields.bestFriend.sys" is not valid), or if more than 99 properties are selected.
*/
public convenience init(selectingFieldsNamed fieldNames: [String], for locale: String? = default) throws
/**
Convenience initializer for a ordering responses by the values at the specified field. Field types that can be
specified are Strings, Numbers, or Booleans.
Example usage:
```
let query = try! Query(orderedBy: "sys.createdAt")
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/order>
and: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/order-with-multiple-parameters>
- Parameter propertyName: One or more properties on the Resource by which the results will be ordered.
- Parameter reverse: An Bool specifying if the returned order should be reversed or not. Defaults to `false`.
- Throws: Will throw an error if property names are not prefixed with either `"sys."` or `"fields."`.
*/
public convenience init(orderedBy propertyName: String..., reverse: Bool = default) throws
/**
Convenience initializer for a limiting responses to a certain number of values. Use in conjunction with the `skip` method
to paginate responses.
Example usage:
```
let query = try! Query(orderedBy: "sys.createdAt")
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
- Parameter numberOfResults: The number of results the response will be limited to.
*/
public convenience init(limitingResultsTo numberOfResults: UInt) throws
/**
Convenience initializer for a skipping the first `n` items in a response.
Use in conjunction with the `limit` method to paginate responses.
Example usage:
```
let query = try! Query(skippingTheFirst: 9)
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
- Parameter numberOfResults: The number of results that will be skipped in the query.
*/
public convenience init(skippingTheFirst numberOfResults: UInt)
/**
Instance method for select operation in which only the fields specified in the fieldNames property will be returned in the JSON response.
The `"sys"` dictionary is always requested by the SDK.
Note that if you are using the select operator with an instance `QueryOn<EntryType>`
that you must make properties that you are ommitting in the response (by not including them in your selections array) optional properties.
Example usage:
```
let query = try! QueryOn<Cat>()
query.select(fieldsNamed: ["fields.bestFriend", "fields.color", "fields.name"])
client.fetchEntries(with: query).observable.then { cats in
// Do stuff with cats.
}
```
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/select-operator>
- Parameter fieldNames: An array of field names to include in the JSON response.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
- Throws: Will throw an error if property names are not prefixed with `"fields."`, if selections go more than 2 levels deep
("fields.bestFriend.sys" is not valid), or if more than 99 properties are selected.
*/
public func select(fieldsNamed fieldNames: [String], locale: String? = default) throws
/**
Instance method for ordering responses by the values at the specified field. Field types that can be
specified are Strings, Numbers, or Booleans.
Example usage:
```
let query = try! Query(orderedBy: "sys.createdAt")
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/order>
and: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/order-with-multiple-parameters>
- Parameter propertyName: One or more properties on the Resource by which the results will be ordered.
- Parameter reverse: An Bool specifying if the returned order should be reversed or not. Defaults to `false`.
- Throws: Will throw an error if property names are not prefixed with either `"sys."` or `"fields."`.
*/
public func order(by propertyName: String..., reverse: Bool = default) throws
/**
Instance method for further mutating a query to limit responses to a certain number of values. Use in conjunction with the `skip` method
to paginate responses.
Example usage:
```
let query = try! Query(orderedBy: "sys.createdAt")
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
- Parameter numberOfResults: The number of results the response will be limited to.
*/
public func limit(to numberOfResults: UInt) throws
/**
Intance method for further mutating a query to skip the first `n` items in a response.
Use in conjunction with the `limit` method to paginate responses.
Example usage:
```
let query = try! Query(skippingTheFirst: 9)
client.fetchEntries(with: query).observable.then { entries in
// Do stuff with entries.
}
```
- Parameter numberOfResults: The number of results that will be skipped in the query.
*/
public func skip(theFirst numberOfResults: UInt)
/**
Convenience initializer for querying entries or assets in which all text and symbol fields contain
the specified, case-insensitive text parameter.
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/full-text-search>
- Parameter text: The text string to match against.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public convenience init(searchingFor text: String, for locale: String? = default) throws
/**
Instance method for appending a full-text search query to an existing query. Returned results will contain
either entries or assets in which all text and symbol fields contain the specified, case-insensitive text parameter.
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/full-text-search>
- Parameter text: The text string to match against.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public func search(for text: String)
}
/// A concrete implementation of ChainableQuery which can be used to make queries on either `/assets/`
/// or `/entries`. All methods from ChainableQuery are available.
public class Query : ChainableQuery {
/// The parameters dictionary that are converted to `URLComponents` (HTTP parameters/arguments) on the HTTP URL. Useful for debugging.
public var parameters: [String : String]
/// Designated initalizer for Query.
public required init()
}
/// Queries on Asset types. All methods from Query, and therefore ChainableQuery, are inherited and available.
public final class AssetQuery : Query {
/**
Convenience intializer for creating an AssetQuery with the "mimetype_group" parameter specified. Example usage:
```
let query = AssetQuery(whereMimetypeGroupIs: .image)
client.fetchAssets(with: query).observable.then { assets in
// Do stuff with assets.
}
```
- Parameter mimetypeGroup: The `mimetype_group` which all returned Assets will match.
*/
public convenience init(whereMimetypeGroupIs mimetypeGroup: MimetypeGroup)
/**
Instance method for mutating the query further to specify the mimetype group when querying assets.
- Parameter mimetypeGroup: The `mimetype_group` which all returned Assets will match.
*/
public func mimetypeGroup(is mimetypeGroup: MimetypeGroup)
}
/**
An additional query to filter by the properties of linked objects when searching on references.
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
and see the init<LinkType: EntryModel>(whereLinkAt fieldNameForLink: String, matches filterQuery: FilterQuery<LinkType>? = nil) methods
on QueryOn for example usage.
*/
public final class FilterQuery<EntryType> : AbstractQuery {
/// The parameters dictionary that are converted to `URLComponents` (HTTP parameters/arguments) on the HTTP URL. Useful for debugging.
public var parameters: [String : String]
/**
Convenience intializer for creating a QueryOn with a QueryOperation. Example usage:
```
let filterQuery = FilterQuery<Cat>(where: "fields.name", .matches("Happy Cat"))
let query = QueryOn<Cat>(whereLinkAt: "bestFriend", matches: filterQuery)
```
- Parameter name: The name of the property you are performing the QueryOperation against. For instance,
`"sys.id"` or `"fields.yourFieldName"`
- Parameter operation: the QueryOperation
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public convenience init(where name: String, _ operation: QueryOperation, for locale: String? = default)
/// Designated initializer for FilterQuery.
public init()
}
/**
A concrete implementation of AbstractQuery which requires that a model class conforming to `EntryType`
be passed in as a generic parameter.
The "content_type" parameter of the query will be set to the `contentTypeID`
of your `EntryType` conforming model class. `QueryOn<EntryType>` are chainable so complex queries can be constructed.
Operations that are only available when querying `Entry`s on specific content types (i.e. content_type must be set)
are available through this class.
*/
public final class QueryOn<EntryType> : ChainableQuery {
/// The parameters dictionary that are converted to `URLComponents` (HTTP parameters/arguments) on the HTTP URL. Useful for debugging.
public var parameters: [String : String]
/// Designated initializer for `QueryOn<EntryType>`.
public init()
/**
Convenience intializer for creating a QueryOn with a QueryOperation. Example usage:
```
let query = QueryOn<Cat>(where: "fields.color", .doesNotEqual("gray"))
```
- Parameter name: The name of the property you are performing the QueryOperation against. For instance,
`"sys.id"` or `"fields.yourFieldName"`
- Parameter operation: The QueryOperation.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public convenience init(where name: String, _ operation: QueryOperation, for locale: String? = default)
/**
Instance method for appending more QueryOperation's to further filter results on the API. Example usage:
```
let query = QueryOn<Cat>(where: "fields.color", .doesNotEqual("gray"))
// Mutate the query further.
query.where("fields.lives", .equals("9"))
```
- Parameter name: The name of the property you are performing the QueryOperation against. For instance,
`"sys.id" or `"fields.yourFieldName"`
- Parameter operation: the QueryOperation
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public func `where`(_ name: String, _ operation: QueryOperation, for locale: String? = default)
/**
Convenience initalizer for performing searches where Linked objects at the specified linking field match the filtering query.
For instance, if you want to query all Entry's of type "cat" where cat's linked via the "bestFriend" field have names that match "Happy Cat"
the code would look like the following:
```
let filterQuery = FilterQuery<Cat>(where: "fields.name", .matches("Happy Cat"))
let query = QueryOn<Cat>(whereLinkAt: "bestFriend", matches: filterQuery)
client.fetchEntries(with: query).observable.then { catsWithHappyCatAsBestFriend in
// Do stuff with catsWithHappyCatAsBestFriend
}
```
See: <https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/search-on-references>
- Parameter fieldNameForLink: The name of the property which contains a link to another Entry.
- Parameter filterQuery: The optional filter query applied to the linked objects which are being searched.
- Parameter locale: An optional locale argument to return localized results. If unspecified, the locale originally
set on the `Client` instance is used.
*/
public convenience init<LinkType>(whereLinkAt fieldNameForLink: String, matches filterQuery: FilterQuery<LinkType>? = default, for locale: String? = default)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment