Update extension documentation
This commit is contained in:
parent
7410d89f87
commit
8bc1f18e12
|
@ -21,6 +21,7 @@ This version also cleans up the code and makes changes to conform to the latest
|
|||
* All previously deprecated features have been removed.
|
||||
* `ApiService` moves the `type` param before the `httpMethod`, since `httpMethod` now has a default value.
|
||||
* `ApiRoute` and `ApiService` now use enum-based HTTP methods instead of string-based ones.
|
||||
* `DispatchQueue+Async` now requires that you explicitly define `seconds` when using that `asyncAfter` function.
|
||||
* `URL+Global` `appStoreUrl(forAppId:)` now returns an optional url.
|
||||
|
||||
|
||||
|
|
|
@ -13,12 +13,18 @@ import Foundation
|
|||
*/
|
||||
extension Bundle: BundleInformation {
|
||||
|
||||
/**
|
||||
Get the bundle build number.
|
||||
*/
|
||||
public var buildNumber: String {
|
||||
let key = String(kCFBundleVersionKey)
|
||||
let version = infoDictionary?[key] as? String
|
||||
return version ?? ""
|
||||
}
|
||||
|
||||
/**
|
||||
Get the bundle version number.
|
||||
*/
|
||||
public var versionNumber: String {
|
||||
let key = "CFBundleShortVersionString"
|
||||
let version = infoDictionary?[key] as? String
|
||||
|
|
|
@ -10,6 +10,10 @@ import Foundation
|
|||
|
||||
public extension Array where Element: Comparable & Strideable {
|
||||
|
||||
/**
|
||||
Create an array using a set of values from the provided
|
||||
`range`, stepping `stepSize` between each value.
|
||||
*/
|
||||
init(_ range: ClosedRange<Element>, stepSize: Element.Stride) {
|
||||
self = Array(stride(from: range.lowerBound, through: range.upperBound, by: stepSize))
|
||||
}
|
||||
|
@ -17,6 +21,10 @@ public extension Array where Element: Comparable & Strideable {
|
|||
|
||||
public extension Array where Element == Double {
|
||||
|
||||
/**
|
||||
Create an array using a set of values from the provided
|
||||
`range`, stepping `stepSize` between each value.
|
||||
*/
|
||||
init(_ range: ClosedRange<Element>, stepSize: Element.Stride) {
|
||||
self = Array(stride(from: range.lowerBound, through: range.upperBound, by: stepSize))
|
||||
.map { $0.roundedWithPrecision(from: stepSize) }
|
||||
|
|
|
@ -10,5 +10,8 @@ import Foundation
|
|||
|
||||
public extension Collection {
|
||||
|
||||
/**
|
||||
Check whether or not the collection has any elements.
|
||||
*/
|
||||
var hasContent: Bool { !isEmpty }
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@ import Foundation
|
|||
|
||||
public extension Collection where Element: Hashable {
|
||||
|
||||
/**
|
||||
Get distinct values from the collection, preserving the
|
||||
original order.
|
||||
*/
|
||||
func distinct() -> [Element] {
|
||||
reduce([]) { $0.contains($1) ? $0 : $0 + [$1] }
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import Foundation
|
|||
public extension Sequence {
|
||||
|
||||
/**
|
||||
Batch the sequence into groups of a certain max size.
|
||||
Batch the sequence into groups of a certain batch size.
|
||||
*/
|
||||
func batched(withBatchSize size: Int) -> [[Element]] {
|
||||
var result: [[Element]] = []
|
||||
|
|
|
@ -15,6 +15,11 @@ public enum PreferredClosestValue {
|
|||
|
||||
public extension Comparable {
|
||||
|
||||
/**
|
||||
Get the closest value in the provided `collection`. The
|
||||
provided `preferred` value whether to prefer a `greater`
|
||||
or a `lower` value if no exact match was found.
|
||||
*/
|
||||
func closest(in collection: [Self], preferred: PreferredClosestValue) -> Self? {
|
||||
if collection.contains(self) { return self }
|
||||
let sorted = collection.sorted()
|
||||
|
|
|
@ -11,14 +11,14 @@ import Foundation
|
|||
public extension Comparable {
|
||||
|
||||
/**
|
||||
Limit the value to a range.
|
||||
Limit the value to a closed range.
|
||||
*/
|
||||
mutating func limit(to range: ClosedRange<Self>) {
|
||||
self = limited(to: range)
|
||||
}
|
||||
|
||||
/**
|
||||
Return the value limited to a range.
|
||||
Return the value limited to a closed range.
|
||||
|
||||
This could be implemented in a oneliner, but that would
|
||||
make the code less readable.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Comparable+Limit.swift
|
||||
// ComparisonResult+Shortcuts.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2020-06-09.
|
||||
|
@ -10,6 +10,17 @@ import Foundation
|
|||
|
||||
public extension ComparisonResult {
|
||||
|
||||
static var ascending: ComparisonResult { return .orderedAscending }
|
||||
static var descending: ComparisonResult { return .orderedDescending }
|
||||
/**
|
||||
This is a shorthand to `.orderedAscending`
|
||||
*/
|
||||
static var ascending: ComparisonResult {
|
||||
.orderedAscending
|
||||
}
|
||||
|
||||
/**
|
||||
This is a shorthand to `.orderedDescending`
|
||||
*/
|
||||
static var descending: ComparisonResult {
|
||||
.orderedDescending
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public extension DispatchQueue {
|
|||
Perform an operation after a time interval.
|
||||
*/
|
||||
func asyncAfter(
|
||||
_ seconds: TimeInterval,
|
||||
seconds: TimeInterval,
|
||||
execute: @escaping () -> Void) {
|
||||
let milli = Int(seconds * 1000)
|
||||
asyncAfter(.milliseconds(milli), execute: execute)
|
||||
|
|
|
@ -10,6 +10,9 @@ import Foundation
|
|||
|
||||
public extension Decimal {
|
||||
|
||||
/**
|
||||
The value's `Double` value representation.
|
||||
*/
|
||||
var doubleValue: Double {
|
||||
Double(truncating: self as NSNumber)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,13 @@ import Foundation
|
|||
|
||||
public extension Optional {
|
||||
|
||||
/**
|
||||
Whether or not the value is `nil`.
|
||||
*/
|
||||
var isNil: Bool { self == nil }
|
||||
|
||||
/**
|
||||
Whether or not the value is set and not `nil`.
|
||||
*/
|
||||
var isSet: Bool { self != nil }
|
||||
}
|
||||
|
|
|
@ -12,11 +12,17 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
|
||||
/**
|
||||
Base64 decode the string.
|
||||
*/
|
||||
func base64Decoded() -> String? {
|
||||
guard let data = Data(base64Encoded: self) else { return nil }
|
||||
return String(data: data, encoding: .utf8)
|
||||
}
|
||||
|
||||
/**
|
||||
Base64 encode the string.
|
||||
*/
|
||||
func base64Encoded() -> String? {
|
||||
data(using: .utf8)?.base64EncodedString()
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
|
||||
/**
|
||||
Check whether or not the string contains another string.
|
||||
*/
|
||||
func contains(_ string: String, caseSensitive: Bool) -> Bool {
|
||||
caseSensitive
|
||||
? contains(string)
|
||||
|
|
|
@ -10,10 +10,17 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
|
||||
/**
|
||||
Check whether or not the string has any content.
|
||||
*/
|
||||
var hasContent: Bool {
|
||||
!isEmpty
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether or not the string has any trimmed content
|
||||
after leading and trailing whitespaces are removed.
|
||||
*/
|
||||
var hasTrimmedContent: Bool {
|
||||
!trimmingCharacters(in: .whitespaces).isEmpty
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ public extension String {
|
|||
This function cleans up the string from space and other
|
||||
strange characters that can be added to the string when
|
||||
the user performs a dictation.
|
||||
|
||||
This happens on the Apple TV, when a user uses a remote
|
||||
to dictate text into a text field. The resulting string
|
||||
contains a bunch of additional information and not just
|
||||
the plain string.
|
||||
*/
|
||||
func cleanedUpAfterDictation() -> String {
|
||||
self
|
||||
|
|
|
@ -8,11 +8,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
This extension is internally used by `TagTextView` and will
|
||||
not be public in order to not collide with the extension in
|
||||
`SwiftKit`. If you want to use the logic, import `SwiftKit`.
|
||||
*/
|
||||
public extension String {
|
||||
|
||||
private static let allowedCharacters = NSCharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-")
|
||||
|
|
|
@ -10,6 +10,9 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
|
||||
/**
|
||||
Split the string using a list of separators.
|
||||
*/
|
||||
func split(by separators: [String]) -> [String] {
|
||||
let separators = CharacterSet(charactersIn: separators.joined())
|
||||
return components(separatedBy: separators)
|
||||
|
|
|
@ -12,6 +12,13 @@ import Foundation
|
|||
|
||||
public extension String {
|
||||
|
||||
/**
|
||||
URL encode the string.
|
||||
|
||||
This will first call `addingPercentEncoding`, using the
|
||||
`.urlPathAllowed` character set, then replace every `&`
|
||||
with `%26`.
|
||||
*/
|
||||
func urlEncoded() -> String? {
|
||||
addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)?
|
||||
.replacingOccurrences(of: "&", with: "%26")
|
||||
|
|
|
@ -10,8 +10,15 @@ import Foundation
|
|||
|
||||
public extension URL {
|
||||
|
||||
/**
|
||||
This url leads to the Apple subscription screen for the
|
||||
currently logged in account.
|
||||
*/
|
||||
static let userSubscriptions = URL(string: "https://apps.apple.com/account/subscriptions")
|
||||
|
||||
/**
|
||||
This url leads to the App Store page for a certain app.
|
||||
*/
|
||||
static func appStoreUrl(forAppId appId: Int) -> URL? {
|
||||
|
||||
URL(string: "https://itunes.apple.com/app/id\(appId)")
|
||||
|
|
|
@ -10,21 +10,35 @@ import Foundation
|
|||
|
||||
public extension URL {
|
||||
|
||||
/**
|
||||
Get the url's query parameters.
|
||||
*/
|
||||
var queryParameters: [URLQueryItem] {
|
||||
URLComponents(string: absoluteString)?.queryItems ?? [URLQueryItem]()
|
||||
}
|
||||
|
||||
/**
|
||||
Get the url's query parameters as a dictionary.
|
||||
*/
|
||||
var queryParametersDictionary: [String: String] {
|
||||
var result = [String: String]()
|
||||
queryParameters.forEach { result[$0.name] = $0.value ?? "" }
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get a certain query parameter by name.
|
||||
*/
|
||||
func queryParameter(named name: String) -> URLQueryItem? {
|
||||
queryParameters.first { $0.isNamed(name) }
|
||||
}
|
||||
|
||||
/**
|
||||
Set the value of a certain query parameter.
|
||||
|
||||
This will return a new url where the query parameter is
|
||||
either updated or added.
|
||||
*/
|
||||
func setQueryParameter(name: String, value: String, urlEncode: Bool = true) -> URL? {
|
||||
guard let urlString = absoluteString.components(separatedBy: "?").first else { return self }
|
||||
let param = queryParameter(named: name)
|
||||
|
@ -34,6 +48,12 @@ public extension URL {
|
|||
return URL(string: "\(urlString)?\(dictionary.queryString)")
|
||||
}
|
||||
|
||||
/**
|
||||
Set the value of a certain set of query parameters.
|
||||
|
||||
This will return a new url, where every query parameter
|
||||
in the dictionary is either updated or added.
|
||||
*/
|
||||
func setQueryParameters(_ dict: [String: String], urlEncode: Bool = true) -> URL? {
|
||||
var result = self
|
||||
dict.forEach {
|
||||
|
|
|
@ -10,12 +10,19 @@ import Foundation
|
|||
|
||||
public extension UserDefaults {
|
||||
|
||||
/**
|
||||
Returns the codable object associated with the provided
|
||||
key, provided that the persisted value can be decoded.
|
||||
*/
|
||||
func codable<T: Codable>(forKey key: String) -> T? {
|
||||
guard let data = object(forKey: key) as? Data else { return nil }
|
||||
let value = try? JSONDecoder().decode(T.self, from: data)
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
Persist a codable item.
|
||||
*/
|
||||
func setCodable<T: Codable>(_ codable: T, forKey key: String) {
|
||||
let data = try? JSONEncoder().encode(codable)
|
||||
set(data, forKey: key)
|
||||
|
|
Loading…
Reference in New Issue