From e6550e201cc00fe60f7f56861209df0da6aeeeae Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 4 Aug 2017 21:53:37 -0300 Subject: [PATCH 001/201] New attributed string operators. (#218) * New attributed string operators. Adding missing string and array exemples. * Update CHANGELOG.md * Fix return types and test methods names. * Update CHANGELOG.md --- CHANGELOG.md | 7 +- .../Cocoa/NSAttributedStringExtensions.swift | 31 ++++++ .../Foundation/ArrayExtensions.swift | 8 +- .../Foundation/StringExtensions.swift | 6 +- .../NSAttributedStringExtensionsTests.swift | 100 +++++++++++++++++- 5 files changed, 146 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebdcaca05..65134e460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,11 @@ All notable changes to this project will be documented in this file. N/A ### Enhancements -N/A - +- New **NSAttributedString** extensions + - added `NSAttributedString + NSAttributedString` operator to return a new appended NSAttributedString. + - added `NSAttributedString += String` operator to append a string to a NSAttributedString. + - added `NSAttributedString + String` operator to return a new appended NSAttributedString. [#218](https://github.com/SwifterSwift/SwifterSwift/pull/218) by [@LucianoPAlmeida](https://github.com/LucianoPAlmeida) + ### Bugfixes N/A diff --git a/Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift b/Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift index 4e85d6248..e02a76990 100644 --- a/Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift @@ -89,4 +89,35 @@ public extension NSAttributedString { ns.append(rhs) lhs = ns } + + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString and return a new NSAttributedString instance. + /// + /// - Parameters: + /// - lhs: NSAttributedString to add. + /// - rhs: NSAttributedString to add. + /// - Returns: New instance with added NSAttributedString. + public static func + (lhs: NSAttributedString, rhs: NSAttributedString) -> NSAttributedString { + let ns = NSMutableAttributedString(attributedString: lhs) + ns.append(rhs) + return NSAttributedString(attributedString: ns) + } + + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString. + /// + /// - Parameters: + /// - lhs: NSAttributedString to add to. + /// - rhs: String to add. + public static func += (lhs: inout NSAttributedString, rhs: String) { + lhs += NSAttributedString(string: rhs) + } + + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString and return a new NSAttributedString instance. + /// + /// - Parameters: + /// - lhs: NSAttributedString to add. + /// - rhs: String to add. + /// - Returns: New instance with added NSAttributedString. + public static func + (lhs: NSAttributedString, rhs: String) -> NSAttributedString { + return lhs + NSAttributedString(string: rhs) + } } diff --git a/Sources/Extensions/Foundation/ArrayExtensions.swift b/Sources/Extensions/Foundation/ArrayExtensions.swift index 28974ed37..bab8e0616 100755 --- a/Sources/Extensions/Foundation/ArrayExtensions.swift +++ b/Sources/Extensions/Foundation/ArrayExtensions.swift @@ -261,7 +261,10 @@ public extension Array { } /// SwifterSwift: Reduces an array while returning each interim combination. - /// + /// + /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] + /// // It also works for other types! + /// /// - Parameters: /// - initial: initial value. /// - next: closure that combines the accumulating value and next element of the array. @@ -276,6 +279,9 @@ public extension Array { /// SwifterSwift: Filtered and map in a single operation. /// + /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] + /// // It also works for other types! + /// /// - Parameters: /// - isIncluded: condition of inclusion to evaluate each element against. /// - transform: transform element function to evaluate every element. diff --git a/Sources/Extensions/Foundation/StringExtensions.swift b/Sources/Extensions/Foundation/StringExtensions.swift index b74494149..f3388ec3d 100755 --- a/Sources/Extensions/Foundation/StringExtensions.swift +++ b/Sources/Extensions/Foundation/StringExtensions.swift @@ -190,8 +190,10 @@ public extension String { } /// SwifterSwift: Check if string is a valid file URL. - /// - public var isValidFileUrl: Bool { + /// + /// "file://Documents/file.txt".isValidFileUrl -> true + /// + public var isValidFileUrl: Bool { return URL(string: self)?.isFileURL ?? false } diff --git a/Tests/CocoaTests/NSAttributedStringExtensionsTests.swift b/Tests/CocoaTests/NSAttributedStringExtensionsTests.swift index fa87ac8d7..3f09eeb6c 100644 --- a/Tests/CocoaTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/CocoaTests/NSAttributedStringExtensionsTests.swift @@ -86,7 +86,7 @@ class NSAttributedStringExtensionsTests: XCTestCase { #if !os(macOS) && !os(tvOS) // MARK: - Operators - func testAppending() { + func testPlusEqual() { var string = NSAttributedString(string: "Test").italicized.underlined.struckthrough string += NSAttributedString(string: " Appending").bolded @@ -117,5 +117,103 @@ class NSAttributedStringExtensionsTests: XCTestCase { XCTAssertEqual(filteredAttributes.count, 1) } + + func testPlusAttributedString() { + let a : NSAttributedString = NSAttributedString(string: "Test").italicized.underlined.struckthrough + let b : NSAttributedString = NSAttributedString(string: " Appending").bolded + let result = a + b + + XCTAssertEqual(result.string, "Test Appending") + + var attributes = result.attributes(at: 0, effectiveRange: nil) + var filteredAttributes = attributes.filter { (key, value) -> Bool in + var valid = false + if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { + valid = true + } + if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + + return valid + } + + XCTAssertEqual(filteredAttributes.count, 3) + + attributes = result.attributes(at: 5, effectiveRange: nil) + filteredAttributes = attributes.filter { (key, value) -> Bool in + return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) + } + + XCTAssertEqual(filteredAttributes.count, 1) + } + + func testPlusEqualString() { + var string = NSAttributedString(string: "Test").italicized.underlined.struckthrough + string += " Appending" + + XCTAssertEqual(string.string, "Test Appending") + + var attributes = string.attributes(at: 0, effectiveRange: nil) + var filteredAttributes = attributes.filter { (key, value) -> Bool in + var valid = false + if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { + valid = true + } + if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + + return valid + } + + XCTAssertEqual(filteredAttributes.count, 3) + + attributes = string.attributes(at: 5, effectiveRange: nil) + filteredAttributes = attributes.filter { (key, value) -> Bool in + return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) + } + + XCTAssertEqual(filteredAttributes.count, 0) + } + + func testPlusString() { + let a : NSAttributedString = NSAttributedString(string: "Test").italicized.underlined.struckthrough + let b : String = " Appending" + let result = a + b + + XCTAssertEqual(result.string, "Test Appending") + + var attributes = result.attributes(at: 0, effectiveRange: nil) + var filteredAttributes = attributes.filter { (key, value) -> Bool in + var valid = false + if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { + valid = true + } + if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + valid = true + } + + return valid + } + + XCTAssertEqual(filteredAttributes.count, 3) + + attributes = result.attributes(at: 5, effectiveRange: nil) + filteredAttributes = attributes.filter { (key, value) -> Bool in + return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) + } + + XCTAssertEqual(filteredAttributes.count, 0) + } #endif } From ae7d3033dd325d8e76c3ac34ecb4c82210b881f3 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 9 Aug 2017 13:14:05 +0300 Subject: [PATCH 002/201] Fixes #219 --- .../Foundation/ArrayExtensions.swift | 516 ++++++++---------- 1 file changed, 240 insertions(+), 276 deletions(-) diff --git a/Sources/Extensions/Foundation/ArrayExtensions.swift b/Sources/Extensions/Foundation/ArrayExtensions.swift index bab8e0616..58a373827 100755 --- a/Sources/Extensions/Foundation/ArrayExtensions.swift +++ b/Sources/Extensions/Foundation/ArrayExtensions.swift @@ -37,7 +37,7 @@ public extension Array where Element: FloatingPoint { // http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift return isEmpty ? 0 : reduce(0, +) / Element(count) } - + /// SwifterSwift: Sum of all elements in array. /// /// [1.2, 2.3, 4.5, 3.4, 4.5].sum -> 15.9 @@ -58,7 +58,6 @@ public extension Array { /// [1, 2, 3, 4, 5].item(at: 2) -> 3 /// [1.2, 2.3, 4.5, 3.4, 4.5].item(at: 3) -> 3.4 /// ["h", "e", "l", "l", "o"].item(at: 10) -> nil - /// // It also works for other types! /// /// - Parameter index: index of element. /// - Returns: optional element (if exists). @@ -71,7 +70,6 @@ public extension Array { /// /// [1, 2, 3, 4, 5].pop() // returns 5 and remove it from the array. /// [].pop() // returns nil since the array is empty. - /// // It also works for other types! /// /// - Returns: last element in array (if applicable). @discardableResult public mutating func pop() -> Element? { @@ -82,7 +80,6 @@ public extension Array { /// /// [2, 3, 4, 5].prepend(1) -> [1, 2, 3, 4, 5] /// ["e", "l", "l", "o"].prepend("h") -> ["h", "e", "l", "l", "o"] - /// // It also works for other types! /// /// - Parameter newElement: element to insert. public mutating func prepend(_ newElement: Element) { @@ -93,7 +90,6 @@ public extension Array { /// /// [1, 2, 3, 4].push(5) -> [1, 2, 3, 4, 5] /// ["h", "e", "l", "l"].push("o") -> ["h", "e", "l", "l", "o"] - /// // It also works for other types! /// /// - Parameter newElement: element to insert. public mutating func push(_ newElement: Element) { @@ -104,15 +100,14 @@ public extension Array { /// /// [1, 2, 3, 4, 5].safeSwap(from: 3, to: 0) -> [4, 2, 3, 1, 5] /// ["h", "e", "l", "l", "o"].safeSwap(from: 1, to: 0) -> ["e", "h", "l", "l", "o"] - /// // It also works for other types! /// /// - Parameters: /// - index: index of first element. /// - otherIndex: index of other element. public mutating func safeSwap(from index: Int, to otherIndex: Int) { guard index != otherIndex, - startIndex.. [4, 2, 3, 1, 5] /// ["h", "e", "l", "l", "o"].swap(from: 1, to: 0) -> ["e", "h", "l", "l", "o"] - /// // It also works for other types! /// /// - Parameters: /// - index: index of first element. @@ -128,317 +122,297 @@ public extension Array { public mutating func swap(from index: Int, to otherIndex: Int) { Swift.swap(&self[index], &self[otherIndex]) } - - /// SwifterSwift: Get first index where condition is met. + + /// SwifterSwift: Get first index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 6].firstIndex { $0 % 2 == 0 } -> 3 - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: first index where the specified condition evaluates to true. (optional) - public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { - for (index, value) in lazy.enumerated() { - if try condition(value) { return index } - } - return nil - } - - /// SwifterSwift: Get last index where condition is met. + /// - Returns: first index where the specified condition evaluates to true. (optional) + public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { + for (index, value) in lazy.enumerated() { + if try condition(value) { return index } + } + return nil + } + + /// SwifterSwift: Get last index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 8].lastIndex { $0 % 2 == 0 } -> 6 - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: last index where the specified condition evaluates to true. (optional) - public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { - for (index, value) in lazy.enumerated().reversed() { - if try condition(value) { return index } - } - return nil - } - - /// SwifterSwift: Get all indices where condition is met. + /// - Returns: last index where the specified condition evaluates to true. (optional) + public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { + for (index, value) in lazy.enumerated().reversed() { + if try condition(value) { return index } + } + return nil + } + + /// SwifterSwift: Get all indices where condition is met. /// /// [1, 7, 1, 2, 4, 1, 8].indices(where: { $0 == 1 }) -> [0, 2, 5] - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: all indices where the specified condition evaluates to true. (optional) - public func indices(where condition: (Element) throws -> Bool) rethrows -> [Int]? { - var indicies: [Int] = [] - for (index, value) in lazy.enumerated() { - if try condition(value) { indicies.append(index) } - } - return indicies.isEmpty ? nil : indicies - } - - /// SwifterSwift: Check if all elements in array match a conditon. + /// - Returns: all indices where the specified condition evaluates to true. (optional) + public func indices(where condition: (Element) throws -> Bool) rethrows -> [Int]? { + var indicies: [Int] = [] + for (index, value) in lazy.enumerated() { + if try condition(value) { indicies.append(index) } + } + return indicies.isEmpty ? nil : indicies + } + + /// SwifterSwift: Check if all elements in array match a conditon. /// /// [2, 2, 4].all(matching: {$0 % 2 == 0}) -> true /// [1,2, 2, 4].all(matching: {$0 % 2 == 0}) -> false - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: true when all elements in the array match the specified condition. - public func all(matching condition: (Element) throws -> Bool) rethrows -> Bool { - return try !contains { try !condition($0) } - } - - /// SwifterSwift: Check if no elements in array match a conditon. + /// - Returns: true when all elements in the array match the specified condition. + public func all(matching condition: (Element) throws -> Bool) rethrows -> Bool { + return try !contains { try !condition($0) } + } + + /// SwifterSwift: Check if no elements in array match a conditon. /// /// [2, 2, 4].none(matching: {$0 % 2 == 0}) -> false /// [1, 3, 5, 7].none(matching: {$0 % 2 == 0}) -> true - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: true when no elements in the array match the specified condition. - public func none(matching condition: (Element) throws -> Bool) rethrows -> Bool { - return try !contains { try condition($0) } - } - - /// SwifterSwift: Get last element that satisfies a conditon. + /// - Returns: true when no elements in the array match the specified condition. + public func none(matching condition: (Element) throws -> Bool) rethrows -> Bool { + return try !contains { try condition($0) } + } + + /// SwifterSwift: Get last element that satisfies a conditon. /// /// [2, 2, 4, 7].last(where: {$0 % 2 == 0}) -> 4 - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: the last element in the array matching the specified condition. (optional) - public func last(where condition: (Element) throws -> Bool) rethrows -> Element? { - for element in reversed() { - if try condition(element) { return element } - } - return nil - } - - /// SwifterSwift: Filter elements based on a rejection condition. + /// - Returns: the last element in the array matching the specified condition. (optional) + public func last(where condition: (Element) throws -> Bool) rethrows -> Element? { + for element in reversed() { + if try condition(element) { return element } + } + return nil + } + + /// SwifterSwift: Filter elements based on a rejection condition. /// /// [2, 2, 4, 7].reject(where: {$0 % 2 == 0}) -> [7] - /// // It also works for other types! /// /// - Parameter condition: to evaluate the exclusion of an element from the array. - /// - Returns: the array with rejected values filtered from it. - public func reject(where condition: (Element) throws -> Bool) rethrows -> [Element] { - return try filter { return try !condition($0) } - } - - /// SwifterSwift: Get element count based on condition. + /// - Returns: the array with rejected values filtered from it. + public func reject(where condition: (Element) throws -> Bool) rethrows -> [Element] { + return try filter { return try !condition($0) } + } + + /// SwifterSwift: Get element count based on condition. /// /// [2, 2, 4, 7].count(where: {$0 % 2 == 0}) -> 3 - /// // It also works for all other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: number of times the condition evaluated to true. - public func count(where condition: (Element) throws -> Bool) rethrows -> Int { - var count = 0 - for element in self { - if try condition(element) { count += 1 } - } - return count - } - - /// SwifterSwift: Iterate over a collection in reverse order. (right to left) + /// - Returns: number of times the condition evaluated to true. + public func count(where condition: (Element) throws -> Bool) rethrows -> Int { + var count = 0 + for element in self { + if try condition(element) { count += 1 } + } + return count + } + + /// SwifterSwift: Iterate over a collection in reverse order. (right to left) /// /// [0, 2, 4, 7].forEachReversed({ print($0)}) -> //Order of print: 7,4,2,0 - /// // It also works for other types! /// /// - Parameter body: a closure that takes an element of the array as a parameter. - public func forEachReversed(_ body: (Element) throws -> Void) rethrows { - try reversed().forEach { try body($0) } - } + public func forEachReversed(_ body: (Element) throws -> Void) rethrows { + try reversed().forEach { try body($0) } + } /// SwifterSwift: Calls given closure with each element where condition is true. /// /// [0, 2, 4, 7].forEach( where: {$0 % 2 == 0}, body: { print($0)}) -> //print: 0, 2, 4 - /// // It also works for all other types! /// /// - Parameters: - /// - condition: condition to evaluate each element against. - /// - body: a closure that takes an element of the array as a parameter. - public func forEach(where condition: (Element) throws -> Bool, body: (Element) throws -> Void) rethrows { - for element in self where try condition(element) { - try body(element) - } - } + /// - condition: condition to evaluate each element against. + /// - body: a closure that takes an element of the array as a parameter. + public func forEach(where condition: (Element) throws -> Bool, body: (Element) throws -> Void) rethrows { + for element in self where try condition(element) { + try body(element) + } + } /// SwifterSwift: Reduces an array while returning each interim combination. - /// - /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] - /// // It also works for other types! - /// + /// + /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] + /// /// - Parameters: - /// - initial: initial value. - /// - next: closure that combines the accumulating value and next element of the array. - /// - Returns: an array of the final accumulated value and each interim combination. - public func accumulate(initial: U, next: (U, Element) throws -> U) rethrows -> [U] { - var runningTotal = initial - return try map { element in - runningTotal = try next(runningTotal, element) - return runningTotal - } - } - - /// SwifterSwift: Filtered and map in a single operation. - /// - /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] - /// // It also works for other types! - /// + /// - initial: initial value. + /// - next: closure that combines the accumulating value and next element of the array. + /// - Returns: an array of the final accumulated value and each interim combination. + public func accumulate(initial: U, next: (U, Element) throws -> U) rethrows -> [U] { + var runningTotal = initial + return try map { element in + runningTotal = try next(runningTotal, element) + return runningTotal + } + } + + /// SwifterSwift: Filtered and map in a single operation. + /// + /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] + /// /// - Parameters: - /// - isIncluded: condition of inclusion to evaluate each element against. - /// - transform: transform element function to evaluate every element. - /// - Returns: Return an filtered and mapped array. - public func filtered(_ isIncluded: (Element) throws -> Bool, map transform: (Element) throws -> T) rethrows -> [T] { - return try flatMap({ - if try isIncluded($0) { - return try transform($0) - } - return nil - }) - } - - - /// SwifterSwift: Keep elements of Array while condition is true. + /// - isIncluded: condition of inclusion to evaluate each element against. + /// - transform: transform element function to evaluate every element. + /// - Returns: Return an filtered and mapped array. + public func filtered(_ isIncluded: (Element) throws -> Bool, map transform: (Element) throws -> T) rethrows -> [T] { + return try flatMap({ + if try isIncluded($0) { + return try transform($0) + } + return nil + }) + } + + + /// SwifterSwift: Keep elements of Array while condition is true. /// /// [0, 2, 4, 7].keep( where: {$0 % 2 == 0}) -> [0, 2, 4] - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - public mutating func keep(while condition: (Element) throws -> Bool) rethrows { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - self = Array(self[startIndex.. Bool) rethrows { + for (index, element) in lazy.enumerated() { + if try !condition(element) { + self = Array(self[startIndex.. [0, 2, 4] - /// // It also works for other types! /// /// - Parameter condition: condition to evaluate each element against. - /// - Returns: All elements up until condition evaluates to false. - public func take(while condition: (Element) throws -> Bool) rethrows -> [Element] { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - return Array(self[startIndex.. Bool) rethrows -> [Element] { + for (index, element) in lazy.enumerated() { + if try !condition(element) { + return Array(self[startIndex.. [6, 8] - /// // It also works for other types! /// /// - Parameter condition: condition to eveluate each element against. - /// - Returns: All elements after the condition evaluates to false. - public func skip(while condition: (Element) throws-> Bool) rethrows -> [Element] { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - return Array(self[index.. //print: [0, 2], [4, 7] - /// [0, 2, 4, 7, 6].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7], [6] - /// // It also works for all other types! - /// - /// - Parameters: - /// - slice: size of array in each interation. - /// - body: a closure that takes an array of slice size as a parameter. - public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { - guard slice > 0, !isEmpty else { return } - - var value : Int = 0 - while value < count { - try body(Array(self[Swift.max(value,startIndex).. [[0, 2], [4, 7]] - /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] - /// // It also works for all other types! - /// - /// - Parameters: - /// - size: The size of the slices to be returned. - public func group(by size: Int) -> [[Element]]? { - //Inspired by: https://lodash.com/docs/4.17.4#chunk - guard size > 0, !isEmpty else { return nil } - var value : Int = 0 - var slices : [[Element]] = [] - while value < count { - slices.append(Array(self[Swift.max(value,startIndex).. [ "evens" : [0, 2, 4], "odds" : [5, 7] ] - /// // It also works for all other types! - /// - /// - Parameter getKey: Clousure to define the key for each element. - /// - Returns: A dictionary with values grouped with keys. - public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { - var group : [K: [Element]] = [:] - for value in self { - let key = try keyForValue(value) - group[key] = (group[key] ?? []) + [value] - } - return group - } - - /// SwifterSwift: Returns a new rotated array by the given places. - /// - /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] - /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] - /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] - /// // It also works for all other types! - /// - /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - /// - Returns: The new rotated array - public func rotated(by places: Int) -> [Element] { - //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate - guard places != 0 && places < count else { - return self - } - var array : [Element] = self - if places > 0 { - let range = (array.count - places).. [4,1,2,3] - /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] - /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] - /// // It also works for all other types! - /// - /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - public mutating func rotate(by places: Int) { - self = rotated(by: places) - } + /// - Returns: All elements after the condition evaluates to false. + public func skip(while condition: (Element) throws-> Bool) rethrows -> [Element] { + for (index, element) in lazy.enumerated() { + if try !condition(element) { + return Array(self[index.. //print: [0, 2], [4, 7] + /// [0, 2, 4, 7, 6].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7], [6] + /// + /// - Parameters: + /// - slice: size of array in each interation. + /// - body: a closure that takes an array of slice size as a parameter. + public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { + guard slice > 0, !isEmpty else { return } + + var value : Int = 0 + while value < count { + try body(Array(self[Swift.max(value,startIndex).. [[0, 2], [4, 7]] + /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] + /// + /// - Parameters: + /// - size: The size of the slices to be returned. + public func group(by size: Int) -> [[Element]]? { + //Inspired by: https://lodash.com/docs/4.17.4#chunk + guard size > 0, !isEmpty else { return nil } + var value : Int = 0 + var slices : [[Element]] = [] + while value < count { + slices.append(Array(self[Swift.max(value,startIndex).. [ "evens" : [0, 2, 4], "odds" : [5, 7] ] + /// + /// - Parameter getKey: Clousure to define the key for each element. + /// - Returns: A dictionary with values grouped with keys. + public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { + var group : [K: [Element]] = [:] + for value in self { + let key = try keyForValue(value) + group[key] = (group[key] ?? []) + [value] + } + return group + } + + /// SwifterSwift: Returns a new rotated array by the given places. + /// + /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] + /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] + /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] + /// + /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Returns: The new rotated array + public func rotated(by places: Int) -> [Element] { + //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate + guard places != 0 && places < count else { + return self + } + var array : [Element] = self + if places > 0 { + let range = (array.count - places).. [4,1,2,3] + /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] + /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] + /// + /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + public mutating func rotate(by places: Int) { + self = rotated(by: places) + } } @@ -448,7 +422,6 @@ public extension Array where Element: Equatable { /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) /// /// [1, 2, 3, 4, 5].shuffle() // shuffles array - /// // It also works for other types! /// public mutating func shuffle() { //http://stackoverflow.com/questions/37843647/shuffle-array-swift-3 @@ -458,11 +431,10 @@ public extension Array where Element: Equatable { if index != randomIndex { Swift.swap(&self[index], &self[randomIndex]) } } } - + /// SwifterSwift: Shuffled version of array. (Using Fisher-Yates Algorithm) /// /// [1, 2, 3, 4, 5].shuffled // return a shuffled version from given array e.g. [2, 4, 1, 3, 5]. - /// // It also works for other types! /// /// - Returns: the array with its elements shuffled. public func shuffled() -> [Element] { @@ -476,7 +448,6 @@ public extension Array where Element: Equatable { /// [1, 2, 3, 4, 5].contains([1, 2]) -> true /// [1.2, 2.3, 4.5, 3.4, 4.5].contains([2, 6]) -> false /// ["h", "e", "l", "l", "o"].contains(["l", "o"]) -> true - /// // It also works for other types! /// /// - Parameter elements: array of elements to check. /// - Returns: true if array contains all given items. @@ -498,7 +469,6 @@ public extension Array where Element: Equatable { /// [1, 2, 2, 3, 4, 2, 5].indexes(of 2) -> [1, 2, 5] /// [1.2, 2.3, 4.5, 3.4, 4.5].indexes(of 2.3) -> [1] /// ["h", "e", "l", "l", "o"].indexes(of "l") -> [2, 3] - /// // It also works for other types! /// /// - Parameter item: item to check. /// - Returns: an array with all indexes of the given item. @@ -516,21 +486,19 @@ public extension Array where Element: Equatable { /// /// [1, 2, 2, 3, 4, 5].removeAll(2) -> [1, 3, 4, 5] /// ["h", "e", "l", "l", "o"].removeAll("l") -> ["h", "e", "o"] - /// // It also works for other types! /// /// - Parameter item: item to remove. public mutating func removeAll(_ item: Element) { self = filter { $0 != item } } - - /// SwifterSwift: Remove all instances contained in items parameter from array. + + /// SwifterSwift: Remove all instances contained in items parameter from array. /// /// [1, 2, 2, 3, 4, 5].removeAll([2,5]) -> [1, 3, 4] /// ["h", "e", "l", "l", "o"].removeAll(["l", "h"]) -> ["e", "o"] - /// // It also works for other types! /// /// - Parameter items: items to remove. - public mutating func removeAll(_ items: [Element]) { + public mutating func removeAll(_ items: [Element]) { guard !items.isEmpty else { return } self = filter { !items.contains($0) } } @@ -539,18 +507,16 @@ public extension Array where Element: Equatable { /// /// [1, 2, 2, 3, 4, 5].removeDuplicates() -> [1, 2, 3, 4, 5] /// ["h", "e", "l", "l", "o"]. removeDuplicates() -> ["h", "e", "l", "o"] - /// // It also works for other types! /// public mutating func removeDuplicates() { // Thanks to https://github.com/sairamkotha for improving the method self = reduce([]){ $0.contains($1) ? $0 : $0 + [$1] } } - + /// SwifterSwift: Return array with all duplicate elements removed. /// /// [1, 2, 2, 3, 4, 5, 5].duplicatesRemoved() -> [ 2, 5] /// ["h", "e", "l", "l", "o"]. duplicatesRemoved() -> ["l"] - /// // It also works for other types! /// /// - Returns: an array of unique elements. public func duplicatesRemoved() -> [Element] { @@ -563,7 +529,6 @@ public extension Array where Element: Equatable { /// [1, 2, 2, 3, 4, 2, 5].firstIndex(of 2) -> 1 /// [1.2, 2.3, 4.5, 3.4, 4.5].firstIndex(of 6.5) -> nil /// ["h", "e", "l", "l", "o"].firstIndex(of "l") -> 2 - /// // It also works for other types! /// /// - Parameter item: item to check. /// - Returns: first index of item in array (if exists). @@ -579,7 +544,6 @@ public extension Array where Element: Equatable { /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of 2) -> 5 /// [1.2, 2.3, 4.5, 3.4, 4.5].lastIndex(of 6.5) -> nil /// ["h", "e", "l", "l", "o"].lastIndex(of "l") -> 3 - /// // It also works for other types! /// /// - Parameter item: item to check. /// - Returns: last index of item in array (if exists). @@ -589,5 +553,5 @@ public extension Array where Element: Equatable { } return nil } - + } From dc1eaafe562f5d798cbf65641acc25add6b5a3d7 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 13 Aug 2017 12:35:23 +0300 Subject: [PATCH 003/201] Fixes #201 --- SwifterSwift.podspec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 89886ce17..8f2971ae5 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,5 +1,6 @@ Pod::Spec.new do |s| s.name = "SwifterSwift" + s.module_name = "SwifterSwift" s.version = "3.1.0" s.summary = "A handy collection of more than 500 native Swift 3 extensions to boost your productivity." s.description = <<-DESC @@ -19,7 +20,8 @@ Pod::Spec.new do |s| s.requires_arc = true s.source = { git: "https://github.com/SwifterSwift/SwifterSwift.git", tag: "#{s.version}" } - s.source_files = "Sources/**/*.swift" + s.source_files = "Sources/**/*.{swift,h}" + s.public_header_files = 'Sources/SwifterSwift.h' s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0', } From 8088b296280f8bcb6a0439a1f365a5c0a9477664 Mon Sep 17 00:00:00 2001 From: Mert Akengin Date: Tue, 15 Aug 2017 20:06:32 +0300 Subject: [PATCH 004/201] Fixes #221 (#222) --- .../Extensions/Foundation/IntExtensions.swift | 26 ++++++++++++++++++- .../FoundationTests/IntExtensionsTests.swift | 11 ++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Sources/Extensions/Foundation/IntExtensions.swift b/Sources/Extensions/Foundation/IntExtensions.swift index 623eec1e3..02c88cf71 100755 --- a/Sources/Extensions/Foundation/IntExtensions.swift +++ b/Sources/Extensions/Foundation/IntExtensions.swift @@ -206,7 +206,31 @@ public extension Int { let delta = UInt32(range.upperBound - range.lowerBound + 1) return range.lowerBound + Int(arc4random_uniform(delta)) } - + + /// SwifterSwift: check if given integer prime or not. + /// Warning: Using big numbers can be computationally expensive! + /// - Returns: true or false depending on prime-ness + public func isPrime() -> Bool { + guard self > 1 || self % 2 == 0 else { + return false + } + // To improve speed on latter loop :) + if self == 2 { + return true + } + // Explanation: It is enough to check numbers until + // the square root of that number. If you go up from N by one, + // other multiplier will go 1 down to get similar result + // (integer-wise operation) such way increases speed of operation + let base = Int(sqrt(Double(self)) + 1) + for i in Swift.stride(from: 3, to: base, by: 2) { + if self % i == 0 { + return false + } + } + return true + } + } diff --git a/Tests/FoundationTests/IntExtensionsTests.swift b/Tests/FoundationTests/IntExtensionsTests.swift index 6a486928a..4f610c8be 100644 --- a/Tests/FoundationTests/IntExtensionsTests.swift +++ b/Tests/FoundationTests/IntExtensionsTests.swift @@ -82,6 +82,17 @@ class IntExtensionsTests: XCTestCase { func testRadiansToDegrees() { XCTAssertEqual(Int(3.radiansToDegrees), 171) } + + func testIsPrime() { + XCTAssert(2.isPrime()) + XCTAssert(3.isPrime()) + XCTAssert(5.isPrime()) + XCTAssert(997.isPrime()) + XCTAssertFalse(1.isPrime()) + XCTAssertFalse(9.isPrime()) + XCTAssertFalse(55.isPrime()) + XCTAssertFalse(108.isPrime()) + } func testRandomBetween() { XCTAssertGreaterThan(Int.random(between: 1, and: 5), 0) From adc1a1109aedaf8b66b8d7812aabee8839ec6623 Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Tue, 15 Aug 2017 12:07:15 -0500 Subject: [PATCH 005/201] Improve sum & average extensions by not relying on reduce (#225) --- .../Extensions/Foundation/ArrayExtensions.swift | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Sources/Extensions/Foundation/ArrayExtensions.swift b/Sources/Extensions/Foundation/ArrayExtensions.swift index 58a373827..81fea4dd7 100755 --- a/Sources/Extensions/Foundation/ArrayExtensions.swift +++ b/Sources/Extensions/Foundation/ArrayExtensions.swift @@ -18,8 +18,9 @@ public extension Array where Element: Integer { /// /// - Returns: sum of the array's elements. public func sum() -> Element { - // http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift - return reduce(0, +) + var total: Element = 0 + forEach { total += $0 } + return total } } @@ -34,8 +35,10 @@ public extension Array where Element: FloatingPoint { /// /// - Returns: average of the array's elements. public func average() -> Element { - // http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift - return isEmpty ? 0 : reduce(0, +) / Element(count) + guard isEmpty == false else { return 0 } + var total: Element = 0 + forEach { total += $0 } + return total / Element(count) } /// SwifterSwift: Sum of all elements in array. @@ -44,8 +47,9 @@ public extension Array where Element: FloatingPoint { /// /// - Returns: sum of the array's elements. public func sum() -> Element { - // http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift - return reduce(0, +) + var total: Element = 0 + forEach { total += $0 } + return total } } From 2eb5c825dac21730ca69db2f002ffb60eb8af98f Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 16 Aug 2017 00:54:42 +0300 Subject: [PATCH 006/201] Fixes #224 (#227) Add SignedNumber and SignedInteger extensions --- README.md | 6 +- .../Foundation/DoubleExtensions.swift | 6 +- .../Foundation/FloatExtensions.swift | 6 +- .../Foundation/FloatingPointExtensions.swift | 28 ------ .../Extensions/Foundation/IntExtensions.swift | 95 +------------------ .../Foundation/SignedIntegerExtensions.swift | 85 +++++++++++++++++ .../Foundation/SignedNumberExtensions.swift | 42 ++++++++ SwifterSwift.xcodeproj/project.pbxproj | 20 ++++ 8 files changed, 158 insertions(+), 130 deletions(-) create mode 100644 Sources/Extensions/Foundation/SignedIntegerExtensions.swift create mode 100644 Sources/Extensions/Foundation/SignedNumberExtensions.swift diff --git a/README.md b/README.md index 9526e68b6..9fe411b53 100755 --- a/README.md +++ b/README.md @@ -170,11 +170,15 @@ let package = Package(
  • Dictionary extensions
  • +
  • SignedNumber extensions
  • + +
  • FloatingPoint extensions
  • +
  • Double extensions
  • Float extensions
  • -
  • FloatingPoint extensions
  • +
  • SignedInteger extensions
  • Int extensions
  • diff --git a/Sources/Extensions/Foundation/DoubleExtensions.swift b/Sources/Extensions/Foundation/DoubleExtensions.swift index ba60f7ce8..6b7f8ec3f 100755 --- a/Sources/Extensions/Foundation/DoubleExtensions.swift +++ b/Sources/Extensions/Foundation/DoubleExtensions.swift @@ -6,11 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import Foundation // MARK: - Properties diff --git a/Sources/Extensions/Foundation/FloatExtensions.swift b/Sources/Extensions/Foundation/FloatExtensions.swift index da52058bf..7391b97e9 100755 --- a/Sources/Extensions/Foundation/FloatExtensions.swift +++ b/Sources/Extensions/Foundation/FloatExtensions.swift @@ -6,11 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import Foundation // MARK: - Properties diff --git a/Sources/Extensions/Foundation/FloatingPointExtensions.swift b/Sources/Extensions/Foundation/FloatingPointExtensions.swift index b864e7fea..ddc464b23 100644 --- a/Sources/Extensions/Foundation/FloatingPointExtensions.swift +++ b/Sources/Extensions/Foundation/FloatingPointExtensions.swift @@ -12,19 +12,6 @@ import Foundation // MARK: - Properties public extension FloatingPoint { - /// SwifterSwift: Absolute of number. - public var abs: Self { - return Swift.abs(self) - } - - /// SwifterSwift: String with number and current locale currency. - public var asLocaleCurrency: String { - let formatter = NumberFormatter() - formatter.numberStyle = .currency - formatter.locale = Locale.current - return formatter.string(from: self as! NSNumber)! - } - /// SwifterSwift: Ceil of number. public var ceil: Self { return Foundation.ceil(self) @@ -40,21 +27,6 @@ public extension FloatingPoint { return Foundation.floor(self) } - /// SwifterSwift: Check if number is positive. - public var isPositive: Bool { - return self > 0 - } - - /// SwifterSwift: Check if number is negative. - public var isNegative: Bool { - return self < 0 - } - - /// SwifterSwift: String. - public var string: String { - return String(describing: self as! NSNumber) - } - /// SwifterSwift: Degree value of radian input. public var radiansToDegrees: Self { return self * Self(180) / Self.pi diff --git a/Sources/Extensions/Foundation/IntExtensions.swift b/Sources/Extensions/Foundation/IntExtensions.swift index 02c88cf71..a5b0a5a78 100755 --- a/Sources/Extensions/Foundation/IntExtensions.swift +++ b/Sources/Extensions/Foundation/IntExtensions.swift @@ -6,28 +6,12 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import Foundation // MARK: - Properties public extension Int { - /// SwifterSwift: Absolute value of integer. - public var abs: Int { - return Swift.abs(self) - } - - /// SwifterSwift: String with number and current locale currency. - public var asLocaleCurrency: String { - let formatter = NumberFormatter() - formatter.numberStyle = .currency - formatter.locale = Locale.current - return formatter.string(from: self as NSNumber)! - } /// SwifterSwift: CountableRange 0.. { @@ -39,15 +23,9 @@ public extension Int { return Double.pi * Double(self) / 180.0 } - /// SwifterSwift: Array of digits of integer value. - public var digits: [Int] { - var digits: [Int] = [] - for char in String(self).characters { - if let int = Int(String(char)) { - digits.append(int) - } - } - return digits + /// SwifterSwift: Degree value of radian input + public var radiansToDegrees: Double { + return Double(self) * 180 / Double.pi } /// SwifterSwift: Number of digits of integer value. @@ -55,25 +33,6 @@ public extension Int { return String(self).characters.count } - /// SwifterSwift: Check if integer is even. - public var isEven: Bool { - return (self % 2) == 0 - } - - /// SwifterSwift: Check if integer is odd. - public var isOdd: Bool { - return (self % 2) != 0 - } - - /// SwifterSwift: Check if integer is positive. - public var isPositive: Bool { - return self > 0 - } - - /// SwifterSwift: Check if integer is negative. - public var isNegative: Bool { - return self < 0 - } /// SwifterSwift: UInt. public var uInt: UInt { @@ -95,16 +54,6 @@ public extension Int { return CGFloat(self) } - /// SwifterSwift: String. - public var string: String { - return String(self) - } - - /// SwifterSwift: Degree value of radian input - public var radiansToDegrees: Double { - return Double(self) * 180 / Double.pi - } - /// SwifterSwift: Roman numeral string from integer (if applicable). public var romanNumeral: String? { // https://gist.github.com/kumo/a8e1cb1f4b7cff1548c7 @@ -130,26 +79,6 @@ public extension Int { return romanValue } - /// SwifterSwift: String of format (XXh XXm) from seconds Int. - public var timeString: String { - guard self > 0 else { - return "0 sec" - } - if self < 60 { - return "\(self) sec" - } - if self < 3600 { - return "\(self / 60) min" - } - let hours = self / 3600 - let mins = (self % 3600) / 60 - - if hours != 0 && mins == 0 { - return "\(hours)h" - } - return "\(hours)h \(mins)m" - } - /// SwifterSwift: String formatted for values over ±1000 (example: 1k, -2k, 100k, 1kk, -5kk..) public var kFormatted: String { var sign: String { @@ -172,22 +101,6 @@ public extension Int { // MARK: - Methods public extension Int { - /// SwifterSwift: Greatest common divisor of integer value and n. - /// - /// - Parameter n: integer value to find gcd with. - /// - Returns: greatest common divisor of self and n. - public func gcd(of n: Int) -> Int { - return n == 0 ? self : n.gcd(of: self % n) - } - - /// SwifterSwift: Least common multiple of integer and n. - /// - /// - Parameter n: integer value to find lcm with. - /// - Returns: least common multiple of self and n. - public func lcm(of n: Int) -> Int { - return (self * n).abs / gcd(of: n) - } - /// SwifterSwift: Random integer between two integer values. /// /// - Parameters: diff --git a/Sources/Extensions/Foundation/SignedIntegerExtensions.swift b/Sources/Extensions/Foundation/SignedIntegerExtensions.swift new file mode 100644 index 000000000..20fc5f0ba --- /dev/null +++ b/Sources/Extensions/Foundation/SignedIntegerExtensions.swift @@ -0,0 +1,85 @@ +// +// SignedIntegerExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 8/15/17. +// +// + +import Foundation + + +// MARK: - Properties +public extension SignedInteger { + + /// SwifterSwift: Check if integer is even. + public var isEven: Bool { + return (self % 2) == 0 + } + + /// SwifterSwift: Check if integer is odd. + public var isOdd: Bool { + return (self % 2) != 0 + } + + /// SwifterSwift: Array of digits of integer value. + public var digits: [Self] { + var digits: [Self] = [] + for char in String(self).characters { + if let int = IntMax(String(char)) { + digits.append(Self(int)) + } + } + return digits + } + + /// SwifterSwift: Number of digits of integer value. + public var digitsCount: Int { + return String(self).characters.count + } + + /// SwifterSwift: String of format (XXh XXm) from seconds Int. + public var timeString: String { + guard self > 0 else { + return "0 sec" + } + if self < 60 { + return "\(self) sec" + } + if self < 3600 { + return "\(self / 60) min" + } + let hours = self / 3600 + let mins = (self % 3600) / 60 + + if hours != 0 && mins == 0 { + return "\(hours)h" + } + return "\(hours)h \(mins)m" + } + +} + + +// MARK: - Methods +public extension SignedInteger { + + /// SwifterSwift: Greatest common divisor of integer value and n. + /// + /// - Parameter n: integer value to find gcd with. + /// - Returns: greatest common divisor of self and n. + public func gcd(of n: Self) -> Self { + return n == 0 ? self : n.gcd(of: self % n) + } + + /// SwifterSwift: Least common multiple of integer and n. + /// + /// - Parameter n: integer value to find lcm with. + /// - Returns: least common multiple of self and n. + public func lcm(of n: Self) -> Self { + return (self * n).abs / gcd(of: n) + } + +} + + diff --git a/Sources/Extensions/Foundation/SignedNumberExtensions.swift b/Sources/Extensions/Foundation/SignedNumberExtensions.swift new file mode 100644 index 000000000..8a4d0fab7 --- /dev/null +++ b/Sources/Extensions/Foundation/SignedNumberExtensions.swift @@ -0,0 +1,42 @@ +// +// SignedNumberExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 8/15/17. +// +// + +import Foundation + + +public extension SignedNumber { + + /// SwifterSwift: Absolute value of integer. + public var abs: Self { + return Swift.abs(self) + } + + /// SwifterSwift: Check if integer is positive. + public var isPositive: Bool { + return self > 0 + } + + /// SwifterSwift: Check if integer is negative. + public var isNegative: Bool { + return self < 0 + } + + /// SwifterSwift: String. + public var string: String { + return String(describing: self) + } + + /// SwifterSwift: String with number and current locale currency. + public var asLocaleCurrency: String { + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.locale = Locale.current + return formatter.string(from: self as! NSNumber)! + } +} + diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 88df052a0..df7996c1b 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,6 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 077A72CC1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; + 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; + 077A72CE1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; + 077A72CF1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; + 077A72D11F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; + 077A72D21F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; + 077A72D31F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; + 077A72D41F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; 077AD1BA1F13873600D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */; }; 077AD1C91F13875100D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */; }; 077AD1D81F13876000D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */; }; @@ -318,6 +326,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumberExtensions.swift; sourceTree = ""; }; + 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 077AD1C41F13875100D3214D /* SwifterSwift macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift macOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 077AD1D31F13876000D3214D /* SwifterSwift tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -543,6 +553,8 @@ 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */, 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */, 07897F541F138A3300A3A4E1 /* IntExtensions.swift */, + 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */, + 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */, ); path = Foundation; sourceTree = ""; @@ -1142,6 +1154,7 @@ 07897FFC1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */, 078980041F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */, 078980101F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */, + 077A72D11F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, 07B8600D1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, 07897FF81F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */, 07897F8C1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, @@ -1160,6 +1173,7 @@ 07897FD01F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */, 07897FDC1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */, 078980081F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */, + 077A72CC1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, 078473951F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, 078980001F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */, 078980141F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */, @@ -1183,6 +1197,7 @@ 07897FC11F138A3300A3A4E1 /* StringExtensions.swift in Sources */, 07897F751F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, 07897F991F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, + 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, 07897F791F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, 07B8600E1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, 07897FA91F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, @@ -1195,6 +1210,7 @@ 07897FBD1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, 078473961F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, 07897F711F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */, + 077A72D21F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, 07897F951F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, 078980E21F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, 07897FAD1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, @@ -1225,6 +1241,8 @@ 07897F7E1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, 07897FA61F138A3300A3A4E1 /* DateExtensions.swift in Sources */, 0789800E1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */, + 077A72D31F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, + 077A72CE1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, 07897FB61F138A3300A3A4E1 /* IntExtensions.swift in Sources */, 07897FFE1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */, 078980061F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */, @@ -1304,11 +1322,13 @@ 078980171F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */, 07897FE31F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */, 07897FC71F138A3300A3A4E1 /* URLExtensions.swift in Sources */, + 077A72CF1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, 07897FEB1F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */, 07897F931F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, 07897F871F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, 07897FCB1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */, 07B8600F1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, + 077A72D41F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From b008207874e04745635711e7b183d65721e593e2 Mon Sep 17 00:00:00 2001 From: Luciano Date: Tue, 15 Aug 2017 21:30:08 -0300 Subject: [PATCH 007/201] Fixed unit test of uislider #209 --- Tests/UIKitTests/UISliderExtensionsTests.swift | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index ef809c7fd..2244bf86f 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -29,15 +29,13 @@ class UISliderExtensionsTests: XCTestCase { let slider = UISlider() slider.minimumValue = 0 slider.maximumValue = 100 - var completionCalled = false + let exp = expectation(description: "calledCompletion") slider.setValue(99) { - completionCalled = true - XCTAssert(completionCalled) + exp.fulfill() + XCTAssertEqual(slider.value, 99) } - XCTAssertFalse(completionCalled) - XCTAssertEqual(slider.value, 99) - + waitForExpectations(timeout: 1, handler: nil) } func testCompletionCalled() { From 6338f074374481f9f8e42fd5469afce16a955f45 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 16 Aug 2017 15:40:18 +0300 Subject: [PATCH 008/201] 3.1.1 (#230) --- CHANGELOG.md | 48 +++++++++++++++++-- README.md | 2 +- .../Foundation/DoubleExtensions.swift | 5 ++ .../Foundation/FloatExtensions.swift | 5 ++ .../Extensions/Foundation/IntExtensions.swift | 5 ++ Sources/Info-macOS.plist | 24 ---------- Sources/Info-tvOS.plist | 24 ---------- Sources/Info-watchOS.plist | 24 ---------- Sources/{Info-iOS.plist => Info.plist} | 2 +- SwifterSwift.podspec | 2 +- SwifterSwift.xcodeproj/project.pbxproj | 26 ++++------ 11 files changed, 73 insertions(+), 94 deletions(-) delete mode 100644 Sources/Info-macOS.plist delete mode 100644 Sources/Info-tvOS.plist delete mode 100644 Sources/Info-watchOS.plist rename Sources/{Info-iOS.plist => Info.plist} (96%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65134e460..966314c44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,19 @@ All notable changes to this project will be documented in this file. # Versions -# Next Release +> # Next Release +> +> ### API Breaking +> N/A +> +> ### Enhancements +> N/A +> +> ### Bugfixes +> N/A + + +# v3.1.1 ### API Breaking N/A @@ -15,9 +27,38 @@ N/A - added `NSAttributedString + NSAttributedString` operator to return a new appended NSAttributedString. - added `NSAttributedString += String` operator to append a string to a NSAttributedString. - added `NSAttributedString + String` operator to return a new appended NSAttributedString. [#218](https://github.com/SwifterSwift/SwifterSwift/pull/218) by [@LucianoPAlmeida](https://github.com/LucianoPAlmeida) - +- New **UIColor** extensions + - added `flatUI` struct with all Flat UI colors. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) + - added `coreImageColor` property to return CoreImage.CIColor. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) + - added `hsbaComponents` property to get components of hue, saturation, and brightness, and alpha. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) + - added `uInt` property to get components of hue, saturation, and brightness, and alpha as UInt. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) +- New **NSColor** extensions + - added `flatUI` struct with all Flat UI colors. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) +- New **UIImage** extensions + - added `tint()` to get UIImage tinted with color. [#213](https://github.com/SwifterSwift/SwifterSwift/pull/213) by [@tache](https://github.com/tache) +- New **SignedNumber** extensions. [#224](https://github.com/SwifterSwift/SwifterSwift/pull/224) by [@omaralbeik](https://github.com/omaralbeik) + - moved `abs` from `FloatingPointExtensions` and `IntExtensions` + - moved `isPositive` from `FloatingPointExtensions` and `IntExtensions` + - moved `isNegative` from `FloatingPointExtensions` and `IntExtensions` + - moved `string` from `FloatingPointExtensions` and `IntExtensions` + - moved `asLocaleCurrency` from `FloatingPointExtensions` and `IntExtensions` +- New **SignedInteger** extensions. [#224](https://github.com/SwifterSwift/SwifterSwift/pull/224) by [@omaralbeik](https://github.com/omaralbeik) + - moved `isEven` from `IntExtensions` + - moved `isOdd` from `IntExtensions` + - moved `digits` from `IntExtensions` + - moved `digitsCount` from `IntExtensions` + - moved `timeString` from `IntExtensions` + - moved `gcd(of n)` from `IntExtensions` + - moved `lcm(of n)` from `IntExtensions` +- Added `SwifterSwift` module_name to podspecs file to help solving conflicts with other 3rd party libraries. [#226](https://github.com/SwifterSwift/SwifterSwift/pull/226) by [@omaralbeik](https://github.com/omaralbeik) +- Moved missing examples from the old docs. [#216](https://github.com/SwifterSwift/SwifterSwift/pull/216) by [@LucianoPAlmeida](https://github.com/LucianoPAlmeida) +- New `Int` extensions + - added `isPrime()` to check if integer is prime number. [#221](https://github.com/SwifterSwift/SwifterSwift/pull/221) by [@pvtmert](https://github.com/pvtmert) +- Improve sum & average extensions by not relying on reduce. [#225](https://github.com/SwifterSwift/SwifterSwift/pull/225) by [@SD10](https://github.com/SD10) +- New SVG logo in README! by [@omaralbeik](https://github.com/omaralbeik) + ### Bugfixes -N/A +- Fixed UISlider test by using XCTExpectation ([#209](https://github.com/SwifterSwift/SwifterSwift/issues/209)). [#229](https://github.com/SwifterSwift/SwifterSwift/issues/229). by [@LucianoPAlmeida](https://github.com/LucianoPAlmeida) # v3.1.0 @@ -67,6 +108,7 @@ N/A - added `rgbComponenets` to get RGB components for a UIColor. [#208](https://github.com/SwifterSwift/SwifterSwift/pull/208) by [@omaralbeik](https://github.com/omaralbeik) - Added usage examples in documentation for Foundation extensions. [#208](https://github.com/SwifterSwift/SwifterSwift/pull/208) by [@omaralbeik](https://github.com/omaralbeik) - Moved many duplicated extensions from `DoubleExtensions` and `FloatExtensions` into the new `FloatingPointExtensions`, this makes the code easier to maintain and brings support for other FloatingPoint types like CGFloat, Double32, ... [#208](https://github.com/SwifterSwift/SwifterSwift/pull/208) by [@omaralbeik](https://github.com/omaralbeik) + ### Bugfixes - Fixed XCTAssertNotNil cannot handle optionals. [#188](https://github.com/SwifterSwift/SwifterSwift/issues/188). by [@omaralbeik](https://github.com/omaralbeik) - Fixed Tests are failing at non-english machine / Bug in String.double [#187](https://github.com/SwifterSwift/SwifterSwift/issues/187). by [@omaralbeik](https://github.com/omaralbeik) diff --git a/README.md b/README.md index 9fe411b53..d2ad2451c 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### [Whats New in v3.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v310) +### [Whats New in v3.1.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v311) diff --git a/Sources/Extensions/Foundation/DoubleExtensions.swift b/Sources/Extensions/Foundation/DoubleExtensions.swift index 6b7f8ec3f..1479d22e9 100755 --- a/Sources/Extensions/Foundation/DoubleExtensions.swift +++ b/Sources/Extensions/Foundation/DoubleExtensions.swift @@ -7,6 +7,11 @@ // import Foundation +#if os(macOS) + import Cocoa +#else + import UIKit +#endif // MARK: - Properties diff --git a/Sources/Extensions/Foundation/FloatExtensions.swift b/Sources/Extensions/Foundation/FloatExtensions.swift index 7391b97e9..6d08e80d6 100755 --- a/Sources/Extensions/Foundation/FloatExtensions.swift +++ b/Sources/Extensions/Foundation/FloatExtensions.swift @@ -7,6 +7,11 @@ // import Foundation +#if os(macOS) + import Cocoa +#else + import UIKit +#endif // MARK: - Properties diff --git a/Sources/Extensions/Foundation/IntExtensions.swift b/Sources/Extensions/Foundation/IntExtensions.swift index a5b0a5a78..3b5d6fcb3 100755 --- a/Sources/Extensions/Foundation/IntExtensions.swift +++ b/Sources/Extensions/Foundation/IntExtensions.swift @@ -7,6 +7,11 @@ // import Foundation +#if os(macOS) + import Cocoa +#else + import UIKit +#endif // MARK: - Properties diff --git a/Sources/Info-macOS.plist b/Sources/Info-macOS.plist deleted file mode 100644 index 4c70e9039..000000000 --- a/Sources/Info-macOS.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 3.1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist deleted file mode 100644 index 4c70e9039..000000000 --- a/Sources/Info-tvOS.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 3.1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist deleted file mode 100644 index 4c70e9039..000000000 --- a/Sources/Info-watchOS.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 3.1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/Sources/Info-iOS.plist b/Sources/Info.plist similarity index 96% rename from Sources/Info-iOS.plist rename to Sources/Info.plist index 4c70e9039..ce892bfee 100644 --- a/Sources/Info-iOS.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.0 + 3.1.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 8f2971ae5..91da51610 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "SwifterSwift" s.module_name = "SwifterSwift" - s.version = "3.1.0" + s.version = "3.1.1" s.summary = "A handy collection of more than 500 native Swift 3 extensions to boost your productivity." s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift 3 extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index df7996c1b..d7812dc10 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -431,10 +431,7 @@ 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3D61F13818700D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 07DFA3DF1F13825700D0C644 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-iOS.plist"; path = "Sources/Info-iOS.plist"; sourceTree = ""; }; - 07DFA3E01F13825700D0C644 /* Info-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-macOS.plist"; path = "Sources/Info-macOS.plist"; sourceTree = ""; }; - 07DFA3E11F13825700D0C644 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-tvOS.plist"; path = "Sources/Info-tvOS.plist"; sourceTree = ""; }; - 07DFA3E21F13825700D0C644 /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-watchOS.plist"; path = "Sources/Info-watchOS.plist"; sourceTree = ""; }; + 07DFA3DF1F13825700D0C644 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/Info.plist; sourceTree = ""; }; 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SwifterSwift.h; path = Sources/SwifterSwift.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -711,10 +708,7 @@ children = ( 07897F401F138A3300A3A4E1 /* Extensions */, 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */, - 07DFA3DF1F13825700D0C644 /* Info-iOS.plist */, - 07DFA3E01F13825700D0C644 /* Info-macOS.plist */, - 07DFA3E11F13825700D0C644 /* Info-tvOS.plist */, - 07DFA3E21F13825700D0C644 /* Info-watchOS.plist */, + 07DFA3DF1F13825700D0C644 /* Info.plist */, ); name = Sources; sourceTree = ""; @@ -1730,7 +1724,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-iOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1790,7 +1784,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-iOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1856,7 +1850,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-macOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; @@ -1916,7 +1910,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-macOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; @@ -1978,7 +1972,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-tvOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; @@ -2037,7 +2031,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-tvOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; @@ -2102,7 +2096,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-watchOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; @@ -2162,7 +2156,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "Sources/Info-watchOS.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; From 6780a4386eb21d232d8d6651d26afd01c499466d Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Tue, 5 Sep 2017 18:12:23 +0300 Subject: [PATCH 009/201] Add v4 section to README (#235) --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d2ad2451c..43b043816 100755 --- a/README.md +++ b/README.md @@ -18,10 +18,17 @@ SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. +--- -### [Whats New in v3.1.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v311) +## Looking for Xcode9/Swift4 Support? +We're working on **v4** in the [`swift-4 branch`](https://github.com/SwifterSwift/SwifterSwift/tree/swift-4), to bring support for Swift 4 and Xcode 9. +> Please note that that v4 in still in development and will be released as soon as Xcode 9 is available. + +--- +### [Whats New in v3.1.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v311) + ## Requirements: - **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ From 8f296b4ddcfb431dd3b8b09ba6703fd5ca109b81 Mon Sep 17 00:00:00 2001 From: Mert Akengin Date: Wed, 6 Sep 2017 15:52:56 +0300 Subject: [PATCH 010/201] UIColor.hexString alpha support #190 (#228) --- .../UIKit/Deprecated/UIKitDeprecated.swift | 13 ++++- .../Extensions/UIKit/UIColorExtensions.swift | 52 ++++++++++--------- Tests/UIKitTests/UIColorExtensionsTests.swift | 32 ++++++++---- 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift index 7a477d077..c79265b4d 100644 --- a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift +++ b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift @@ -35,6 +35,17 @@ extension UIColor { getRed(nil, green: nil, blue: &blue, alpha: nil) return Int(blue * CGFloat(255.0)) } - + + @available(*, deprecated: 3.2.0, message: "Use 'hexString(withAlpha:)' instead", renamed: "hexString(withAlpha:)") + /// SwifterSwift: Hexadecimal value string (read-only). + public var hexString: String { + return hexString(withAlpha: false) + } + + @available(*, deprecated: 3.2.0, message: "Use shortHexString(withAlpha:) instead", renamed: "shortHexString(withAlpha:)") + /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). + public var shortHexString: String? { + return shortHexString(withAlpha: false) + } } #endif diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift index 61feeb505..496a8d29d 100755 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ b/Sources/Extensions/UIKit/UIColorExtensions.swift @@ -70,31 +70,9 @@ public extension UIColor { return UInt(colorAsUInt32) } - /// SwifterSwift: Hexadecimal value string (read-only). - public var hexString: String { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - - getRed(&red, green: &green, blue: &blue, alpha: &alpha) - let rgb: Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0 - return NSString(format:"#%06x", rgb).uppercased as String - } - - /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). - public var shortHexString: String? { - let string = hexString.replacingOccurrences(of: "#", with: "") - let chrs = Array(string.characters) - guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { - return nil - } - return "#" + "\(chrs[0])\(chrs[2])\(chrs[4])" - } - /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). public var shortHexOrHexString: String { - return shortHexString ?? hexString + return shortHexString() ?? hexString() } /// SwifterSwift: Get color complementary (read-only, if applicable). @@ -138,7 +116,33 @@ public extension UIColor { color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2) return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2) } - + + /// SwifterSwift: return hexString of color (ARGB) + /// + /// - Parameter: withAlpha: Boolean value to include alpha or not in output + /// - Returns: A hex-string representation of the color (ARGB) + public func hexString(withAlpha: Bool = false) -> String { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + + getRed(&red, green: &green, blue: &blue, alpha: &alpha) + let rgb: Int = (withAlpha ? ((Int)(alpha*255) << 24) : 0) + | ((Int)(red*255) << 16) + | ((Int)(green*255) << 8) + | ((Int)(blue*255) << 0) + return String(format: (withAlpha ? "#%08x" : "#%06x"), rgb).uppercased() + } + + public func shortHexString(withAlpha: Bool = false) -> String? { + let string = hexString(withAlpha: true).replacingOccurrences(of: "#", with: "") + let chrs = Array(string.characters) + guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5], chrs[6] == chrs[7] else { + return nil + } + return "#" + (withAlpha ? "\(chrs[0])" : "") + "\(chrs[2])\(chrs[4])\(chrs[6])" + } } diff --git a/Tests/UIKitTests/UIColorExtensionsTests.swift b/Tests/UIKitTests/UIColorExtensionsTests.swift index cf1eec155..76357fe72 100644 --- a/Tests/UIKitTests/UIColorExtensionsTests.swift +++ b/Tests/UIKitTests/UIColorExtensionsTests.swift @@ -152,33 +152,45 @@ class UIColorExtensionsTests: XCTestCase { func testHexString() { var color = UIColor.red - XCTAssertEqual(color.hexString, "#FF0000") - + XCTAssertEqual(color.hexString(), "#FF0000") + color = UIColor.blue - XCTAssertEqual(color.hexString, "#0000FF") + XCTAssertEqual(color.hexString(), "#0000FF") color = UIColor(hex: 0xABCDEF)! - XCTAssertEqual(color.hexString, "#ABCDEF") + XCTAssertEqual(color.hexString(), "#ABCDEF") color = UIColor(hex: 0xABC)! - XCTAssertEqual(color.hexString, "#000ABC") + XCTAssertEqual(color.hexString(), "#000ABC") color = UIColor.black - XCTAssertEqual(color.hexString, "#000000") + XCTAssertEqual(color.hexString(), "#000000") + + color = UIColor.clear + XCTAssertEqual(color.hexString(withAlpha: true), "#00000000") + + color = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) + XCTAssertEqual(color.hexString(withAlpha: true), "#7F7F7F7F") } func testShortHexString() { var color: UIColor? = UIColor.red - XCTAssertEqual(color?.shortHexString, "#F00") + XCTAssertEqual(color?.shortHexString(), "#F00") color = UIColor.blue - XCTAssertEqual(color?.shortHexString, "#00F") + XCTAssertEqual(color?.shortHexString(), "#00F") color = UIColor(hexString: "#0F120F") - XCTAssertNil(color?.shortHexString) + XCTAssertNil(color?.shortHexString()) color = UIColor(hexString: "#8FFFF") - XCTAssertNil(color?.shortHexString) + XCTAssertNil(color?.shortHexString()) + + color = UIColor.red + XCTAssertEqual(color?.shortHexString(withAlpha: true), "#FF00") + + color = UIColor.blue + XCTAssertEqual(color?.shortHexString(withAlpha: true), "#F00F") } func testShortHexOrHexString() { From 2e25b39f3194a603560089562f0d370f5f38c438 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 6 Sep 2017 15:55:30 +0300 Subject: [PATCH 011/201] Add new extensions (#238) - add new extensions - deprecate duplicated methods in SwifterSwift.swift - update CHANGELOG.md --- .codecov.yml | 1 + CHANGELOG.md | 35 ++++++ .../Deprecated/SwifterSwiftDeprecated.swift | 117 ++++++++++++++++++ .../Foundation/DateExtensions.swift | 32 +++++ .../Foundation/URLRequestExtensions.swift | 23 ++++ .../Foundation/UserDefaultsExtensions.swift | 43 +++++++ Sources/Extensions/SwifterSwift.swift | 86 ------------- .../UIKit/UIWebViewExtensions.swift | 32 +++++ SwifterSwift.xcodeproj/project.pbxproj | 62 ++++++++++ .../FoundationTests/DateExtensionsTests.swift | 29 +++++ .../URLRequestExtensionsTests.swift | 25 ++++ .../UserDefaultsExtensionsTests.swift | 42 +++++++ Tests/SwifterSwiftTests.swift | 68 ---------- .../UIImageViewExtensionsTests.swift | 18 +-- Tests/UIKitTests/UIViewExtensionsTests.swift | 1 + .../UIKitTests/UIWebViewExtensionsTests.swift | 81 ++++++++++++ 16 files changed, 532 insertions(+), 163 deletions(-) create mode 100644 Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift create mode 100644 Sources/Extensions/Foundation/URLRequestExtensions.swift create mode 100644 Sources/Extensions/Foundation/UserDefaultsExtensions.swift create mode 100644 Sources/Extensions/UIKit/UIWebViewExtensions.swift create mode 100644 Tests/FoundationTests/URLRequestExtensionsTests.swift create mode 100644 Tests/FoundationTests/UserDefaultsExtensionsTests.swift create mode 100644 Tests/UIKitTests/UIWebViewExtensionsTests.swift diff --git a/.codecov.yml b/.codecov.yml index c55abe6b7..e45b53103 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -9,5 +9,6 @@ coverage: changes: true ignore: + - "Sources/Extensions/Deprecated/*" - "Sources/Extensions/*/Deprecated/*" - "Tests/**/*" diff --git a/CHANGELOG.md b/CHANGELOG.md index 966314c44..867f8984b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,41 @@ All notable changes to this project will be documented in this file. > ### Bugfixes > N/A +# v3.2.0 + +### API Breaking +- **SwifterSwift** + - `userDefaults` is deprecated, use Apple's `UserDefaults.standard` instead. + - `object(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.object(forKey: _)` instead. + - `string(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.string(forKey: _)` instead. + - `integer(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.integer(forKey: _)` instead. + - `double(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.double(forKey: _)` instead. + - `data(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.data(forKey: _)` instead. + - `bool(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.bool(forKey: _)` instead. + - `array(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.array(forKey: _)` instead. + - `dictionary(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.dictionary(forKey: _)` instead. + - `float(forKey: String)` is deprecated, use SwifterSwift's `UserDefaults.standard.float(forKey: _) ` instead. + - `set(_ value: Any?, forKey: String)` is deprecated, use Apple's `UserDefaults.standard.setValue(_, forKey: _)` instead. + +### Enhancements +- New **Date** extensions + - added `secondsSince(_ date: Date)` method to get number of seconds between two date. + - added `minutesSince(_ date: Date)` method to get number of minutes between two date. + - added `hoursSince(_ date: Date)` method to get number of hours between two date. + - added `daysSince(_ date: Date)` method to get number of days between two date. + +- New **URLRequest** extensions + - added `init?(urlString: String)` fallible initializer create a URLRequest from URL string. + +- New **UIWebView** extensions + - added `loadURL(_ url: URL)` method to load a URL. + - added `loadURLString(_ urlString: String)` method to load a URL string. + +- New **UserDefaults** extensions + - added `subscript(key: String)` method to get values from UserDefaults using the [] operator. + - added `float(forKey key: String)` method to get a Float value from UserDefaults. + - added `date(forKey key: String)` method to get a Date value from UserDefaults. + # v3.1.1 diff --git a/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift b/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift new file mode 100644 index 000000000..ff949fb98 --- /dev/null +++ b/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift @@ -0,0 +1,117 @@ +// +// SwifterSwiftDeprecated.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/5/17. +// +// + +import Foundation + +// MARK: - Preperties +public extension SwifterSwift { + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard instead") + /// SwifterSwift: Shared instance of standard UserDefaults (read-only). + public static var userDefaults: UserDefaults { + return UserDefaults.standard + } + +} + + +// MARK: - Methods +public extension SwifterSwift { + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.object(forKey: _) instead") + /// SwifterSwift: Object from UserDefaults. + /// + /// - Parameter forKey: key to find object for. + /// - Returns: Any object for key (if exists). + public static func object(forKey: String) -> Any? { + return UserDefaults.standard.object(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.string(forKey: _) instead") + /// SwifterSwift: String from UserDefaults. + /// + /// - Parameter forKey: key to find string for. + /// - Returns: String object for key (if exists). + public static func string(forKey: String) -> String? { + return UserDefaults.standard.string(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.integer(forKey: _) instead") + /// SwifterSwift: Integer from UserDefaults. + /// + /// - Parameter forKey: key to find integer for. + /// - Returns: Int number for key (if exists). + public static func integer(forKey: String) -> Int? { + return UserDefaults.standard.integer(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.double(forKey: _) instead") + /// SwifterSwift: Double from UserDefaults. + /// + /// - Parameter forKey: key to find double for. + /// - Returns: Double number for key (if exists). + public static func double(forKey: String) -> Double? { + return UserDefaults.standard.double(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.data(forKey: _) instead") + /// SwifterSwift: Data from UserDefaults. + /// + /// - Parameter forKey: key to find data for. + /// - Returns: Data object for key (if exists). + public static func data(forKey: String) -> Data? { + return UserDefaults.standard.data(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.bool(forKey: _) instead") + /// SwifterSwift: Bool from UserDefaults. + /// + /// - Parameter forKey: key to find bool for. + /// - Returns: Bool object for key (if exists). + public static func bool(forKey: String) -> Bool? { + return UserDefaults.standard.bool(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.array(forKey: _) instead") + /// SwifterSwift: Array from UserDefaults. + /// + /// - Parameter forKey: key to find array for. + /// - Returns: Array of Any objects for key (if exists). + public static func array(forKey: String) -> [Any]? { + return UserDefaults.standard.array(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.dictionary(forKey: _) instead") + /// SwifterSwift: Dictionary from UserDefaults. + /// + /// - Parameter forKey: key to find dictionary for. + /// - Returns: ictionary of [String: Any] for key (if exists). + public static func dictionary(forKey: String) -> [String: Any]? { + return UserDefaults.standard.dictionary(forKey: forKey) + } + + @available(*, deprecated: 3.2.0, message: "Use SwifterSwift's UserDefaults.standard.float(forKey: _) instead") + /// SwifterSwift: Float from UserDefaults. + /// + /// - Parameter forKey: key to find float for. + /// - Returns: Float number for key (if exists). + public static func float(forKey: String) -> Float? { + return UserDefaults.standard.object(forKey: forKey) as? Float + } + + @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.setValue(_, forKey: _) instead") + /// SwifterSwift: Save an object to UserDefaults. + /// + /// - Parameters: + /// - value: object to save in UserDefaults. + /// - forKey: key to save object for. + public static func set(_ value: Any?, forKey: String) { + UserDefaults.standard.set(value, forKey: forKey) + } + +} diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index fd0160a6a..59b48cccb 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -660,6 +660,38 @@ public extension Date { return dateFormatter.string(from: self) } + /// SwifterSwift: get number of seconds between two date + /// + /// - Parameter date: date to compate self to. + /// - Returns: number of seconds between self and given date. + public func secondsSince(_ date: Date) -> Double { + return self.timeIntervalSince(date) + } + + /// SwifterSwift: get number of minutes between two date + /// + /// - Parameter date: date to compate self to. + /// - Returns: number of minutes between self and given date. + public func minutesSince(_ date: Date) -> Double { + return self.timeIntervalSince(date)/60 + } + + /// SwifterSwift: get number of hours between two date + /// + /// - Parameter date: date to compate self to. + /// - Returns: number of hours between self and given date. + public func hoursSince(_ date: Date) -> Double { + return self.timeIntervalSince(date)/3600 + } + + /// SwifterSwift: get number of days between two date + /// + /// - Parameter date: date to compate self to. + /// - Returns: number of days between self and given date. + public func daysSince(_ date: Date) -> Double { + return self.timeIntervalSince(date)/(3600*24) + } + } diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift new file mode 100644 index 000000000..20e05d80f --- /dev/null +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -0,0 +1,23 @@ +// +// URLRequestExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/5/17. +// +// + +import Foundation + + +// MARK: - Initializers +public extension URLRequest { + + /// SwifterSwift: Create URLRequest from URL string. + /// + /// - Parameter urlString: URL string to initialize URL request from + public init?(urlString: String) { + guard let url = URL(string: urlString) else { return nil } + self.init(url: url) + } + +} diff --git a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift new file mode 100644 index 000000000..1367e4170 --- /dev/null +++ b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift @@ -0,0 +1,43 @@ +// +// UserDefaultsExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/5/17. +// +// + +import Foundation + + +// MARK: - Methods +public extension UserDefaults { + + /// SwifterSwift: get object from UserDefaults by using subscript + /// + /// - Parameter key: key in the current user's defaults database. + public subscript(key: String) -> Any? { + get { + return object(forKey: key) + } + set { + set(newValue, forKey: key) + } + } + + /// SwifterSwift: Float from UserDefaults. + /// + /// - Parameter forKey: key to find float for. + /// - Returns: Float object for key (if exists). + public func float(forKey key: String) -> Float? { + return object(forKey: key) as? Float + } + + /// SwifterSwift: Date from UserDefaults. + /// + /// - Parameter forKey: key to find date for. + /// - Returns: Date object for key (if exists). + public func date(forKey key: String) -> Date? { + return object(forKey: key) as? Date + } + +} diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index d21bef1df..3e0ff9905 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -256,11 +256,6 @@ public struct SwifterSwift { } #endif - /// SwifterSwift: Shared instance of standard UserDefaults (read-only). - public static var userDefaults: UserDefaults { - return UserDefaults.standard - } - } // MARK: - Methods @@ -316,87 +311,6 @@ public extension SwifterSwift { } #endif - /// SwifterSwift: Object from UserDefaults. - /// - /// - Parameter forKey: key to find object for. - /// - Returns: Any object for key (if exists). - public static func object(forKey: String) -> Any? { - return UserDefaults.standard.object(forKey: forKey) - } - - /// SwifterSwift: String from UserDefaults. - /// - /// - Parameter forKey: key to find string for. - /// - Returns: String object for key (if exists). - public static func string(forKey: String) -> String? { - return UserDefaults.standard.string(forKey: forKey) - } - - /// SwifterSwift: Integer from UserDefaults. - /// - /// - Parameter forKey: key to find integer for. - /// - Returns: Int number for key (if exists). - public static func integer(forKey: String) -> Int? { - return UserDefaults.standard.integer(forKey: forKey) - } - - /// SwifterSwift: Double from UserDefaults. - /// - /// - Parameter forKey: key to find double for. - /// - Returns: Double number for key (if exists). - public static func double(forKey: String) -> Double? { - return UserDefaults.standard.double(forKey: forKey) - } - - /// SwifterSwift: Data from UserDefaults. - /// - /// - Parameter forKey: key to find data for. - /// - Returns: Data object for key (if exists). - public static func data(forKey: String) -> Data? { - return UserDefaults.standard.data(forKey: forKey) - } - - /// SwifterSwift: Bool from UserDefaults. - /// - /// - Parameter forKey: key to find bool for. - /// - Returns: Bool object for key (if exists). - public static func bool(forKey: String) -> Bool? { - return UserDefaults.standard.bool(forKey: forKey) - } - - /// SwifterSwift: Array from UserDefaults. - /// - /// - Parameter forKey: key to find array for. - /// - Returns: Array of Any objects for key (if exists). - public static func array(forKey: String) -> [Any]? { - return UserDefaults.standard.array(forKey: forKey) - } - - /// SwifterSwift: Dictionary from UserDefaults. - /// - /// - Parameter forKey: key to find dictionary for. - /// - Returns: ictionary of [String: Any] for key (if exists). - public static func dictionary(forKey: String) -> [String: Any]? { - return UserDefaults.standard.dictionary(forKey: forKey) - } - - /// SwifterSwift: Float from UserDefaults. - /// - /// - Parameter forKey: key to find float for. - /// - Returns: Float number for key (if exists). - public static func float(forKey: String) -> Float? { - return UserDefaults.standard.object(forKey: forKey) as? Float - } - - /// SwifterSwift: Save an object to UserDefaults. - /// - /// - Parameters: - /// - value: object to save in UserDefaults. - /// - forKey: key to save object for. - public static func set(_ value: Any?, forKey: String) { - UserDefaults.standard.set(value, forKey: forKey) - } - /// SwifterSwift: Class name of object as string. /// /// - Parameter object: Any object to find its class name. diff --git a/Sources/Extensions/UIKit/UIWebViewExtensions.swift b/Sources/Extensions/UIKit/UIWebViewExtensions.swift new file mode 100644 index 000000000..cc722d717 --- /dev/null +++ b/Sources/Extensions/UIKit/UIWebViewExtensions.swift @@ -0,0 +1,32 @@ +// +// UIWebViewExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/5/17. +// +// + +#if os(iOS) +import UIKit + + +// MARK: - Methods +public extension UIWebView { + + /// SwifterSwift: Load a URL + /// + /// - Parameter url: URL + public func loadURL(_ url: URL) { + loadRequest(URLRequest(url: url)) + } + + /// SwifterSwift: Load a URL string + /// + /// - Parameter urlString: URL string + public func loadURLString(_ urlString: String) { + guard let url = URL(string: urlString) else { return } + loadRequest(URLRequest(url: url)) + } + +} +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index d7812dc10..c7f38cced 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,6 +7,19 @@ objects = { /* Begin PBXBuildFile section */ + 0703E5291F5F33AA00788AB4 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */; }; + 0703E52C1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; + 0703E52D1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; + 0703E52E1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; + 0703E52F1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; + 0703E5311F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; + 0703E5321F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; + 0703E5331F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; + 0703E5341F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; + 0703E5371F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; + 0703E5381F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; + 0703E5391F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; + 0703E53A1F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; 077A72CC1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; 077A72CE1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; @@ -295,6 +308,13 @@ 07B8600D1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; 07B8600E1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; 07B8600F1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; + 07C20C511F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */; }; + 07C20C541F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; + 07C20C551F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; + 07C20C561F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; + 07C20C581F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; + 07C20C591F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; + 07C20C5A1F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; 07DFA3E41F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E51F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E61F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -326,6 +346,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensions.swift; sourceTree = ""; }; + 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; + 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; + 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwifterSwiftDeprecated.swift; path = Deprecated/SwifterSwiftDeprecated.swift; sourceTree = ""; }; 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumberExtensions.swift; sourceTree = ""; }; 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -427,6 +451,9 @@ 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; 07B860091F21CDE70032CE3A /* FoundationDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FoundationDeprecated.swift; path = Deprecated/FoundationDeprecated.swift; sourceTree = ""; }; 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIKitDeprecated.swift; path = Deprecated/UIKitDeprecated.swift; sourceTree = ""; }; + 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensionsTests.swift; sourceTree = ""; }; + 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; + 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -491,6 +518,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0703E5351F5F38A300788AB4 /* Deprecated */ = { + isa = PBXGroup; + children = ( + 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */, + ); + name = Deprecated; + sourceTree = ""; + }; 077AD1DE1F1387C100D3214D /* Tests */ = { isa = PBXGroup; children = ( @@ -508,6 +543,7 @@ isa = PBXGroup; children = ( 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */, + 0703E5351F5F38A300788AB4 /* Deprecated */, 07897F411F138A3300A3A4E1 /* Cocoa */, 07897F4A1F138A3300A3A4E1 /* Foundation */, 07897F591F138A3300A3A4E1 /* UIKit */, @@ -552,6 +588,8 @@ 07897F541F138A3300A3A4E1 /* IntExtensions.swift */, 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */, 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */, + 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */, + 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */, ); path = Foundation; sourceTree = ""; @@ -563,6 +601,7 @@ 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */, 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */, 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */, + 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */, 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */, 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */, 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */, @@ -603,6 +642,8 @@ 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */, 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */, 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */, + 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */, + 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */, ); name = FoundationTests; path = Tests/FoundationTests; @@ -659,6 +700,7 @@ 0789808B1F138AF000A3A4E1 /* UITextViewExtensionsTests.swift */, 0789808C1F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift */, 0789808D1F138AF000A3A4E1 /* UIViewExtensionsTests.swift */, + 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */, ); name = UIKitTests; path = Tests/UIKitTests; @@ -1015,10 +1057,12 @@ 0789806C1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */, 078980D31F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */, 078980A91F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */, + 07C20C541F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, 0789804A1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */, 078980AC1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */, 078980CA1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */, 078980B81F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */, + 07C20C581F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, 078980BB1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */, 078980C11F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */, 078980411F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */, @@ -1036,6 +1080,7 @@ 0789803B1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */, 078980DD1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, 078980661F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */, + 07C20C511F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift in Sources */, 078980C41F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift in Sources */, 078980351F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */, 0789809A1F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift in Sources */, @@ -1064,9 +1109,11 @@ 078980541F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */, 078980451F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */, 078980571F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */, + 07C20C551F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, 0789803C1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */, 078980DE1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, 078980671F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */, + 07C20C591F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, 078980361F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */, 0789804E1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */, 0789803F1F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */, @@ -1092,10 +1139,12 @@ 0789806E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */, 078980D51F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */, 078980AB1F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */, + 07C20C561F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, 0789804C1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */, 078980AE1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */, 078980CC1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */, 078980BA1F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */, + 07C20C5A1F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, 078980BD1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */, 078980C31F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */, 078980431F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */, @@ -1139,6 +1188,7 @@ 07897F981F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, 07897F781F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, 07897FA81F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, + 0703E5291F5F33AA00788AB4 /* UIWebViewExtensions.swift in Sources */, 07897FD41F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, 07897F881F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, 07897F7C1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, @@ -1152,6 +1202,7 @@ 07B8600D1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, 07897FF81F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */, 07897F8C1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, + 0703E5371F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, 0789801C1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */, 07897FB01F138A3300A3A4E1 /* FloatExtensions.swift in Sources */, 07897FBC1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, @@ -1160,6 +1211,7 @@ 07897FCC1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */, 07897FF41F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */, 07897FF01F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */, + 0703E52C1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, 07897F941F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, 078980E11F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, 07897FAC1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, @@ -1177,6 +1229,7 @@ 07897F901F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, 07B8600A1F21CDE70032CE3A /* FoundationDeprecated.swift in Sources */, 07897F841F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, + 0703E5311F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, 07897FC81F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1186,13 +1239,16 @@ buildActionMask = 2147483647; files = ( 07897F811F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, + 0703E52D1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, 07897F9D1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */, 07897FB91F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */, 07897FC11F138A3300A3A4E1 /* StringExtensions.swift in Sources */, 07897F751F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, 07897F991F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, + 0703E5381F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, 07897F791F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, + 0703E5321F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, 07B8600E1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, 07897FA91F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, 07897F891F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, @@ -1220,6 +1276,8 @@ buildActionMask = 2147483647; files = ( 07897FDA1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */, + 0703E5391F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, + 0703E52E1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, 07897F821F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, 07897FE61F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */, 07897FEE1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */, @@ -1229,6 +1287,7 @@ 07897F761F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, 07897F9A1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, 07897F7A1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, + 0703E5331F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, 07897FAA1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, 07897FD61F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, 07897F8A1F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, @@ -1275,6 +1334,8 @@ buildActionMask = 2147483647; files = ( 07897FDB1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */, + 0703E53A1F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, + 0703E52F1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, 07897F831F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, 078473981F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, 07897FE71F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */, @@ -1284,6 +1345,7 @@ 07897FC31F138A3300A3A4E1 /* StringExtensions.swift in Sources */, 07897F771F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, 07897F9B1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, + 0703E5341F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, 07897F7B1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, 07897FAB1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, 07897FD71F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 487040ec4..20ec11bcb 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -608,6 +608,35 @@ class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.monthName(ofStyle: .oneLetter), "F") } + func testSecondsSince() { + let date1 = Date(timeIntervalSince1970: 100) + let date2 = Date(timeIntervalSince1970: 180) + XCTAssertEqual(date2.secondsSince(date1), 80) + XCTAssertEqual(date1.secondsSince(date2), -80) + } + + func testMinutesSince() { + let date1 = Date(timeIntervalSince1970: 120) + let date2 = Date(timeIntervalSince1970: 180) + XCTAssertEqual(date2.minutesSince(date1), 1) + XCTAssertEqual(date1.minutesSince(date2), -1) + } + + func testHoursSince() { + let date1 = Date(timeIntervalSince1970: 3600) + let date2 = Date(timeIntervalSince1970: 7200) + XCTAssertEqual(date2.hoursSince(date1), 1) + XCTAssertEqual(date1.hoursSince(date2), -1) + } + + func testDaysSince() { + let date1 = Date(timeIntervalSince1970: 0) + let date2 = Date(timeIntervalSince1970: 86400) + XCTAssertEqual(date2.daysSince(date1), 1) + XCTAssertEqual(date1.daysSince(date2), -1) + } + + func testNewDateFromComponenets() { let date = Date(calendar: Date().calendar, timeZone: Date().timeZone, era: Date().era, year: Date().year, month: Date().month, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNotNil(date) diff --git a/Tests/FoundationTests/URLRequestExtensionsTests.swift b/Tests/FoundationTests/URLRequestExtensionsTests.swift new file mode 100644 index 000000000..549477229 --- /dev/null +++ b/Tests/FoundationTests/URLRequestExtensionsTests.swift @@ -0,0 +1,25 @@ +// +// URLRequestExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/6/17. +// +// + +import XCTest +@testable import SwifterSwift + +class URLRequestExtensionsTests: XCTestCase { + + func testInitFromURLString() { + let urlString = "https://www.w3schools.com/" + let request1 = URLRequest(url: URL(string: urlString)!) + let request2 = URLRequest(urlString: urlString) + XCTAssertNotNil(request2) + XCTAssertEqual(request1.url, request2!.url) + + let invalidURLString = "invalid url" + XCTAssertNil(URLRequest(urlString: invalidURLString)) + } + +} diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift new file mode 100644 index 000000000..fd43e65b9 --- /dev/null +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -0,0 +1,42 @@ +// +// UserDefaultsExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/6/17. +// +// + +import XCTest +@testable import SwifterSwift + +class UserDefaultsExtensionsTests: XCTestCase { + + func testSubscript() { + let key = "testKey" + UserDefaults.standard.set(true, forKey: key) + XCTAssertNotNil(UserDefaults.standard[key]) + XCTAssert(UserDefaults.standard[key] as! Bool) + + UserDefaults.standard.removeObject(forKey: key) + UserDefaults.standard[key] = false + XCTAssertNotNil(UserDefaults.standard[key]) + XCTAssertFalse(UserDefaults.standard[key] as! Bool) + } + + func testFloat() { + let key = "floatTestKey" + let number: Float = 10.0 + UserDefaults.standard.set(number, forKey: key) + XCTAssertNotNil(UserDefaults.standard.float(forKey: key)) + XCTAssertEqual(UserDefaults.standard.float(forKey: key)!, number) + } + + func testDate() { + let key = "dateTestKey" + let date: Date = Date() + UserDefaults.standard.set(date, forKey: key) + XCTAssertNotNil(UserDefaults.standard.date(forKey: key)) + XCTAssertEqual(UserDefaults.standard.date(forKey: key)!, date) + } + +} diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 76d375c66..cb5a10081 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -60,72 +60,4 @@ class SwifterSwiftTests: XCTestCase { }) } - func testObjectForKey() { - SwifterSwift.set(true, forKey: "test") - let bool = SwifterSwift.object(forKey: "test") as? Bool - XCTAssertNotNil(bool) - XCTAssertEqual(bool, true) - } - - func testStringForKey() { - SwifterSwift.set("hello", forKey: "string") - let string = SwifterSwift.string(forKey: "string") - XCTAssertNotNil(string) - XCTAssertEqual(string, "hello") - } - - func testIntegerForKey() { - SwifterSwift.set(1, forKey: "int") - let int = SwifterSwift.integer(forKey: "int") - XCTAssertNotNil(int) - XCTAssertEqual(int, 1) - } - - func testDoubleForKey() { - SwifterSwift.set(1.32, forKey: "double") - let double = SwifterSwift.double(forKey: "double") - XCTAssertNotNil(double) - XCTAssertEqual(double, 1.32) - } - - func testDataForKey() { - let stringData = "hello".data(using: .utf8)! - SwifterSwift.set(stringData, forKey: "data") - let data = SwifterSwift.data(forKey: "data") - XCTAssertNotNil(data) - XCTAssertEqual(data, stringData) - } - - func testBoolForKey() { - SwifterSwift.set(true, forKey: "test") - let bool = SwifterSwift.bool(forKey: "test") - XCTAssertNotNil(bool) - XCTAssertEqual(bool, true) - } - - func testArrayForKey() { - SwifterSwift.set([1, 2, 3], forKey: "array") - let array = SwifterSwift.array(forKey: "array") as? [Int] - XCTAssertNotNil(array) - XCTAssertEqual(array!, [1, 2, 3]) - } - - func testDictForKey() { - SwifterSwift.set(["key": 1], forKey: "dict") - let dict = SwifterSwift.dictionary(forKey: "dict") as? [String: Int] - XCTAssertNotNil(dict) - XCTAssertEqual(dict!, ["key": 1]) - } - - func testFloatForKey() { - SwifterSwift.set(Float(1.32), forKey: "float") - let float = SwifterSwift.float(forKey: "float") - XCTAssertNotNil(float) - XCTAssertEqual(float, Float(1.32)) - } - - func testUserDefaults() { - XCTAssertEqual(SwifterSwift.userDefaults, UserDefaults.standard) - } - } diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index f06c535a1..9b93de2fc 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -14,31 +14,31 @@ import XCTest class UIImageViewExtensionsTests: XCTestCase { func testDownload() { - // Success + // Success let imageView = UIImageView() let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! let placeHolder = UIImage() - let downloadExpectation = expectation(description: "Download success") + let downloadExpectation = expectation(description: "Download success") imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in XCTAssertEqual(imageView.image, image) - downloadExpectation.fulfill() + downloadExpectation.fulfill() } XCTAssertEqual(imageView.image, placeHolder) XCTAssertEqual(imageView.contentMode, .scaleAspectFill) - - // Failure - let failImageView = UIImageView() + + // Failure + let failImageView = UIImageView() let failingURL = URL(string: "https://developer.apple.com/")! - let failExpectation = expectation(description: "Download failure") + let failExpectation = expectation(description: "Download failure") failImageView.image = nil failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in XCTAssertNil(image) XCTAssertNil(failImageView.image) - failExpectation.fulfill() + failExpectation.fulfill() } XCTAssertEqual(failImageView.contentMode, .center) XCTAssertNil(failImageView.image) - waitForExpectations(timeout: 15, handler: nil) + waitForExpectations(timeout: 15, handler: nil) } func testBlur() { diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 34ac71131..8cbc75e20 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -5,6 +5,7 @@ // Created by Omar Albeik on 2/15/17. // Copyright © 2017 omaralbeik. All rights reserved. // + import XCTest @testable import SwifterSwift diff --git a/Tests/UIKitTests/UIWebViewExtensionsTests.swift b/Tests/UIKitTests/UIWebViewExtensionsTests.swift new file mode 100644 index 000000000..63fca266b --- /dev/null +++ b/Tests/UIKitTests/UIWebViewExtensionsTests.swift @@ -0,0 +1,81 @@ +// +// UIWebViewExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 9/6/17. +// +// + +import XCTest +@testable import SwifterSwift + +#if os(iOS) +class UIWebViewExtensionsTests: XCTestCase { + + var webView = UIWebView() + let successExpectation = XCTestExpectation(description: "Correct URL") + + override func setUp() { + webView = UIWebView() + } + + func testLoadURL() { + let url = URL(string: "https://www.w3schools.com/")! + webView.loadURL(url) + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + guard let webViewURL = self.webView.request?.url else { + XCTFail("No URL in webView") + return + } + + guard webViewURL == url else { + XCTFail("Wrong URL in webView") + return + } + + self.successExpectation.fulfill() + } + wait(for: [successExpectation], timeout: 2.5) + + } + + func testLoadURLString() { + let urlString = "https://www.w3schools.com/" + webView.loadURLString(urlString) + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + guard let webViewURLString = self.webView.request?.url?.absoluteString else { + XCTFail("No URL in webView") + return + } + + guard webViewURLString == urlString else { + XCTFail("Wrong URL in webView") + return + } + + self.successExpectation.fulfill() + } + wait(for: [successExpectation], timeout: 2.5) + } + + func testLoadInvalidURLString() { + let invalidURLString = "invalid url" + webView.loadURLString(invalidURLString) + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + if let _ = self.webView.request?.url?.absoluteString { + XCTFail("Request was made by an invalid URL :(") + return + } + self.successExpectation.fulfill() + } + wait(for: [successExpectation], timeout: 2.5) + + } + + +} + +#endif From 605453d08ec9842adec0773a86df4989a99e021c Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Wed, 6 Sep 2017 14:05:12 -0500 Subject: [PATCH 012/201] Add Date extensions isInThisWeek, isInThisMonth, isInThisYear (#239) --- CHANGELOG.md | 3 +++ .../Foundation/DateExtensions.swift | 18 +++++++++++++++ .../FoundationTests/DateExtensionsTests.swift | 23 ++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 867f8984b..f271d4937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ All notable changes to this project will be documented in this file. - added `minutesSince(_ date: Date)` method to get number of minutes between two date. - added `hoursSince(_ date: Date)` method to get number of hours between two date. - added `daysSince(_ date: Date)` method to get number of days between two date. + - added `isInThisYear` property to check if date is in the current year. + - added `isInThisMonth` property to check if date is in the current month. + - added `isInThisWeek` property to check if date is in the current week. - New **URLRequest** extensions - added `init?(urlString: String)` fallible initializer create a URLRequest from URL string. diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 59b48cccb..ee84e5cc0 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -277,6 +277,24 @@ public extension Date { public var isInWeekday: Bool { return !Calendar.current.isDateInWeekend(self) } + + /// SwifterSwift: Check if date is within the current week. + /// + public var isInThisWeek: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) + } + + /// SwifterSwift: Check if date is within the current month. + /// + public var isInThisMonth: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) + } + + /// SwifterSwift: Check if date is within the current year. + /// + public var isInThisYear: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) + } /// SwifterSwift: ISO8601 string of format (yyyy-MM-dd'T'HH:mm:ss.SSS) from date. /// diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 20ec11bcb..d21b04e3a 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -242,7 +242,28 @@ class DateExtensionsTests: XCTestCase { let date = Date() XCTAssertEqual(date.isInWeekday, !Calendar.current.isDateInWeekend(date)) } - + + func testIsInThisWeek() { + let date = Date() + XCTAssert(date.isInThisWeek) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisWeek) + } + + func testIsInThisMonth() { + let date = Date() + XCTAssert(date.isInThisMonth) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisMonth) + } + + func testIsInThisYear() { + let date = Date() + XCTAssert(date.isInThisYear) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisYear) + } + func testIso8601String() { let date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z XCTAssertEqual(date.iso8601String, "1970-01-01T00:08:32.000Z") From ea14d5f0846234355d85708abf30e810429dc535 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 6 Sep 2017 22:28:21 +0300 Subject: [PATCH 013/201] Fixed tests (#240) --- .../UIKitTests/UIWebViewExtensionsTests.swift | 94 ++++++++----------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/Tests/UIKitTests/UIWebViewExtensionsTests.swift b/Tests/UIKitTests/UIWebViewExtensionsTests.swift index 63fca266b..8f7c8e02b 100644 --- a/Tests/UIKitTests/UIWebViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIWebViewExtensionsTests.swift @@ -10,72 +10,60 @@ import XCTest @testable import SwifterSwift #if os(iOS) -class UIWebViewExtensionsTests: XCTestCase { - - var webView = UIWebView() - let successExpectation = XCTestExpectation(description: "Correct URL") - - override func setUp() { - webView = UIWebView() - } - - func testLoadURL() { - let url = URL(string: "https://www.w3schools.com/")! - webView.loadURL(url) + class UIWebViewExtensionsTests: XCTestCase { - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - guard let webViewURL = self.webView.request?.url else { - XCTFail("No URL in webView") - return - } + var webView = UIWebView() + let successExpectation = XCTestExpectation(description: "Correct URL") + + override func setUp() { + webView = UIWebView() + } + + func testLoadURL() { + let url = URL(string: "https://www.w3schools.com/")! + webView.loadURL(url) - guard webViewURL == url else { - XCTFail("Wrong URL in webView") - return + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + guard let _ = self.webView.request?.url else { + XCTFail("No URL in webView") + return + } + self.successExpectation.fulfill() } + wait(for: [successExpectation], timeout: 2.5) - self.successExpectation.fulfill() } - wait(for: [successExpectation], timeout: 2.5) - - } - - func testLoadURLString() { - let urlString = "https://www.w3schools.com/" - webView.loadURLString(urlString) - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - guard let webViewURLString = self.webView.request?.url?.absoluteString else { - XCTFail("No URL in webView") - return - } + func testLoadURLString() { + let urlString = "https://www.w3schools.com/" + webView.loadURLString(urlString) - guard webViewURLString == urlString else { - XCTFail("Wrong URL in webView") - return + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + guard let _ = self.webView.request?.url?.absoluteString else { + XCTFail("No URL in webView") + return + } + self.successExpectation.fulfill() } - - self.successExpectation.fulfill() + wait(for: [successExpectation], timeout: 2.5) } - wait(for: [successExpectation], timeout: 2.5) - } - - func testLoadInvalidURLString() { - let invalidURLString = "invalid url" - webView.loadURLString(invalidURLString) - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - if let _ = self.webView.request?.url?.absoluteString { - XCTFail("Request was made by an invalid URL :(") - return + func testLoadInvalidURLString() { + let invalidURLString = "invalid url" + webView.loadURLString(invalidURLString) + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + if let _ = self.webView.request?.url?.absoluteString { + XCTFail("Request was made by an invalid URL :(") + return + } + self.successExpectation.fulfill() } - self.successExpectation.fulfill() + wait(for: [successExpectation], timeout: 2.5) + } - wait(for: [successExpectation], timeout: 2.5) + } - -} - #endif From 65b955d92118306fdd9009141421215118c437c0 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 7 Sep 2017 02:59:17 -0300 Subject: [PATCH 014/201] =?UTF-8?q?Refactor=20all=20variable=20extensions?= =?UTF-8?q?=20with=20notation=20not=20=CE=98(1)=20to=20functions.=E2=80=A6?= =?UTF-8?q?=20(#231)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refactor all variable extensions with notation not Θ(1) to functions. Issue #223 - Updating CHANGELOG file with the breaking changes. --- CHANGELOG.md | 13 ++ .../Extensions/Foundation/IntExtensions.swift | 53 ++--- .../Foundation/SignedIntegerExtensions.swift | 29 +-- .../Foundation/StringExtensions.swift | 197 +++++++++--------- .../UIKit/UICollectionViewExtensions.swift | 25 ++- .../UIKit/UISearchBarExtensions.swift | 17 +- .../UIKit/UITableViewExtensions.swift | 24 ++- .../UIKit/UITextFieldExtensions.swift | 2 +- .../Extensions/UIKit/UIViewExtensions.swift | 51 +++-- .../FoundationTests/IntExtensionsTests.swift | 4 +- .../StringExtensionsTests.swift | 14 +- .../UICollectionViewExtensionsTests.swift | 4 +- .../UITableViewExtensionsTests.swift | 8 +- 13 files changed, 233 insertions(+), 208 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f271d4937..7851a9472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,19 @@ All notable changes to this project will be documented in this file. - `dictionary(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.dictionary(forKey: _)` instead. - `float(forKey: String)` is deprecated, use SwifterSwift's `UserDefaults.standard.float(forKey: _) ` instead. - `set(_ value: Any?, forKey: String)` is deprecated, use Apple's `UserDefaults.standard.setValue(_, forKey: _)` instead. +- **Int** + - Property `romanNumeral` is now a method. +- **String** + - Property `lines` is now a method. + - Property `mostCommonCharacter` is now a method. + - Property `reversed` is now a method. + - Property `unicodeArray` is now a method. + - Property `words` is now a method. + - Property `wordCount` is now a method. +- **UICollectionView** + - Property `numberOfItems` is now a method. +- **UITableView** + - Property `numberOfRows` is now a method. ### Enhancements - New **Date** extensions diff --git a/Sources/Extensions/Foundation/IntExtensions.swift b/Sources/Extensions/Foundation/IntExtensions.swift index 3b5d6fcb3..7a35044b8 100755 --- a/Sources/Extensions/Foundation/IntExtensions.swift +++ b/Sources/Extensions/Foundation/IntExtensions.swift @@ -59,31 +59,6 @@ public extension Int { return CGFloat(self) } - /// SwifterSwift: Roman numeral string from integer (if applicable). - public var romanNumeral: String? { - // https://gist.github.com/kumo/a8e1cb1f4b7cff1548c7 - guard self > 0 else { // there is no roman numerals for 0 or negative numbers - return nil - } - let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] - let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] - - var romanValue = "" - var startingValue = self - - for (index, romanChar) in romanValues.enumerated() { - let arabicValue = arabicValues[index] - let div = startingValue / arabicValue - if (div > 0) { - for _ in 0..
    "X" + /// + /// - Returns: The roman numeral string. + public func romanNumeral() -> String? { + // https://gist.github.com/kumo/a8e1cb1f4b7cff1548c7 + guard self > 0 else { // there is no roman numerals for 0 or negative numbers + return nil + } + let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] + let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] + + var romanValue = "" + var startingValue = self + + for (index, romanChar) in romanValues.enumerated() { + let arabicValue = arabicValues[index] + let div = startingValue / arabicValue + if (div > 0) { + for _ in 0..
    [1, 8, 0] + /// + public var digits: [Self] { + var digits: [Self] = [] + for char in String(self).characters { + if let int = IntMax(String(char)) { + digits.append(Self(int)) + } + } + return digits + } + /// SwifterSwift: Number of digits of integer value. public var digitsCount: Int { return String(self).characters.count @@ -79,7 +82,7 @@ public extension SignedInteger { public func lcm(of n: Self) -> Self { return (self * n).abs / gcd(of: n) } - + } diff --git a/Sources/Extensions/Foundation/StringExtensions.swift b/Sources/Extensions/Foundation/StringExtensions.swift index f3388ec3d..67e6319fe 100755 --- a/Sources/Extensions/Foundation/StringExtensions.swift +++ b/Sources/Extensions/Foundation/StringExtensions.swift @@ -236,39 +236,6 @@ public extension String { return characters.count } - /// SwifterSwift: Array of strings separated by new lines. - /// - /// "Hello\ntest".lines -> ["Hello", "test"] - /// - public var lines: [String] { - var result = [String]() - enumerateLines { line, _ in - result.append(line) - } - return result - } - - /// SwifterSwift: The most common character in string. - /// - /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter -> "e" - /// - public var mostCommonCharacter: String { - let mostCommon = withoutSpacesAndNewLines.characters.reduce([Character: Int]()) { - var counts = $0 - counts[$1] = ($0[$1] ?? 0) + 1 - return counts - }.max { $0.1 < $1.1 }?.0 - return mostCommon?.string ?? "" - } - - /// SwifterSwift: Reversed string. - /// - /// "foo".reversed -> "oof" - /// - public var reversed: String { - return String(characters.reversed()) - } - /// SwifterSwift: Bool value from string (if applicable). /// /// "1".bool -> true @@ -309,39 +276,6 @@ public extension String { return formatter.date(from: selfLowercased) } - /// Float value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional Float value from given string. - public func float(locale: Locale = .current) -> Float? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? Float - } - - /// Double value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional Double value from given string. - public func double(locale: Locale = .current) -> Double? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? Double - } - - /// CGFloat value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional CGFloat value from given string. - public func cgFloat(locale: Locale = .current) -> CGFloat? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? CGFloat - } - /// SwifterSwift: Integer value from string (if applicable). /// /// "101".int -> 101 @@ -367,14 +301,6 @@ public extension String { return trimmingCharacters(in: .whitespacesAndNewlines) } - /// SwifterSwift: Array with unicodes for all characters in a string. - /// - /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] - /// - public var unicodeArray: [Int] { - return unicodeScalars.map({$0.hashValue}) - } - /// SwifterSwift: Readable string from a URL string. /// /// "it's%20easy%20to%20decode%20strings".urlDecoded -> "it's easy to decode strings" @@ -399,35 +325,112 @@ public extension String { return replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "") } - /// SwifterSwift: an array of all words in a string - /// - /// "Swift is amazing".words -> ["Swift", "is", "amazing"] - /// - public var words: [String] { - // https://stackoverflow.com/questions/42822838 - let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) - let comps = components(separatedBy: chararacterSet) - return comps.filter { !$0.isEmpty } - } - - /// SwifterSwift: Count of words in a string. - /// - /// "Swift is amazing".wordsCount -> 3 - /// - public var wordCount: Int { - // https://stackoverflow.com/questions/42822838 - let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) - let comps = components(separatedBy: chararacterSet) - let words = comps.filter { !$0.isEmpty } - return words.count - } - } // MARK: - Methods public extension String { + /// Float value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional Float value from given string. + public func float(locale: Locale = .current) -> Float? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? Float + } + + /// Double value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional Double value from given string. + public func double(locale: Locale = .current) -> Double? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? Double + } + + /// CGFloat value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional CGFloat value from given string. + public func cgFloat(locale: Locale = .current) -> CGFloat? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? CGFloat + } + + /// SwifterSwift: Array of strings separated by new lines. + /// + /// "Hello\ntest".lines() -> ["Hello", "test"] + /// + /// - Returns: Strings separated by new lines. + public func lines() -> [String] { + var result = [String]() + enumerateLines { line, _ in + result.append(line) + } + return result + } + + /// SwifterSwift: The most common character in string. + /// + /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter() -> "e" + /// + /// - Returns: The most common character. + public func mostCommonCharacter() -> String { + let mostCommon = withoutSpacesAndNewLines.characters.reduce([Character: Int]()) { + var counts = $0 + counts[$1] = ($0[$1] ?? 0) + 1 + return counts + }.max { $0.1 < $1.1 }?.0 + return mostCommon?.string ?? "" + } + + /// SwifterSwift: Reversed string. + /// + /// "foo".reversed() -> "oof" + /// + /// - Returns: The reversed string. + public func reversed() -> String { + return String(characters.reversed()) + } + + /// SwifterSwift: Array with unicodes for all characters in a string. + /// + /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] + /// + /// - Returns: The unicodes for all characters in a string. + public func unicodeArray() -> [Int] { + return unicodeScalars.map({ $0.hashValue }) + } + + /// SwifterSwift: an array of all words in a string + /// + /// "Swift is amazing".words() -> ["Swift", "is", "amazing"] + /// + /// - Returns: The words contained in a string. + public func words() -> [String] { + // https://stackoverflow.com/questions/42822838 + let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) + let comps = components(separatedBy: chararacterSet) + return comps.filter { !$0.isEmpty } + } + + /// SwifterSwift: Count of words in a string. + /// + /// "Swift is amazing".wordsCount() -> 3 + /// + /// - Returns: The count of words contained in a string. + public func wordCount() -> Int { + // https://stackoverflow.com/questions/42822838 + return words().count + } + /// SwifterSwift: Safely subscript string with index. /// /// "Hello World!"[3] -> "l" diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index 7cc556c29..943fa22f9 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -23,23 +23,26 @@ public extension UICollectionView { return numberOfSections > 0 ? numberOfSections - 1 : 0 } - /// SwifterSwift: Number of all items in all sections of collectionView. - public var numberOfItems: Int { - var section = 0 - var itemsCount = 0 - while section < self.numberOfSections { - itemsCount += numberOfItems(inSection: section) - section += 1 - } - return itemsCount - } - } // MARK: - Methods public extension UICollectionView { + + /// SwifterSwift: Number of all items in all sections of collectionView. + /// + /// - Returns: The count of all rows in the collectionView. + public func numberOfItems() -> Int { + var section = 0 + var itemsCount = 0 + while section < self.numberOfSections { + itemsCount += numberOfItems(inSection: section) + section += 1 + } + return itemsCount + } + /// SwifterSwift: IndexPath for last item in section. /// /// - Parameter section: section to get last item in. diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index d0044b92b..8b0c0c00a 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -13,20 +13,19 @@ import UIKit // MARK: - Properties public extension UISearchBar { - /// SwifterSwift: Text field inside search bar (if applicable). - public var textField: UITextField? { - let subViews = subviews.flatMap { $0.subviews } - guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else { - return nil - } - return textField - } - /// SwifterSwift: Text with no spaces or new lines in beginning and end (if applicable). public var trimmedText: String? { return text?.trimmingCharacters(in: .whitespacesAndNewlines) } + /// SwifterSwift: Text field inside search bar (if applicable). + public var textField : UITextField? { + let subViews = subviews.flatMap { $0.subviews } + guard let textField = (subViews.first { $0 is UITextField }) as? UITextField else { + return nil + } + return textField + } } diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index 00d3d69f6..ccf450677 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -23,22 +23,24 @@ public extension UITableView { return numberOfSections > 0 ? numberOfSections - 1 : 0 } - /// SwifterSwift: Number of all rows in all sections of tableView. - public var numberOfRows: Int { - var section = 0 - var rowCount = 0 - while section < numberOfSections { - rowCount += numberOfRows(inSection: section) - section += 1 - } - return rowCount - } - } // MARK: - Methods public extension UITableView { + /// SwifterSwift: Number of all rows in all sections of tableView. + /// + /// - Returns: The count of all rows in the tableView. + public func numberOfRows() -> Int { + var section = 0 + var rowCount = 0 + while section < numberOfSections { + rowCount += numberOfRows(inSection: section) + section += 1 + } + return rowCount + } + /// SwifterSwift: IndexPath for last row in section. /// /// - Parameter section: section to get last row in. diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index 21c5e6587..5e1655214 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -83,7 +83,7 @@ public extension UITextField { /// public var hasValidEmail: Bool { // http://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift - return text!.range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", + return text?.range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", options: String.CompareOptions.regularExpression, range: nil, locale: nil) != nil } diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index dc27de995..5aed24c9c 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -88,19 +88,6 @@ public extension UIView { } } - /// SwifterSwift: First responder. - public var firstResponder: UIView? { - guard !isFirstResponder else { - return self - } - for subView in subviews { - if subView.isFirstResponder { - return subView - } - } - return nil - } - // SwifterSwift: Height of view. public var height: CGFloat { get { @@ -191,18 +178,6 @@ public extension UIView { } } - /// SwifterSwift: Get view's parent view controller - public var parentViewController: UIViewController? { - weak var parentResponder: UIResponder? = self - while parentResponder != nil { - parentResponder = parentResponder!.next - if let viewController = parentResponder as? UIViewController { - return viewController - } - } - return nil - } - /// SwifterSwift: Width of view. public var width: CGFloat { get { @@ -233,12 +208,36 @@ public extension UIView { } } + /// SwifterSwift: Get view's parent view controller + public var parentViewController: UIViewController? { + weak var parentResponder: UIResponder? = self + while parentResponder != nil { + parentResponder = parentResponder!.next + if let viewController = parentResponder as? UIViewController { + return viewController + } + } + return nil + } + + /// SwifterSwift: First responder. + public var firstResponder: UIView? { + guard !isFirstResponder else { + return self + } + for subView in subviews { + if subView.isFirstResponder { + return subView + } + } + return nil + } } // MARK: - Methods public extension UIView { - + /// SwifterSwift: Set some or all corners radiuses of view. /// /// - Parameters: diff --git a/Tests/FoundationTests/IntExtensionsTests.swift b/Tests/FoundationTests/IntExtensionsTests.swift index 4f610c8be..6fc110935 100644 --- a/Tests/FoundationTests/IntExtensionsTests.swift +++ b/Tests/FoundationTests/IntExtensionsTests.swift @@ -109,8 +109,8 @@ class IntExtensionsTests: XCTestCase { } func testRomanNumeral() { - XCTAssertEqual(10.romanNumeral, "X") - XCTAssertNil((-1).romanNumeral) + XCTAssertEqual(10.romanNumeral(), "X") + XCTAssertNil((-1).romanNumeral()) } func testTimeString() { diff --git a/Tests/FoundationTests/StringExtensionsTests.swift b/Tests/FoundationTests/StringExtensionsTests.swift index 73283ae6c..206ba357f 100644 --- a/Tests/FoundationTests/StringExtensionsTests.swift +++ b/Tests/FoundationTests/StringExtensionsTests.swift @@ -170,13 +170,13 @@ class StringExtensionsTests: XCTestCase { } func testLines() { - XCTAssertEqual("Hello\ntest".lines, ["Hello", "test"]) + XCTAssertEqual("Hello\ntest".lines(), ["Hello", "test"]) } func testMostCommonCharacter() { - let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter + let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter() XCTAssertEqual(mostCommonCharacter, "e") - XCTAssertEqual("".mostCommonCharacter, "") + XCTAssertEqual("".mostCommonCharacter(), "") } func testRandom() { @@ -198,7 +198,7 @@ class StringExtensionsTests: XCTestCase { } func testReversed() { - XCTAssertEqual("Hello".reversed, "olleH") + XCTAssertEqual("Hello".reversed(), "olleH") } func testSlice() { @@ -377,7 +377,7 @@ class StringExtensionsTests: XCTestCase { } func testUnicodeArray() { - XCTAssertEqual("Hello".unicodeArray, [72, 101, 108, 108, 111]) + XCTAssertEqual("Hello".unicodeArray(), [72, 101, 108, 108, 111]) } func testUrlDecode() { @@ -556,11 +556,11 @@ class StringExtensionsTests: XCTestCase { } func testWords() { - XCTAssertEqual("Swift is amazing".words, ["Swift", "is", "amazing"]) + XCTAssertEqual("Swift is amazing".words(), ["Swift", "is", "amazing"]) } func testWordsCount() { - XCTAssertEqual("Swift is amazing".wordCount, 3) + XCTAssertEqual("Swift is amazing".wordCount(), 3) } } diff --git a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift index 75c039f99..a3c25de93 100644 --- a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift +++ b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift @@ -36,8 +36,8 @@ class UICollectionViewExtensionsTests: XCTestCase { } func testNumberOfRows() { - XCTAssertEqual(collectionView.numberOfItems, 5) - XCTAssertEqual(emptyCollectionView.numberOfItems, 0) + XCTAssertEqual(collectionView.numberOfItems(), 5) + XCTAssertEqual(emptyCollectionView.numberOfItems(), 0) } func testIndexPathForLastRowInSection() { diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index b88832681..00e547c03 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -17,8 +17,8 @@ class UITableViewExtensionsTests: XCTestCase { override func setUp() { super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - tableView.dataSource = self + + tableView.dataSource = self emptyTableView.dataSource = self tableView.reloadData() } @@ -33,8 +33,8 @@ class UITableViewExtensionsTests: XCTestCase { } func testNumberOfRows() { - XCTAssertEqual(tableView.numberOfRows, 13) - XCTAssertEqual(emptyTableView.numberOfRows, 0) + XCTAssertEqual(tableView.numberOfRows(), 13) + XCTAssertEqual(emptyTableView.numberOfRows(), 0) } func testIndexPathForLastRowInSection() { From 14ea584fdce90c60270732ef7b2d69781968e090 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 7 Sep 2017 19:20:25 +0300 Subject: [PATCH 015/201] Update files structure (#241) - Closes #236 - Fix subspecs after pod lib lint - Update CHANGELOG.md --- CHANGELOG.md | 10 +- README.md | 201 +- .../{Cocoa => AppKit}/NSColorExtensions.swift | 0 .../{Cocoa => AppKit}/NSViewExtensions.swift | 6 +- .../CGColorExtensions.swift | 0 .../CGFloatExtensions.swift | 0 .../CGPointExtensions.swift | 0 .../CGSizeExtensions.swift | 0 .../CLLocationExtensions.swift | 0 .../NSAttributedStringExtensions.swift | 0 .../ArrayExtensions.swift | 0 .../BoolExtensions.swift | 0 .../CharacterExtensions.swift | 0 .../CollectionExtensions.swift | 0 .../DictionaryExtensions.swift | 3 +- .../DoubleExtensions.swift | 0 .../FloatExtensions.swift | 0 .../FloatingPointExtensions.swift | 0 .../IntExtensions.swift | 0 .../OptionalExtensions.swift | 0 .../SignedIntegerExtensions.swift | 0 .../SignedNumberExtensions.swift | 0 .../StringExtensions.swift | 0 SwifterSwift.podspec | 25 +- SwifterSwift.xcodeproj/project.pbxproj | 1779 +++++++++-------- .../NSAttributedStringExtensionsTests.swift | 0 .../NSViewExtensionsTests.swift | 0 .../CGFloatExtensionsTests.swift | 0 .../CGPointExtensionsTests.swift | 0 .../CGSizeExtensionsTests.swift | 0 .../CLLocationExtensionsTests.swift | 0 .../ArrayExtensionsTests.swift | 0 .../BoolExtensionsTests.swift | 0 .../CharacterExtensionsTests.swift | 0 .../CollectionExtensionsTests.swift | 0 .../DictionaryExtensionsTests.swift | 0 .../DoubleExtensionsTests.swift | 0 .../FloatExtensionsTests.swift | 0 .../IntExtensionsTests.swift | 0 .../OptionalExtensionsTests.swift | 0 .../StringExtensionsTests.swift | 0 41 files changed, 1035 insertions(+), 989 deletions(-) rename Sources/Extensions/{Cocoa => AppKit}/NSColorExtensions.swift (100%) rename Sources/Extensions/{Cocoa => AppKit}/NSViewExtensions.swift (93%) rename Sources/Extensions/{Cocoa => CoreGraphics}/CGColorExtensions.swift (100%) rename Sources/Extensions/{Cocoa => CoreGraphics}/CGFloatExtensions.swift (100%) rename Sources/Extensions/{Cocoa => CoreGraphics}/CGPointExtensions.swift (100%) rename Sources/Extensions/{Cocoa => CoreGraphics}/CGSizeExtensions.swift (100%) rename Sources/Extensions/{Cocoa => CoreLocation}/CLLocationExtensions.swift (100%) rename Sources/Extensions/{Cocoa => Foundation}/NSAttributedStringExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/ArrayExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/BoolExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/CharacterExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/CollectionExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/DictionaryExtensions.swift (98%) rename Sources/Extensions/{Foundation => SwiftStdlib}/DoubleExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/FloatExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/FloatingPointExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/IntExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/OptionalExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/SignedIntegerExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/SignedNumberExtensions.swift (100%) rename Sources/Extensions/{Foundation => SwiftStdlib}/StringExtensions.swift (100%) rename Tests/{CocoaTests => AppKitTests}/NSAttributedStringExtensionsTests.swift (100%) rename Tests/{CocoaTests => AppKitTests}/NSViewExtensionsTests.swift (100%) rename Tests/{CocoaTests => CoreGraphicsTests}/CGFloatExtensionsTests.swift (100%) rename Tests/{CocoaTests => CoreGraphicsTests}/CGPointExtensionsTests.swift (100%) rename Tests/{CocoaTests => CoreGraphicsTests}/CGSizeExtensionsTests.swift (100%) rename Tests/{CocoaTests => CoreLocationTests}/CLLocationExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/ArrayExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/BoolExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/CharacterExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/CollectionExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/DictionaryExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/DoubleExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/FloatExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/IntExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/OptionalExtensionsTests.swift (100%) rename Tests/{FoundationTests => SwiftStdlibTests}/StringExtensionsTests.swift (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7851a9472..851bdb195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,18 +54,22 @@ All notable changes to this project will be documented in this file. - added `isInThisYear` property to check if date is in the current year. - added `isInThisMonth` property to check if date is in the current month. - added `isInThisWeek` property to check if date is in the current week. - - New **URLRequest** extensions - added `init?(urlString: String)` fallible initializer create a URLRequest from URL string. - - New **UIWebView** extensions - added `loadURL(_ url: URL)` method to load a URL. - added `loadURLString(_ urlString: String)` method to load a URL string. - - New **UserDefaults** extensions - added `subscript(key: String)` method to get values from UserDefaults using the [] operator. - added `float(forKey key: String)` method to get a Float value from UserDefaults. - added `date(forKey key: String)` method to get a Date value from UserDefaults. +- Improved file structre, as in [#236](https://github.com/SwifterSwift/SwifterSwift/issues/236) +- Improved README + - Removed unnecessary description in Installation section + - Updated **List of All Extensions** section to match the new file structure. + +### Bugfixes +N/A # v3.1.1 diff --git a/README.md b/README.md index 43b043816..00366727e 100755 --- a/README.md +++ b/README.md @@ -15,8 +15,7 @@ [![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) [![Slack Channel](http://slack.swifterswift.com/badge.svg)](http://slack.swifterswift.com/) - -SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. +SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types like SwiftStdlib, Foundation, UIKit, AppKit and many other classes. –over 500 in 1– for iOS, macOS, tvOS and watchOS. --- @@ -27,7 +26,7 @@ We're working on **v4** in the [`swift-4 branch`](https://github.com/SwifterSwif --- -### [Whats New in v3.1.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v311) +### [Whats New in v3.2.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v320) ## Requirements: @@ -42,92 +41,41 @@ We're working on **v4** in the [`swift-4 branch`](https://github.com/SwifterSwif
    CocoaPods
    +

    To integrate SwifterSwift into your Xcode project using CocoaPods, specify it in your Podfile:

    -

    CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

    - -
    $ gem install cocoapods
    -
    - -

    To integrate SwifterSwift into your Xcode project using CocoaPods, specify it in your Podfile:

    - -

    1. Integrate All extensions:

    - -
    source 'https://github.com/CocoaPods/Specs.git'
    -platform :ios, '8.0'
    -use_frameworks!
    -
    -target '<Your Target Name>' do
    -    pod 'SwifterSwift'
    -end
    -
    - -

    2. Integrate Foundation extensions only:

    - -
    source 'https://github.com/CocoaPods/Specs.git'
    -platform :ios, '8.0'
    -use_frameworks!
    -
    -target '<Your Target Name>' do
    -    pod 'SwifterSwift/Foundation'
    -end
    -
    - -

    3. Integrate UIKit extensions only:

    - -
    source 'https://github.com/CocoaPods/Specs.git'
    -platform :ios, '8.0'
    -use_frameworks!
    -
    -target '<Your Target Name>' do
    -    pod 'SwifterSwift/UIKit'
    -end
    -
    - -

    4. Integrate Cocoa extensions only:

    +

    - Integrate All extensions (recommended):

    +
    pod 'SwifterSwift'
    -
    source 'https://github.com/CocoaPods/Specs.git'
    -platform :ios, '8.0'
    -use_frameworks!
    +

    - Integrate SwiftStdlib extensions only:

    +
    pod 'SwifterSwift/SwiftStdlib'
    -target '<Your Target Name>' do - pod 'SwifterSwift/Cocoa' -end -
    +

    - Integrate Foundation extensions only:

    +
    pod 'SwifterSwift/Foundation'
    -

    Then, run the following command:

    +

    - Integrate AppKit extensions only:

    +
    pod 'SwifterSwift/AppKit'
    -
    $ pod install
    -
    +

    - Integrate CoreGraphics extensions only:

    +
    pod 'SwifterSwift/CoreGraphics'
    +

    - Integrate CoreLocation extensions only:

    +
    pod 'SwifterSwift/CoreLocation'
    Carthage
    - -

    Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

    - -

    You can install Carthage with Homebrew using the following command:

    - -
    $ brew update
    -$ brew install carthage
    -
    - -

    To integrate SwifterSwift into your Xcode project using Carthage, specify it in your Cartfile:

    +

    To integrate SwifterSwift into your Xcode project using Carthage, specify it in your Cartfile:

    github "SwifterSwift/SwifterSwift" ~> 3.0
     
    - -

    Run carthage update to build the framework and drag the built SwifterSwift.framework into your Xcode project.

    -
    Swift Package Manager
    -

    You can use The Swift Package Manager to install SwifterSwift by adding the proper description to your Package.swift file:

    import PackageDescription
    @@ -142,16 +90,13 @@ let package = Package(
     

    Note that the Swift Package Manager is still in early design and development, for more information checkout its GitHub Page

    -
    Manually
    -

    Add the extensions folder to your Xcode project to use all extensions, or a specific extension.

    -
    @@ -159,134 +104,107 @@ let package = Package( ## List of All Extensions
    -Foundation Extensions +SwiftStdlib Extensions
    - +
    -
  • Collection extensions
  • +
    +Foundation Extensions +
    + -
    UIKit Extensions
    - -
    -Cocoa Extensions +AppKit Extensions
    - +
    -
  • NSAttributedString extensions
  • +
    +CoreGraphics Extensions +
    + +
    -
  • NSColor extensions
  • -
  • NSView extensions
  • +
    +CoreLocation Extensions +
    + -
    Misc. Extensions
    - -
    @@ -298,6 +216,7 @@ SwifterSwift is a library of **over 500 properties and methods**, designed to ex Check [Examples.md](https://github.com/SwifterSwift/SwifterSwift/tree/master/Examples/Examples.md) for some cool examples! + ## Documentation A complete documentation for all extensions with examples is available at [swifterswift.com/docs](http://swifterswift.com/docs) diff --git a/Sources/Extensions/Cocoa/NSColorExtensions.swift b/Sources/Extensions/AppKit/NSColorExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/NSColorExtensions.swift rename to Sources/Extensions/AppKit/NSColorExtensions.swift diff --git a/Sources/Extensions/Cocoa/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift similarity index 93% rename from Sources/Extensions/Cocoa/NSViewExtensions.swift rename to Sources/Extensions/AppKit/NSViewExtensions.swift index 42f3f946d..1fa2a438c 100644 --- a/Sources/Extensions/Cocoa/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -16,7 +16,8 @@ public extension NSView { /// SwifterSwift: Border color of view; also inspectable from Storyboard. public var borderColor: NSColor? { get { - return layer?.borderColor?.nsColor + guard let color = layer?.borderColor else { return nil } + return NSColor(cgColor: color) } set { wantsLayer = true @@ -63,7 +64,8 @@ public extension NSView { /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. public var shadowColor: NSColor? { get { - return layer?.shadowColor?.nsColor + guard let color = layer?.shadowColor else { return nil } + return NSColor(cgColor: color) } set { wantsLayer = true diff --git a/Sources/Extensions/Cocoa/CGColorExtensions.swift b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/CGColorExtensions.swift rename to Sources/Extensions/CoreGraphics/CGColorExtensions.swift diff --git a/Sources/Extensions/Cocoa/CGFloatExtensions.swift b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/CGFloatExtensions.swift rename to Sources/Extensions/CoreGraphics/CGFloatExtensions.swift diff --git a/Sources/Extensions/Cocoa/CGPointExtensions.swift b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/CGPointExtensions.swift rename to Sources/Extensions/CoreGraphics/CGPointExtensions.swift diff --git a/Sources/Extensions/Cocoa/CGSizeExtensions.swift b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/CGSizeExtensions.swift rename to Sources/Extensions/CoreGraphics/CGSizeExtensions.swift diff --git a/Sources/Extensions/Cocoa/CLLocationExtensions.swift b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/CLLocationExtensions.swift rename to Sources/Extensions/CoreLocation/CLLocationExtensions.swift diff --git a/Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift similarity index 100% rename from Sources/Extensions/Cocoa/NSAttributedStringExtensions.swift rename to Sources/Extensions/Foundation/NSAttributedStringExtensions.swift diff --git a/Sources/Extensions/Foundation/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/ArrayExtensions.swift rename to Sources/Extensions/SwiftStdlib/ArrayExtensions.swift diff --git a/Sources/Extensions/Foundation/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/BoolExtensions.swift rename to Sources/Extensions/SwiftStdlib/BoolExtensions.swift diff --git a/Sources/Extensions/Foundation/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/CharacterExtensions.swift rename to Sources/Extensions/SwiftStdlib/CharacterExtensions.swift diff --git a/Sources/Extensions/Foundation/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/CollectionExtensions.swift rename to Sources/Extensions/SwiftStdlib/CollectionExtensions.swift diff --git a/Sources/Extensions/Foundation/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift similarity index 98% rename from Sources/Extensions/Foundation/DictionaryExtensions.swift rename to Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index ed5c0d52a..a6366826d 100644 --- a/Sources/Extensions/Foundation/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -77,7 +77,8 @@ public extension Dictionary { } let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) - return jsonData?.string(encoding: .utf8) + guard let data = jsonData else { return nil } + return String(data: data, encoding: .utf8) } /// SwifterSwift: Count dictionary entries that where function returns true. diff --git a/Sources/Extensions/Foundation/DoubleExtensions.swift b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/DoubleExtensions.swift rename to Sources/Extensions/SwiftStdlib/DoubleExtensions.swift diff --git a/Sources/Extensions/Foundation/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/FloatExtensions.swift rename to Sources/Extensions/SwiftStdlib/FloatExtensions.swift diff --git a/Sources/Extensions/Foundation/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/FloatingPointExtensions.swift rename to Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift diff --git a/Sources/Extensions/Foundation/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/IntExtensions.swift rename to Sources/Extensions/SwiftStdlib/IntExtensions.swift diff --git a/Sources/Extensions/Foundation/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/OptionalExtensions.swift rename to Sources/Extensions/SwiftStdlib/OptionalExtensions.swift diff --git a/Sources/Extensions/Foundation/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/SignedIntegerExtensions.swift rename to Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift diff --git a/Sources/Extensions/Foundation/SignedNumberExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumberExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/SignedNumberExtensions.swift rename to Sources/Extensions/SwiftStdlib/SignedNumberExtensions.swift diff --git a/Sources/Extensions/Foundation/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift similarity index 100% rename from Sources/Extensions/Foundation/StringExtensions.swift rename to Sources/Extensions/SwiftStdlib/StringExtensions.swift diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 91da51610..27269986a 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,10 +1,10 @@ Pod::Spec.new do |s| s.name = "SwifterSwift" s.module_name = "SwifterSwift" - s.version = "3.1.1" + s.version = "3.2.0" s.summary = "A handy collection of more than 500 native Swift 3 extensions to boost your productivity." s.description = <<-DESC - SwifterSwift is a collection of over 500 native Swift 3 extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. + SwifterSwift is a collection of over 500 native Swift 3 extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types like SwiftStdlib, Foundation, UIKit, AppKit and many other classes. –over 500 in 1– for iOS, macOS, tvOS and watchOS. DESC s.homepage = "https://github.com/SwifterSwift/SwifterSwift" @@ -27,6 +27,11 @@ Pod::Spec.new do |s| } s.documentation_url = 'http://swifterswift.com/docs' + # SwiftStdlib Extensions + s.subspec 'SwiftStdlib' do |sp| + sp.source_files = "Sources/Extensions/SwiftStdlib/*.swift" + end + # Foundation Extensions s.subspec 'Foundation' do |sp| sp.source_files = "Sources/Extensions/Foundation/*.swift" @@ -37,9 +42,19 @@ Pod::Spec.new do |s| sp.source_files = "Sources/Extensions/UIKit/*.swift" end - # Cocoa Extensions - s.subspec 'Cocoa' do |sp| - sp.source_files = "Sources/Extensions/Cocoa/*.swift" + # AppKit Extensions + s.subspec 'AppKit' do |sp| + sp.source_files = "Sources/Extensions/AppKit/*.swift" + end + + # CoreGraphics Extensions + s.subspec 'CoreGraphics' do |sp| + sp.source_files = "Sources/Extensions/CoreGraphics/*.swift" + end + + # CoreLocation Extensions + s.subspec 'CoreLocation' do |sp| + sp.source_files = "Sources/Extensions/CoreLocation/*.swift" end end diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index c7f38cced..fe3f0c2bc 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,314 +7,339 @@ objects = { /* Begin PBXBuildFile section */ - 0703E5291F5F33AA00788AB4 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */; }; - 0703E52C1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; - 0703E52D1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; - 0703E52E1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; - 0703E52F1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */; }; - 0703E5311F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; - 0703E5321F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; - 0703E5331F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; - 0703E5341F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */; }; - 0703E5371F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; - 0703E5381F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; - 0703E5391F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; - 0703E53A1F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */; }; - 077A72CC1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; - 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; - 077A72CE1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; - 077A72CF1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */; }; - 077A72D11F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; - 077A72D21F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; - 077A72D31F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; - 077A72D41F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */; }; + 0743F2B71F611B63008386F7 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2781F611B62008386F7 /* NSColorExtensions.swift */; }; + 0743F2BB1F611B63008386F7 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2791F611B62008386F7 /* NSViewExtensions.swift */; }; + 0743F2BE1F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; + 0743F2BF1F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; + 0743F2C01F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; + 0743F2C11F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; + 0743F2C21F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; + 0743F2C31F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; + 0743F2C41F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; + 0743F2C51F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; + 0743F2C61F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; + 0743F2C71F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; + 0743F2C81F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; + 0743F2C91F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; + 0743F2CA1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; + 0743F2CB1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; + 0743F2CC1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; + 0743F2CD1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; + 0743F2CE1F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; + 0743F2CF1F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; + 0743F2D01F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; + 0743F2D11F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; + 0743F2D21F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; + 0743F2D31F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; + 0743F2D41F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; + 0743F2D51F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; + 0743F2D61F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; + 0743F2D71F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; + 0743F2D81F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; + 0743F2D91F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; + 0743F2DA1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; + 0743F2DB1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; + 0743F2DC1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; + 0743F2DD1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; + 0743F2DE1F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; + 0743F2DF1F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; + 0743F2E01F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; + 0743F2E11F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; + 0743F2E21F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; + 0743F2E31F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; + 0743F2E41F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; + 0743F2E51F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; + 0743F2E61F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; + 0743F2E71F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; + 0743F2E81F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; + 0743F2E91F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; + 0743F2EA1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; + 0743F2EB1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; + 0743F2EC1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; + 0743F2ED1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; + 0743F2EE1F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; + 0743F2EF1F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; + 0743F2F01F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; + 0743F2F11F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; + 0743F2F21F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; + 0743F2F31F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; + 0743F2F41F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; + 0743F2F51F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; + 0743F2F61F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; + 0743F2F71F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; + 0743F2F81F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; + 0743F2F91F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; + 0743F2FA1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; + 0743F2FB1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; + 0743F2FC1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; + 0743F2FD1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; + 0743F2FE1F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; + 0743F2FF1F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; + 0743F3001F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; + 0743F3011F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; + 0743F3021F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; + 0743F3031F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; + 0743F3041F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; + 0743F3051F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; + 0743F3061F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; + 0743F3071F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; + 0743F3081F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; + 0743F3091F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; + 0743F30A1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; + 0743F30B1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; + 0743F30C1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; + 0743F30D1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; + 0743F30E1F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; + 0743F30F1F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; + 0743F3101F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; + 0743F3111F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; + 0743F3121F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; + 0743F3131F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; + 0743F3141F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; + 0743F3151F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; + 0743F3161F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; + 0743F3171F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; + 0743F3181F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; + 0743F3191F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; + 0743F31A1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; + 0743F31B1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; + 0743F31C1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; + 0743F31D1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; + 0743F31E1F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; + 0743F31F1F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; + 0743F3201F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; + 0743F3211F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; + 0743F3221F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; + 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; + 0743F3241F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; + 0743F3251F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; + 0743F3261F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; + 0743F3271F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; + 0743F3281F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; + 0743F3291F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; + 0743F32A1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; + 0743F32B1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; + 0743F32C1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; + 0743F32D1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; + 0743F32E1F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; + 0743F3301F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; + 0743F3311F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; + 0743F3321F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; + 0743F3341F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; + 0743F3351F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; + 0743F3361F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; + 0743F3381F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; + 0743F3391F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; + 0743F33A1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; + 0743F33C1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; + 0743F33D1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; + 0743F33E1F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; + 0743F3401F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; + 0743F3411F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; + 0743F3421F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; + 0743F3441F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; + 0743F3451F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; + 0743F3461F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; + 0743F3481F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; + 0743F3491F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; + 0743F34A1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; + 0743F34C1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; + 0743F34D1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; + 0743F34E1F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; + 0743F3501F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; + 0743F3511F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; + 0743F3521F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; + 0743F3541F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; + 0743F3551F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; + 0743F3561F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; + 0743F3581F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; + 0743F3591F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; + 0743F35A1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; + 0743F35C1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; + 0743F35D1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; + 0743F35E1F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; + 0743F3601F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; + 0743F3611F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; + 0743F3621F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; + 0743F3641F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; + 0743F3651F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; + 0743F3661F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; + 0743F3681F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; + 0743F3691F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; + 0743F36A1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; + 0743F36C1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; + 0743F36D1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; + 0743F36E1F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; + 0743F3701F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; + 0743F3711F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; + 0743F3721F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; + 0743F3741F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; + 0743F3751F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; + 0743F3761F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; + 0743F3781F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; + 0743F3791F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; + 0743F37A1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; + 0743F37C1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; + 0743F37D1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; + 0743F37E1F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; + 0743F3801F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; + 0743F3811F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; + 0743F3821F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; + 0743F3841F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; + 0743F3851F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; + 0743F3861F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; + 0743F3881F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; + 0743F3891F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; + 0743F38A1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; + 0743F38C1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; + 0743F38D1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; + 0743F3C11F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; + 0743F3C21F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; + 0743F3C31F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; + 0743F3C41F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; + 0743F3C51F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; + 0743F3C61F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; + 0743F3C71F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; + 0743F3C81F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; + 0743F3C91F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; + 0743F3CA1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; + 0743F3CB1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; + 0743F3CC1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; + 0743F3CD1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; + 0743F3CE1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; + 0743F3CF1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; + 0743F3D01F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; + 0743F3D11F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; + 0743F3D21F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; + 0743F3D31F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; + 0743F3D41F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; + 0743F3D51F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; + 0743F3D61F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; + 0743F3D71F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; + 0743F3D81F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; + 0743F3D91F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; + 0743F3DA1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; + 0743F3DB1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; + 0743F3DC1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; + 0743F3DD1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; + 0743F3DE1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; + 0743F3DF1F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; + 0743F3E01F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; + 0743F3E11F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; + 0743F3E21F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; + 0743F3E31F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; + 0743F3E41F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; + 0743F3E51F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; + 0743F3E61F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; + 0743F3E71F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; + 0743F3E81F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; + 0743F3E91F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; + 0743F3EA1F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; + 0743F3EB1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; + 0743F3EC1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; + 0743F3ED1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; + 0743F3EE1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; + 0743F3EF1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; + 0743F3F01F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; + 0743F3F11F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; + 0743F3F21F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; + 0743F3F31F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; + 0743F3F41F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; + 0743F3F51F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; + 0743F3F61F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; + 0743F3F71F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; + 0743F3F81F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; + 0743F3F91F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; + 0743F3FA1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; + 0743F3FB1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; + 0743F3FC1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; + 0743F3FD1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; + 0743F3FE1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; + 0743F3FF1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; + 0743F4001F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; + 0743F4011F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; + 0743F4021F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; + 0743F4031F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; + 0743F4041F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; + 0743F4051F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; + 0743F4061F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; + 0743F4071F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; + 0743F4081F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; + 0743F4091F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; + 0743F40A1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; + 0743F40B1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; + 0743F40C1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; + 0743F40D1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; + 0743F40E1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; + 0743F40F1F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; + 0743F4101F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; + 0743F4111F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; + 0743F4121F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; + 0743F4131F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; + 0743F4141F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; + 0743F4151F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; + 0743F4161F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; + 0743F4171F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; + 0743F4181F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; + 0743F4191F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; + 0743F41A1F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; + 0743F41B1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; + 0743F41C1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; + 0743F41D1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; + 0743F41E1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; + 0743F41F1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; + 0743F4201F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; + 0743F4211F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; + 0743F4221F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; + 0743F4231F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; + 0743F4241F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; + 0743F4251F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; + 0743F4261F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; + 0743F4271F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; + 0743F4281F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; + 0743F4291F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; + 0743F42A1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; + 0743F42B1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; + 0743F42C1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; + 0743F42D1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; + 0743F42E1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; + 0743F42F1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; + 0743F4301F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; + 0743F4311F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; + 0743F4321F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; + 0743F4331F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; + 0743F4341F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; + 0743F4351F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; + 0743F4361F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; + 0743F4371F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; + 0743F4381F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; + 0743F4391F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; + 0743F43A1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; + 0743F43B1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; + 0743F43C1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; + 0743F43D1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; + 0743F43E1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; + 0743F43F1F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; + 0743F4401F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; + 0743F4411F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; + 0743F4421F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; + 0743F4431F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; + 0743F4441F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; + 0743F4451F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; + 0743F4461F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; + 0743F4471F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; 077AD1BA1F13873600D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */; }; 077AD1C91F13875100D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */; }; 077AD1D81F13876000D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */; }; - 078473951F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */; }; - 078473961F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */; }; - 078473971F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */; }; - 078473981F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */; }; - 07897F701F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */; }; - 07897F711F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */; }; - 07897F721F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */; }; - 07897F731F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */; }; - 07897F741F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */; }; - 07897F751F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */; }; - 07897F761F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */; }; - 07897F771F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */; }; - 07897F781F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */; }; - 07897F791F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */; }; - 07897F7A1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */; }; - 07897F7B1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */; }; - 07897F7C1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */; }; - 07897F7D1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */; }; - 07897F7E1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */; }; - 07897F7F1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */; }; - 07897F801F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */; }; - 07897F811F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */; }; - 07897F821F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */; }; - 07897F831F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */; }; - 07897F841F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */; }; - 07897F851F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */; }; - 07897F861F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */; }; - 07897F871F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */; }; - 07897F881F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */; }; - 07897F891F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */; }; - 07897F8A1F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */; }; - 07897F8B1F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */; }; - 07897F8C1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */; }; - 07897F8D1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */; }; - 07897F8E1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */; }; - 07897F8F1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */; }; - 07897F901F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */; }; - 07897F911F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */; }; - 07897F921F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */; }; - 07897F931F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */; }; - 07897F941F138A3300A3A4E1 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */; }; - 07897F951F138A3300A3A4E1 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */; }; - 07897F961F138A3300A3A4E1 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */; }; - 07897F971F138A3300A3A4E1 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */; }; - 07897F981F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */; }; - 07897F991F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */; }; - 07897F9A1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */; }; - 07897F9B1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */; }; - 07897F9C1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */; }; - 07897F9D1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */; }; - 07897F9E1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */; }; - 07897F9F1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */; }; - 07897FA01F138A3300A3A4E1 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */; }; - 07897FA11F138A3300A3A4E1 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */; }; - 07897FA21F138A3300A3A4E1 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */; }; - 07897FA31F138A3300A3A4E1 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */; }; - 07897FA41F138A3300A3A4E1 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F501F138A3300A3A4E1 /* DateExtensions.swift */; }; - 07897FA51F138A3300A3A4E1 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F501F138A3300A3A4E1 /* DateExtensions.swift */; }; - 07897FA61F138A3300A3A4E1 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F501F138A3300A3A4E1 /* DateExtensions.swift */; }; - 07897FA71F138A3300A3A4E1 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F501F138A3300A3A4E1 /* DateExtensions.swift */; }; - 07897FA81F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */; }; - 07897FA91F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */; }; - 07897FAA1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */; }; - 07897FAB1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */; }; - 07897FAC1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */; }; - 07897FAD1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */; }; - 07897FAE1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */; }; - 07897FAF1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */; }; - 07897FB01F138A3300A3A4E1 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */; }; - 07897FB11F138A3300A3A4E1 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */; }; - 07897FB21F138A3300A3A4E1 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */; }; - 07897FB31F138A3300A3A4E1 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */; }; - 07897FB41F138A3300A3A4E1 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F541F138A3300A3A4E1 /* IntExtensions.swift */; }; - 07897FB51F138A3300A3A4E1 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F541F138A3300A3A4E1 /* IntExtensions.swift */; }; - 07897FB61F138A3300A3A4E1 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F541F138A3300A3A4E1 /* IntExtensions.swift */; }; - 07897FB71F138A3300A3A4E1 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F541F138A3300A3A4E1 /* IntExtensions.swift */; }; - 07897FB81F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */; }; - 07897FB91F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */; }; - 07897FBA1F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */; }; - 07897FBB1F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */; }; - 07897FBC1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */; }; - 07897FBD1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */; }; - 07897FBE1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */; }; - 07897FBF1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */; }; - 07897FC01F138A3300A3A4E1 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F571F138A3300A3A4E1 /* StringExtensions.swift */; }; - 07897FC11F138A3300A3A4E1 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F571F138A3300A3A4E1 /* StringExtensions.swift */; }; - 07897FC21F138A3300A3A4E1 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F571F138A3300A3A4E1 /* StringExtensions.swift */; }; - 07897FC31F138A3300A3A4E1 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F571F138A3300A3A4E1 /* StringExtensions.swift */; }; - 07897FC41F138A3300A3A4E1 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F581F138A3300A3A4E1 /* URLExtensions.swift */; }; - 07897FC51F138A3300A3A4E1 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F581F138A3300A3A4E1 /* URLExtensions.swift */; }; - 07897FC61F138A3300A3A4E1 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F581F138A3300A3A4E1 /* URLExtensions.swift */; }; - 07897FC71F138A3300A3A4E1 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F581F138A3300A3A4E1 /* URLExtensions.swift */; }; - 07897FC81F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */; }; - 07897FCA1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */; }; - 07897FCB1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */; }; - 07897FCC1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */; }; - 07897FCE1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */; }; - 07897FCF1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */; }; - 07897FD01F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */; }; - 07897FD21F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */; }; - 07897FD31F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */; }; - 07897FD41F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */; }; - 07897FD61F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */; }; - 07897FD71F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */; }; - 07897FD81F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */; }; - 07897FDA1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */; }; - 07897FDB1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */; }; - 07897FDC1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */; }; - 07897FDE1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */; }; - 07897FDF1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */; }; - 07897FE01F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F601F138A3300A3A4E1 /* UIImageViewExtensions.swift */; }; - 07897FE21F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F601F138A3300A3A4E1 /* UIImageViewExtensions.swift */; }; - 07897FE31F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F601F138A3300A3A4E1 /* UIImageViewExtensions.swift */; }; - 07897FE41F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F611F138A3300A3A4E1 /* UILabelExtensions.swift */; }; - 07897FE61F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F611F138A3300A3A4E1 /* UILabelExtensions.swift */; }; - 07897FE71F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F611F138A3300A3A4E1 /* UILabelExtensions.swift */; }; - 07897FE81F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F621F138A3300A3A4E1 /* UINavigationBarExtensions.swift */; }; - 07897FEA1F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F621F138A3300A3A4E1 /* UINavigationBarExtensions.swift */; }; - 07897FEB1F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F621F138A3300A3A4E1 /* UINavigationBarExtensions.swift */; }; - 07897FEC1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F631F138A3300A3A4E1 /* UINavigationControllerExtensions.swift */; }; - 07897FEE1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F631F138A3300A3A4E1 /* UINavigationControllerExtensions.swift */; }; - 07897FEF1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F631F138A3300A3A4E1 /* UINavigationControllerExtensions.swift */; }; - 07897FF01F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F641F138A3300A3A4E1 /* UINavigationItemExtensions.swift */; }; - 07897FF21F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F641F138A3300A3A4E1 /* UINavigationItemExtensions.swift */; }; - 07897FF31F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F641F138A3300A3A4E1 /* UINavigationItemExtensions.swift */; }; - 07897FF41F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F651F138A3300A3A4E1 /* UISearchBarExtensions.swift */; }; - 07897FF61F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F651F138A3300A3A4E1 /* UISearchBarExtensions.swift */; }; - 07897FF71F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F651F138A3300A3A4E1 /* UISearchBarExtensions.swift */; }; - 07897FF81F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F661F138A3300A3A4E1 /* UISegmentedControlExtensions.swift */; }; - 07897FFA1F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F661F138A3300A3A4E1 /* UISegmentedControlExtensions.swift */; }; - 07897FFB1F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F661F138A3300A3A4E1 /* UISegmentedControlExtensions.swift */; }; - 07897FFC1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F671F138A3300A3A4E1 /* UISliderExtensions.swift */; }; - 07897FFE1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F671F138A3300A3A4E1 /* UISliderExtensions.swift */; }; - 07897FFF1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F671F138A3300A3A4E1 /* UISliderExtensions.swift */; }; - 078980001F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F681F138A3300A3A4E1 /* UIStoryboardExtensions.swift */; }; - 078980021F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F681F138A3300A3A4E1 /* UIStoryboardExtensions.swift */; }; - 078980031F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F681F138A3300A3A4E1 /* UIStoryboardExtensions.swift */; }; - 078980041F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F691F138A3300A3A4E1 /* UISwitchExtensions.swift */; }; - 078980061F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F691F138A3300A3A4E1 /* UISwitchExtensions.swift */; }; - 078980071F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F691F138A3300A3A4E1 /* UISwitchExtensions.swift */; }; - 078980081F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6A1F138A3300A3A4E1 /* UITabBarExtensions.swift */; }; - 0789800A1F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6A1F138A3300A3A4E1 /* UITabBarExtensions.swift */; }; - 0789800B1F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6A1F138A3300A3A4E1 /* UITabBarExtensions.swift */; }; - 0789800C1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6B1F138A3300A3A4E1 /* UITableViewExtensions.swift */; }; - 0789800E1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6B1F138A3300A3A4E1 /* UITableViewExtensions.swift */; }; - 0789800F1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6B1F138A3300A3A4E1 /* UITableViewExtensions.swift */; }; - 078980101F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6C1F138A3300A3A4E1 /* UITextFieldExtensions.swift */; }; - 078980121F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6C1F138A3300A3A4E1 /* UITextFieldExtensions.swift */; }; - 078980131F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6C1F138A3300A3A4E1 /* UITextFieldExtensions.swift */; }; - 078980141F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6D1F138A3300A3A4E1 /* UITextViewExtensions.swift */; }; - 078980161F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6D1F138A3300A3A4E1 /* UITextViewExtensions.swift */; }; - 078980171F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6D1F138A3300A3A4E1 /* UITextViewExtensions.swift */; }; - 078980181F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6E1F138A3300A3A4E1 /* UIViewControllerExtensions.swift */; }; - 0789801A1F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6E1F138A3300A3A4E1 /* UIViewControllerExtensions.swift */; }; - 0789801B1F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6E1F138A3300A3A4E1 /* UIViewControllerExtensions.swift */; }; - 0789801C1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6F1F138A3300A3A4E1 /* UIViewExtensions.swift */; }; - 0789801E1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6F1F138A3300A3A4E1 /* UIViewExtensions.swift */; }; - 0789801F1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07897F6F1F138A3300A3A4E1 /* UIViewExtensions.swift */; }; - 0789802F1F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980211F138A5E00A3A4E1 /* ArrayExtensionsTests.swift */; }; - 078980301F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980211F138A5E00A3A4E1 /* ArrayExtensionsTests.swift */; }; - 078980311F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980211F138A5E00A3A4E1 /* ArrayExtensionsTests.swift */; }; - 078980321F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980221F138A5E00A3A4E1 /* BoolExtensionsTests.swift */; }; - 078980331F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980221F138A5E00A3A4E1 /* BoolExtensionsTests.swift */; }; - 078980341F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980221F138A5E00A3A4E1 /* BoolExtensionsTests.swift */; }; - 078980351F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980231F138A5E00A3A4E1 /* CharacterExtensionsTests.swift */; }; - 078980361F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980231F138A5E00A3A4E1 /* CharacterExtensionsTests.swift */; }; - 078980371F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980231F138A5E00A3A4E1 /* CharacterExtensionsTests.swift */; }; - 078980381F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980241F138A5E00A3A4E1 /* CollectionExtensionsTests.swift */; }; - 078980391F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980241F138A5E00A3A4E1 /* CollectionExtensionsTests.swift */; }; - 0789803A1F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980241F138A5E00A3A4E1 /* CollectionExtensionsTests.swift */; }; - 0789803B1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980251F138A5E00A3A4E1 /* DataExtensionsTests.swift */; }; - 0789803C1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980251F138A5E00A3A4E1 /* DataExtensionsTests.swift */; }; - 0789803D1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980251F138A5E00A3A4E1 /* DataExtensionsTests.swift */; }; - 0789803E1F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980261F138A5E00A3A4E1 /* DateExtensionsTests.swift */; }; - 0789803F1F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980261F138A5E00A3A4E1 /* DateExtensionsTests.swift */; }; - 078980401F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980261F138A5E00A3A4E1 /* DateExtensionsTests.swift */; }; - 078980411F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980271F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift */; }; - 078980421F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980271F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift */; }; - 078980431F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980271F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift */; }; - 078980441F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980281F138A5E00A3A4E1 /* DoubleExtensionsTests.swift */; }; - 078980451F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980281F138A5E00A3A4E1 /* DoubleExtensionsTests.swift */; }; - 078980461F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980281F138A5E00A3A4E1 /* DoubleExtensionsTests.swift */; }; - 078980471F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980291F138A5E00A3A4E1 /* FloatExtensionsTests.swift */; }; - 078980481F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980291F138A5E00A3A4E1 /* FloatExtensionsTests.swift */; }; - 078980491F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980291F138A5E00A3A4E1 /* FloatExtensionsTests.swift */; }; - 0789804A1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802A1F138A5E00A3A4E1 /* IntExtensionsTests.swift */; }; - 0789804B1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802A1F138A5E00A3A4E1 /* IntExtensionsTests.swift */; }; - 0789804C1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802A1F138A5E00A3A4E1 /* IntExtensionsTests.swift */; }; - 0789804D1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802B1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift */; }; - 0789804E1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802B1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift */; }; - 0789804F1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802B1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift */; }; - 078980501F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */; }; - 078980511F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */; }; - 078980521F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */; }; - 078980531F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */; }; - 078980541F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */; }; - 078980551F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */; }; - 078980561F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */; }; - 078980571F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */; }; - 078980581F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */; }; - 078980601F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805A1F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift */; }; - 078980611F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805A1F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift */; }; - 078980621F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805A1F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift */; }; - 078980631F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805B1F138A9E00A3A4E1 /* CGPointExtensionsTests.swift */; }; - 078980641F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805B1F138A9E00A3A4E1 /* CGPointExtensionsTests.swift */; }; - 078980651F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805B1F138A9E00A3A4E1 /* CGPointExtensionsTests.swift */; }; - 078980661F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805C1F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift */; }; - 078980671F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805C1F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift */; }; - 078980681F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805C1F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift */; }; - 078980691F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805D1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift */; }; - 0789806A1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805D1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift */; }; - 0789806B1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805D1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift */; }; - 0789806C1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift */; }; - 0789806D1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift */; }; - 0789806E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift */; }; - 078980701F138A9E00A3A4E1 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789805F1F138A9E00A3A4E1 /* NSViewExtensionsTests.swift */; }; 0789808E1F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; 0789808F1F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; 078980901F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; 078980911F138AF000A3A4E1 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */; }; 078980941F138AF000A3A4E1 /* UITableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 078980751F138AF000A3A4E1 /* UITableViewCell.xib */; }; 078980971F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */; }; - 0789809A1F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980781F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift */; }; - 0789809C1F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980781F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift */; }; - 0789809D1F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980791F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift */; }; - 0789809F1F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980791F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift */; }; - 078980A01F138AF000A3A4E1 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807A1F138AF000A3A4E1 /* UIButtonExtensionsTests.swift */; }; - 078980A21F138AF000A3A4E1 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807A1F138AF000A3A4E1 /* UIButtonExtensionsTests.swift */; }; - 078980A31F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807B1F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift */; }; - 078980A51F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807B1F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift */; }; - 078980A61F138AF000A3A4E1 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807C1F138AF000A3A4E1 /* UIColorExtensionsTests.swift */; }; - 078980A81F138AF000A3A4E1 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807C1F138AF000A3A4E1 /* UIColorExtensionsTests.swift */; }; - 078980A91F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807D1F138AF000A3A4E1 /* UIImageExtensionsTests.swift */; }; - 078980AB1F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807D1F138AF000A3A4E1 /* UIImageExtensionsTests.swift */; }; - 078980AC1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807E1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift */; }; - 078980AE1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807E1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift */; }; - 078980AF1F138AF000A3A4E1 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807F1F138AF000A3A4E1 /* UILabelExtensionsTests.swift */; }; - 078980B11F138AF000A3A4E1 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789807F1F138AF000A3A4E1 /* UILabelExtensionsTests.swift */; }; - 078980B21F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980801F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift */; }; - 078980B41F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980801F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift */; }; - 078980B51F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980811F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift */; }; - 078980B71F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980811F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift */; }; - 078980B81F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980821F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift */; }; - 078980BA1F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980821F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift */; }; - 078980BB1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980831F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift */; }; - 078980BD1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980831F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift */; }; - 078980BE1F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980841F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift */; }; - 078980C01F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980841F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift */; }; - 078980C11F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980851F138AF000A3A4E1 /* UISliderExtensionsTests.swift */; }; - 078980C31F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980851F138AF000A3A4E1 /* UISliderExtensionsTests.swift */; }; - 078980C41F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980861F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift */; }; - 078980C61F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980861F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift */; }; - 078980C71F138AF000A3A4E1 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980871F138AF000A3A4E1 /* UISwitchExtensionsTests.swift */; }; - 078980C91F138AF000A3A4E1 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980871F138AF000A3A4E1 /* UISwitchExtensionsTests.swift */; }; - 078980CA1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980881F138AF000A3A4E1 /* UITabBarExtensionsTests.swift */; }; - 078980CC1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980881F138AF000A3A4E1 /* UITabBarExtensionsTests.swift */; }; - 078980CD1F138AF000A3A4E1 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980891F138AF000A3A4E1 /* UITableViewExtensionsTests.swift */; }; - 078980CF1F138AF000A3A4E1 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980891F138AF000A3A4E1 /* UITableViewExtensionsTests.swift */; }; - 078980D01F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808A1F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift */; }; - 078980D21F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808A1F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift */; }; - 078980D31F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808B1F138AF000A3A4E1 /* UITextViewExtensionsTests.swift */; }; - 078980D51F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808B1F138AF000A3A4E1 /* UITextViewExtensionsTests.swift */; }; - 078980D61F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808C1F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift */; }; - 078980D81F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808C1F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift */; }; - 078980D91F138AF000A3A4E1 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808D1F138AF000A3A4E1 /* UIViewExtensionsTests.swift */; }; - 078980DB1F138AF000A3A4E1 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0789808D1F138AF000A3A4E1 /* UIViewExtensionsTests.swift */; }; 078980DD1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; 078980DE1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; 078980DF1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; - 078980E11F138B7900A3A4E1 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */; }; - 078980E21F138B7900A3A4E1 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */; }; - 078980E31F138B7900A3A4E1 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */; }; - 078980E41F138B7900A3A4E1 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */; }; - 07B8600A1F21CDE70032CE3A /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B860091F21CDE70032CE3A /* FoundationDeprecated.swift */; }; - 07B8600D1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; - 07B8600E1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; - 07B8600F1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */; }; - 07C20C511F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */; }; - 07C20C541F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; - 07C20C551F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; - 07C20C561F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */; }; - 07C20C581F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; - 07C20C591F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; - 07C20C5A1F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */; }; 07DFA3E41F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E51F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E61F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -346,114 +371,114 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensions.swift; sourceTree = ""; }; - 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; - 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; - 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwifterSwiftDeprecated.swift; path = Deprecated/SwifterSwiftDeprecated.swift; sourceTree = ""; }; - 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumberExtensions.swift; sourceTree = ""; }; - 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; + 0743F2781F611B62008386F7 /* NSColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSColorExtensions.swift; sourceTree = ""; }; + 0743F2791F611B62008386F7 /* NSViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensions.swift; sourceTree = ""; }; + 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColorExtensions.swift; sourceTree = ""; }; + 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensions.swift; sourceTree = ""; }; + 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensions.swift; sourceTree = ""; }; + 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensions.swift; sourceTree = ""; }; + 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensions.swift; sourceTree = ""; }; + 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwiftDeprecated.swift; sourceTree = ""; }; + 0743F2841F611B62008386F7 /* DataExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensions.swift; sourceTree = ""; }; + 0743F2851F611B62008386F7 /* DateExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensions.swift; sourceTree = ""; }; + 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; + 0743F2881F611B62008386F7 /* LocaleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensions.swift; sourceTree = ""; }; + 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensions.swift; sourceTree = ""; }; + 0743F28A1F611B62008386F7 /* URLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; }; + 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; + 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; + 0743F28D1F611B62008386F7 /* SwifterSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; + 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; + 0743F2901F611B62008386F7 /* BoolExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; + 0743F2911F611B62008386F7 /* CharacterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensions.swift; sourceTree = ""; }; + 0743F2921F611B62008386F7 /* CollectionExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = ""; }; + 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; + 0743F2941F611B62008386F7 /* DoubleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensions.swift; sourceTree = ""; }; + 0743F2951F611B62008386F7 /* FloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensions.swift; sourceTree = ""; }; + 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPointExtensions.swift; sourceTree = ""; }; + 0743F2971F611B62008386F7 /* IntExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensions.swift; sourceTree = ""; }; + 0743F2981F611B62008386F7 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; + 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; + 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumberExtensions.swift; sourceTree = ""; }; + 0743F29B1F611B62008386F7 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; + 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIKitDeprecated.swift; sourceTree = ""; }; + 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensions.swift; sourceTree = ""; }; + 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemExtensions.swift; sourceTree = ""; }; + 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; + 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = ""; }; + 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; + 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; + 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; + 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensions.swift; sourceTree = ""; }; + 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensions.swift; sourceTree = ""; }; + 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensions.swift; sourceTree = ""; }; + 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensions.swift; sourceTree = ""; }; + 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensions.swift; sourceTree = ""; }; + 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensions.swift; sourceTree = ""; }; + 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensions.swift; sourceTree = ""; }; + 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensions.swift; sourceTree = ""; }; + 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensions.swift; sourceTree = ""; }; + 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensions.swift; sourceTree = ""; }; + 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensions.swift; sourceTree = ""; }; + 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensions.swift; sourceTree = ""; }; + 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensions.swift; sourceTree = ""; }; + 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensions.swift; sourceTree = ""; }; + 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = ""; }; + 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensions.swift; sourceTree = ""; }; + 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; + 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensionsTests.swift; sourceTree = ""; }; + 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensionsTests.swift; sourceTree = ""; }; + 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensionsTests.swift; sourceTree = ""; }; + 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; + 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensionsTests.swift; sourceTree = ""; }; + 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensionsTests.swift; sourceTree = ""; }; + 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensionsTests.swift; sourceTree = ""; }; + 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; }; + 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; + 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; + 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionsTests.swift; sourceTree = ""; }; + 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; }; + 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensionsTests.swift; sourceTree = ""; }; + 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensionsTests.swift; sourceTree = ""; }; + 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionsTests.swift; sourceTree = ""; }; + 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensionsTests.swift; sourceTree = ""; }; + 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensionsTests.swift; sourceTree = ""; }; + 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensionsTests.swift; sourceTree = ""; }; + 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensionsTests.swift; sourceTree = ""; }; + 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; }; + 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensionsTests.swift; sourceTree = ""; }; + 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonExtensionsTests.swift; sourceTree = ""; }; + 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensionsTests.swift; sourceTree = ""; }; + 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; }; + 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensionsTests.swift; sourceTree = ""; }; + 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensionsTests.swift; sourceTree = ""; }; + 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensionTests.swift; sourceTree = ""; }; + 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensionsTests.swift; sourceTree = ""; }; + 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensionsTests.swift; sourceTree = ""; }; + 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensionsTests.swift; sourceTree = ""; }; + 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensionsTests.swift; sourceTree = ""; }; + 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensionsTests.swift; sourceTree = ""; }; + 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensionsTests.swift; sourceTree = ""; }; + 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensionsTests.swift; sourceTree = ""; }; + 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensionsTests.swift; sourceTree = ""; }; + 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensionsTests.swift; sourceTree = ""; }; + 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensionsTests.swift; sourceTree = ""; }; + 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensionsTests.swift; sourceTree = ""; }; + 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensionsTests.swift; sourceTree = ""; }; 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 077AD1C41F13875100D3214D /* SwifterSwift macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift macOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 077AD1D31F13876000D3214D /* SwifterSwift tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 077AD1DF1F1387D600D3214D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = ""; }; - 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPointExtensions.swift; sourceTree = ""; }; - 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColorExtensions.swift; sourceTree = ""; }; - 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensions.swift; sourceTree = ""; }; - 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensions.swift; sourceTree = ""; }; - 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensions.swift; sourceTree = ""; }; - 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensions.swift; sourceTree = ""; }; - 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensions.swift; sourceTree = ""; }; - 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSColorExtensions.swift; sourceTree = ""; }; - 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensions.swift; sourceTree = ""; }; - 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; - 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; - 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensions.swift; sourceTree = ""; }; - 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = ""; }; - 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensions.swift; sourceTree = ""; }; - 07897F501F138A3300A3A4E1 /* DateExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensions.swift; sourceTree = ""; }; - 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; - 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensions.swift; sourceTree = ""; }; - 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensions.swift; sourceTree = ""; }; - 07897F541F138A3300A3A4E1 /* IntExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensions.swift; sourceTree = ""; }; - 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensions.swift; sourceTree = ""; }; - 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; - 07897F571F138A3300A3A4E1 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; - 07897F581F138A3300A3A4E1 /* URLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; }; - 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensions.swift; sourceTree = ""; }; - 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemExtensions.swift; sourceTree = ""; }; - 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; - 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = ""; }; - 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; - 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; - 07897F601F138A3300A3A4E1 /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; - 07897F611F138A3300A3A4E1 /* UILabelExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensions.swift; sourceTree = ""; }; - 07897F621F138A3300A3A4E1 /* UINavigationBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensions.swift; sourceTree = ""; }; - 07897F631F138A3300A3A4E1 /* UINavigationControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensions.swift; sourceTree = ""; }; - 07897F641F138A3300A3A4E1 /* UINavigationItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensions.swift; sourceTree = ""; }; - 07897F651F138A3300A3A4E1 /* UISearchBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensions.swift; sourceTree = ""; }; - 07897F661F138A3300A3A4E1 /* UISegmentedControlExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensions.swift; sourceTree = ""; }; - 07897F671F138A3300A3A4E1 /* UISliderExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensions.swift; sourceTree = ""; }; - 07897F681F138A3300A3A4E1 /* UIStoryboardExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensions.swift; sourceTree = ""; }; - 07897F691F138A3300A3A4E1 /* UISwitchExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensions.swift; sourceTree = ""; }; - 07897F6A1F138A3300A3A4E1 /* UITabBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensions.swift; sourceTree = ""; }; - 07897F6B1F138A3300A3A4E1 /* UITableViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensions.swift; sourceTree = ""; }; - 07897F6C1F138A3300A3A4E1 /* UITextFieldExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensions.swift; sourceTree = ""; }; - 07897F6D1F138A3300A3A4E1 /* UITextViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensions.swift; sourceTree = ""; }; - 07897F6E1F138A3300A3A4E1 /* UIViewControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensions.swift; sourceTree = ""; }; - 07897F6F1F138A3300A3A4E1 /* UIViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = ""; }; - 078980211F138A5E00A3A4E1 /* ArrayExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionsTests.swift; sourceTree = ""; }; - 078980221F138A5E00A3A4E1 /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; }; - 078980231F138A5E00A3A4E1 /* CharacterExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensionsTests.swift; sourceTree = ""; }; - 078980241F138A5E00A3A4E1 /* CollectionExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensionsTests.swift; sourceTree = ""; }; - 078980251F138A5E00A3A4E1 /* DataExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensionsTests.swift; sourceTree = ""; }; - 078980261F138A5E00A3A4E1 /* DateExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensionsTests.swift; sourceTree = ""; }; - 078980271F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionsTests.swift; sourceTree = ""; }; - 078980281F138A5E00A3A4E1 /* DoubleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensionsTests.swift; sourceTree = ""; }; - 078980291F138A5E00A3A4E1 /* FloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensionsTests.swift; sourceTree = ""; }; - 0789802A1F138A5E00A3A4E1 /* IntExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensionsTests.swift; sourceTree = ""; }; - 0789802B1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensionsTests.swift; sourceTree = ""; }; - 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensionsTests.swift; sourceTree = ""; }; - 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; }; - 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; }; - 0789805A1F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensionsTests.swift; sourceTree = ""; }; - 0789805B1F138A9E00A3A4E1 /* CGPointExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensionsTests.swift; sourceTree = ""; }; - 0789805C1F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensionsTests.swift; sourceTree = ""; }; - 0789805D1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; - 0789805E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; - 0789805F1F138A9E00A3A4E1 /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 078980731F138AF000A3A4E1 /* TestImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestImage.png; sourceTree = ""; }; 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = TestStoryboard.storyboard; sourceTree = ""; }; 078980751F138AF000A3A4E1 /* UITableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UITableViewCell.xib; sourceTree = ""; }; 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UITableViewHeaderFooterView.xib; sourceTree = ""; }; - 078980781F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensionsTests.swift; sourceTree = ""; }; - 078980791F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonExtensionsTests.swift; sourceTree = ""; }; - 0789807A1F138AF000A3A4E1 /* UIButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensionsTests.swift; sourceTree = ""; }; - 0789807B1F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; }; - 0789807C1F138AF000A3A4E1 /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; }; - 0789807D1F138AF000A3A4E1 /* UIImageExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensionsTests.swift; sourceTree = ""; }; - 0789807E1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensionsTests.swift; sourceTree = ""; }; - 0789807F1F138AF000A3A4E1 /* UILabelExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensionsTests.swift; sourceTree = ""; }; - 078980801F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensionTests.swift; sourceTree = ""; }; - 078980811F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensionsTests.swift; sourceTree = ""; }; - 078980821F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensionsTests.swift; sourceTree = ""; }; - 078980831F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensionsTests.swift; sourceTree = ""; }; - 078980841F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensionsTests.swift; sourceTree = ""; }; - 078980851F138AF000A3A4E1 /* UISliderExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensionsTests.swift; sourceTree = ""; }; - 078980861F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensionsTests.swift; sourceTree = ""; }; - 078980871F138AF000A3A4E1 /* UISwitchExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensionsTests.swift; sourceTree = ""; }; - 078980881F138AF000A3A4E1 /* UITabBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensionsTests.swift; sourceTree = ""; }; - 078980891F138AF000A3A4E1 /* UITableViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensionsTests.swift; sourceTree = ""; }; - 0789808A1F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensionsTests.swift; sourceTree = ""; }; - 0789808B1F138AF000A3A4E1 /* UITextViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensionsTests.swift; sourceTree = ""; }; - 0789808C1F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensionsTests.swift; sourceTree = ""; }; - 0789808D1F138AF000A3A4E1 /* UIViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensionsTests.swift; sourceTree = ""; }; 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwifterSwiftTests.swift; path = Tests/SwifterSwiftTests.swift; sourceTree = ""; }; - 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; - 07B860091F21CDE70032CE3A /* FoundationDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FoundationDeprecated.swift; path = Deprecated/FoundationDeprecated.swift; sourceTree = ""; }; - 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIKitDeprecated.swift; path = Deprecated/UIKitDeprecated.swift; sourceTree = ""; }; - 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensionsTests.swift; sourceTree = ""; }; - 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; - 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -518,217 +543,268 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0703E5351F5F38A300788AB4 /* Deprecated */ = { + 0743F2771F611B62008386F7 /* AppKit */ = { isa = PBXGroup; children = ( - 0703E5361F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift */, + 0743F2781F611B62008386F7 /* NSColorExtensions.swift */, + 0743F2791F611B62008386F7 /* NSViewExtensions.swift */, ); - name = Deprecated; + path = AppKit; sourceTree = ""; }; - 077AD1DE1F1387C100D3214D /* Tests */ = { + 0743F27A1F611B62008386F7 /* CoreGraphics */ = { isa = PBXGroup; children = ( - 077AD1DF1F1387D600D3214D /* Info.plist */, - 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */, - 078980201F138A5E00A3A4E1 /* FoundationTests */, - 078980771F138AF000A3A4E1 /* UIKitTests */, - 078980591F138A9E00A3A4E1 /* CocoaTests */, - 078980721F138AF000A3A4E1 /* Resources */, + 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */, + 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */, + 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */, + 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */, ); - name = Tests; + path = CoreGraphics; sourceTree = ""; }; - 07897F401F138A3300A3A4E1 /* Extensions */ = { + 0743F27F1F611B62008386F7 /* CoreLocation */ = { isa = PBXGroup; children = ( - 078980E01F138B7900A3A4E1 /* SwifterSwift.swift */, - 0703E5351F5F38A300788AB4 /* Deprecated */, - 07897F411F138A3300A3A4E1 /* Cocoa */, - 07897F4A1F138A3300A3A4E1 /* Foundation */, - 07897F591F138A3300A3A4E1 /* UIKit */, + 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */, ); - name = Extensions; - path = Sources/Extensions; + path = CoreLocation; sourceTree = ""; }; - 07897F411F138A3300A3A4E1 /* Cocoa */ = { + 0743F2811F611B62008386F7 /* Deprecated */ = { isa = PBXGroup; children = ( - 07897F421F138A3300A3A4E1 /* CGColorExtensions.swift */, - 07897F431F138A3300A3A4E1 /* CGFloatExtensions.swift */, - 07897F441F138A3300A3A4E1 /* CGPointExtensions.swift */, - 07897F451F138A3300A3A4E1 /* CGSizeExtensions.swift */, - 07897F461F138A3300A3A4E1 /* CLLocationExtensions.swift */, - 07897F471F138A3300A3A4E1 /* NSAttributedStringExtensions.swift */, - 07897F481F138A3300A3A4E1 /* NSColorExtensions.swift */, - 07897F491F138A3300A3A4E1 /* NSViewExtensions.swift */, - ); - path = Cocoa; + 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */, + ); + path = Deprecated; sourceTree = ""; }; - 07897F4A1F138A3300A3A4E1 /* Foundation */ = { + 0743F2831F611B62008386F7 /* Foundation */ = { isa = PBXGroup; children = ( - 07B860081F21CDA70032CE3A /* Deprecated */, - 07897F4C1F138A3300A3A4E1 /* BoolExtensions.swift */, - 07897F4D1F138A3300A3A4E1 /* CharacterExtensions.swift */, - 07897F561F138A3300A3A4E1 /* OptionalExtensions.swift */, - 07897F581F138A3300A3A4E1 /* URLExtensions.swift */, - 07897F551F138A3300A3A4E1 /* LocaleExtensions.swift */, - 07897F4B1F138A3300A3A4E1 /* ArrayExtensions.swift */, - 07897F511F138A3300A3A4E1 /* DictionaryExtensions.swift */, - 07897F571F138A3300A3A4E1 /* StringExtensions.swift */, - 07897F4E1F138A3300A3A4E1 /* CollectionExtensions.swift */, - 07897F4F1F138A3300A3A4E1 /* DataExtensions.swift */, - 07897F501F138A3300A3A4E1 /* DateExtensions.swift */, - 078473941F24F3E1001F8575 /* FloatingPointExtensions.swift */, - 07897F521F138A3300A3A4E1 /* DoubleExtensions.swift */, - 07897F531F138A3300A3A4E1 /* FloatExtensions.swift */, - 07897F541F138A3300A3A4E1 /* IntExtensions.swift */, - 077A72CB1F436357003DC1C4 /* SignedNumberExtensions.swift */, - 077A72D01F436433003DC1C4 /* SignedIntegerExtensions.swift */, - 0703E52B1F5F34C900788AB4 /* URLRequestExtensions.swift */, - 0703E5301F5F367C00788AB4 /* UserDefaultsExtensions.swift */, + 0743F2861F611B62008386F7 /* Deprecated */, + 0743F2841F611B62008386F7 /* DataExtensions.swift */, + 0743F2851F611B62008386F7 /* DateExtensions.swift */, + 0743F2881F611B62008386F7 /* LocaleExtensions.swift */, + 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */, + 0743F28A1F611B62008386F7 /* URLExtensions.swift */, + 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */, + 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */, ); path = Foundation; sourceTree = ""; }; - 07897F591F138A3300A3A4E1 /* UIKit */ = { + 0743F2861F611B62008386F7 /* Deprecated */ = { + isa = PBXGroup; + children = ( + 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */, + ); + path = Deprecated; + sourceTree = ""; + }; + 0743F28E1F611B62008386F7 /* SwiftStdlib */ = { + isa = PBXGroup; + children = ( + 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */, + 0743F2901F611B62008386F7 /* BoolExtensions.swift */, + 0743F2911F611B62008386F7 /* CharacterExtensions.swift */, + 0743F2921F611B62008386F7 /* CollectionExtensions.swift */, + 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */, + 0743F2941F611B62008386F7 /* DoubleExtensions.swift */, + 0743F2951F611B62008386F7 /* FloatExtensions.swift */, + 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */, + 0743F2971F611B62008386F7 /* IntExtensions.swift */, + 0743F2981F611B62008386F7 /* OptionalExtensions.swift */, + 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */, + 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */, + 0743F29B1F611B62008386F7 /* StringExtensions.swift */, + ); + path = SwiftStdlib; + sourceTree = ""; + }; + 0743F29C1F611B62008386F7 /* UIKit */ = { isa = PBXGroup; children = ( - 07B8600B1F21CE370032CE3A /* Deprecated */, - 07897F5A1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift */, - 07897F5B1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift */, - 07897F5C1F138A3300A3A4E1 /* UIButtonExtensions.swift */, - 0703E5281F5F33AA00788AB4 /* UIWebViewExtensions.swift */, - 07897F5D1F138A3300A3A4E1 /* UICollectionViewExtensions.swift */, - 07897F5E1F138A3300A3A4E1 /* UIColorExtensions.swift */, - 07897F5F1F138A3300A3A4E1 /* UIImageExtensions.swift */, - 07897F601F138A3300A3A4E1 /* UIImageViewExtensions.swift */, - 07897F611F138A3300A3A4E1 /* UILabelExtensions.swift */, - 07897F621F138A3300A3A4E1 /* UINavigationBarExtensions.swift */, - 07897F631F138A3300A3A4E1 /* UINavigationControllerExtensions.swift */, - 07897F641F138A3300A3A4E1 /* UINavigationItemExtensions.swift */, - 07897F651F138A3300A3A4E1 /* UISearchBarExtensions.swift */, - 07897F661F138A3300A3A4E1 /* UISegmentedControlExtensions.swift */, - 07897F671F138A3300A3A4E1 /* UISliderExtensions.swift */, - 07897F681F138A3300A3A4E1 /* UIStoryboardExtensions.swift */, - 07897F691F138A3300A3A4E1 /* UISwitchExtensions.swift */, - 07897F6A1F138A3300A3A4E1 /* UITabBarExtensions.swift */, - 07897F6B1F138A3300A3A4E1 /* UITableViewExtensions.swift */, - 07897F6C1F138A3300A3A4E1 /* UITextFieldExtensions.swift */, - 07897F6D1F138A3300A3A4E1 /* UITextViewExtensions.swift */, - 07897F6E1F138A3300A3A4E1 /* UIViewControllerExtensions.swift */, - 07897F6F1F138A3300A3A4E1 /* UIViewExtensions.swift */, + 0743F29D1F611B62008386F7 /* Deprecated */, + 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */, + 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */, + 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */, + 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */, + 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */, + 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */, + 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */, + 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */, + 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */, + 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */, + 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */, + 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */, + 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */, + 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */, + 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */, + 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */, + 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */, + 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */, + 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */, + 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */, + 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */, + 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */, + 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */, ); path = UIKit; sourceTree = ""; }; - 078980201F138A5E00A3A4E1 /* FoundationTests */ = { + 0743F29D1F611B62008386F7 /* Deprecated */ = { isa = PBXGroup; children = ( - 078980211F138A5E00A3A4E1 /* ArrayExtensionsTests.swift */, - 078980221F138A5E00A3A4E1 /* BoolExtensionsTests.swift */, - 078980231F138A5E00A3A4E1 /* CharacterExtensionsTests.swift */, - 078980241F138A5E00A3A4E1 /* CollectionExtensionsTests.swift */, - 078980251F138A5E00A3A4E1 /* DataExtensionsTests.swift */, - 078980261F138A5E00A3A4E1 /* DateExtensionsTests.swift */, - 078980271F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift */, - 078980281F138A5E00A3A4E1 /* DoubleExtensionsTests.swift */, - 078980291F138A5E00A3A4E1 /* FloatExtensionsTests.swift */, - 0789802A1F138A5E00A3A4E1 /* IntExtensionsTests.swift */, - 0789802B1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift */, - 0789802C1F138A5E00A3A4E1 /* OptionalExtensionsTests.swift */, - 0789802D1F138A5E00A3A4E1 /* StringExtensionsTests.swift */, - 0789802E1F138A5E00A3A4E1 /* URLExtensionsTests.swift */, - 07C20C531F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift */, - 07C20C571F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift */, + 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */, ); - name = FoundationTests; - path = Tests/FoundationTests; + path = Deprecated; sourceTree = ""; }; - 078980591F138A9E00A3A4E1 /* CocoaTests */ = { + 0743F38E1F611B87008386F7 /* AppKitTests */ = { isa = PBXGroup; children = ( - 0789805A1F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift */, - 0789805B1F138A9E00A3A4E1 /* CGPointExtensionsTests.swift */, - 0789805C1F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift */, - 0789805D1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift */, - 0789805E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift */, - 0789805F1F138A9E00A3A4E1 /* NSViewExtensionsTests.swift */, - ); - name = CocoaTests; - path = Tests/CocoaTests; + 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */, + 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */, + ); + name = AppKitTests; + path = Tests/AppKitTests; sourceTree = ""; }; - 078980721F138AF000A3A4E1 /* Resources */ = { + 0743F3911F611B87008386F7 /* CoreGraphicsTests */ = { isa = PBXGroup; children = ( - 078980731F138AF000A3A4E1 /* TestImage.png */, - 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */, - 078980751F138AF000A3A4E1 /* UITableViewCell.xib */, - 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */, + 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */, + 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */, + 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */, ); - name = Resources; - path = Tests/Resources; + name = CoreGraphicsTests; + path = Tests/CoreGraphicsTests; + sourceTree = ""; + }; + 0743F3951F611B87008386F7 /* CoreLocationTests */ = { + isa = PBXGroup; + children = ( + 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */, + ); + name = CoreLocationTests; + path = Tests/CoreLocationTests; + sourceTree = ""; + }; + 0743F3971F611B87008386F7 /* FoundationTests */ = { + isa = PBXGroup; + children = ( + 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */, + 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */, + 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */, + 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */, + 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */, + 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */, + ); + name = FoundationTests; + path = Tests/FoundationTests; sourceTree = ""; }; - 078980771F138AF000A3A4E1 /* UIKitTests */ = { + 0743F39E1F611B87008386F7 /* SwiftStdlibTests */ = { isa = PBXGroup; children = ( - 078980781F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift */, - 078980791F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift */, - 0789807A1F138AF000A3A4E1 /* UIButtonExtensionsTests.swift */, - 0789807B1F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift */, - 0789807C1F138AF000A3A4E1 /* UIColorExtensionsTests.swift */, - 0789807D1F138AF000A3A4E1 /* UIImageExtensionsTests.swift */, - 0789807E1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift */, - 0789807F1F138AF000A3A4E1 /* UILabelExtensionsTests.swift */, - 078980801F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift */, - 078980811F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift */, - 078980821F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift */, - 078980831F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift */, - 078980841F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift */, - 078980851F138AF000A3A4E1 /* UISliderExtensionsTests.swift */, - 078980861F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift */, - 078980871F138AF000A3A4E1 /* UISwitchExtensionsTests.swift */, - 078980881F138AF000A3A4E1 /* UITabBarExtensionsTests.swift */, - 078980891F138AF000A3A4E1 /* UITableViewExtensionsTests.swift */, - 0789808A1F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift */, - 0789808B1F138AF000A3A4E1 /* UITextViewExtensionsTests.swift */, - 0789808C1F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift */, - 0789808D1F138AF000A3A4E1 /* UIViewExtensionsTests.swift */, - 07C20C501F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift */, + 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */, + 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */, + 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */, + 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */, + 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */, + 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */, + 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */, + 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */, + 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */, + 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */, + ); + name = SwiftStdlibTests; + path = Tests/SwiftStdlibTests; + sourceTree = ""; + }; + 0743F3A91F611B87008386F7 /* UIKitTests */ = { + isa = PBXGroup; + children = ( + 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */, + 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */, + 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */, + 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */, + 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */, + 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */, + 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */, + 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */, + 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */, + 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */, + 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */, + 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */, + 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */, + 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */, + 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */, + 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */, + 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */, + 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */, + 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */, + 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */, + 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */, + 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */, + 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */, ); name = UIKitTests; path = Tests/UIKitTests; sourceTree = ""; }; - 079412C41F137D5C006AA1F8 = { + 077AD1DE1F1387C100D3214D /* Tests */ = { isa = PBXGroup; children = ( - 07DFA3DE1F13824300D0C644 /* Sources */, - 077AD1DE1F1387C100D3214D /* Tests */, - 07DFA3AF1F1380F100D0C644 /* Products */, + 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */, + 0743F39E1F611B87008386F7 /* SwiftStdlibTests */, + 0743F3971F611B87008386F7 /* FoundationTests */, + 0743F3A91F611B87008386F7 /* UIKitTests */, + 0743F38E1F611B87008386F7 /* AppKitTests */, + 0743F3911F611B87008386F7 /* CoreGraphicsTests */, + 0743F3951F611B87008386F7 /* CoreLocationTests */, + 078980721F138AF000A3A4E1 /* Resources */, + 077AD1DF1F1387D600D3214D /* Info.plist */, + ); + name = Tests; + sourceTree = ""; + }; + 07897F401F138A3300A3A4E1 /* Extensions */ = { + isa = PBXGroup; + children = ( + 0743F28D1F611B62008386F7 /* SwifterSwift.swift */, + 0743F28E1F611B62008386F7 /* SwiftStdlib */, + 0743F2831F611B62008386F7 /* Foundation */, + 0743F29C1F611B62008386F7 /* UIKit */, + 0743F2771F611B62008386F7 /* AppKit */, + 0743F27A1F611B62008386F7 /* CoreGraphics */, + 0743F27F1F611B62008386F7 /* CoreLocation */, + 0743F2811F611B62008386F7 /* Deprecated */, ); + name = Extensions; + path = Sources/Extensions; sourceTree = ""; }; - 07B860081F21CDA70032CE3A /* Deprecated */ = { + 078980721F138AF000A3A4E1 /* Resources */ = { isa = PBXGroup; children = ( - 07B860091F21CDE70032CE3A /* FoundationDeprecated.swift */, + 078980731F138AF000A3A4E1 /* TestImage.png */, + 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */, + 078980751F138AF000A3A4E1 /* UITableViewCell.xib */, + 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */, ); - name = Deprecated; + name = Resources; + path = Tests/Resources; sourceTree = ""; }; - 07B8600B1F21CE370032CE3A /* Deprecated */ = { + 079412C41F137D5C006AA1F8 = { isa = PBXGroup; children = ( - 07B8600C1F21CE550032CE3A /* UIKitDeprecated.swift */, + 07DFA3DE1F13824300D0C644 /* Sources */, + 077AD1DE1F1387C100D3214D /* Tests */, + 07DFA3AF1F1380F100D0C644 /* Products */, ); - name = Deprecated; sourceTree = ""; }; 07DFA3AF1F1380F100D0C644 /* Products */ = { @@ -942,18 +1018,22 @@ }; 07DFA3AD1F1380F100D0C644 = { CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 0830; ProvisioningStyle = Automatic; }; 07DFA3BB1F13816200D0C644 = { CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 0830; ProvisioningStyle = Automatic; }; 07DFA3C81F13817200D0C644 = { CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 0830; ProvisioningStyle = Automatic; }; 07DFA3D51F13818700D0C644 = { CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 0830; ProvisioningStyle = Automatic; }; }; @@ -1044,51 +1124,52 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 078980A31F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift in Sources */, - 0789802F1F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */, - 078980501F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */, - 078980381F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */, - 078980691F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */, - 0789809D1F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift in Sources */, - 078980321F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */, - 078980D91F138AF000A3A4E1 /* UIViewExtensionsTests.swift in Sources */, - 078980BE1F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift in Sources */, - 078980B21F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift in Sources */, - 0789806C1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */, - 078980D31F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */, - 078980A91F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */, - 07C20C541F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, - 0789804A1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */, - 078980AC1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */, - 078980CA1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */, - 078980B81F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */, - 07C20C581F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, - 078980BB1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */, - 078980C11F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */, - 078980411F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */, - 078980A61F138AF000A3A4E1 /* UIColorExtensionsTests.swift in Sources */, - 078980C71F138AF000A3A4E1 /* UISwitchExtensionsTests.swift in Sources */, - 078980A01F138AF000A3A4E1 /* UIButtonExtensionsTests.swift in Sources */, - 078980D01F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift in Sources */, - 078980CD1F138AF000A3A4E1 /* UITableViewExtensionsTests.swift in Sources */, - 078980471F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */, - 078980B51F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift in Sources */, - 078980AF1F138AF000A3A4E1 /* UILabelExtensionsTests.swift in Sources */, - 078980531F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */, - 078980441F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */, - 078980561F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */, - 0789803B1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */, + 0743F3CA1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, + 0743F3E51F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, + 0743F41E1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, + 0743F4061F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, + 0743F4211F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, + 0743F3D91F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, + 0743F3D31F611B87008386F7 /* DataExtensionsTests.swift in Sources */, + 0743F3D61F611B87008386F7 /* DateExtensionsTests.swift in Sources */, + 0743F3F11F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, + 0743F4091F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, + 0743F42D1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, + 0743F3EE1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, 078980DD1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 078980661F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */, - 07C20C511F5FD1870035F7C0 /* UIWebViewExtensionsTests.swift in Sources */, - 078980C41F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift in Sources */, - 078980351F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */, - 0789809A1F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift in Sources */, - 0789804D1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */, - 0789803E1F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */, - 078980D61F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift in Sources */, - 078980631F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */, - 078980601F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4331F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, + 0743F3DF1F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, + 0743F40F1F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, + 0743F43F1F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, + 0743F4391F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, + 0743F4361F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, + 0743F3CD1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, + 0743F3F71F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, + 0743F4151F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, + 0743F3F41F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, + 0743F3FA1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, + 0743F4181F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, + 0743F4271F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, + 0743F4301F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, + 0743F40C1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, + 0743F3E81F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, + 0743F3EB1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, + 0743F3DC1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, + 0743F43C1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, + 0743F3D01F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, + 0743F3FD1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, + 0743F3C11F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, + 0743F41B1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, + 0743F42A1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, + 0743F4001F611B87008386F7 /* StringExtensionsTests.swift in Sources */, + 0743F4421F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, + 0743F4121F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, + 0743F3E21F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, + 0743F4451F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, + 0743F3C71F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4031F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, + 0743F4241F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, + 0743F3C41F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1096,29 +1177,52 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 078980301F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */, - 078980511F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */, - 078980391F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */, - 0789806A1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */, - 078980331F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */, - 078980701F138A9E00A3A4E1 /* NSViewExtensionsTests.swift in Sources */, - 0789806D1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */, - 0789804B1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */, - 078980421F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */, - 078980481F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */, - 078980541F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */, - 078980451F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */, - 078980571F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */, - 07C20C551F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, - 0789803C1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */, + 0743F3CB1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, + 0743F3E61F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, + 0743F41F1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, + 0743F4071F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, + 0743F4221F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, + 0743F3DA1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, + 0743F3D41F611B87008386F7 /* DataExtensionsTests.swift in Sources */, + 0743F3D71F611B87008386F7 /* DateExtensionsTests.swift in Sources */, + 0743F3F21F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, + 0743F40A1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, + 0743F42E1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, + 0743F3EF1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, 078980DE1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 078980671F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */, - 07C20C591F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, - 078980361F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */, - 0789804E1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */, - 0789803F1F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */, - 078980641F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */, - 078980611F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4341F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, + 0743F3E01F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, + 0743F4101F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, + 0743F4401F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, + 0743F43A1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, + 0743F4371F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, + 0743F3CE1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, + 0743F3F81F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, + 0743F4161F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, + 0743F3F51F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, + 0743F3FB1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, + 0743F4191F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, + 0743F4281F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, + 0743F4311F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, + 0743F40D1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, + 0743F3E91F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, + 0743F3EC1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, + 0743F3DD1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, + 0743F43D1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, + 0743F3D11F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, + 0743F3FE1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, + 0743F3C21F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, + 0743F41C1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, + 0743F42B1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, + 0743F4011F611B87008386F7 /* StringExtensionsTests.swift in Sources */, + 0743F4431F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, + 0743F4131F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, + 0743F3E31F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, + 0743F4461F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, + 0743F3C81F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4041F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, + 0743F4251F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, + 0743F3C51F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1126,50 +1230,52 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 078980A51F138AF000A3A4E1 /* UICollectionViewExtensionsTests.swift in Sources */, - 078980311F138A5E00A3A4E1 /* ArrayExtensionsTests.swift in Sources */, - 078980521F138A5E00A3A4E1 /* OptionalExtensionsTests.swift in Sources */, - 0789803A1F138A5E00A3A4E1 /* CollectionExtensionsTests.swift in Sources */, - 0789806B1F138A9E00A3A4E1 /* CLLocationExtensionsTests.swift in Sources */, - 0789809F1F138AF000A3A4E1 /* UIBarButtonExtensionsTests.swift in Sources */, - 078980341F138A5E00A3A4E1 /* BoolExtensionsTests.swift in Sources */, - 078980DB1F138AF000A3A4E1 /* UIViewExtensionsTests.swift in Sources */, - 078980C01F138AF000A3A4E1 /* UISegmentedControlExtensionsTests.swift in Sources */, - 078980B41F138AF000A3A4E1 /* UINavigationBarExtensionTests.swift in Sources */, - 0789806E1F138A9E00A3A4E1 /* NSAttributedStringExtensionsTests.swift in Sources */, - 078980D51F138AF000A3A4E1 /* UITextViewExtensionsTests.swift in Sources */, - 078980AB1F138AF000A3A4E1 /* UIImageExtensionsTests.swift in Sources */, - 07C20C561F5FE0D70035F7C0 /* URLRequestExtensionsTests.swift in Sources */, - 0789804C1F138A5E00A3A4E1 /* IntExtensionsTests.swift in Sources */, - 078980AE1F138AF000A3A4E1 /* UIImageViewExtensionsTests.swift in Sources */, - 078980CC1F138AF000A3A4E1 /* UITabBarExtensionsTests.swift in Sources */, - 078980BA1F138AF000A3A4E1 /* UINavigationItemExtensionsTests.swift in Sources */, - 07C20C5A1F5FE2850035F7C0 /* UserDefaultsExtensionsTests.swift in Sources */, - 078980BD1F138AF000A3A4E1 /* UISearchBarExtensionsTests.swift in Sources */, - 078980C31F138AF000A3A4E1 /* UISliderExtensionsTests.swift in Sources */, - 078980431F138A5E00A3A4E1 /* DictionaryExtensionsTests.swift in Sources */, - 078980A81F138AF000A3A4E1 /* UIColorExtensionsTests.swift in Sources */, - 078980C91F138AF000A3A4E1 /* UISwitchExtensionsTests.swift in Sources */, - 078980A21F138AF000A3A4E1 /* UIButtonExtensionsTests.swift in Sources */, - 078980D21F138AF000A3A4E1 /* UITextFieldExtensionsTests.swift in Sources */, - 078980CF1F138AF000A3A4E1 /* UITableViewExtensionsTests.swift in Sources */, - 078980491F138A5E00A3A4E1 /* FloatExtensionsTests.swift in Sources */, - 078980B71F138AF000A3A4E1 /* UINavigationControllerExtensionsTests.swift in Sources */, - 078980B11F138AF000A3A4E1 /* UILabelExtensionsTests.swift in Sources */, - 078980551F138A5E00A3A4E1 /* StringExtensionsTests.swift in Sources */, - 078980461F138A5E00A3A4E1 /* DoubleExtensionsTests.swift in Sources */, - 078980581F138A5E00A3A4E1 /* URLExtensionsTests.swift in Sources */, - 0789803D1F138A5E00A3A4E1 /* DataExtensionsTests.swift in Sources */, + 0743F3CC1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, + 0743F3E71F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, + 0743F4201F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, + 0743F4081F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, + 0743F4231F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, + 0743F3DB1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, + 0743F3D51F611B87008386F7 /* DataExtensionsTests.swift in Sources */, + 0743F3D81F611B87008386F7 /* DateExtensionsTests.swift in Sources */, + 0743F3F31F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, + 0743F40B1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, + 0743F42F1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, + 0743F3F01F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, 078980DF1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 078980681F138A9E00A3A4E1 /* CGSizeExtensionsTests.swift in Sources */, - 078980C61F138AF000A3A4E1 /* UIStoryboardExtensionsTests.swift in Sources */, - 078980371F138A5E00A3A4E1 /* CharacterExtensionsTests.swift in Sources */, - 0789809C1F138AF000A3A4E1 /* UIAlertControllerExtensionsTests.swift in Sources */, - 0789804F1F138A5E00A3A4E1 /* LocaleExtensionsTests.swift in Sources */, - 078980401F138A5E00A3A4E1 /* DateExtensionsTests.swift in Sources */, - 078980D81F138AF000A3A4E1 /* UIViewControllerExtensionsTests.swift in Sources */, - 078980651F138A9E00A3A4E1 /* CGPointExtensionsTests.swift in Sources */, - 078980621F138A9E00A3A4E1 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4351F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, + 0743F3E11F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, + 0743F4111F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, + 0743F4411F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, + 0743F43B1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, + 0743F4381F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, + 0743F3CF1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, + 0743F3F91F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, + 0743F4171F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, + 0743F3F61F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, + 0743F3FC1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, + 0743F41A1F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, + 0743F4291F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, + 0743F4321F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, + 0743F40E1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, + 0743F3EA1F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, + 0743F3ED1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, + 0743F3DE1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, + 0743F43E1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, + 0743F3D21F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, + 0743F3FF1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, + 0743F3C31F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, + 0743F41D1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, + 0743F42C1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, + 0743F4021F611B87008386F7 /* StringExtensionsTests.swift in Sources */, + 0743F4441F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, + 0743F4141F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, + 0743F3E41F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, + 0743F4471F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, + 0743F3C91F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, + 0743F4051F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, + 0743F4261F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, + 0743F3C61F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1177,60 +1283,58 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 07897FD81F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */, - 07897F801F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, - 07897FE41F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */, - 07897FEC1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */, - 07897F9C1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */, - 07897FB81F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */, - 07897FC01F138A3300A3A4E1 /* StringExtensions.swift in Sources */, - 07897F741F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, - 07897F981F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, - 07897F781F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, - 07897FA81F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, - 0703E5291F5F33AA00788AB4 /* UIWebViewExtensions.swift in Sources */, - 07897FD41F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, - 07897F881F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, - 07897F7C1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, - 07897FA41F138A3300A3A4E1 /* DateExtensions.swift in Sources */, - 0789800C1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */, - 07897FB41F138A3300A3A4E1 /* IntExtensions.swift in Sources */, - 07897FFC1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */, - 078980041F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */, - 078980101F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */, - 077A72D11F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, - 07B8600D1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, - 07897FF81F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */, - 07897F8C1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, - 0703E5371F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, - 0789801C1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */, - 07897FB01F138A3300A3A4E1 /* FloatExtensions.swift in Sources */, - 07897FBC1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, - 07897F701F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */, - 078980181F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */, - 07897FCC1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */, - 07897FF41F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */, - 07897FF01F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */, - 0703E52C1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, - 07897F941F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, - 078980E11F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, - 07897FAC1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, - 07897FA01F138A3300A3A4E1 /* DataExtensions.swift in Sources */, - 07897FD01F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */, - 07897FDC1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */, - 078980081F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */, - 077A72CC1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, - 078473951F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, - 078980001F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */, - 078980141F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */, - 07897FE01F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */, - 07897FC41F138A3300A3A4E1 /* URLExtensions.swift in Sources */, - 07897FE81F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */, - 07897F901F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, - 07B8600A1F21CDE70032CE3A /* FoundationDeprecated.swift in Sources */, - 07897F841F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, - 0703E5311F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, - 07897FC81F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */, + 0743F34A1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, + 0743F36A1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, + 0743F3061F611B63008386F7 /* CollectionExtensions.swift in Sources */, + 0743F3021F611B63008386F7 /* CharacterExtensions.swift in Sources */, + 0743F2EE1F611B63008386F7 /* URLRequestExtensions.swift in Sources */, + 0743F2DA1F611B63008386F7 /* DateExtensions.swift in Sources */, + 0743F2D21F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, + 0743F3661F611B63008386F7 /* UISliderExtensions.swift in Sources */, + 0743F2BE1F611B63008386F7 /* CGColorExtensions.swift in Sources */, + 0743F3361F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, + 0743F38A1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, + 0743F31A1F611B63008386F7 /* IntExtensions.swift in Sources */, + 0743F36E1F611B63008386F7 /* UISwitchExtensions.swift in Sources */, + 0743F3721F611B63008386F7 /* UITabBarExtensions.swift in Sources */, + 0743F35E1F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, + 0743F33A1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, + 0743F3821F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, + 0743F33E1F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, + 0743F2C61F611B63008386F7 /* CGPointExtensions.swift in Sources */, + 0743F2C21F611B63008386F7 /* CGFloatExtensions.swift in Sources */, + 0743F2FA1F611B63008386F7 /* ArrayExtensions.swift in Sources */, + 0743F2D61F611B63008386F7 /* DataExtensions.swift in Sources */, + 0743F32A1F611B63008386F7 /* StringExtensions.swift in Sources */, + 0743F2EA1F611B63008386F7 /* URLExtensions.swift in Sources */, + 0743F2DE1F611B63008386F7 /* FoundationDeprecated.swift in Sources */, + 0743F32E1F611B63008386F7 /* UIKitDeprecated.swift in Sources */, + 0743F30A1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, + 0743F3521F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, + 0743F37A1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, + 0743F3121F611B63008386F7 /* FloatExtensions.swift in Sources */, + 0743F3321F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, + 0743F31E1F611B63008386F7 /* OptionalExtensions.swift in Sources */, + 0743F2FE1F611B63008386F7 /* BoolExtensions.swift in Sources */, + 0743F3461F611B63008386F7 /* UIImageExtensions.swift in Sources */, + 0743F3861F611B63008386F7 /* UIViewExtensions.swift in Sources */, + 0743F3621F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, + 0743F3261F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F37E1F611B63008386F7 /* UITextViewExtensions.swift in Sources */, + 0743F3161F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, + 0743F30E1F611B63008386F7 /* DoubleExtensions.swift in Sources */, + 0743F35A1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, + 0743F34E1F611B63008386F7 /* UILabelExtensions.swift in Sources */, + 0743F3421F611B63008386F7 /* UIColorExtensions.swift in Sources */, + 0743F3221F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, + 0743F2E61F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, + 0743F2CE1F611B63008386F7 /* CLLocationExtensions.swift in Sources */, + 0743F3761F611B63008386F7 /* UITableViewExtensions.swift in Sources */, + 0743F2E21F611B63008386F7 /* LocaleExtensions.swift in Sources */, + 0743F2F61F611B63008386F7 /* SwifterSwift.swift in Sources */, + 0743F2CA1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, + 0743F2F21F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, + 0743F3561F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1238,36 +1342,36 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 07897F811F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, - 0703E52D1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, - 07897F9D1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */, - 07897FB91F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */, - 07897FC11F138A3300A3A4E1 /* StringExtensions.swift in Sources */, - 07897F751F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, - 07897F991F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, - 0703E5381F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, - 077A72CD1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, - 07897F791F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, - 0703E5321F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, - 07B8600E1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, - 07897FA91F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, - 07897F891F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, - 07897F7D1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, - 07897FA51F138A3300A3A4E1 /* DateExtensions.swift in Sources */, - 07897FB51F138A3300A3A4E1 /* IntExtensions.swift in Sources */, - 07897F8D1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, - 07897FB11F138A3300A3A4E1 /* FloatExtensions.swift in Sources */, - 07897FBD1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, - 078473961F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, - 07897F711F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */, - 077A72D21F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, - 07897F951F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, - 078980E21F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, - 07897FAD1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, - 07897FA11F138A3300A3A4E1 /* DataExtensions.swift in Sources */, - 07897FC51F138A3300A3A4E1 /* URLExtensions.swift in Sources */, - 07897F911F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, - 07897F851F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, + 0743F2B71F611B63008386F7 /* NSColorExtensions.swift in Sources */, + 0743F3071F611B63008386F7 /* CollectionExtensions.swift in Sources */, + 0743F3031F611B63008386F7 /* CharacterExtensions.swift in Sources */, + 0743F2EF1F611B63008386F7 /* URLRequestExtensions.swift in Sources */, + 0743F2DB1F611B63008386F7 /* DateExtensions.swift in Sources */, + 0743F2D31F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, + 0743F2BF1F611B63008386F7 /* CGColorExtensions.swift in Sources */, + 0743F31B1F611B63008386F7 /* IntExtensions.swift in Sources */, + 0743F2C71F611B63008386F7 /* CGPointExtensions.swift in Sources */, + 0743F2C31F611B63008386F7 /* CGFloatExtensions.swift in Sources */, + 0743F2FB1F611B63008386F7 /* ArrayExtensions.swift in Sources */, + 0743F2D71F611B63008386F7 /* DataExtensions.swift in Sources */, + 0743F32B1F611B63008386F7 /* StringExtensions.swift in Sources */, + 0743F2EB1F611B63008386F7 /* URLExtensions.swift in Sources */, + 0743F2DF1F611B63008386F7 /* FoundationDeprecated.swift in Sources */, + 0743F30B1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, + 0743F3131F611B63008386F7 /* FloatExtensions.swift in Sources */, + 0743F31F1F611B63008386F7 /* OptionalExtensions.swift in Sources */, + 0743F2FF1F611B63008386F7 /* BoolExtensions.swift in Sources */, + 0743F3271F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3171F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, + 0743F30F1F611B63008386F7 /* DoubleExtensions.swift in Sources */, + 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, + 0743F2E71F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, + 0743F2CF1F611B63008386F7 /* CLLocationExtensions.swift in Sources */, + 0743F2E31F611B63008386F7 /* LocaleExtensions.swift in Sources */, + 0743F2F71F611B63008386F7 /* SwifterSwift.swift in Sources */, + 0743F2CB1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, + 0743F2F31F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, + 0743F2BB1F611B63008386F7 /* NSViewExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1275,57 +1379,58 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 07897FDA1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */, - 0703E5391F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, - 0703E52E1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, - 07897F821F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, - 07897FE61F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */, - 07897FEE1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */, - 07897F9E1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */, - 07897FBA1F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */, - 07897FC21F138A3300A3A4E1 /* StringExtensions.swift in Sources */, - 07897F761F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, - 07897F9A1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, - 07897F7A1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, - 0703E5331F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, - 07897FAA1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, - 07897FD61F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, - 07897F8A1F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, - 07897F7E1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, - 07897FA61F138A3300A3A4E1 /* DateExtensions.swift in Sources */, - 0789800E1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */, - 077A72D31F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, - 077A72CE1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, - 07897FB61F138A3300A3A4E1 /* IntExtensions.swift in Sources */, - 07897FFE1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */, - 078980061F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */, - 078980121F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */, - 07897FFA1F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */, - 07897F8E1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, - 0789801E1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */, - 07897FB21F138A3300A3A4E1 /* FloatExtensions.swift in Sources */, - 07897FBE1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, - 07897F721F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */, - 0789801A1F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */, - 07897FCE1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */, - 07897FF61F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */, - 07897FF21F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */, - 07897F961F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, - 078980E31F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, - 07897FAE1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, - 07897FA21F138A3300A3A4E1 /* DataExtensions.swift in Sources */, - 07897FD21F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */, - 07897FDE1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */, - 078473971F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, - 0789800A1F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */, - 078980021F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */, - 078980161F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */, - 07897FE21F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */, - 07897FC61F138A3300A3A4E1 /* URLExtensions.swift in Sources */, - 07897FEA1F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */, - 07897F921F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, - 07897F861F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, - 07897FCA1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */, + 0743F34C1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, + 0743F36C1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, + 0743F3081F611B63008386F7 /* CollectionExtensions.swift in Sources */, + 0743F3041F611B63008386F7 /* CharacterExtensions.swift in Sources */, + 0743F2F01F611B63008386F7 /* URLRequestExtensions.swift in Sources */, + 0743F2DC1F611B63008386F7 /* DateExtensions.swift in Sources */, + 0743F2D41F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, + 0743F3681F611B63008386F7 /* UISliderExtensions.swift in Sources */, + 0743F2C01F611B63008386F7 /* CGColorExtensions.swift in Sources */, + 0743F3381F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, + 0743F38C1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, + 0743F31C1F611B63008386F7 /* IntExtensions.swift in Sources */, + 0743F3701F611B63008386F7 /* UISwitchExtensions.swift in Sources */, + 0743F3741F611B63008386F7 /* UITabBarExtensions.swift in Sources */, + 0743F3601F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, + 0743F33C1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, + 0743F3841F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, + 0743F3401F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, + 0743F2C81F611B63008386F7 /* CGPointExtensions.swift in Sources */, + 0743F2C41F611B63008386F7 /* CGFloatExtensions.swift in Sources */, + 0743F2FC1F611B63008386F7 /* ArrayExtensions.swift in Sources */, + 0743F2D81F611B63008386F7 /* DataExtensions.swift in Sources */, + 0743F32C1F611B63008386F7 /* StringExtensions.swift in Sources */, + 0743F2EC1F611B63008386F7 /* URLExtensions.swift in Sources */, + 0743F2E01F611B63008386F7 /* FoundationDeprecated.swift in Sources */, + 0743F3301F611B63008386F7 /* UIKitDeprecated.swift in Sources */, + 0743F30C1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, + 0743F3541F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, + 0743F37C1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, + 0743F3141F611B63008386F7 /* FloatExtensions.swift in Sources */, + 0743F3341F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, + 0743F3201F611B63008386F7 /* OptionalExtensions.swift in Sources */, + 0743F3001F611B63008386F7 /* BoolExtensions.swift in Sources */, + 0743F3481F611B63008386F7 /* UIImageExtensions.swift in Sources */, + 0743F3881F611B63008386F7 /* UIViewExtensions.swift in Sources */, + 0743F3641F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, + 0743F3281F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3801F611B63008386F7 /* UITextViewExtensions.swift in Sources */, + 0743F3181F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, + 0743F3101F611B63008386F7 /* DoubleExtensions.swift in Sources */, + 0743F35C1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, + 0743F3501F611B63008386F7 /* UILabelExtensions.swift in Sources */, + 0743F3441F611B63008386F7 /* UIColorExtensions.swift in Sources */, + 0743F3241F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, + 0743F2E81F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, + 0743F2D01F611B63008386F7 /* CLLocationExtensions.swift in Sources */, + 0743F3781F611B63008386F7 /* UITableViewExtensions.swift in Sources */, + 0743F2E41F611B63008386F7 /* LocaleExtensions.swift in Sources */, + 0743F2F81F611B63008386F7 /* SwifterSwift.swift in Sources */, + 0743F2CC1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, + 0743F2F41F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, + 0743F3581F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1333,58 +1438,58 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 07897FDB1F138A3300A3A4E1 /* UIColorExtensions.swift in Sources */, - 0703E53A1F5F38CC00788AB4 /* SwifterSwiftDeprecated.swift in Sources */, - 0703E52F1F5F34C900788AB4 /* URLRequestExtensions.swift in Sources */, - 07897F831F138A3300A3A4E1 /* CLLocationExtensions.swift in Sources */, - 078473981F24F3E1001F8575 /* FloatingPointExtensions.swift in Sources */, - 07897FE71F138A3300A3A4E1 /* UILabelExtensions.swift in Sources */, - 07897FEF1F138A3300A3A4E1 /* UINavigationControllerExtensions.swift in Sources */, - 07897F9F1F138A3300A3A4E1 /* CollectionExtensions.swift in Sources */, - 07897FBB1F138A3300A3A4E1 /* LocaleExtensions.swift in Sources */, - 07897FC31F138A3300A3A4E1 /* StringExtensions.swift in Sources */, - 07897F771F138A3300A3A4E1 /* CGFloatExtensions.swift in Sources */, - 07897F9B1F138A3300A3A4E1 /* CharacterExtensions.swift in Sources */, - 0703E5341F5F367C00788AB4 /* UserDefaultsExtensions.swift in Sources */, - 07897F7B1F138A3300A3A4E1 /* CGPointExtensions.swift in Sources */, - 07897FAB1F138A3300A3A4E1 /* DictionaryExtensions.swift in Sources */, - 07897FD71F138A3300A3A4E1 /* UICollectionViewExtensions.swift in Sources */, - 07897F8B1F138A3300A3A4E1 /* NSColorExtensions.swift in Sources */, - 07897F7F1F138A3300A3A4E1 /* CGSizeExtensions.swift in Sources */, - 07897FA71F138A3300A3A4E1 /* DateExtensions.swift in Sources */, - 0789800F1F138A3300A3A4E1 /* UITableViewExtensions.swift in Sources */, - 07897FB71F138A3300A3A4E1 /* IntExtensions.swift in Sources */, - 07897FFF1F138A3300A3A4E1 /* UISliderExtensions.swift in Sources */, - 078980071F138A3300A3A4E1 /* UISwitchExtensions.swift in Sources */, - 078980131F138A3300A3A4E1 /* UITextFieldExtensions.swift in Sources */, - 07897FFB1F138A3300A3A4E1 /* UISegmentedControlExtensions.swift in Sources */, - 07897F8F1F138A3300A3A4E1 /* NSViewExtensions.swift in Sources */, - 0789801F1F138A3300A3A4E1 /* UIViewExtensions.swift in Sources */, - 07897FB31F138A3300A3A4E1 /* FloatExtensions.swift in Sources */, - 07897FBF1F138A3300A3A4E1 /* OptionalExtensions.swift in Sources */, - 07897F731F138A3300A3A4E1 /* CGColorExtensions.swift in Sources */, - 0789801B1F138A3300A3A4E1 /* UIViewControllerExtensions.swift in Sources */, - 07897FCF1F138A3300A3A4E1 /* UIBarButtonItemExtensions.swift in Sources */, - 07897FF71F138A3300A3A4E1 /* UISearchBarExtensions.swift in Sources */, - 07897FF31F138A3300A3A4E1 /* UINavigationItemExtensions.swift in Sources */, - 07897F971F138A3300A3A4E1 /* BoolExtensions.swift in Sources */, - 078980E41F138B7900A3A4E1 /* SwifterSwift.swift in Sources */, - 07897FAF1F138A3300A3A4E1 /* DoubleExtensions.swift in Sources */, - 07897FA31F138A3300A3A4E1 /* DataExtensions.swift in Sources */, - 07897FD31F138A3300A3A4E1 /* UIButtonExtensions.swift in Sources */, - 07897FDF1F138A3300A3A4E1 /* UIImageExtensions.swift in Sources */, - 0789800B1F138A3300A3A4E1 /* UITabBarExtensions.swift in Sources */, - 078980031F138A3300A3A4E1 /* UIStoryboardExtensions.swift in Sources */, - 078980171F138A3300A3A4E1 /* UITextViewExtensions.swift in Sources */, - 07897FE31F138A3300A3A4E1 /* UIImageViewExtensions.swift in Sources */, - 07897FC71F138A3300A3A4E1 /* URLExtensions.swift in Sources */, - 077A72CF1F436357003DC1C4 /* SignedNumberExtensions.swift in Sources */, - 07897FEB1F138A3300A3A4E1 /* UINavigationBarExtensions.swift in Sources */, - 07897F931F138A3300A3A4E1 /* ArrayExtensions.swift in Sources */, - 07897F871F138A3300A3A4E1 /* NSAttributedStringExtensions.swift in Sources */, - 07897FCB1F138A3300A3A4E1 /* UIAlertControllerExtensions.swift in Sources */, - 07B8600F1F21CE550032CE3A /* UIKitDeprecated.swift in Sources */, - 077A72D41F436433003DC1C4 /* SignedIntegerExtensions.swift in Sources */, + 0743F34D1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, + 0743F36D1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, + 0743F3091F611B63008386F7 /* CollectionExtensions.swift in Sources */, + 0743F3051F611B63008386F7 /* CharacterExtensions.swift in Sources */, + 0743F2F11F611B63008386F7 /* URLRequestExtensions.swift in Sources */, + 0743F2DD1F611B63008386F7 /* DateExtensions.swift in Sources */, + 0743F2D51F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, + 0743F3691F611B63008386F7 /* UISliderExtensions.swift in Sources */, + 0743F2C11F611B63008386F7 /* CGColorExtensions.swift in Sources */, + 0743F3391F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, + 0743F38D1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, + 0743F31D1F611B63008386F7 /* IntExtensions.swift in Sources */, + 0743F3711F611B63008386F7 /* UISwitchExtensions.swift in Sources */, + 0743F3751F611B63008386F7 /* UITabBarExtensions.swift in Sources */, + 0743F3611F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, + 0743F33D1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, + 0743F3851F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, + 0743F3411F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, + 0743F2C91F611B63008386F7 /* CGPointExtensions.swift in Sources */, + 0743F2C51F611B63008386F7 /* CGFloatExtensions.swift in Sources */, + 0743F2FD1F611B63008386F7 /* ArrayExtensions.swift in Sources */, + 0743F2D91F611B63008386F7 /* DataExtensions.swift in Sources */, + 0743F32D1F611B63008386F7 /* StringExtensions.swift in Sources */, + 0743F2ED1F611B63008386F7 /* URLExtensions.swift in Sources */, + 0743F2E11F611B63008386F7 /* FoundationDeprecated.swift in Sources */, + 0743F3311F611B63008386F7 /* UIKitDeprecated.swift in Sources */, + 0743F30D1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, + 0743F3551F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, + 0743F37D1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, + 0743F3151F611B63008386F7 /* FloatExtensions.swift in Sources */, + 0743F3351F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, + 0743F3211F611B63008386F7 /* OptionalExtensions.swift in Sources */, + 0743F3011F611B63008386F7 /* BoolExtensions.swift in Sources */, + 0743F3491F611B63008386F7 /* UIImageExtensions.swift in Sources */, + 0743F3891F611B63008386F7 /* UIViewExtensions.swift in Sources */, + 0743F3651F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, + 0743F3291F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3811F611B63008386F7 /* UITextViewExtensions.swift in Sources */, + 0743F3191F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, + 0743F3111F611B63008386F7 /* DoubleExtensions.swift in Sources */, + 0743F35D1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, + 0743F3511F611B63008386F7 /* UILabelExtensions.swift in Sources */, + 0743F3451F611B63008386F7 /* UIColorExtensions.swift in Sources */, + 0743F3251F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, + 0743F2E91F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, + 0743F2D11F611B63008386F7 /* CLLocationExtensions.swift in Sources */, + 0743F3791F611B63008386F7 /* UITableViewExtensions.swift in Sources */, + 0743F2E51F611B63008386F7 /* LocaleExtensions.swift in Sources */, + 0743F2F91F611B63008386F7 /* SwifterSwift.swift in Sources */, + 0743F2CD1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, + 0743F2F51F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, + 0743F3591F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/CocoaTests/NSAttributedStringExtensionsTests.swift b/Tests/AppKitTests/NSAttributedStringExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/NSAttributedStringExtensionsTests.swift rename to Tests/AppKitTests/NSAttributedStringExtensionsTests.swift diff --git a/Tests/CocoaTests/NSViewExtensionsTests.swift b/Tests/AppKitTests/NSViewExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/NSViewExtensionsTests.swift rename to Tests/AppKitTests/NSViewExtensionsTests.swift diff --git a/Tests/CocoaTests/CGFloatExtensionsTests.swift b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/CGFloatExtensionsTests.swift rename to Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift diff --git a/Tests/CocoaTests/CGPointExtensionsTests.swift b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/CGPointExtensionsTests.swift rename to Tests/CoreGraphicsTests/CGPointExtensionsTests.swift diff --git a/Tests/CocoaTests/CGSizeExtensionsTests.swift b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/CGSizeExtensionsTests.swift rename to Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift diff --git a/Tests/CocoaTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift similarity index 100% rename from Tests/CocoaTests/CLLocationExtensionsTests.swift rename to Tests/CoreLocationTests/CLLocationExtensionsTests.swift diff --git a/Tests/FoundationTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/ArrayExtensionsTests.swift rename to Tests/SwiftStdlibTests/ArrayExtensionsTests.swift diff --git a/Tests/FoundationTests/BoolExtensionsTests.swift b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/BoolExtensionsTests.swift rename to Tests/SwiftStdlibTests/BoolExtensionsTests.swift diff --git a/Tests/FoundationTests/CharacterExtensionsTests.swift b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/CharacterExtensionsTests.swift rename to Tests/SwiftStdlibTests/CharacterExtensionsTests.swift diff --git a/Tests/FoundationTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/CollectionExtensionsTests.swift rename to Tests/SwiftStdlibTests/CollectionExtensionsTests.swift diff --git a/Tests/FoundationTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/DictionaryExtensionsTests.swift rename to Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift diff --git a/Tests/FoundationTests/DoubleExtensionsTests.swift b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/DoubleExtensionsTests.swift rename to Tests/SwiftStdlibTests/DoubleExtensionsTests.swift diff --git a/Tests/FoundationTests/FloatExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/FloatExtensionsTests.swift rename to Tests/SwiftStdlibTests/FloatExtensionsTests.swift diff --git a/Tests/FoundationTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/IntExtensionsTests.swift rename to Tests/SwiftStdlibTests/IntExtensionsTests.swift diff --git a/Tests/FoundationTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/OptionalExtensionsTests.swift rename to Tests/SwiftStdlibTests/OptionalExtensionsTests.swift diff --git a/Tests/FoundationTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift similarity index 100% rename from Tests/FoundationTests/StringExtensionsTests.swift rename to Tests/SwiftStdlibTests/StringExtensionsTests.swift From 79cb9f12cf2f1ef2a38ceb07a113dbdf97707df4 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sat, 16 Sep 2017 10:38:32 +0300 Subject: [PATCH 016/201] Swift 3.2 (#246) - Swift 3.2 :tada: - Fixed typeName - Moved NSAttributedStringExtensionsTests to FoundationTests - Remove navigationBar, Fixes #243 - Update build.sh --- .swift-version | 2 +- .travis.yml | 2 +- CHANGELOG.md | 5 + README.md | 8 +- .../SwiftStdlib/ArrayExtensions.swift | 49 ++++------ .../SwiftStdlib/CollectionExtensions.swift | 4 - .../SwiftStdlib/FloatingPointExtensions.swift | 16 +++- .../SwiftStdlib/SignedIntegerExtensions.swift | 47 +++++---- ...ns.swift => SignedNumericExtensions.swift} | 20 +--- Sources/Extensions/SwifterSwift.swift | 4 +- .../UIKit/UIViewControllerExtensions.swift | 5 - SwifterSwift.xcodeproj/project.pbxproj | 78 ++++++++++++--- .../xcschemes/SwifterSwift iOS.xcscheme | 4 +- .../xcschemes/SwifterSwift iOSTests.xcscheme | 4 +- .../xcschemes/SwifterSwift macOS.xcscheme | 4 +- .../SwifterSwift macOSTests.xcscheme | 4 +- .../xcschemes/SwifterSwift tvOS.xcscheme | 4 +- .../xcschemes/SwifterSwift tvOSTests.xcscheme | 4 +- .../xcschemes/SwifterSwift watchOS.xcscheme | 4 +- .../CGPointExtensionsTests.swift | 4 +- .../CLLocationExtensionsTests.swift | 10 +- .../NSAttributedStringExtensionsTests.swift | 0 .../FloatExtensionsTests.swift | 4 +- .../UIImageViewExtensionsTests.swift | 95 ++++++++++--------- .../UIViewControllerExtensionsTests.swift | 7 -- Tests/build.sh | 8 +- 26 files changed, 221 insertions(+), 175 deletions(-) rename Sources/Extensions/SwiftStdlib/{SignedNumberExtensions.swift => SignedNumericExtensions.swift} (58%) rename Tests/{AppKitTests => FoundationTests}/NSAttributedStringExtensionsTests.swift (100%) diff --git a/.swift-version b/.swift-version index 9f55b2ccb..a3ec5a4bd 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.0 +3.2 diff --git a/.travis.yml b/.travis.yml index 28ca134c1..ac8d9fcde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -osx_image: xcode8.3 +osx_image: xcode9 language: objective-c before_install: - brew update diff --git a/CHANGELOG.md b/CHANGELOG.md index 851bdb195..90a89e08e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ All notable changes to this project will be documented in this file. # v3.2.0 ### API Breaking +- **Swift 3.2** + - Code has been updated to Swift 3.2, please use [`v3.1.1`](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1) if you are still using Swift 3 or Xcode 8 - **SwifterSwift** - `userDefaults` is deprecated, use Apple's `UserDefaults.standard` instead. - `object(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.object(forKey: _)` instead. @@ -44,6 +46,9 @@ All notable changes to this project will be documented in this file. - Property `numberOfItems` is now a method. - **UITableView** - Property `numberOfRows` is now a method. +- **UIViewController** + - Removed `navigationBar` that was causing app to crash, thanks to [drewpitchford](https://github.com/drewpitchford) for reporting in [#243](https://github.com/SwifterSwift/SwifterSwift/issues/243). + ### Enhancements - New **Date** extensions diff --git a/README.md b/README.md index 00366727e..63fda82fa 100755 --- a/README.md +++ b/README.md @@ -19,9 +19,11 @@ SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with han --- -## Looking for Xcode9/Swift4 Support? -We're working on **v4** in the [`swift-4 branch`](https://github.com/SwifterSwift/SwifterSwift/tree/swift-4), to bring support for Swift 4 and Xcode 9. -> Please note that that v4 in still in development and will be released as soon as Xcode 9 is available. +### ⚠️ To use with **Swift 3 / Xcode 8.x** please ensure you are using [**`v3.1.1`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1). + +### ⚠️ To use with **Swift 3.2 / Xcode 9.x** please ensure you are using [**`v3.2`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.2.0). + +### ⚠️ To use with **Swift 4 / Xcode 9.x** please ensure you are using the [**`swift-4`**](https://github.com/SwifterSwift/SwifterSwift/tree/swift-4) branch. --- diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 81fea4dd7..b5b0d4c5b 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -5,12 +5,11 @@ // Created by Omar Albeik on 8/5/16. // Copyright © 2016 Omar Albeik. All rights reserved. // - import Foundation // MARK: - Methods (Integer) -public extension Array where Element: Integer { +public extension Array where Element: Numeric { /// SwifterSwift: Sum of all elements in array. /// @@ -18,9 +17,9 @@ public extension Array where Element: Integer { /// /// - Returns: sum of the array's elements. public func sum() -> Element { - var total: Element = 0 - forEach { total += $0 } - return total + var total: Element = 0 + forEach { total += $0 } + return total } } @@ -35,22 +34,12 @@ public extension Array where Element: FloatingPoint { /// /// - Returns: average of the array's elements. public func average() -> Element { - guard isEmpty == false else { return 0 } - var total: Element = 0 - forEach { total += $0 } - return total / Element(count) + guard isEmpty == false else { return 0 } + var total: Element = 0 + forEach { total += $0 } + return total / Element(count) } - /// SwifterSwift: Sum of all elements in array. - /// - /// [1.2, 2.3, 4.5, 3.4, 4.5].sum -> 15.9 - /// - /// - Returns: sum of the array's elements. - public func sum() -> Element { - var total: Element = 0 - forEach { total += $0 } - return total - } } @@ -112,7 +101,7 @@ public extension Array { guard index != otherIndex, startIndex.. [ "evens" : [0, 2, 4], "odds" : [5, 7] ] /// - /// - Parameter getKey: Clousure to define the key for each element. - /// - Returns: A dictionary with values grouped with keys. + /// - Parameter getKey: Clousure to define the key for each element. + /// - Returns: A dictionary with values grouped with keys. public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { var group : [K: [Element]] = [:] for value in self { @@ -379,14 +368,14 @@ public extension Array { return group } - /// SwifterSwift: Returns a new rotated array by the given places. + /// SwifterSwift: Returns a new rotated array by the given places. /// /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - /// - Returns: The new rotated array + /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Returns: The new rotated array public func rotated(by places: Int) -> [Element] { //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate guard places != 0 && places < count else { @@ -407,13 +396,13 @@ public extension Array { return array } - /// SwifterSwift: Rotate the array by the given places. + /// SwifterSwift: Rotate the array by the given places. /// /// [1, 2, 3, 4].rotate(by: 1) -> [4,1,2,3] /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. public mutating func rotate(by places: Int) { self = rotated(by: places) } @@ -432,7 +421,7 @@ public extension Array where Element: Equatable { guard count > 1 else { return } for index in startIndex.. 0 + } + + /// SwifterSwift: Check if integer is negative. + public var isNegative: Bool { + return self < 0 + } + /// SwifterSwift: Ceil of number. public var ceil: Self { return Foundation.ceil(self) diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index 115a738ff..10597653c 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -1,3 +1,4 @@ + // // SignedIntegerExtensions.swift // SwifterSwift @@ -5,13 +6,27 @@ // Created by Omar Albeik on 8/15/17. // // - import Foundation // MARK: - Properties public extension SignedInteger { + /// SwifterSwift: Absolute value of integer number. + public var abs: Self { + return Swift.abs(self) + } + + /// SwifterSwift: Check if integer is positive. + public var isPositive: Bool { + return self > 0 + } + + /// SwifterSwift: Check if integer is negative. + public var isNegative: Bool { + return self < 0 + } + /// SwifterSwift: Check if integer is even. public var isEven: Bool { return (self % 2) == 0 @@ -21,24 +36,16 @@ public extension SignedInteger { public var isOdd: Bool { return (self % 2) != 0 } - - /// SwifterSwift: Array of digits of integer value. - /// - /// 180.digits -> [1, 8, 0] - /// - public var digits: [Self] { - var digits: [Self] = [] - for char in String(self).characters { - if let int = IntMax(String(char)) { - digits.append(Self(int)) - } - } - return digits - } - + + /// SwifterSwift: Array of digits of integer value. + public var digits: [Self] { + let intsArray = description.flatMap({Int(String($0))}) + return intsArray.map({Self($0)}) + } + /// SwifterSwift: Number of digits of integer value. public var digitsCount: Int { - return String(self).characters.count + return description.flatMap({Int(String($0))}).count } /// SwifterSwift: String of format (XXh XXm) from seconds Int. @@ -60,7 +67,7 @@ public extension SignedInteger { } return "\(hours)h \(mins)m" } - + } @@ -82,7 +89,5 @@ public extension SignedInteger { public func lcm(of n: Self) -> Self { return (self * n).abs / gcd(of: n) } - + } - - diff --git a/Sources/Extensions/SwiftStdlib/SignedNumberExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift similarity index 58% rename from Sources/Extensions/SwiftStdlib/SignedNumberExtensions.swift rename to Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index 8a4d0fab7..88a360447 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumberExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -5,26 +5,9 @@ // Created by Omar Albeik on 8/15/17. // // - import Foundation - -public extension SignedNumber { - - /// SwifterSwift: Absolute value of integer. - public var abs: Self { - return Swift.abs(self) - } - - /// SwifterSwift: Check if integer is positive. - public var isPositive: Bool { - return self > 0 - } - - /// SwifterSwift: Check if integer is negative. - public var isNegative: Bool { - return self < 0 - } +public extension SignedNumeric { /// SwifterSwift: String. public var string: String { @@ -39,4 +22,3 @@ public extension SignedNumber { return formatter.string(from: self as! NSNumber)! } } - diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 3e0ff9905..374674eb7 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -316,8 +316,8 @@ public extension SwifterSwift { /// - Parameter object: Any object to find its class name. /// - Returns: Class name for given object. public static func typeName(for object: Any) -> String { - let type = type(of: object.self) - return String.init(describing: type) + let objectType = type(of: object.self) + return String.init(describing: objectType) } } diff --git a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift index 4dd5e165b..9b3428fcf 100755 --- a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift @@ -19,11 +19,6 @@ public extension UIViewController { return self.isViewLoaded && view.window != nil } - /// SwifterSwift: NavigationBar in a ViewController. - public var navigationBar: UINavigationBar? { - return navigationController?.navigationBar - } - } // MARK: - Methods diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index fe3f0c2bc..7641a4ee6 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -113,10 +113,10 @@ 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; 0743F3241F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; 0743F3251F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; - 0743F3261F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; - 0743F3271F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; - 0743F3281F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; - 0743F3291F611B63008386F7 /* SignedNumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */; }; + 0743F3261F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; + 0743F3271F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; + 0743F3281F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; + 0743F3291F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; 0743F32A1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; 0743F32B1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; 0743F32C1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; @@ -399,7 +399,7 @@ 0743F2971F611B62008386F7 /* IntExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensions.swift; sourceTree = ""; }; 0743F2981F611B62008386F7 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; - 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumberExtensions.swift; sourceTree = ""; }; + 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensions.swift; sourceTree = ""; }; 0743F29B1F611B62008386F7 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIKitDeprecated.swift; sourceTree = ""; }; 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensions.swift; sourceTree = ""; }; @@ -616,7 +616,7 @@ 0743F2971F611B62008386F7 /* IntExtensions.swift */, 0743F2981F611B62008386F7 /* OptionalExtensions.swift */, 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */, - 0743F29A1F611B62008386F7 /* SignedNumberExtensions.swift */, + 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */, 0743F29B1F611B62008386F7 /* StringExtensions.swift */, ); path = SwiftStdlib; @@ -664,7 +664,6 @@ 0743F38E1F611B87008386F7 /* AppKitTests */ = { isa = PBXGroup; children = ( - 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */, 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */, ); name = AppKitTests; @@ -697,6 +696,7 @@ 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */, 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */, 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */, + 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */, 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */, 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */, 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */, @@ -1002,7 +1002,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 0830; + LastUpgradeCheck = 0900; TargetAttributes = { 077AD1B41F13873600D3214D = { CreatedOnToolsVersion = 8.3.3; @@ -1319,7 +1319,7 @@ 0743F3461F611B63008386F7 /* UIImageExtensions.swift in Sources */, 0743F3861F611B63008386F7 /* UIViewExtensions.swift in Sources */, 0743F3621F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3261F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3261F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, 0743F37E1F611B63008386F7 /* UITextViewExtensions.swift in Sources */, 0743F3161F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, 0743F30E1F611B63008386F7 /* DoubleExtensions.swift in Sources */, @@ -1361,7 +1361,7 @@ 0743F3131F611B63008386F7 /* FloatExtensions.swift in Sources */, 0743F31F1F611B63008386F7 /* OptionalExtensions.swift in Sources */, 0743F2FF1F611B63008386F7 /* BoolExtensions.swift in Sources */, - 0743F3271F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3271F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, 0743F3171F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, 0743F30F1F611B63008386F7 /* DoubleExtensions.swift in Sources */, 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, @@ -1415,7 +1415,7 @@ 0743F3481F611B63008386F7 /* UIImageExtensions.swift in Sources */, 0743F3881F611B63008386F7 /* UIViewExtensions.swift in Sources */, 0743F3641F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3281F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3281F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, 0743F3801F611B63008386F7 /* UITextViewExtensions.swift in Sources */, 0743F3181F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, 0743F3101F611B63008386F7 /* DoubleExtensions.swift in Sources */, @@ -1474,7 +1474,7 @@ 0743F3491F611B63008386F7 /* UIImageExtensions.swift in Sources */, 0743F3891F611B63008386F7 /* UIViewExtensions.swift in Sources */, 0743F3651F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3291F611B63008386F7 /* SignedNumberExtensions.swift in Sources */, + 0743F3291F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, 0743F3811F611B63008386F7 /* UITextViewExtensions.swift in Sources */, 0743F3191F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, 0743F3111F611B63008386F7 /* DoubleExtensions.swift in Sources */, @@ -1831,16 +1831,66 @@ 079412C91F137D5C006AA1F8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; + ONLY_ACTIVE_ARCH = YES; + SWIFT_VERSION = 3.0; }; name = Debug; }; 079412CA1F137D5C006AA1F8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -1867,7 +1917,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; @@ -1933,7 +1983,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme index 4d650c283..b71c1648b 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme @@ -1,6 +1,6 @@ @@ -56,6 +57,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme index 292535bde..3c60d93f9 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme @@ -1,6 +1,6 @@ @@ -56,6 +57,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme index 0d0807396..fbe50179e 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme @@ -1,6 +1,6 @@ @@ -56,6 +57,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme index eb7ae91d0..3cce66a03 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme @@ -1,6 +1,6 @@ @@ -36,6 +37,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift index 693cf6a2e..03ea9e53b 100644 --- a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift @@ -16,12 +16,12 @@ class CGPointExtensionsTests: XCTestCase { func testDistanceFromPoint() { let distance = point1.distance(from: point2) - XCTAssertEqualWithAccuracy(distance, 28.28, accuracy: 0.01) + XCTAssertEqual(distance, 28.28, accuracy: 0.01) } func testStaticDistance() { let distance = CGPoint.distance(from: point2, to: point1) - XCTAssertEqualWithAccuracy(distance, 28.28, accuracy: 0.01) + XCTAssertEqual(distance, 28.28, accuracy: 0.01) } func testAdd() { diff --git a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift index 1a2f1ed4a..ee7731f51 100644 --- a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift +++ b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift @@ -17,11 +17,11 @@ class CLLocationExtensionsTests: XCTestCase { let b = CLLocation(latitude: -15.692030, longitude: -47.594397) let mid = CLLocation.midLocation(start: a, end: b) - XCTAssertEqualWithAccuracy(mid.coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) - XCTAssertEqualWithAccuracy(mid.coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) + XCTAssertEqual(mid.coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) + XCTAssertEqual(mid.coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) - XCTAssertEqualWithAccuracy(a.midLocation(to: b).coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) - XCTAssertEqualWithAccuracy(a.midLocation(to: b).coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) + XCTAssertEqual(a.midLocation(to: b).coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) + XCTAssertEqual(a.midLocation(to: b).coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) } @@ -30,6 +30,6 @@ class CLLocationExtensionsTests: XCTestCase { let b = CLLocation(latitude: 38.5352759115441, longitude: -89.8448181152343) let bearing = a.bearing(to: b) - XCTAssertEqualWithAccuracy(bearing, 105.619, accuracy: 0.001) + XCTAssertEqual(bearing, 105.619, accuracy: 0.001) } } diff --git a/Tests/AppKitTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift similarity index 100% rename from Tests/AppKitTests/NSAttributedStringExtensionsTests.swift rename to Tests/FoundationTests/NSAttributedStringExtensionsTests.swift diff --git a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift index e08c8adec..bb2dca10d 100644 --- a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift @@ -62,11 +62,11 @@ class FloatExtensionsTests: XCTestCase { func testDouble() { XCTAssertEqual(Float(-1).double, Double(-1)) XCTAssertEqual(Float(2).double, Double(2)) - XCTAssertEqualWithAccuracy(Float(4.3).double, Double(4.3), accuracy: 0.00001) + XCTAssertEqual(Float(4.3).double, Double(4.3), accuracy: 0.00001) } func testCGFloat() { - XCTAssertEqualWithAccuracy(Float(4.3).cgFloat, CGFloat(4.3), accuracy: 0.00001) + XCTAssertEqual(Float(4.3).cgFloat, CGFloat(4.3), accuracy: 0.00001) } func testString() { diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index 9b93de2fc..8655a37de 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -5,59 +5,60 @@ // Created by Steven on 2/19/17. // Copyright © 2017 omaralbeik. All rights reserved. // - #if os(iOS) || os(tvOS) -import XCTest -@testable import SwifterSwift - -class UIImageViewExtensionsTests: XCTestCase { + import XCTest + @testable import SwifterSwift - func testDownload() { - // Success - let imageView = UIImageView() - let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! - let placeHolder = UIImage() - let downloadExpectation = expectation(description: "Download success") - imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in - XCTAssertEqual(imageView.image, image) - downloadExpectation.fulfill() - } - XCTAssertEqual(imageView.image, placeHolder) - XCTAssertEqual(imageView.contentMode, .scaleAspectFill) + class UIImageViewExtensionsTests: XCTestCase { - // Failure - let failImageView = UIImageView() - let failingURL = URL(string: "https://developer.apple.com/")! - let failExpectation = expectation(description: "Download failure") - failImageView.image = nil - failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in - XCTAssertNil(image) + func testDownload() { + // Success + let imageView = UIImageView() + let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! + let placeHolder = UIImage() + let downloadExpectation = expectation(description: "Download success") + imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in + XCTAssertEqual(imageView.image, image) + downloadExpectation.fulfill() + } + XCTAssertEqual(imageView.image, placeHolder) + XCTAssertEqual(imageView.contentMode, .scaleAspectFill) + + // Failure + let failImageView = UIImageView() + let failingURL = URL(string: "https://developer.apple.com/")! + let failExpectation = expectation(description: "Download failure") + failImageView.image = nil + failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in + XCTAssertNil(image) + DispatchQueue.main.async { + XCTAssertNil(failImageView.image) + } + failExpectation.fulfill() + } + XCTAssertEqual(failImageView.contentMode, .center) XCTAssertNil(failImageView.image) - failExpectation.fulfill() + waitForExpectations(timeout: 15, handler: nil) + } + + func testBlur() { + let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100)) + imageView.blur(withStyle: .dark) + + let blurView = imageView.subviews.first as? UIVisualEffectView + XCTAssertNotNil(blurView) + XCTAssertNotNil(blurView?.effect) + XCTAssertEqual(blurView?.frame, imageView.bounds) + XCTAssertEqual(blurView?.autoresizingMask, [.flexibleWidth, .flexibleHeight]) + XCTAssert(imageView.clipsToBounds) + } + + func testBlurred() { + let imageView = UIImageView() + let blurredImageView = imageView.blurred(withStyle: .extraLight) + XCTAssertEqual(blurredImageView, imageView) } - XCTAssertEqual(failImageView.contentMode, .center) - XCTAssertNil(failImageView.image) - waitForExpectations(timeout: 15, handler: nil) - } - - func testBlur() { - let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100)) - imageView.blur(withStyle: .dark) - let blurView = imageView.subviews.first as? UIVisualEffectView - XCTAssertNotNil(blurView) - XCTAssertNotNil(blurView?.effect) - XCTAssertEqual(blurView?.frame, imageView.bounds) - XCTAssertEqual(blurView?.autoresizingMask, [.flexibleWidth, .flexibleHeight]) - XCTAssert(imageView.clipsToBounds) - } - - func testBlurred() { - let imageView = UIImageView() - let blurredImageView = imageView.blurred(withStyle: .extraLight) - XCTAssertEqual(blurredImageView, imageView) } - -} #endif diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index bdfa7548f..6346c906e 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -23,13 +23,6 @@ class UIViewControllerExtensionsTests: XCTestCase { let notificationIdentifier = Notification.Name("MockNotification") - func testNavigationBar() { - let viewController = UIViewController() - XCTAssertNil(viewController.navigationBar) - let navigationController = UINavigationController(rootViewController: viewController) - XCTAssertEqual(navigationController.navigationBar, viewController.navigationBar) - } - func testAddNotificationObserver() { let viewController = MockNotificationViewController() let selector = #selector(MockNotificationViewController.testSelector) diff --git a/Tests/build.sh b/Tests/build.sh index c3eabfe46..81decb98b 100644 --- a/Tests/build.sh +++ b/Tests/build.sh @@ -9,7 +9,7 @@ rm -rf $DERIVED_DATA && time xcodebuild clean test \ -project SwifterSwift.xcodeproj \ -scheme 'SwifterSwift macOS' \ - -sdk macosx10.12 \ + -sdk macosx10.13 \ -derivedDataPath $DERIVED_DATA \ | tee build.log \ | xcpretty && @@ -18,7 +18,7 @@ rm -rf $DERIVED_DATA && time xcodebuild clean test \ -project SwifterSwift.xcodeproj \ -scheme 'SwifterSwift tvOS' \ - -sdk appletvsimulator10.2 \ + -sdk appletvsimulator11.0 \ -derivedDataPath $DERIVED_DATA \ -destination 'platform=tvOS Simulator,name=Apple TV 1080p' \ | tee build.log \ @@ -28,9 +28,9 @@ rm -rf $DERIVED_DATA && time xcodebuild clean test \ -project SwifterSwift.xcodeproj \ -scheme 'SwifterSwift iOS' \ - -sdk iphonesimulator10.3 \ + -sdk iphonesimulator11.0 \ -derivedDataPath $DERIVED_DATA \ - -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.3.1' \ + -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.0' \ | tee build.log \ | xcpretty && cat build.log From 1b67f8c2892428cb66223a46844eb8e6205c71be Mon Sep 17 00:00:00 2001 From: BennX Date: Sat, 16 Sep 2017 18:47:56 +0200 Subject: [PATCH 017/201] Add isBetween method to date extension --- .../Foundation/DateExtensions.swift | 16 +++++++++++- .../FoundationTests/DateExtensionsTests.swift | 25 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index ee84e5cc0..b51ee39cc 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -709,7 +709,21 @@ public extension Date { public func daysSince(_ date: Date) -> Double { return self.timeIntervalSince(date)/(3600*24) } - + + /// SwifterSwift: check if a date is between two other dates + /// + /// - Parameter startDate: start date to compare self to. + /// - Parameter endDate: endDate date to compare self to. + /// - Parameter includeBounds: true if the start and end date should be included (default is true) + /// - Returns: true if the date is between the two given dates. + public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = true) -> Bool { + if includeBounds { + return startDate.compare(self).rawValue * self.compare(endDate).rawValue >= 0 + } else { + return startDate.compare(self).rawValue * self.compare(endDate).rawValue > 0 + } + } + } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index d21b04e3a..11908cb13 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -683,4 +683,29 @@ class DateExtensionsTests: XCTestCase { XCTAssertEqual(date, dateFromUnixTimestamp) } + func testIfDateIsBetween() { + var date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z + let startDate = Date(timeIntervalSince1970: 511) + let endDate = Date(timeIntervalSince1970: 513) + XCTAssertTrue(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 511) + XCTAssertTrue(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 513) + XCTAssertTrue(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 230) + XCTAssertFalse(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 550) + XCTAssertFalse(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 511) + XCTAssertFalse(date.isBetween(startDate, endDate, includeBounds: false)) + + date = Date(timeIntervalSince1970: 513) + XCTAssertFalse(date.isBetween(startDate, endDate, includeBounds: false)) + } + } From 729aaad834605c7609d4ba0cd926800b39389ef6 Mon Sep 17 00:00:00 2001 From: BennX Date: Sat, 16 Sep 2017 19:05:58 +0200 Subject: [PATCH 018/201] Set includeBounds to false on Date extension --- .../Extensions/Foundation/DateExtensions.swift | 4 ++-- Tests/FoundationTests/DateExtensionsTests.swift | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index b51ee39cc..dc26143c3 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -714,9 +714,9 @@ public extension Date { /// /// - Parameter startDate: start date to compare self to. /// - Parameter endDate: endDate date to compare self to. - /// - Parameter includeBounds: true if the start and end date should be included (default is true) + /// - Parameter includeBounds: true if the start and end date should be included (default is false) /// - Returns: true if the date is between the two given dates. - public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = true) -> Bool { + public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool { if includeBounds { return startDate.compare(self).rawValue * self.compare(endDate).rawValue >= 0 } else { diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 11908cb13..352c6a75c 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -688,24 +688,24 @@ class DateExtensionsTests: XCTestCase { let startDate = Date(timeIntervalSince1970: 511) let endDate = Date(timeIntervalSince1970: 513) XCTAssertTrue(date.isBetween(startDate, endDate)) + + date = Date(timeIntervalSince1970: 511) + XCTAssertTrue(date.isBetween(startDate, endDate, includeBounds: true)) + + date = Date(timeIntervalSince1970: 513) + XCTAssertTrue(date.isBetween(startDate, endDate, includeBounds: true)) date = Date(timeIntervalSince1970: 511) - XCTAssertTrue(date.isBetween(startDate, endDate)) + XCTAssertFalse(date.isBetween(startDate, endDate)) date = Date(timeIntervalSince1970: 513) - XCTAssertTrue(date.isBetween(startDate, endDate)) + XCTAssertFalse(date.isBetween(startDate, endDate)) date = Date(timeIntervalSince1970: 230) XCTAssertFalse(date.isBetween(startDate, endDate)) date = Date(timeIntervalSince1970: 550) XCTAssertFalse(date.isBetween(startDate, endDate)) - - date = Date(timeIntervalSince1970: 511) - XCTAssertFalse(date.isBetween(startDate, endDate, includeBounds: false)) - - date = Date(timeIntervalSince1970: 513) - XCTAssertFalse(date.isBetween(startDate, endDate, includeBounds: false)) } } From 1dd315c910f706c27fe3702c80fa64dcdbbfb4bd Mon Sep 17 00:00:00 2001 From: BennX Date: Sat, 16 Sep 2017 20:21:06 +0200 Subject: [PATCH 019/201] Add CHANGELOG entry for new isBetween Date extension. --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a89e08e..fefec74db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,18 @@ All notable changes to this project will be documented in this file. > ### Bugfixes > N/A +# v3.2.1 + +### API Breaking +N/A + +### Enhancements +- New **Date** extensions + - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. + +### Bugfixes +N/A + # v3.2.0 ### API Breaking From f3b57a22f879010c6aa59839af956b45e3208249 Mon Sep 17 00:00:00 2001 From: BennX Date: Sat, 16 Sep 2017 20:30:52 +0200 Subject: [PATCH 020/201] Fix CHANGELOG entry --- CHANGELOG.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefec74db..2825a97c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,23 +11,12 @@ All notable changes to this project will be documented in this file. > N/A > > ### Enhancements -> N/A +> - New **Date** extensions +> - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. > > ### Bugfixes > N/A -# v3.2.1 - -### API Breaking -N/A - -### Enhancements -- New **Date** extensions - - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. - -### Bugfixes -N/A - # v3.2.0 ### API Breaking From 05b7ee499afe73fc78ef42cf4e56c5e450138530 Mon Sep 17 00:00:00 2001 From: BennX Date: Sun, 24 Sep 2017 12:59:03 +0200 Subject: [PATCH 021/201] Add UIFontExtension and make SwifterSwift's UIImageView even Swiftier --- CHANGELOG.md | 3 ++- .../Foundation/DateExtensions.swift | 7 +++--- .../Extensions/UIKit/UIFontExtensions.swift | 24 +++++++++++++++++++ .../UIKit/UIImageViewExtensions.swift | 4 ++-- SwifterSwift.xcodeproj/project.pbxproj | 18 ++++++++++++++ Tests/UIKitTests/UIFontExtensionsTest.swift | 24 +++++++++++++++++++ 6 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 Sources/Extensions/UIKit/UIFontExtensions.swift create mode 100644 Tests/UIKitTests/UIFontExtensionsTest.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 2825a97c9..935c3d1a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ All notable changes to this project will be documented in this file. > ### Enhancements > - New **Date** extensions > - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. -> +> - New **UIFont** extensions +> - added `asMonospacedDigitFont() -> UIFont` method to get the current font as monospaced digit font. [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) > ### Bugfixes > N/A diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index dc26143c3..271f9f7fb 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -712,9 +712,10 @@ public extension Date { /// SwifterSwift: check if a date is between two other dates /// - /// - Parameter startDate: start date to compare self to. - /// - Parameter endDate: endDate date to compare self to. - /// - Parameter includeBounds: true if the start and end date should be included (default is false) + /// - Parameters: + /// - startDate: start date to compare self to. + /// - endDate: endDate date to compare self to. + /// - includeBounds: true if the start and end date should be included (default is false) /// - Returns: true if the date is between the two given dates. public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool { if includeBounds { diff --git a/Sources/Extensions/UIKit/UIFontExtensions.swift b/Sources/Extensions/UIKit/UIFontExtensions.swift new file mode 100644 index 000000000..ee160a062 --- /dev/null +++ b/Sources/Extensions/UIKit/UIFontExtensions.swift @@ -0,0 +1,24 @@ +// +// UIFontExtensions.swift +// SwifterSwift +// +// Created by Benjamin Meyer on 9/16/17. +// + +#if os(iOS) || os(tvOS) || os(watchOS) +import UIKit + +// MARK: - Properties +public extension UIFont { + /// SwifterSwift: Font as monospaced digit font. [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) + /// + /// UIFont.preferredFont(forTextStyle: .body).asMonospacedDigitFont() + /// + public func asMonospacedDigitFont() -> UIFont { + let fontDescriptorFeatureSettings = [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]] + let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings] + let newFontDescriptor = fontDescriptor.addingAttributes(fontDescriptorAttributes) + return UIFont(descriptor: newFontDescriptor, size: 0) + } +} +#endif diff --git a/Sources/Extensions/UIKit/UIImageViewExtensions.swift b/Sources/Extensions/UIKit/UIImageViewExtensions.swift index c738cac75..074660515 100644 --- a/Sources/Extensions/UIKit/UIImageViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageViewExtensions.swift @@ -37,11 +37,11 @@ public extension UIImageView { completionHandler?(nil) return } - DispatchQueue.main.async() { () -> Void in + DispatchQueue.main.async { self.image = image completionHandler?(image) } - }.resume() + }.resume() } /// SwifterSwift: Make image view blurry diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 7641a4ee6..54d337f88 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -344,6 +344,13 @@ 07DFA3E51F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E61F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07DFA3E71F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4222B1EA1F77C4B7007760F8 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4222B1E91F77C4B7007760F8 /* UIFontExtensionsTest.swift */; }; + 4222B1EB1F77C4D8007760F8 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */; }; + 4222B1EC1F77C4E1007760F8 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */; }; + 4222B1ED1F77C4E8007760F8 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */; }; + 4222B1EE1F77C4F9007760F8 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4222B1E91F77C4B7007760F8 /* UIFontExtensionsTest.swift */; }; + 4222B1EF1F77C501007760F8 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4222B1E91F77C4B7007760F8 /* UIFontExtensionsTest.swift */; }; + 425ADF231F7783CC000E0462 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -485,6 +492,8 @@ 07DFA3D61F13818700D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07DFA3DF1F13825700D0C644 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/Info.plist; sourceTree = ""; }; 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SwifterSwift.h; path = Sources/SwifterSwift.h; sourceTree = ""; }; + 4222B1E91F77C4B7007760F8 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; + 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -631,6 +640,7 @@ 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */, 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */, 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */, + 425ADF221F7783CC000E0462 /* UIFontExtensions.swift */, 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */, 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */, 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */, @@ -731,6 +741,7 @@ 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */, 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */, 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */, + 4222B1E91F77C4B7007760F8 /* UIFontExtensionsTest.swift */, 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */, 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */, 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */, @@ -1127,6 +1138,7 @@ 0743F3CA1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, 0743F3E51F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, 0743F41E1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, + 4222B1EA1F77C4B7007760F8 /* UIFontExtensionsTest.swift in Sources */, 0743F4061F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, 0743F4211F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, 0743F3D91F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, @@ -1177,6 +1189,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4222B1EE1F77C4F9007760F8 /* UIFontExtensionsTest.swift in Sources */, 0743F3CB1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, 0743F3E61F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, 0743F41F1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, @@ -1230,6 +1243,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4222B1EF1F77C501007760F8 /* UIFontExtensionsTest.swift in Sources */, 0743F3CC1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, 0743F3E71F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, 0743F4201F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, @@ -1288,6 +1302,7 @@ 0743F3061F611B63008386F7 /* CollectionExtensions.swift in Sources */, 0743F3021F611B63008386F7 /* CharacterExtensions.swift in Sources */, 0743F2EE1F611B63008386F7 /* URLRequestExtensions.swift in Sources */, + 425ADF231F7783CC000E0462 /* UIFontExtensions.swift in Sources */, 0743F2DA1F611B63008386F7 /* DateExtensions.swift in Sources */, 0743F2D21F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, 0743F3661F611B63008386F7 /* UISliderExtensions.swift in Sources */, @@ -1342,6 +1357,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4222B1ED1F77C4E8007760F8 /* UIFontExtensions.swift in Sources */, 0743F2B71F611B63008386F7 /* NSColorExtensions.swift in Sources */, 0743F3071F611B63008386F7 /* CollectionExtensions.swift in Sources */, 0743F3031F611B63008386F7 /* CharacterExtensions.swift in Sources */, @@ -1379,6 +1395,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4222B1EC1F77C4E1007760F8 /* UIFontExtensions.swift in Sources */, 0743F34C1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, 0743F36C1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, 0743F3081F611B63008386F7 /* CollectionExtensions.swift in Sources */, @@ -1438,6 +1455,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4222B1EB1F77C4D8007760F8 /* UIFontExtensions.swift in Sources */, 0743F34D1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, 0743F36D1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, 0743F3091F611B63008386F7 /* CollectionExtensions.swift in Sources */, diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift new file mode 100644 index 000000000..5cf258f75 --- /dev/null +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -0,0 +1,24 @@ +// +// UIFontExtensionsTest.swift +// SwifterSwift +// +// Created by Benjamin Meyer on 9/16/17. +// +#if os(iOS) || os(tvOS) || os(watchOS) +import XCTest +@testable import SwifterSwift +class UIFontExtension: XCTestCase { + func testMonospacedDigitFont() { + let font = UIFont.preferredFont(forTextStyle: .body) + let monoFont = font.asMonospacedDigitFont() + let attributes: [[String: Int]] = monoFont.fontDescriptor.fontAttributes[UIFontDescriptorFeatureSettingsAttribute] as! [[String: Int]] + XCTAssertEqual(attributes[0][UIFontFeatureTypeIdentifierKey], kNumberSpacingType) + XCTAssertEqual(attributes[0][UIFontFeatureSelectorIdentifierKey], kMonospacedNumbersSelector) + XCTAssertEqual(font.fontName, monoFont.fontName) + XCTAssertEqual(font.familyName, monoFont.familyName) + XCTAssertEqual(font.lineHeight, monoFont.lineHeight) + } +} + +#endif + From 69c3786f16c384ba24fefbd63b5814ca470802e1 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 27 Sep 2017 09:42:14 +0300 Subject: [PATCH 022/201] V4.0.0 (#251) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .swift-version | 2 +- .travis.yml | 33 +- Examples/Examples.md | 22 +- README.md | 36 +- .../Extensions/AppKit/NSViewExtensions.swift | 6 +- .../Deprecated/SwifterSwiftDeprecated.swift | 117 - .../Foundation/DataExtensions.swift | 8 - .../Foundation/DateExtensions.swift | 133 +- .../Deprecated/FoundationDeprecated.swift | 177 - .../NSAttributedStringExtensions.swift | 14 +- .../Foundation/URLRequestExtensions.swift | 1 - .../Foundation/UserDefaultsExtensions.swift | 1 - .../SwiftStdlib/ArrayExtensions.swift | 33 +- .../SwiftStdlib/CollectionExtensions.swift | 6 +- .../SwiftStdlib/DictionaryExtensions.swift | 3 +- .../SwiftStdlib/FloatingPointExtensions.swift | 1 + .../SwiftStdlib/IntExtensions.swift | 63 +- .../SwiftStdlib/SignedIntegerExtensions.swift | 6 +- .../SwiftStdlib/SignedNumericExtensions.swift | 1 + .../SwiftStdlib/StringExtensions.swift | 272 +- Sources/Extensions/SwifterSwift.swift | 53 +- .../UIKit/Deprecated/UIKitDeprecated.swift | 51 - .../UIKit/UICollectionViewExtensions.swift | 27 +- .../Extensions/UIKit/UIColorExtensions.swift | 52 +- .../UIKit/UINavigationBarExtensions.swift | 10 +- .../UINavigationControllerExtensions.swift | 2 +- .../UIKit/UISearchBarExtensions.swift | 17 +- .../Extensions/UIKit/UITabBarExtensions.swift | 4 +- .../UIKit/UITableViewExtensions.swift | 28 +- .../UIKit/UITextFieldExtensions.swift | 4 +- .../Extensions/UIKit/UIViewExtensions.swift | 51 +- .../UIKit/UIWebViewExtensions.swift | 32 - Sources/Info.plist | 4 +- SwifterSwift.podspec | 37 +- SwifterSwift.xcodeproj/project.pbxproj | 2866 ++++++++--------- .../xcschemes/SwifterSwift iOSTests.xcscheme | 58 - .../SwifterSwift macOSTests.xcscheme | 58 - .../xcschemes/SwifterSwift tvOSTests.xcscheme | 58 - ...iOS.xcscheme => SwifterSwift-iOS.xcscheme} | 22 +- ...S.xcscheme => SwifterSwift-macOS.xcscheme} | 22 +- ...OS.xcscheme => SwifterSwift-tvOS.xcscheme} | 22 +- ...xcscheme => SwifterSwift-watchOS.xcscheme} | 12 +- .../FoundationTests/DataExtensionsTests.swift | 5 - .../FoundationTests/DateExtensionsTests.swift | 80 +- .../NSAttributedStringExtensionsTests.swift | 124 +- .../URLRequestExtensionsTests.swift | 1 - .../UserDefaultsExtensionsTests.swift | 1 - Tests/Info.plist | 2 +- Tests/Resources/TestStoryboard.storyboard | 5 +- .../SwiftStdlibTests/IntExtensionsTests.swift | 11 - .../StringExtensionsTests.swift | 30 +- Tests/SwifterSwiftTests.swift | 1 - Tests/UIKitTests/UIColorExtensionsTests.swift | 58 +- .../UIImageViewExtensionsTests.swift | 99 +- .../UINavigationBarExtensionTests.swift | 12 +- ...INavigationControllerExtensionsTests.swift | 20 +- .../UIKitTests/UISliderExtensionsTests.swift | 10 +- .../UITableViewExtensionsTests.swift | 4 +- .../UITextFieldExtensionsTests.swift | 4 +- .../UIViewControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UIViewExtensionsTests.swift | 1 - .../UIKitTests/UIWebViewExtensionsTests.swift | 69 - Tests/build.sh | 36 - 64 files changed, 2056 insertions(+), 2946 deletions(-) delete mode 100644 Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift delete mode 100644 Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift delete mode 100644 Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift delete mode 100644 Sources/Extensions/UIKit/UIWebViewExtensions.swift delete mode 100644 SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme delete mode 100644 SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme delete mode 100644 SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme rename SwifterSwift.xcodeproj/xcshareddata/xcschemes/{SwifterSwift iOS.xcscheme => SwifterSwift-iOS.xcscheme} (83%) rename SwifterSwift.xcodeproj/xcshareddata/xcschemes/{SwifterSwift macOS.xcscheme => SwifterSwift-macOS.xcscheme} (83%) rename SwifterSwift.xcodeproj/xcshareddata/xcschemes/{SwifterSwift tvOS.xcscheme => SwifterSwift-tvOS.xcscheme} (83%) rename SwifterSwift.xcodeproj/xcshareddata/xcschemes/{SwifterSwift watchOS.xcscheme => SwifterSwift-watchOS.xcscheme} (88%) delete mode 100644 Tests/UIKitTests/UIWebViewExtensionsTests.swift delete mode 100644 Tests/build.sh diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c0db07f92..356340151 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,7 @@ - [ ] I checked the [**Contributing Guidelines**](https://github.com/SwifterSwift/SwifterSwift/blob/master/CONTRIBUTING.md) before creating this request. -- [ ] New extensions are written in Swift 3. +- [ ] New extensions are written in Swift 4. - [ ] New extensions support iOS 8.0+ / tvOS 9.0+ / macOS 10.10+ / watchOS 2.0+. - [ ] I have added tests for new extensions, and they passed. - [ ] All extensions have a **clear** comments explaining their functionality, all parameters and return type in English. diff --git a/.swift-version b/.swift-version index a3ec5a4bd..5186d0706 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.2 +4.0 diff --git a/.travis.yml b/.travis.yml index ac8d9fcde..105fa7370 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,30 @@ -osx_image: xcode9 language: objective-c +osx_image: xcode9 + +env: + global: + - PROJECT='SwifterSwift.xcodeproj' + - IOS_SCHEME='SwifterSwift-iOS' + - TVOS_SCHEME='SwifterSwift-tvOS' + - WATCHOS_SCHEME='SwifterSwift-watchOS' + - MACOS_SCHEME='SwifterSwift-macOS' + - IOS_DESTINATION='platform=iOS Simulator,name=iPhone 6S' + - TVOS_DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p' + - WATCHOS_DESTINATION='name=Apple Watch - 42mm' + - MACOS_DESTINATION='platform=OS X' + + before_install: - - brew update - - brew outdated xctool || brew upgrade xctool - - gem install xcpretty -script: sh Tests/build.sh /tmp/SwifterSwift + - brew update + - brew outdated xctool || brew upgrade xctool + - gem install xcpretty + +script: + - set -o pipefail + - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty + - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty + - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty + - xcodebuild clean build -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty + after_success: - - bash <(curl -s https://codecov.io/bash) -D /tmp/SwifterSwift + - bash <(curl -s https://codecov.io/bash) diff --git a/Examples/Examples.md b/Examples/Examples.md index 7d3bc4acd..a558f4a84 100644 --- a/Examples/Examples.md +++ b/Examples/Examples.md @@ -14,7 +14,7 @@ Here are some examples: ["h", "e", "l", "l", "o"].indexes(of: "l") -> [2, 3] // Shuffle an array -["h", "e", "l", "l", "o"].shuffled -> ["e", "l", "o", "l", "h"] +["h", "e", "l", "l", "o"].shuffled() -> ["e", "l", "o", "l", "h"] // Return random item from an array [1, 2, 3, 4, 5].randomItem -> 3 @@ -53,8 +53,8 @@ Date().iso8601String -> "2016-08-23T21:26:15.287Z" let date = Date(iso8601String: "2016-08-23T21:26:15.287Z") // Create date from DateComponents -let date = Date(year: 2016, month: 8, day: 15) // other components set to current -let date = Date(hour: 9, minute: 18, second: 1) // other components set to current +let date = Date(year: 2016, month: 8, day: 15) // other components are set to current by default. +let date = Date(hour: 9, minute: 18, second: 1) // other components are set to current by default. // Represent date as a string with ease Date().dateString(ofStyle: .medium) -> "Aug 26, 2016" @@ -191,10 +191,6 @@ Int.randomBetween(min: 1, max: 10) -> 6 --- -## UIKit Extensions - -SwifterSwift has many great extensions for UIKit also: - ### UIColor Extensions: ```swift @@ -213,9 +209,6 @@ UIColor.blend(UIColor.red, intensity1: 0.5, with: UIColor.green, intensity2: 0.3 // Return hexadecimal value string UIColor.red.hexString -> "#FF0000" -// Return short hexadecimal value string -UIColor(hex: #00ffff) -> "#0FF" - // Use Google Material design colors with ease let indigo = UIColor.material.indigo @@ -345,7 +338,7 @@ imageView.blur(withStyle: .light) ```swift // Change navigation bar font and color -navbar.setTitleFont(UIFont, with color: UIColor.black) +navbar.setTitleFont(UIFont.systemFont(ofSize: 10), with color: UIColor.black) // and many others! ``` @@ -383,15 +376,8 @@ tableView.scrollToTop(animated: true) // and many others! ``` - --- - -## Cocoa Extensions - -SwifterSwift has many great extensions for Cocoa too: - - ### CGPoint Extensions ```swift diff --git a/README.md b/README.md index 63fda82fa..a58405257 100755 --- a/README.md +++ b/README.md @@ -3,38 +3,34 @@

    [![Build Status](https://api.travis-ci.org/SwifterSwift/SwifterSwift.svg?branch=master)](https://travis-ci.org/SwifterSwift/SwifterSwift) +[![Platforms](https://img.shields.io/cocoapods/p/SwifterSwift.svg?style=flat)](https://github.com/SwifterSwift/swifterSwift) [![Cocoapods](https://img.shields.io/cocoapods/v/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) [![codecov](https://codecov.io/gh/SwifterSwift/SwifterSwift/branch/master/graph/badge.svg)](https://codecov.io/gh/SwifterSwift/SwifterSwift) [![docs](http://swifterswift.com/docs/badge.svg)](http://swifterswift.com/docs) [![CocoaPods](https://img.shields.io/cocoapods/dt/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) [![CocoaPods](https://img.shields.io/cocoapods/dm/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) -[![Platform](https://img.shields.io/cocoapods/p/SwifterSwift.svg?style=flat)](https://github.com/SwifterSwift/swifterSwift) -[![Swift](https://img.shields.io/badge/Swift-3.2-orange.svg)](https://swift.org) -[![Xcode](https://img.shields.io/badge/Xcode-8.3-blue.svg)](https://developer.apple.com/xcode) +[![Swift](https://img.shields.io/badge/Swift-4.0-orange.svg)](https://swift.org) +[![Xcode](https://img.shields.io/badge/Xcode-9.0-blue.svg)](https://developer.apple.com/xcode) [![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) [![Slack Channel](http://slack.swifterswift.com/badge.svg)](http://slack.swifterswift.com/) -SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types like SwiftStdlib, Foundation, UIKit, AppKit and many other classes. –over 500 in 1– for iOS, macOS, tvOS and watchOS. ---- +SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### ⚠️ To use with **Swift 3 / Xcode 8.x** please ensure you are using [**`v3.1.1`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1). -### ⚠️ To use with **Swift 3.2 / Xcode 9.x** please ensure you are using [**`v3.2`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.2.0). - -### ⚠️ To use with **Swift 4 / Xcode 9.x** please ensure you are using the [**`swift-4`**](https://github.com/SwifterSwift/SwifterSwift/tree/swift-4) branch. - ---- +### [Whats New in v4.0.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v400) +## Requirements: +- **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ +- Xcode 9.0+ +- Swift 4.0+ -### [Whats New in v3.2.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v320) -## Requirements: -- **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ -- Xcode 8.0+ -- Swift 3.0+ +## Looking for Swift 3 +- To use with **Swift 3 / Xcode 8.x** please ensure you are using [**`v3.1.1`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1). +- To use with **Swift 3.2 / Xcode 9.x** please ensure you are using [**`v3.2.0`**](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.2.0). @@ -70,7 +66,7 @@ SwifterSwift is a collection of **over 500 native Swift 3 extensions**, with han

    To integrate SwifterSwift into your Xcode project using Carthage, specify it in your Cartfile:

    -
    github "SwifterSwift/SwifterSwift" ~> 3.0
    +
    github "SwifterSwift/SwifterSwift" ~> 4.0
     
    @@ -86,7 +82,7 @@ let package = Package( name: "YOUR_PROJECT_NAME", targets: [], dependencies: [ - .Package(url: "https://github.com/SwifterSwift/SwifterSwift.git", majorVersion: 3), + .Package(url: "https://github.com/SwifterSwift/SwifterSwift.git", majorVersion: 4), ] )
    @@ -120,7 +116,7 @@ let package = Package(
  • Int extensions
  • Optional extensions
  • SignedInteger extensions
  • -
  • SignedNumber extensions
  • +
  • SignedNumeric extensions
  • String extensions
  • @@ -213,7 +209,7 @@ let package = Package( ## How cool is this? -SwifterSwift is a library of **over 500 properties and methods**, designed to extend Swift's functionality and productivity, staying faithful to the original API design guidelines of Swift 3. +SwifterSwift is a library of **over 500 properties and methods**, designed to extend Swift's functionality and productivity, staying faithful to the original API design guidelines of Swift. Check [Examples.md](https://github.com/SwifterSwift/SwifterSwift/tree/master/Examples/Examples.md) for some cool examples! diff --git a/Sources/Extensions/AppKit/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift index 1fa2a438c..42f3f946d 100644 --- a/Sources/Extensions/AppKit/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -16,8 +16,7 @@ public extension NSView { /// SwifterSwift: Border color of view; also inspectable from Storyboard. public var borderColor: NSColor? { get { - guard let color = layer?.borderColor else { return nil } - return NSColor(cgColor: color) + return layer?.borderColor?.nsColor } set { wantsLayer = true @@ -64,8 +63,7 @@ public extension NSView { /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. public var shadowColor: NSColor? { get { - guard let color = layer?.shadowColor else { return nil } - return NSColor(cgColor: color) + return layer?.shadowColor?.nsColor } set { wantsLayer = true diff --git a/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift b/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift deleted file mode 100644 index ff949fb98..000000000 --- a/Sources/Extensions/Deprecated/SwifterSwiftDeprecated.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// SwifterSwiftDeprecated.swift -// SwifterSwift -// -// Created by Omar Albeik on 9/5/17. -// -// - -import Foundation - -// MARK: - Preperties -public extension SwifterSwift { - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard instead") - /// SwifterSwift: Shared instance of standard UserDefaults (read-only). - public static var userDefaults: UserDefaults { - return UserDefaults.standard - } - -} - - -// MARK: - Methods -public extension SwifterSwift { - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.object(forKey: _) instead") - /// SwifterSwift: Object from UserDefaults. - /// - /// - Parameter forKey: key to find object for. - /// - Returns: Any object for key (if exists). - public static func object(forKey: String) -> Any? { - return UserDefaults.standard.object(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.string(forKey: _) instead") - /// SwifterSwift: String from UserDefaults. - /// - /// - Parameter forKey: key to find string for. - /// - Returns: String object for key (if exists). - public static func string(forKey: String) -> String? { - return UserDefaults.standard.string(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.integer(forKey: _) instead") - /// SwifterSwift: Integer from UserDefaults. - /// - /// - Parameter forKey: key to find integer for. - /// - Returns: Int number for key (if exists). - public static func integer(forKey: String) -> Int? { - return UserDefaults.standard.integer(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.double(forKey: _) instead") - /// SwifterSwift: Double from UserDefaults. - /// - /// - Parameter forKey: key to find double for. - /// - Returns: Double number for key (if exists). - public static func double(forKey: String) -> Double? { - return UserDefaults.standard.double(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.data(forKey: _) instead") - /// SwifterSwift: Data from UserDefaults. - /// - /// - Parameter forKey: key to find data for. - /// - Returns: Data object for key (if exists). - public static func data(forKey: String) -> Data? { - return UserDefaults.standard.data(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.bool(forKey: _) instead") - /// SwifterSwift: Bool from UserDefaults. - /// - /// - Parameter forKey: key to find bool for. - /// - Returns: Bool object for key (if exists). - public static func bool(forKey: String) -> Bool? { - return UserDefaults.standard.bool(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.array(forKey: _) instead") - /// SwifterSwift: Array from UserDefaults. - /// - /// - Parameter forKey: key to find array for. - /// - Returns: Array of Any objects for key (if exists). - public static func array(forKey: String) -> [Any]? { - return UserDefaults.standard.array(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.dictionary(forKey: _) instead") - /// SwifterSwift: Dictionary from UserDefaults. - /// - /// - Parameter forKey: key to find dictionary for. - /// - Returns: ictionary of [String: Any] for key (if exists). - public static func dictionary(forKey: String) -> [String: Any]? { - return UserDefaults.standard.dictionary(forKey: forKey) - } - - @available(*, deprecated: 3.2.0, message: "Use SwifterSwift's UserDefaults.standard.float(forKey: _) instead") - /// SwifterSwift: Float from UserDefaults. - /// - /// - Parameter forKey: key to find float for. - /// - Returns: Float number for key (if exists). - public static func float(forKey: String) -> Float? { - return UserDefaults.standard.object(forKey: forKey) as? Float - } - - @available(*, deprecated: 3.2.0, message: "Use Apple's UserDefaults.standard.setValue(_, forKey: _) instead") - /// SwifterSwift: Save an object to UserDefaults. - /// - /// - Parameters: - /// - value: object to save in UserDefaults. - /// - forKey: key to save object for. - public static func set(_ value: Any?, forKey: String) { - UserDefaults.standard.set(value, forKey: forKey) - } - -} diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index 18c714524..a6da5b70a 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -16,14 +16,6 @@ // MARK: - Properties public extension Data { - /// SwifterSwift: NSAttributedString from Data (if applicable). - public var attributedString: NSAttributedString? { - // http://stackoverflow.com/questions/39248092/nsattributedstring-extension-in-swift-3 - return try? NSAttributedString(data: self, options: [ - NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, - NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil) - } - /// SwifterSwift: Return data as an array of bytes. public var bytes: [UInt8] { //http://stackoverflow.com/questions/38097710/swift-3-changes-for-getbytes-method diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index dc26143c3..4592e6de2 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -53,7 +53,6 @@ public extension Date { } /// SwifterSwift: Quarter. - /// public var quarter: Int { return Calendar.current.component(.quarter, from: self) } @@ -74,41 +73,41 @@ public extension Date { return Calendar.current.component(.weekOfMonth, from: self) } - /// SwifterSwift: Year. + /// SwifterSwift: Year. /// /// Date().year -> 2017 /// /// var someDate = Date() /// someDate.year = 2000 // sets someDate's year to 2000 /// - public var year: Int { - get { - return Calendar.current.component(.year, from: self) - } - set { - if let date = Calendar.current.date(bySetting: .year, value: newValue, of: self) { - self = date - } - } - } - - /// SwifterSwift: Month. + public var year: Int { + get { + return Calendar.current.component(.year, from: self) + } + set { + if let date = Calendar.current.date(bySetting: .year, value: newValue, of: self) { + self = date + } + } + } + + /// SwifterSwift: Month. /// /// Date().month -> 1 /// /// var someDate = Date() /// someDate.year = 10 // sets someDate's month to 10. /// - public var month: Int { - get { - return Calendar.current.component(.month, from: self) - } - set { - if let date = Calendar.current.date(bySetting: .month, value: newValue, of: self) { - self = date - } - } - } + public var month: Int { + get { + return Calendar.current.component(.month, from: self) + } + set { + if let date = Calendar.current.date(bySetting: .month, value: newValue, of: self) { + self = date + } + } + } /// SwifterSwift: Day. /// @@ -127,21 +126,21 @@ public extension Date { } } } - - /// SwifterSwift: Weekday. + + /// SwifterSwift: Weekday. /// /// Date().weekOfMonth -> 5 // fifth day in the current week. /// - public var weekday: Int { - get { - return Calendar.current.component(.weekday, from: self) - } - set { - if let date = Calendar.current.date(bySetting: .weekday, value: newValue, of: self) { - self = date - } - } - } + public var weekday: Int { + get { + return Calendar.current.component(.weekday, from: self) + } + set { + if let date = Calendar.current.date(bySetting: .weekday, value: newValue, of: self) { + self = date + } + } + } /// SwifterSwift: Hour. /// @@ -213,7 +212,6 @@ public extension Date { } /// SwifterSwift: Milliseconds. - /// public var millisecond: Int { get { return Calendar.current.component(.nanosecond, from: self) / 1000000 @@ -267,34 +265,29 @@ public extension Date { } /// SwifterSwift: Check if date is within a weekend period. - /// public var isInWeekend: Bool { return Calendar.current.isDateInWeekend(self) } - - /// SwifterSwift: Check if date is within a weekday period. - /// - public var isInWeekday: Bool { - return !Calendar.current.isDateInWeekend(self) - } - - /// SwifterSwift: Check if date is within the current week. - /// - public var isInThisWeek: Bool { - return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) - } - - /// SwifterSwift: Check if date is within the current month. - /// - public var isInThisMonth: Bool { - return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) - } - - /// SwifterSwift: Check if date is within the current year. - /// - public var isInThisYear: Bool { - return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) - } + + /// SwifterSwift: Check if date is within a weekday period. + public var isInWeekday: Bool { + return !Calendar.current.isDateInWeekend(self) + } + + /// SwifterSwift: Check if date is within the current week. + public var isInThisWeek: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) + } + + /// SwifterSwift: Check if date is within the current month. + public var isInThisMonth: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) + } + + /// SwifterSwift: Check if date is within the current year. + public var isInThisYear: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) + } /// SwifterSwift: ISO8601 string of format (yyyy-MM-dd'T'HH:mm:ss.SSS) from date. /// @@ -709,21 +702,7 @@ public extension Date { public func daysSince(_ date: Date) -> Double { return self.timeIntervalSince(date)/(3600*24) } - - /// SwifterSwift: check if a date is between two other dates - /// - /// - Parameter startDate: start date to compare self to. - /// - Parameter endDate: endDate date to compare self to. - /// - Parameter includeBounds: true if the start and end date should be included (default is false) - /// - Returns: true if the date is between the two given dates. - public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool { - if includeBounds { - return startDate.compare(self).rawValue * self.compare(endDate).rawValue >= 0 - } else { - return startDate.compare(self).rawValue * self.compare(endDate).rawValue > 0 - } - } - + } diff --git a/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift b/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift deleted file mode 100644 index e8acc0c4e..000000000 --- a/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift +++ /dev/null @@ -1,177 +0,0 @@ -// -// FoundationDeprecated.swift -// SwifterSwift -// -// Created by Omar Albeik on 7/21/17. -// -// - -import Foundation - - -// MARK: - Deprecated String -public extension String { - - @available(*, deprecated: 3.1.0, message: "Use Apple's replacingOccurrences(of: substring, with: newString) instead") - /// SwifterSwift: String by replacing part of string with another string. - /// - /// "#number# items".replacing("#number#", with: "10") -> "10 items" - /// - /// - Parameters: - /// - substring: old substring to find and replace. - /// - newString: new string to insert in old string place. - /// - Returns: string after replacing substring with newString. - public func replacing(_ substring: String, with newString: String) -> String { - return replacingOccurrences(of: substring, with: newString) - } - - @available(*, deprecated: 3.1.0, message: "Use firstCharacterAsString instead", renamed: "firstCharacterAsString") - /// SwifterSwift: First character of string (if applicable). - /// - /// "Hello".firstCharacter -> Optional("H") - /// "".firstCharacter -> nil - /// - public var firstCharacter: String? { - guard let first = characters.first else { - return nil - } - return String(first) - } - - @available(*, deprecated: 3.1.0, message: "Use lastCharacterAsString instead", renamed: "lastCharacterAsString") - /// SwifterSwift: Last character of string (if applicable). - /// - /// "Hello".lastCharacter -> Optional("o") - /// "".lastCharacter -> nil - /// - public var lastCharacter: String? { - guard let last = characters.last else { - return nil - } - return String(last) - } - - @available(*, deprecated: 3.1.0, message: "Use double() instead", renamed: "double(locale:)") - /// SwifterSwift: Double value from string (if applicable). - /// - /// "20".double -> 20.0 - /// - public var double: Double? { - let formatter = NumberFormatter() - return formatter.number(from: self) as? Double - } - - @available(*, deprecated: 3.1.0, message: "Use float() instead", renamed: "float(locale:)") - /// SwifterSwift: Float value from string (if applicable). - /// - /// "21".float -> 21.0 - /// - public var float: Float? { - let formatter = NumberFormatter() - return formatter.number(from: self) as? Float - } - - @available(*, deprecated: 3.1.0, message: "Use Float32(string) instead") - /// SwifterSwift: Float32 value from string (if applicable). - /// - /// "21.86".float32 -> 21.86 - /// - public var float32: Float32? { - let formatter = NumberFormatter() - return formatter.number(from: self) as? Float32 - } - - @available(*, deprecated: 3.1.0, message: "Use Float64(string) instead") - /// SwifterSwift: Float64 value from string (if applicable). - /// - /// "23.45".float64 -> 23.45 - /// - public var float64: Float64? { - let formatter = NumberFormatter() - return formatter.number(from: self) as? Float64 - } - - @available(*, deprecated: 3.1.0, message: "Use Int16(string) instead") - /// SwifterSwift: Int16 value from string (if applicable). - /// - /// "101".int16 -> 101 - /// - public var int16: Int16? { - return Int16(self) - } - - @available(*, deprecated: 3.1.0, message: "Use Int32(string) instead") - /// SwifterSwift: Int32 value from string (if applicable). - /// - /// "101".int32 -> 101 - /// - public var int32: Int32? { - return Int32(self) - } - - @available(*, deprecated: 3.1.0, message: "Use Int64(string) instead") - /// SwifterSwift: Int64 value from string (if applicable). - /// - /// "101".int64 -> 101 - /// - public var int64: Int64? { - return Int64(self) - } - - @available(*, deprecated: 3.1.0, message: "Use Int8(string) instead") - /// SwifterSwift: Int8 value from string (if applicable). - /// - /// "101".int8 -> 101 - /// - public var int8: Int8? { - return Int8(self) - } - - @available(*, deprecated: 3.1.0, message: "Use subscript(safe i) instead") - /// SwifterSwift: Safely subscript string with index. - /// - /// "Hello World!"[3] -> "l" - /// "Hello World!"[20] -> nil - /// - /// - Parameter i: index. - public subscript(i: Int) -> String? { - guard i >= 0 && i < characters.count else { - return nil - } - return String(self[index(startIndex, offsetBy: i)]) - } - - @available(*, deprecated: 3.1.0, message: "Use subscript(safe range) instead") - /// SwifterSwift: Safely subscript string within a half-open range. - /// - /// "Hello World!"[6..<11] -> "World" - /// "Hello World!"[21..<110] -> nil - /// - /// - Parameter range: Half-open range. - public subscript(range: CountableRange) -> String? { - guard let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) else { - return nil - } - guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) else { - return nil - } - return self[lowerIndex.. "World!" - /// "Hello World!"[21...110] -> nil - /// - /// - Parameter range: Closed range. - public subscript(range: ClosedRange) -> String? { - guard let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) else { - return nil - } - guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound + 1, limitedBy: endIndex) else { - return nil - } - return self[lowerIndex.. NSAttributedString { + fileprivate func applying(attributes: [NSAttributedStringKey: Any]) -> NSAttributedString { let copy = NSMutableAttributedString(attributedString: self) let range = (string as NSString).range(of: string) copy.addAttributes(attributes, range: range) @@ -63,7 +63,7 @@ public extension NSAttributedString { /// - Parameter color: text color. /// - Returns: a NSAttributedString colored with given color. public func colored(with color: NSColor) -> NSAttributedString { - return applying(attributes: [NSForegroundColorAttributeName: color]) + return applying(attributes: [.foregroundColor: color]) } #else /// SwifterSwift: Add color to NSAttributedString. @@ -71,7 +71,7 @@ public extension NSAttributedString { /// - Parameter color: text color. /// - Returns: a NSAttributedString colored with given color. public func colored(with color: UIColor) -> NSAttributedString { - return applying(attributes: [NSForegroundColorAttributeName: color]) + return applying(attributes: [.foregroundColor: color]) } #endif } diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift index 20e05d80f..cda4f1665 100644 --- a/Sources/Extensions/Foundation/URLRequestExtensions.swift +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 9/5/17. // // - import Foundation diff --git a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift index 1367e4170..6c3d8519c 100644 --- a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift +++ b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 9/5/17. // // - import Foundation diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index b5b0d4c5b..ba943f923 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -5,6 +5,7 @@ // Created by Omar Albeik on 8/5/16. // Copyright © 2016 Omar Albeik. All rights reserved. // + import Foundation @@ -17,9 +18,9 @@ public extension Array where Element: Numeric { /// /// - Returns: sum of the array's elements. public func sum() -> Element { - var total: Element = 0 - forEach { total += $0 } - return total + var total: Element = 0 + forEach { total += $0 } + return total } } @@ -34,12 +35,12 @@ public extension Array where Element: FloatingPoint { /// /// - Returns: average of the array's elements. public func average() -> Element { - guard isEmpty == false else { return 0 } - var total: Element = 0 - forEach { total += $0 } - return total / Element(count) + guard isEmpty == false else { return 0 } + var total: Element = 0 + forEach { total += $0 } + return total / Element(count) } - + } @@ -353,12 +354,12 @@ public extension Array { return slices } - /// SwifterSwift: Group the elements of the array in a dictionary. + /// SwifterSwift: Group the elements of the array in a dictionary. /// /// [0, 2, 5, 4, 7].groupByKey { $0%2 ? "evens" : "odds" } -> [ "evens" : [0, 2, 4], "odds" : [5, 7] ] /// - /// - Parameter getKey: Clousure to define the key for each element. - /// - Returns: A dictionary with values grouped with keys. + /// - Parameter getKey: Clousure to define the key for each element. + /// - Returns: A dictionary with values grouped with keys. public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { var group : [K: [Element]] = [:] for value in self { @@ -368,14 +369,14 @@ public extension Array { return group } - /// SwifterSwift: Returns a new rotated array by the given places. + /// SwifterSwift: Returns a new rotated array by the given places. /// /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - /// - Returns: The new rotated array + /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Returns: The new rotated array public func rotated(by places: Int) -> [Element] { //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate guard places != 0 && places < count else { @@ -396,13 +397,13 @@ public extension Array { return array } - /// SwifterSwift: Rotate the array by the given places. + /// SwifterSwift: Rotate the array by the given places. /// /// [1, 2, 3, 4].rotate(by: 1) -> [4,1,2,3] /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. public mutating func rotate(by places: Int) { self = rotated(by: places) } diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index ec425fa90..609918dc5 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -38,6 +38,10 @@ public extension Collection { } } +} + +public extension Collection { + /// SwifterSwift: Safe protects the array from out of bounds by use of optional. /// /// let arr = [1, 2, 3, 4, 5] @@ -54,7 +58,7 @@ public extension Collection { public extension Collection where Index == Int, IndexDistance == Int { /// SwifterSwift: Random item from array. - public var randomItem: Generator.Element { + public var randomItem: Iterator.Element { let index = Int(arc4random_uniform(UInt32(count))) return self[index] } diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index a6366826d..ed5c0d52a 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -77,8 +77,7 @@ public extension Dictionary { } let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) - guard let data = jsonData else { return nil } - return String(data: data, encoding: .utf8) + return jsonData?.string(encoding: .utf8) } /// SwifterSwift: Count dictionary entries that where function returns true. diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index fb162b452..7eafaca34 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -5,6 +5,7 @@ // Created by Omar Albeik on 7/23/17. // // + import Foundation diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 7a35044b8..3d618e860 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -33,12 +33,6 @@ public extension Int { return Double(self) * 180 / Double.pi } - /// SwifterSwift: Number of digits of integer value. - public var digitsCount: Int { - return String(self).characters.count - } - - /// SwifterSwift: UInt. public var uInt: UInt { return UInt(self) @@ -123,35 +117,36 @@ public extension Int { } return true } + + /// SwifterSwift: Roman numeral string from integer (if applicable). + /// + /// 10.romanNumeral() -> "X" + /// + /// - Returns: The roman numeral string. + public func romanNumeral() -> String? { + // https://gist.github.com/kumo/a8e1cb1f4b7cff1548c7 + guard self > 0 else { // there is no roman numerals for 0 or negative numbers + return nil + } + let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] + let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] + + var romanValue = "" + var startingValue = self + + for (index, romanChar) in romanValues.enumerated() { + let arabicValue = arabicValues[index] + let div = startingValue / arabicValue + if (div > 0) { + for _ in 0..
    "X" - /// - /// - Returns: The roman numeral string. - public func romanNumeral() -> String? { - // https://gist.github.com/kumo/a8e1cb1f4b7cff1548c7 - guard self > 0 else { // there is no roman numerals for 0 or negative numbers - return nil - } - let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] - let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] - - var romanValue = "" - var startingValue = self - - for (index, romanChar) in romanValues.enumerated() { - let arabicValue = arabicValues[index] - let div = startingValue / arabicValue - if (div > 0) { - for _ in 0..
    true - /// - public var isValidFileUrl: Bool { + /// + /// "file://Documents/file.txt".isValidFileUrl -> true + /// + public var isValidFileUrl: Bool { return URL(string: self)?.isFileURL ?? false } @@ -331,106 +328,106 @@ public extension String { // MARK: - Methods public extension String { - /// Float value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional Float value from given string. - public func float(locale: Locale = .current) -> Float? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? Float - } - - /// Double value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional Double value from given string. - public func double(locale: Locale = .current) -> Double? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? Double - } - - /// CGFloat value from string (if applicable). - /// - /// - Parameter locale: Locale (default is Locale.current) - /// - Returns: Optional CGFloat value from given string. - public func cgFloat(locale: Locale = .current) -> CGFloat? { - let formatter = NumberFormatter() - formatter.locale = locale - formatter.allowsFloats = true - return formatter.number(from: self) as? CGFloat - } - - /// SwifterSwift: Array of strings separated by new lines. - /// - /// "Hello\ntest".lines() -> ["Hello", "test"] - /// - /// - Returns: Strings separated by new lines. - public func lines() -> [String] { - var result = [String]() - enumerateLines { line, _ in - result.append(line) - } - return result - } - - /// SwifterSwift: The most common character in string. - /// - /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter() -> "e" - /// - /// - Returns: The most common character. - public func mostCommonCharacter() -> String { - let mostCommon = withoutSpacesAndNewLines.characters.reduce([Character: Int]()) { - var counts = $0 - counts[$1] = ($0[$1] ?? 0) + 1 - return counts - }.max { $0.1 < $1.1 }?.0 - return mostCommon?.string ?? "" - } - - /// SwifterSwift: Reversed string. - /// - /// "foo".reversed() -> "oof" - /// - /// - Returns: The reversed string. - public func reversed() -> String { - return String(characters.reversed()) - } - - /// SwifterSwift: Array with unicodes for all characters in a string. - /// - /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] - /// - /// - Returns: The unicodes for all characters in a string. - public func unicodeArray() -> [Int] { - return unicodeScalars.map({ $0.hashValue }) - } - - /// SwifterSwift: an array of all words in a string - /// - /// "Swift is amazing".words() -> ["Swift", "is", "amazing"] - /// - /// - Returns: The words contained in a string. - public func words() -> [String] { - // https://stackoverflow.com/questions/42822838 - let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) - let comps = components(separatedBy: chararacterSet) - return comps.filter { !$0.isEmpty } - } - - /// SwifterSwift: Count of words in a string. - /// - /// "Swift is amazing".wordsCount() -> 3 - /// - /// - Returns: The count of words contained in a string. - public func wordCount() -> Int { - // https://stackoverflow.com/questions/42822838 - return words().count - } - + /// Float value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional Float value from given string. + public func float(locale: Locale = .current) -> Float? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? Float + } + + /// Double value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional Double value from given string. + public func double(locale: Locale = .current) -> Double? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? Double + } + + /// CGFloat value from string (if applicable). + /// + /// - Parameter locale: Locale (default is Locale.current) + /// - Returns: Optional CGFloat value from given string. + public func cgFloat(locale: Locale = .current) -> CGFloat? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.allowsFloats = true + return formatter.number(from: self) as? CGFloat + } + + /// SwifterSwift: Array of strings separated by new lines. + /// + /// "Hello\ntest".lines() -> ["Hello", "test"] + /// + /// - Returns: Strings separated by new lines. + public func lines() -> [String] { + var result = [String]() + enumerateLines { line, _ in + result.append(line) + } + return result + } + + /// SwifterSwift: The most common character in string. + /// + /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter() -> "e" + /// + /// - Returns: The most common character. + public func mostCommonCharacter() -> String { + let mostCommon = withoutSpacesAndNewLines.characters.reduce([Character: Int]()) { + var counts = $0 + counts[$1] = ($0[$1] ?? 0) + 1 + return counts + }.max { $0.1 < $1.1 }?.0 + return mostCommon?.string ?? "" + } + + /// SwifterSwift: Reversed string. + /// + /// "foo".reversed() -> "oof" + /// + /// - Returns: The reversed string. + public func reversed() -> String { + return String(characters.reversed()) + } + + /// SwifterSwift: Array with unicodes for all characters in a string. + /// + /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] + /// + /// - Returns: The unicodes for all characters in a string. + public func unicodeArray() -> [Int] { + return unicodeScalars.map({ $0.hashValue }) + } + + /// SwifterSwift: an array of all words in a string + /// + /// "Swift is amazing".words() -> ["Swift", "is", "amazing"] + /// + /// - Returns: The words contained in a string. + public func words() -> [String] { + // https://stackoverflow.com/questions/42822838 + let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) + let comps = components(separatedBy: chararacterSet) + return comps.filter { !$0.isEmpty } + } + + /// SwifterSwift: Count of words in a string. + /// + /// "Swift is amazing".wordsCount() -> 3 + /// + /// - Returns: The count of words contained in a string. + public func wordCount() -> Int { + // https://stackoverflow.com/questions/42822838 + return words().count + } + /// SwifterSwift: Safely subscript string with index. /// /// "Hello World!"[3] -> "l" @@ -457,7 +454,7 @@ public extension String { guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) else { return nil } - return self[lowerIndex.. String { guard length > 0 else { return "" } let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - return (0.. 0 else { + public mutating func truncate(toLength length: Int, trailing: String? = "...") { + guard length > 0 else { return } - if characters.count > toLength { - self = substring(to: index(startIndex, offsetBy: toLength)) + (trailing ?? "") + if characters.count > length { + self = self[startIndex.. String { - guard 1.. String { + guard 1.. NSAttributedString { - return NSMutableAttributedString(string: self, attributes: [NSForegroundColorAttributeName: color]) + return NSMutableAttributedString(string: self, attributes: [.foregroundColor: color]) } #else /// SwifterSwift: Add color to string. @@ -928,7 +928,7 @@ public extension String { /// - Parameter color: text color. /// - Returns: a NSAttributedString versions of string colored with given color. public func colored(with color: UIColor) -> NSAttributedString { - return NSMutableAttributedString(string: self, attributes: [NSForegroundColorAttributeName: color]) + return NSMutableAttributedString(string: self, attributes: [.foregroundColor: color]) } #endif diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 374674eb7..73f45fdad 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 8/8/16. // Copyright © 2016 Omar Albeik. All rights reserved. // - #if os(macOS) import Cocoa #elseif os(watchOS) @@ -36,7 +35,7 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: StatusBar height public static var statusBarHeight: CGFloat { - return UIApplication.shared.statusBarFrame.height + return UIApplication.shared.statusBarFrame.height } #endif @@ -69,7 +68,7 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: Current battery level. public static var batteryLevel: Float { - return UIDevice.current.batteryLevel + return UIDevice.current.batteryLevel } #endif @@ -114,7 +113,7 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: Current orientation of device. public static var deviceOrientation: UIDeviceOrientation { - return currentDevice.orientation + return currentDevice.orientation } #endif @@ -150,33 +149,33 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: Check if multitasking is supported in current device. public static var isMultitaskingSupported: Bool { - return UIDevice.current.isMultitaskingSupported + return UIDevice.current.isMultitaskingSupported } #endif #if os(iOS) /// SwifterSwift: Current status bar network activity indicator state. public static var isNetworkActivityIndicatorVisible: Bool { - get { - return UIApplication.shared.isNetworkActivityIndicatorVisible - } - set { - UIApplication.shared.isNetworkActivityIndicatorVisible = newValue - } + get { + return UIApplication.shared.isNetworkActivityIndicatorVisible + } + set { + UIApplication.shared.isNetworkActivityIndicatorVisible = newValue + } } #endif #if os(iOS) /// SwifterSwift: Check if device is iPad. public static var isPad: Bool { - return UIDevice.current.userInterfaceIdiom == .pad + return UIDevice.current.userInterfaceIdiom == .pad } #endif #if os(iOS) /// SwifterSwift: Check if device is iPhone. public static var isPhone: Bool { - return UIDevice.current.userInterfaceIdiom == .phone + return UIDevice.current.userInterfaceIdiom == .phone } #endif @@ -200,12 +199,12 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: Status bar visibility state. public static var isStatusBarHidden: Bool { - get { - return UIApplication.shared.isStatusBarHidden - } - set { - UIApplication.shared.isStatusBarHidden = newValue - } + get { + return UIApplication.shared.isStatusBarHidden + } + set { + UIApplication.shared.isStatusBarHidden = newValue + } } #endif @@ -238,14 +237,14 @@ public struct SwifterSwift { #if os(iOS) /// SwifterSwift: Current status bar style (if applicable). public static var statusBarStyle: UIStatusBarStyle? { - get { - return UIApplication.shared.statusBarStyle - } - set { - if let style = newValue { - UIApplication.shared.statusBarStyle = style - } - } + get { + return UIApplication.shared.statusBarStyle + } + set { + if let style = newValue { + UIApplication.shared.statusBarStyle = style + } + } } #endif diff --git a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift deleted file mode 100644 index c79265b4d..000000000 --- a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// UIKitDeprecated.swift -// SwifterSwift -// -// Created by Omar Albeik on 7/21/17. -// -// - -#if os(iOS) || os(tvOS) -import UIKit - - -// MARK: - Deprecated -extension UIColor { - - @available(*, deprecated: 3.1.0, message: "Use rgbComponenets.red instead", renamed: "rgbComponenets.red") - /// SwifterSwift: Red component of UIColor (read-only). - public var redComponent: Int { - let red = CIColor(color: self).red - return Int(red * CGFloat(255.0)) - } - - @available(*, deprecated: 3.1.0, message: "Use rgbComponenets.green instead", renamed: "rgbComponenets.green") - /// SwifterSwift: Green component of UIColor (read-only). - public var greenComponent: Int { - var green: CGFloat = 0.0 - getRed(nil, green: &green, blue: nil, alpha: nil) - return Int(green * CGFloat(255.0)) - } - - @available(*, deprecated: 3.1.0, message: "Use rgbComponenets.blue instead", renamed: "rgbComponenets.blue") - /// SwifterSwift: blue component of UIColor (read-only). - public var blueComponent: Int { - var blue: CGFloat = 0.0 - getRed(nil, green: nil, blue: &blue, alpha: nil) - return Int(blue * CGFloat(255.0)) - } - - @available(*, deprecated: 3.2.0, message: "Use 'hexString(withAlpha:)' instead", renamed: "hexString(withAlpha:)") - /// SwifterSwift: Hexadecimal value string (read-only). - public var hexString: String { - return hexString(withAlpha: false) - } - - @available(*, deprecated: 3.2.0, message: "Use shortHexString(withAlpha:) instead", renamed: "shortHexString(withAlpha:)") - /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). - public var shortHexString: String? { - return shortHexString(withAlpha: false) - } -} -#endif diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index 943fa22f9..86fda512b 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -28,20 +28,19 @@ public extension UICollectionView { // MARK: - Methods public extension UICollectionView { - - - /// SwifterSwift: Number of all items in all sections of collectionView. - /// - /// - Returns: The count of all rows in the collectionView. - public func numberOfItems() -> Int { - var section = 0 - var itemsCount = 0 - while section < self.numberOfSections { - itemsCount += numberOfItems(inSection: section) - section += 1 - } - return itemsCount - } + + /// SwifterSwift: Number of all items in all sections of collectionView. + /// + /// - Returns: The count of all rows in the collectionView. + public func numberOfItems() -> Int { + var section = 0 + var itemsCount = 0 + while section < self.numberOfSections { + itemsCount += numberOfItems(inSection: section) + section += 1 + } + return itemsCount + } /// SwifterSwift: IndexPath for last item in section. /// diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift index 496a8d29d..61feeb505 100755 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ b/Sources/Extensions/UIKit/UIColorExtensions.swift @@ -70,9 +70,31 @@ public extension UIColor { return UInt(colorAsUInt32) } + /// SwifterSwift: Hexadecimal value string (read-only). + public var hexString: String { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + + getRed(&red, green: &green, blue: &blue, alpha: &alpha) + let rgb: Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0 + return NSString(format:"#%06x", rgb).uppercased as String + } + + /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). + public var shortHexString: String? { + let string = hexString.replacingOccurrences(of: "#", with: "") + let chrs = Array(string.characters) + guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { + return nil + } + return "#" + "\(chrs[0])\(chrs[2])\(chrs[4])" + } + /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). public var shortHexOrHexString: String { - return shortHexString() ?? hexString() + return shortHexString ?? hexString } /// SwifterSwift: Get color complementary (read-only, if applicable). @@ -116,33 +138,7 @@ public extension UIColor { color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2) return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2) } - - /// SwifterSwift: return hexString of color (ARGB) - /// - /// - Parameter: withAlpha: Boolean value to include alpha or not in output - /// - Returns: A hex-string representation of the color (ARGB) - public func hexString(withAlpha: Bool = false) -> String { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - - getRed(&red, green: &green, blue: &blue, alpha: &alpha) - let rgb: Int = (withAlpha ? ((Int)(alpha*255) << 24) : 0) - | ((Int)(red*255) << 16) - | ((Int)(green*255) << 8) - | ((Int)(blue*255) << 0) - return String(format: (withAlpha ? "#%08x" : "#%06x"), rgb).uppercased() - } - - public func shortHexString(withAlpha: Bool = false) -> String? { - let string = hexString(withAlpha: true).replacingOccurrences(of: "#", with: "") - let chrs = Array(string.characters) - guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5], chrs[6] == chrs[7] else { - return nil - } - return "#" + (withAlpha ? "\(chrs[0])" : "") + "\(chrs[2])\(chrs[4])\(chrs[6])" - } + } diff --git a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift index c8b1a0869..e93c4250b 100644 --- a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift @@ -19,9 +19,9 @@ public extension UINavigationBar { /// - font: title font /// - color: title text color (default is .black). public func setTitleFont(_ font: UIFont, color: UIColor = UIColor.black) { - var attrs = [String: AnyObject]() - attrs[NSFontAttributeName] = font - attrs[NSForegroundColorAttributeName] = color + var attrs = [NSAttributedStringKey: Any]() + attrs[.font] = font + attrs[.foregroundColor] = color titleTextAttributes = attrs } @@ -33,7 +33,7 @@ public extension UINavigationBar { shadowImage = UIImage() isTranslucent = true tintColor = tint - titleTextAttributes = [NSForegroundColorAttributeName: tint] + titleTextAttributes = [NSAttributedStringKey.foregroundColor: tint] } /// SwifterSwift: Set navigationBar background and text colors @@ -47,7 +47,7 @@ public extension UINavigationBar { barTintColor = background setBackgroundImage(UIImage(), for: UIBarMetrics.default) tintColor = text - titleTextAttributes = [NSForegroundColorAttributeName: text] + titleTextAttributes = [.foregroundColor: text] } } #endif diff --git a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift index c4aeb07ba..5aa41b9e1 100755 --- a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift @@ -45,7 +45,7 @@ public extension UINavigationController { navigationBar.shadowImage = UIImage() navigationBar.isTranslucent = true navigationBar.tintColor = tint - navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: tint] + navigationBar.titleTextAttributes = [.foregroundColor: tint] } } diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index 8b0c0c00a..d0044b92b 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -13,19 +13,20 @@ import UIKit // MARK: - Properties public extension UISearchBar { + /// SwifterSwift: Text field inside search bar (if applicable). + public var textField: UITextField? { + let subViews = subviews.flatMap { $0.subviews } + guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else { + return nil + } + return textField + } + /// SwifterSwift: Text with no spaces or new lines in beginning and end (if applicable). public var trimmedText: String? { return text?.trimmingCharacters(in: .whitespacesAndNewlines) } - /// SwifterSwift: Text field inside search bar (if applicable). - public var textField : UITextField? { - let subViews = subviews.flatMap { $0.subviews } - guard let textField = (subViews.first { $0 is UITextField }) as? UITextField else { - return nil - } - return textField - } } diff --git a/Sources/Extensions/UIKit/UITabBarExtensions.swift b/Sources/Extensions/UIKit/UITabBarExtensions.swift index b53299d85..b38aac29b 100644 --- a/Sources/Extensions/UIKit/UITabBarExtensions.swift +++ b/Sources/Extensions/UIKit/UITabBarExtensions.swift @@ -51,9 +51,9 @@ public extension UITabBar { continue } barItem.image = image.filled(withColor: itemColor).withRenderingMode(.alwaysOriginal) - barItem.setTitleTextAttributes([NSForegroundColorAttributeName : itemColor], for: .normal) + barItem.setTitleTextAttributes([.foregroundColor : itemColor], for: .normal) if let selected = selectedItem { - barItem.setTitleTextAttributes([NSForegroundColorAttributeName : selected], for: .selected) + barItem.setTitleTextAttributes([.foregroundColor : selected], for: .selected) } } } diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index ccf450677..c8c269fcc 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -24,23 +24,23 @@ public extension UITableView { } } - + // MARK: - Methods public extension UITableView { + + /// SwifterSwift: Number of all rows in all sections of tableView. + /// + /// - Returns: The count of all rows in the tableView. + public func numberOfRows() -> Int { + var section = 0 + var rowCount = 0 + while section < numberOfSections { + rowCount += numberOfRows(inSection: section) + section += 1 + } + return rowCount + } - /// SwifterSwift: Number of all rows in all sections of tableView. - /// - /// - Returns: The count of all rows in the tableView. - public func numberOfRows() -> Int { - var section = 0 - var rowCount = 0 - while section < numberOfSections { - rowCount += numberOfRows(inSection: section) - section += 1 - } - return rowCount - } - /// SwifterSwift: IndexPath for last row in section. /// /// - Parameter section: section to get last row in. diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index 5e1655214..40651f9d2 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -83,7 +83,7 @@ public extension UITextField { /// public var hasValidEmail: Bool { // http://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift - return text?.range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", + return text!.range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", options: String.CompareOptions.regularExpression, range: nil, locale: nil) != nil } @@ -142,7 +142,7 @@ public extension UITextField { guard let holder = placeholder, !holder.isEmpty else { return } - self.attributedPlaceholder = NSAttributedString(string: holder, attributes: [NSForegroundColorAttributeName: color]) + self.attributedPlaceholder = NSAttributedString(string: holder, attributes: [.foregroundColor: color]) } /// SwifterSwift: Add padding to the left of the textfield rect. diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 5aed24c9c..dc27de995 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -88,6 +88,19 @@ public extension UIView { } } + /// SwifterSwift: First responder. + public var firstResponder: UIView? { + guard !isFirstResponder else { + return self + } + for subView in subviews { + if subView.isFirstResponder { + return subView + } + } + return nil + } + // SwifterSwift: Height of view. public var height: CGFloat { get { @@ -178,6 +191,18 @@ public extension UIView { } } + /// SwifterSwift: Get view's parent view controller + public var parentViewController: UIViewController? { + weak var parentResponder: UIResponder? = self + while parentResponder != nil { + parentResponder = parentResponder!.next + if let viewController = parentResponder as? UIViewController { + return viewController + } + } + return nil + } + /// SwifterSwift: Width of view. public var width: CGFloat { get { @@ -208,36 +233,12 @@ public extension UIView { } } - /// SwifterSwift: Get view's parent view controller - public var parentViewController: UIViewController? { - weak var parentResponder: UIResponder? = self - while parentResponder != nil { - parentResponder = parentResponder!.next - if let viewController = parentResponder as? UIViewController { - return viewController - } - } - return nil - } - - /// SwifterSwift: First responder. - public var firstResponder: UIView? { - guard !isFirstResponder else { - return self - } - for subView in subviews { - if subView.isFirstResponder { - return subView - } - } - return nil - } } // MARK: - Methods public extension UIView { - + /// SwifterSwift: Set some or all corners radiuses of view. /// /// - Parameters: diff --git a/Sources/Extensions/UIKit/UIWebViewExtensions.swift b/Sources/Extensions/UIKit/UIWebViewExtensions.swift deleted file mode 100644 index cc722d717..000000000 --- a/Sources/Extensions/UIKit/UIWebViewExtensions.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// UIWebViewExtensions.swift -// SwifterSwift -// -// Created by Omar Albeik on 9/5/17. -// -// - -#if os(iOS) -import UIKit - - -// MARK: - Methods -public extension UIWebView { - - /// SwifterSwift: Load a URL - /// - /// - Parameter url: URL - public func loadURL(_ url: URL) { - loadRequest(URLRequest(url: url)) - } - - /// SwifterSwift: Load a URL string - /// - /// - Parameter urlString: URL string - public func loadURLString(_ urlString: String) { - guard let url = URL(string: urlString) else { return } - loadRequest(URLRequest(url: url)) - } - -} -#endif diff --git a/Sources/Info.plist b/Sources/Info.plist index ce892bfee..1b41cf5ab 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.1 + 4.0.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 27269986a..a9021651c 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,17 +1,16 @@ Pod::Spec.new do |s| - s.name = "SwifterSwift" - s.module_name = "SwifterSwift" - s.version = "3.2.0" - s.summary = "A handy collection of more than 500 native Swift 3 extensions to boost your productivity." + s.name = 'SwifterSwift' + s.version = '4.0.0' + s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC - SwifterSwift is a collection of over 500 native Swift 3 extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types like SwiftStdlib, Foundation, UIKit, AppKit and many other classes. –over 500 in 1– for iOS, macOS, tvOS and watchOS. + SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. DESC - s.homepage = "https://github.com/SwifterSwift/SwifterSwift" + s.homepage = 'https://github.com/SwifterSwift/SwifterSwift' s.license = { type: 'MIT', file: 'LICENSE' } - s.authors = { "Omar Albeik" => 'omaralbeik@gmail.com' } - s.social_media_url = "http://twitter.com/omaralbeik" - s.screenshot = 'https://raw.githubusercontent.com/SwifterSwift/SwifterSwift/master/Assets/logo.png' + s.authors = { 'Omar Albeik' => 'omaralbeik@gmail.com' } + s.social_media_url = 'http://twitter.com/omaralbeik' + s.screenshot = 'https://raw.githubusercontent.com/SwifterSwift/SwifterSwift/master/Assets/logo.png' s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' @@ -19,42 +18,40 @@ Pod::Spec.new do |s| s.watchos.deployment_target = '2.0' s.requires_arc = true - s.source = { git: "https://github.com/SwifterSwift/SwifterSwift.git", tag: "#{s.version}" } - s.source_files = "Sources/**/*.{swift,h}" - s.public_header_files = 'Sources/SwifterSwift.h' + s.source = { git: 'https://github.com/SwifterSwift/SwifterSwift.git', tag: s.version.to_s } + s.source_files = 'Sources/**/*.swift' s.pod_target_xcconfig = { - 'SWIFT_VERSION' => '3.0', + 'SWIFT_VERSION' => '4.0' } s.documentation_url = 'http://swifterswift.com/docs' # SwiftStdlib Extensions s.subspec 'SwiftStdlib' do |sp| - sp.source_files = "Sources/Extensions/SwiftStdlib/*.swift" + sp.source_files = 'Sources/Extensions/SwiftStdlib/*.swift' end # Foundation Extensions s.subspec 'Foundation' do |sp| - sp.source_files = "Sources/Extensions/Foundation/*.swift" + sp.source_files = 'Sources/Extensions/Foundation/*.swift' end # UIKit Extensions s.subspec 'UIKit' do |sp| - sp.source_files = "Sources/Extensions/UIKit/*.swift" + sp.source_files = 'Sources/Extensions/UIKit/*.swift' end # AppKit Extensions s.subspec 'AppKit' do |sp| - sp.source_files = "Sources/Extensions/AppKit/*.swift" + sp.source_files = 'Sources/Extensions/AppKit/*.swift' end # CoreGraphics Extensions s.subspec 'CoreGraphics' do |sp| - sp.source_files = "Sources/Extensions/CoreGraphics/*.swift" + sp.source_files = 'Sources/Extensions/CoreGraphics/*.swift' end # CoreLocation Extensions s.subspec 'CoreLocation' do |sp| - sp.source_files = "Sources/Extensions/CoreLocation/*.swift" + sp.source_files = 'Sources/Extensions/CoreLocation/*.swift' end - end diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 7641a4ee6..2047fc150 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -3,1529 +3,1424 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ - 0743F2B71F611B63008386F7 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2781F611B62008386F7 /* NSColorExtensions.swift */; }; - 0743F2BB1F611B63008386F7 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2791F611B62008386F7 /* NSViewExtensions.swift */; }; - 0743F2BE1F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; - 0743F2BF1F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; - 0743F2C01F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; - 0743F2C11F611B63008386F7 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */; }; - 0743F2C21F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; - 0743F2C31F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; - 0743F2C41F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; - 0743F2C51F611B63008386F7 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */; }; - 0743F2C61F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; - 0743F2C71F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; - 0743F2C81F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; - 0743F2C91F611B63008386F7 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */; }; - 0743F2CA1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; - 0743F2CB1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; - 0743F2CC1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; - 0743F2CD1F611B63008386F7 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */; }; - 0743F2CE1F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; - 0743F2CF1F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; - 0743F2D01F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; - 0743F2D11F611B63008386F7 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */; }; - 0743F2D21F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; - 0743F2D31F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; - 0743F2D41F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; - 0743F2D51F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */; }; - 0743F2D61F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; - 0743F2D71F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; - 0743F2D81F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; - 0743F2D91F611B63008386F7 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2841F611B62008386F7 /* DataExtensions.swift */; }; - 0743F2DA1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; - 0743F2DB1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; - 0743F2DC1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; - 0743F2DD1F611B63008386F7 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2851F611B62008386F7 /* DateExtensions.swift */; }; - 0743F2DE1F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; - 0743F2DF1F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; - 0743F2E01F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; - 0743F2E11F611B63008386F7 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */; }; - 0743F2E21F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; - 0743F2E31F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; - 0743F2E41F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; - 0743F2E51F611B63008386F7 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2881F611B62008386F7 /* LocaleExtensions.swift */; }; - 0743F2E61F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; - 0743F2E71F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; - 0743F2E81F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; - 0743F2E91F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */; }; - 0743F2EA1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; - 0743F2EB1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; - 0743F2EC1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; - 0743F2ED1F611B63008386F7 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28A1F611B62008386F7 /* URLExtensions.swift */; }; - 0743F2EE1F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; - 0743F2EF1F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; - 0743F2F01F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; - 0743F2F11F611B63008386F7 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */; }; - 0743F2F21F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; - 0743F2F31F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; - 0743F2F41F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; - 0743F2F51F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */; }; - 0743F2F61F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; - 0743F2F71F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; - 0743F2F81F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; - 0743F2F91F611B63008386F7 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28D1F611B62008386F7 /* SwifterSwift.swift */; }; - 0743F2FA1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; - 0743F2FB1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; - 0743F2FC1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; - 0743F2FD1F611B63008386F7 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */; }; - 0743F2FE1F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; - 0743F2FF1F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; - 0743F3001F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; - 0743F3011F611B63008386F7 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2901F611B62008386F7 /* BoolExtensions.swift */; }; - 0743F3021F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; - 0743F3031F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; - 0743F3041F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; - 0743F3051F611B63008386F7 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2911F611B62008386F7 /* CharacterExtensions.swift */; }; - 0743F3061F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; - 0743F3071F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; - 0743F3081F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; - 0743F3091F611B63008386F7 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2921F611B62008386F7 /* CollectionExtensions.swift */; }; - 0743F30A1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; - 0743F30B1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; - 0743F30C1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; - 0743F30D1F611B63008386F7 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */; }; - 0743F30E1F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; - 0743F30F1F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; - 0743F3101F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; - 0743F3111F611B63008386F7 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2941F611B62008386F7 /* DoubleExtensions.swift */; }; - 0743F3121F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; - 0743F3131F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; - 0743F3141F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; - 0743F3151F611B63008386F7 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2951F611B62008386F7 /* FloatExtensions.swift */; }; - 0743F3161F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; - 0743F3171F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; - 0743F3181F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; - 0743F3191F611B63008386F7 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */; }; - 0743F31A1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; - 0743F31B1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; - 0743F31C1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; - 0743F31D1F611B63008386F7 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2971F611B62008386F7 /* IntExtensions.swift */; }; - 0743F31E1F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; - 0743F31F1F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; - 0743F3201F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; - 0743F3211F611B63008386F7 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2981F611B62008386F7 /* OptionalExtensions.swift */; }; - 0743F3221F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; - 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; - 0743F3241F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; - 0743F3251F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */; }; - 0743F3261F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; - 0743F3271F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; - 0743F3281F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; - 0743F3291F611B63008386F7 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */; }; - 0743F32A1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; - 0743F32B1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; - 0743F32C1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; - 0743F32D1F611B63008386F7 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29B1F611B62008386F7 /* StringExtensions.swift */; }; - 0743F32E1F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; - 0743F3301F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; - 0743F3311F611B63008386F7 /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */; }; - 0743F3321F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; - 0743F3341F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; - 0743F3351F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */; }; - 0743F3361F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; - 0743F3381F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; - 0743F3391F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */; }; - 0743F33A1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; - 0743F33C1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; - 0743F33D1F611B63008386F7 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */; }; - 0743F33E1F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; - 0743F3401F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; - 0743F3411F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */; }; - 0743F3421F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; - 0743F3441F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; - 0743F3451F611B63008386F7 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */; }; - 0743F3461F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; - 0743F3481F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; - 0743F3491F611B63008386F7 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */; }; - 0743F34A1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; - 0743F34C1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; - 0743F34D1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */; }; - 0743F34E1F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; - 0743F3501F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; - 0743F3511F611B63008386F7 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */; }; - 0743F3521F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; - 0743F3541F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; - 0743F3551F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */; }; - 0743F3561F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; - 0743F3581F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; - 0743F3591F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */; }; - 0743F35A1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; - 0743F35C1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; - 0743F35D1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */; }; - 0743F35E1F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; - 0743F3601F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; - 0743F3611F611B63008386F7 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */; }; - 0743F3621F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; - 0743F3641F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; - 0743F3651F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */; }; - 0743F3661F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; - 0743F3681F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; - 0743F3691F611B63008386F7 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */; }; - 0743F36A1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; - 0743F36C1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; - 0743F36D1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */; }; - 0743F36E1F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; - 0743F3701F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; - 0743F3711F611B63008386F7 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */; }; - 0743F3721F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; - 0743F3741F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; - 0743F3751F611B63008386F7 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */; }; - 0743F3761F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; - 0743F3781F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; - 0743F3791F611B63008386F7 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */; }; - 0743F37A1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; - 0743F37C1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; - 0743F37D1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */; }; - 0743F37E1F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; - 0743F3801F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; - 0743F3811F611B63008386F7 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */; }; - 0743F3821F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; - 0743F3841F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; - 0743F3851F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */; }; - 0743F3861F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; - 0743F3881F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; - 0743F3891F611B63008386F7 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */; }; - 0743F38A1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; - 0743F38C1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; - 0743F38D1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */; }; - 0743F3C11F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; - 0743F3C21F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; - 0743F3C31F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */; }; - 0743F3C41F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; - 0743F3C51F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; - 0743F3C61F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */; }; - 0743F3C71F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; - 0743F3C81F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; - 0743F3C91F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */; }; - 0743F3CA1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; - 0743F3CB1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; - 0743F3CC1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */; }; - 0743F3CD1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; - 0743F3CE1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; - 0743F3CF1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */; }; - 0743F3D01F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; - 0743F3D11F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; - 0743F3D21F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */; }; - 0743F3D31F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; - 0743F3D41F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; - 0743F3D51F611B87008386F7 /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */; }; - 0743F3D61F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; - 0743F3D71F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; - 0743F3D81F611B87008386F7 /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */; }; - 0743F3D91F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; - 0743F3DA1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; - 0743F3DB1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */; }; - 0743F3DC1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; - 0743F3DD1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; - 0743F3DE1F611B87008386F7 /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */; }; - 0743F3DF1F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; - 0743F3E01F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; - 0743F3E11F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */; }; - 0743F3E21F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; - 0743F3E31F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; - 0743F3E41F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */; }; - 0743F3E51F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; - 0743F3E61F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; - 0743F3E71F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */; }; - 0743F3E81F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; - 0743F3E91F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; - 0743F3EA1F611B87008386F7 /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */; }; - 0743F3EB1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; - 0743F3EC1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; - 0743F3ED1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */; }; - 0743F3EE1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; - 0743F3EF1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; - 0743F3F01F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */; }; - 0743F3F11F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; - 0743F3F21F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; - 0743F3F31F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */; }; - 0743F3F41F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; - 0743F3F51F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; - 0743F3F61F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */; }; - 0743F3F71F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; - 0743F3F81F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; - 0743F3F91F611B87008386F7 /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */; }; - 0743F3FA1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; - 0743F3FB1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; - 0743F3FC1F611B87008386F7 /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */; }; - 0743F3FD1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; - 0743F3FE1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; - 0743F3FF1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */; }; - 0743F4001F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; - 0743F4011F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; - 0743F4021F611B87008386F7 /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */; }; - 0743F4031F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; - 0743F4041F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; - 0743F4051F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */; }; - 0743F4061F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; - 0743F4071F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; - 0743F4081F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */; }; - 0743F4091F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; - 0743F40A1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; - 0743F40B1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */; }; - 0743F40C1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; - 0743F40D1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; - 0743F40E1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */; }; - 0743F40F1F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; - 0743F4101F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; - 0743F4111F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */; }; - 0743F4121F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; - 0743F4131F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; - 0743F4141F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */; }; - 0743F4151F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; - 0743F4161F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; - 0743F4171F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */; }; - 0743F4181F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; - 0743F4191F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; - 0743F41A1F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */; }; - 0743F41B1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; - 0743F41C1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; - 0743F41D1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */; }; - 0743F41E1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; - 0743F41F1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; - 0743F4201F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */; }; - 0743F4211F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; - 0743F4221F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; - 0743F4231F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */; }; - 0743F4241F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; - 0743F4251F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; - 0743F4261F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */; }; - 0743F4271F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; - 0743F4281F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; - 0743F4291F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */; }; - 0743F42A1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; - 0743F42B1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; - 0743F42C1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */; }; - 0743F42D1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; - 0743F42E1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; - 0743F42F1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */; }; - 0743F4301F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; - 0743F4311F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; - 0743F4321F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */; }; - 0743F4331F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; - 0743F4341F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; - 0743F4351F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */; }; - 0743F4361F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; - 0743F4371F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; - 0743F4381F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */; }; - 0743F4391F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; - 0743F43A1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; - 0743F43B1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */; }; - 0743F43C1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; - 0743F43D1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; - 0743F43E1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */; }; - 0743F43F1F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; - 0743F4401F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; - 0743F4411F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */; }; - 0743F4421F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; - 0743F4431F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; - 0743F4441F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */; }; - 0743F4451F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; - 0743F4461F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; - 0743F4471F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */; }; - 077AD1BA1F13873600D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */; }; - 077AD1C91F13875100D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */; }; - 077AD1D81F13876000D3214D /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */; }; - 0789808E1F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; - 0789808F1F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; - 078980901F138AF000A3A4E1 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 078980731F138AF000A3A4E1 /* TestImage.png */; }; - 078980911F138AF000A3A4E1 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */; }; - 078980941F138AF000A3A4E1 /* UITableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 078980751F138AF000A3A4E1 /* UITableViewCell.xib */; }; - 078980971F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */; }; - 078980DD1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; - 078980DE1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; - 078980DF1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */; }; - 07DFA3E41F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 07DFA3E51F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 07DFA3E61F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 07DFA3E71F13844C00D0C644 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; + 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; + 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; + 077BA08D1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; + 077BA08F1F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */; }; + 077BA0901F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */; }; + 077BA0911F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */; }; + 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */; }; + 077BA09E1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */; }; + 077BA09F1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */; }; + 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */; }; + 077BA0B91F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; + 077BA0BA1F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; + 077BA0BB1F6BEA6B00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; + 07898B901F278F0800558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 07898B911F278F0C00558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 07898B921F278F1000558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 07898B931F278F1300558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */; }; + 07B7F1931F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; + 07B7F1941F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; + 07B7F1951F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; + 07B7F1961F5EB42000E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; + 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; + 07B7F1981F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; + 07B7F1991F5EB42000E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; + 07B7F19A1F5EB42000E6F910 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */; }; + 07B7F19B1F5EB42000E6F910 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */; }; + 07B7F19C1F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */; }; + 07B7F19D1F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */; }; + 07B7F19E1F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */; }; + 07B7F19F1F5EB42000E6F910 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */; }; + 07B7F1A01F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */; }; + 07B7F1A11F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18B1F5EB41600E6F910 /* UISwitchExtensions.swift */; }; + 07B7F1A21F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18C1F5EB41600E6F910 /* UITabBarExtensions.swift */; }; + 07B7F1A31F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18D1F5EB41600E6F910 /* UITableViewExtensions.swift */; }; + 07B7F1A41F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18E1F5EB41600E6F910 /* UITextFieldExtensions.swift */; }; + 07B7F1A51F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */; }; + 07B7F1A61F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */; }; + 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */; }; + 07B7F1A81F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */; }; + 07B7F1A91F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; + 07B7F1AA1F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; + 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; + 07B7F1AC1F5EB42000E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; + 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; + 07B7F1AE1F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; + 07B7F1AF1F5EB42000E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; + 07B7F1B01F5EB42000E6F910 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */; }; + 07B7F1B11F5EB42000E6F910 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */; }; + 07B7F1B21F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */; }; + 07B7F1B31F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */; }; + 07B7F1B41F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */; }; + 07B7F1B51F5EB42000E6F910 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */; }; + 07B7F1B61F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */; }; + 07B7F1B71F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18B1F5EB41600E6F910 /* UISwitchExtensions.swift */; }; + 07B7F1B81F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18C1F5EB41600E6F910 /* UITabBarExtensions.swift */; }; + 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18D1F5EB41600E6F910 /* UITableViewExtensions.swift */; }; + 07B7F1BA1F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18E1F5EB41600E6F910 /* UITextFieldExtensions.swift */; }; + 07B7F1BB1F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */; }; + 07B7F1BC1F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */; }; + 07B7F1BD1F5EB42000E6F910 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */; }; + 07B7F1BE1F5EB42200E6F910 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */; }; + 07B7F1BF1F5EB42200E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; + 07B7F1C01F5EB42200E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; + 07B7F1C11F5EB42200E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; + 07B7F1C21F5EB42200E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; + 07B7F1C31F5EB42200E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; + 07B7F1C41F5EB42200E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; + 07B7F1C51F5EB42200E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; + 07B7F1C61F5EB42200E6F910 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */; }; + 07B7F1C71F5EB42200E6F910 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */; }; + 07B7F1C81F5EB42200E6F910 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */; }; + 07B7F1C91F5EB42200E6F910 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */; }; + 07B7F1CA1F5EB42200E6F910 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */; }; + 07B7F1CB1F5EB42200E6F910 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */; }; + 07B7F1CC1F5EB42200E6F910 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */; }; + 07B7F1CD1F5EB42200E6F910 /* UISwitchExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18B1F5EB41600E6F910 /* UISwitchExtensions.swift */; }; + 07B7F1CE1F5EB42200E6F910 /* UITabBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18C1F5EB41600E6F910 /* UITabBarExtensions.swift */; }; + 07B7F1CF1F5EB42200E6F910 /* UITableViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18D1F5EB41600E6F910 /* UITableViewExtensions.swift */; }; + 07B7F1D01F5EB42200E6F910 /* UITextFieldExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18E1F5EB41600E6F910 /* UITextFieldExtensions.swift */; }; + 07B7F1D11F5EB42200E6F910 /* UITextViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */; }; + 07B7F1D21F5EB42200E6F910 /* UIViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */; }; + 07B7F1D31F5EB42200E6F910 /* UIViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */; }; + 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */; }; + 07B7F1D61F5EB43B00E6F910 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */; }; + 07B7F1D71F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */; }; + 07B7F1D81F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */; }; + 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */; }; + 07B7F1DA1F5EB43B00E6F910 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */; }; + 07B7F1DB1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */; }; + 07B7F1DC1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */; }; + 07B7F1DD1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */; }; + 07B7F1DE1F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */; }; + 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */; }; + 07B7F1E01F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */; }; + 07B7F1E11F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */; }; + 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */; }; + 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */; }; + 07B7F1E41F5EB43B00E6F910 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */; }; + 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */; }; + 07B7F1E71F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */; }; + 07B7F1E81F5EB43B00E6F910 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */; }; + 07B7F1E91F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */; }; + 07B7F1EA1F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */; }; + 07B7F1EB1F5EB43B00E6F910 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */; }; + 07B7F1EC1F5EB43B00E6F910 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */; }; + 07B7F1ED1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */; }; + 07B7F1EE1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */; }; + 07B7F1EF1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */; }; + 07B7F1F01F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */; }; + 07B7F1F11F5EB43B00E6F910 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */; }; + 07B7F1F21F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */; }; + 07B7F1F31F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */; }; + 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */; }; + 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */; }; + 07B7F1F61F5EB43B00E6F910 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */; }; + 07B7F1F71F5EB43B00E6F910 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */; }; + 07B7F1F91F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */; }; + 07B7F1FA1F5EB43C00E6F910 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */; }; + 07B7F1FB1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */; }; + 07B7F1FC1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */; }; + 07B7F1FD1F5EB43C00E6F910 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */; }; + 07B7F1FE1F5EB43C00E6F910 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */; }; + 07B7F1FF1F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */; }; + 07B7F2001F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */; }; + 07B7F2011F5EB43C00E6F910 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */; }; + 07B7F2021F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */; }; + 07B7F2031F5EB43C00E6F910 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */; }; + 07B7F2041F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */; }; + 07B7F2051F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */; }; + 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */; }; + 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */; }; + 07B7F2081F5EB43C00E6F910 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */; }; + 07B7F2091F5EB43C00E6F910 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */; }; + 07B7F20B1F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */; }; + 07B7F20C1F5EB43C00E6F910 /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */; }; + 07B7F20D1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */; }; + 07B7F20E1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */; }; + 07B7F20F1F5EB43C00E6F910 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */; }; + 07B7F2101F5EB43C00E6F910 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */; }; + 07B7F2111F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */; }; + 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */; }; + 07B7F2131F5EB43C00E6F910 /* FloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */; }; + 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */; }; + 07B7F2151F5EB43C00E6F910 /* IntExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */; }; + 07B7F2161F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */; }; + 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */; }; + 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */; }; + 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */; }; + 07B7F21A1F5EB43C00E6F910 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */; }; + 07B7F21B1F5EB43C00E6F910 /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */; }; + 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */; }; + 07B7F21D1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */; }; + 07B7F21E1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */; }; + 07B7F21F1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */; }; + 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */; }; + 07B7F2211F5EB44600E6F910 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */; }; + 07B7F2221F5EB44600E6F910 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */; }; + 07B7F2231F5EB44600E6F910 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */; }; + 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */; }; + 07B7F2251F5EB44600E6F910 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */; }; + 07B7F2261F5EB44600E6F910 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */; }; + 07B7F2271F5EB44600E6F910 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */; }; + 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */; }; + 07B7F2291F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */; }; + 07B7F22A1F5EB45100E6F910 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */; }; + 07B7F22B1F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */; }; + 07B7F22C1F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */; }; + 07B7F22D1F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */; }; + 07B7F22E1F5EB45100E6F910 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */; }; + 07B7F22F1F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */; }; + 07B7F2301F5EB45100E6F910 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */; }; + 07B7F2311F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */; }; + 07B7F2321F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */; }; + 07B7F2331F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */; }; + 07B7F2341F5EB45200E6F910 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */; }; + 07B7F2351F5EB45200E6F910 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */; }; + 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */; }; + 07B7F2371F5EB45200E6F910 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */; }; + 07B7F2381F5EB45200E6F910 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */; }; + 07B7F2391F5EB45200E6F910 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */; }; + 07C50CCE1F5EAF2700F46E5A /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07898B5D1F278D7600558C97 /* SwifterSwift.framework */; }; + 07C50CDD1F5EAF4B00F46E5A /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07898B6B1F278D9700558C97 /* SwifterSwift.framework */; }; + 07C50CEC1F5EAF6300F46E5A /* SwifterSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07898B851F278DD200558C97 /* SwifterSwift.framework */; }; + 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0E1F5EB03200F46E5A /* UIAlertControllerExtensionsTests.swift */; }; + 07C50D2C1F5EB04600F46E5A /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */; }; + 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */; }; + 07C50D2E1F5EB04600F46E5A /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */; }; + 07C50D2F1F5EB04600F46E5A /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */; }; + 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */; }; + 07C50D311F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */; }; + 07C50D321F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */; }; + 07C50D331F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */; }; + 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */; }; + 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */; }; + 07C50D361F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */; }; + 07C50D371F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1A1F5EB03200F46E5A /* UISegmentedControlExtensionsTests.swift */; }; + 07C50D381F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1B1F5EB03200F46E5A /* UISliderExtensionsTests.swift */; }; + 07C50D391F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1C1F5EB03200F46E5A /* UIStoryboardExtensionsTests.swift */; }; + 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1D1F5EB03200F46E5A /* UISwitchExtensionsTests.swift */; }; + 07C50D3B1F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1E1F5EB03200F46E5A /* UITabBarExtensionsTests.swift */; }; + 07C50D3C1F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1F1F5EB03200F46E5A /* UITableViewExtensionsTests.swift */; }; + 07C50D3D1F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D201F5EB03200F46E5A /* UITextFieldExtensionsTests.swift */; }; + 07C50D3E1F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D211F5EB03200F46E5A /* UITextViewExtensionsTests.swift */; }; + 07C50D3F1F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */; }; + 07C50D401F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */; }; + 07C50D411F5EB04700F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0E1F5EB03200F46E5A /* UIAlertControllerExtensionsTests.swift */; }; + 07C50D421F5EB04700F46E5A /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */; }; + 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */; }; + 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */; }; + 07C50D451F5EB04700F46E5A /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */; }; + 07C50D461F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */; }; + 07C50D471F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */; }; + 07C50D481F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */; }; + 07C50D491F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */; }; + 07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */; }; + 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */; }; + 07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */; }; + 07C50D4D1F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1A1F5EB03200F46E5A /* UISegmentedControlExtensionsTests.swift */; }; + 07C50D4E1F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1B1F5EB03200F46E5A /* UISliderExtensionsTests.swift */; }; + 07C50D4F1F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1C1F5EB03200F46E5A /* UIStoryboardExtensionsTests.swift */; }; + 07C50D501F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1D1F5EB03200F46E5A /* UISwitchExtensionsTests.swift */; }; + 07C50D511F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1E1F5EB03200F46E5A /* UITabBarExtensionsTests.swift */; }; + 07C50D521F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D1F1F5EB03200F46E5A /* UITableViewExtensionsTests.swift */; }; + 07C50D531F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D201F5EB03200F46E5A /* UITextFieldExtensionsTests.swift */; }; + 07C50D541F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D211F5EB03200F46E5A /* UITextViewExtensionsTests.swift */; }; + 07C50D551F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */; }; + 07C50D561F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */; }; + 07C50D571F5EB05000F46E5A /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFA1F5EB03200F46E5A /* ArrayExtensionsTests.swift */; }; + 07C50D581F5EB05000F46E5A /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */; }; + 07C50D591F5EB05000F46E5A /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */; }; + 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */; }; + 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */; }; + 07C50D5C1F5EB05000F46E5A /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */; }; + 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */; }; + 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */; }; + 07C50D5F1F5EB05000F46E5A /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */; }; + 07C50D601F5EB05000F46E5A /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */; }; + 07C50D611F5EB05000F46E5A /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */; }; + 07C50D621F5EB05000F46E5A /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */; }; + 07C50D631F5EB05000F46E5A /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */; }; + 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */; }; + 07C50D651F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFA1F5EB03200F46E5A /* ArrayExtensionsTests.swift */; }; + 07C50D661F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */; }; + 07C50D671F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */; }; + 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */; }; + 07C50D691F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */; }; + 07C50D6A1F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */; }; + 07C50D6B1F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */; }; + 07C50D6C1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */; }; + 07C50D6D1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */; }; + 07C50D6E1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */; }; + 07C50D6F1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */; }; + 07C50D701F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */; }; + 07C50D711F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */; }; + 07C50D721F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */; }; + 07C50D731F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFA1F5EB03200F46E5A /* ArrayExtensionsTests.swift */; }; + 07C50D741F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */; }; + 07C50D751F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */; }; + 07C50D761F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */; }; + 07C50D771F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */; }; + 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */; }; + 07C50D791F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */; }; + 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */; }; + 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */; }; + 07C50D7C1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */; }; + 07C50D7D1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */; }; + 07C50D7E1F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */; }; + 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */; }; + 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */; }; + 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */; }; + 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */; }; + 07C50D831F5EB05800F46E5A /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */; }; + 07C50D841F5EB05800F46E5A /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */; }; + 07C50D851F5EB05800F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */; }; + 07C50D861F5EB05800F46E5A /* NSViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */; }; + 07C50D871F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */; }; + 07C50D881F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */; }; + 07C50D891F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */; }; + 07C50D8A1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */; }; + 07C50D8B1F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */; }; + 07C50D8C1F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */; }; + 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */; }; + 07C50D8E1F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */; }; + 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */; }; + 07C50D901F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */; }; + 07C50D911F5EB07400F46E5A /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D091F5EB03200F46E5A /* TestImage.png */; }; + 07C50D921F5EB07500F46E5A /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D091F5EB03200F46E5A /* TestImage.png */; }; + 07C50D931F5EB07500F46E5A /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D091F5EB03200F46E5A /* TestImage.png */; }; + 07C50D941F5EB07D00F46E5A /* UITableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D0B1F5EB03200F46E5A /* UITableViewCell.xib */; }; + 07C50D951F5EB07D00F46E5A /* UITableViewHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D0C1F5EB03200F46E5A /* UITableViewHeaderFooterView.xib */; }; + 07C50D981F5EB08200F46E5A /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07C50D0A1F5EB03200F46E5A /* TestStoryboard.storyboard */; }; + 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; + 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; + 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 077AD1BB1F13873600D3214D /* PBXContainerItemProxy */ = { + 07C50CCF1F5EAF2700F46E5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 079412C51F137D5C006AA1F8 /* Project object */; + containerPortal = 07898B521F278CF900558C97 /* Project object */; proxyType = 1; - remoteGlobalIDString = 07DFA3AD1F1380F100D0C644; - remoteInfo = "SwifterSwift iOS"; + remoteGlobalIDString = 07898B5C1F278D7600558C97; + remoteInfo = "SwifterSwift-iOS"; }; - 077AD1CA1F13875100D3214D /* PBXContainerItemProxy */ = { + 07C50CDE1F5EAF4B00F46E5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 079412C51F137D5C006AA1F8 /* Project object */; + containerPortal = 07898B521F278CF900558C97 /* Project object */; proxyType = 1; - remoteGlobalIDString = 07DFA3BB1F13816200D0C644; - remoteInfo = "SwifterSwift macOS"; + remoteGlobalIDString = 07898B6A1F278D9700558C97; + remoteInfo = "SwifterSwift-tvOS"; }; - 077AD1D91F13876000D3214D /* PBXContainerItemProxy */ = { + 07C50CED1F5EAF6300F46E5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 079412C51F137D5C006AA1F8 /* Project object */; + containerPortal = 07898B521F278CF900558C97 /* Project object */; proxyType = 1; - remoteGlobalIDString = 07DFA3C81F13817200D0C644; - remoteInfo = "SwifterSwift tvOS"; + remoteGlobalIDString = 07898B841F278DD200558C97; + remoteInfo = "SwifterSwift-macOS"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0743F2781F611B62008386F7 /* NSColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSColorExtensions.swift; sourceTree = ""; }; - 0743F2791F611B62008386F7 /* NSViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensions.swift; sourceTree = ""; }; - 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColorExtensions.swift; sourceTree = ""; }; - 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensions.swift; sourceTree = ""; }; - 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensions.swift; sourceTree = ""; }; - 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensions.swift; sourceTree = ""; }; - 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensions.swift; sourceTree = ""; }; - 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwiftDeprecated.swift; sourceTree = ""; }; - 0743F2841F611B62008386F7 /* DataExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensions.swift; sourceTree = ""; }; - 0743F2851F611B62008386F7 /* DateExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensions.swift; sourceTree = ""; }; - 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; - 0743F2881F611B62008386F7 /* LocaleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensions.swift; sourceTree = ""; }; - 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensions.swift; sourceTree = ""; }; - 0743F28A1F611B62008386F7 /* URLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; }; - 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; - 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; - 0743F28D1F611B62008386F7 /* SwifterSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; - 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; - 0743F2901F611B62008386F7 /* BoolExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; - 0743F2911F611B62008386F7 /* CharacterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensions.swift; sourceTree = ""; }; - 0743F2921F611B62008386F7 /* CollectionExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = ""; }; - 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; - 0743F2941F611B62008386F7 /* DoubleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensions.swift; sourceTree = ""; }; - 0743F2951F611B62008386F7 /* FloatExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensions.swift; sourceTree = ""; }; - 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPointExtensions.swift; sourceTree = ""; }; - 0743F2971F611B62008386F7 /* IntExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensions.swift; sourceTree = ""; }; - 0743F2981F611B62008386F7 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; - 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; - 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensions.swift; sourceTree = ""; }; - 0743F29B1F611B62008386F7 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; - 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIKitDeprecated.swift; sourceTree = ""; }; - 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensions.swift; sourceTree = ""; }; - 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemExtensions.swift; sourceTree = ""; }; - 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; - 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = ""; }; - 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; - 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; - 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; - 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensions.swift; sourceTree = ""; }; - 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensions.swift; sourceTree = ""; }; - 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensions.swift; sourceTree = ""; }; - 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensions.swift; sourceTree = ""; }; - 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensions.swift; sourceTree = ""; }; - 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensions.swift; sourceTree = ""; }; - 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensions.swift; sourceTree = ""; }; - 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensions.swift; sourceTree = ""; }; - 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensions.swift; sourceTree = ""; }; - 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensions.swift; sourceTree = ""; }; - 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensions.swift; sourceTree = ""; }; - 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensions.swift; sourceTree = ""; }; - 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensions.swift; sourceTree = ""; }; - 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensions.swift; sourceTree = ""; }; - 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = ""; }; - 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensions.swift; sourceTree = ""; }; - 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; - 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatExtensionsTests.swift; sourceTree = ""; }; - 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGPointExtensionsTests.swift; sourceTree = ""; }; - 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtensionsTests.swift; sourceTree = ""; }; - 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; - 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataExtensionsTests.swift; sourceTree = ""; }; - 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensionsTests.swift; sourceTree = ""; }; - 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleExtensionsTests.swift; sourceTree = ""; }; - 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; }; - 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; - 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; - 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionsTests.swift; sourceTree = ""; }; - 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; }; - 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterExtensionsTests.swift; sourceTree = ""; }; - 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionExtensionsTests.swift; sourceTree = ""; }; - 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionsTests.swift; sourceTree = ""; }; - 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensionsTests.swift; sourceTree = ""; }; - 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatExtensionsTests.swift; sourceTree = ""; }; - 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntExtensionsTests.swift; sourceTree = ""; }; - 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensionsTests.swift; sourceTree = ""; }; - 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; }; - 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensionsTests.swift; sourceTree = ""; }; - 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIBarButtonExtensionsTests.swift; sourceTree = ""; }; - 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIButtonExtensionsTests.swift; sourceTree = ""; }; - 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; }; - 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensionsTests.swift; sourceTree = ""; }; - 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtensionsTests.swift; sourceTree = ""; }; - 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensionTests.swift; sourceTree = ""; }; - 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensionsTests.swift; sourceTree = ""; }; - 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensionsTests.swift; sourceTree = ""; }; - 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensionsTests.swift; sourceTree = ""; }; - 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensionsTests.swift; sourceTree = ""; }; - 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISliderExtensionsTests.swift; sourceTree = ""; }; - 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensionsTests.swift; sourceTree = ""; }; - 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISwitchExtensionsTests.swift; sourceTree = ""; }; - 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITabBarExtensionsTests.swift; sourceTree = ""; }; - 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensionsTests.swift; sourceTree = ""; }; - 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensionsTests.swift; sourceTree = ""; }; - 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewExtensionsTests.swift; sourceTree = ""; }; - 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWebViewExtensionsTests.swift; sourceTree = ""; }; - 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 077AD1C41F13875100D3214D /* SwifterSwift macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift macOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 077AD1D31F13876000D3214D /* SwifterSwift tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 077AD1DF1F1387D600D3214D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = ""; }; - 078980731F138AF000A3A4E1 /* TestImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestImage.png; sourceTree = ""; }; - 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = TestStoryboard.storyboard; sourceTree = ""; }; - 078980751F138AF000A3A4E1 /* UITableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UITableViewCell.xib; sourceTree = ""; }; - 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UITableViewHeaderFooterView.xib; sourceTree = ""; }; - 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwifterSwiftTests.swift; path = Tests/SwifterSwiftTests.swift; sourceTree = ""; }; - 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 07DFA3D61F13818700D0C644 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 07DFA3DF1F13825700D0C644 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/Info.plist; sourceTree = ""; }; - 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SwifterSwift.h; path = Sources/SwifterSwift.h; sourceTree = ""; }; + 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; + 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; + 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; + 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; + 07898B5D1F278D7600558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 07898B6B1F278D9700558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 07898B781F278DBC00558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 07898B851F278DD200558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 07898B8E1F278E6300558C97 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 07898B8F1F278E6300558C97 /* SwifterSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwifterSwift.h; sourceTree = ""; }; + 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; + 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensions.swift; sourceTree = ""; }; + 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGFloatExtensions.swift; sourceTree = ""; }; + 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGPointExtensions.swift; sourceTree = ""; }; + 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGSizeExtensions.swift; sourceTree = ""; }; + 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationExtensions.swift; sourceTree = ""; }; + 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensions.swift; sourceTree = ""; }; + 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSColorExtensions.swift; sourceTree = ""; }; + 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensions.swift; sourceTree = ""; }; + 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; + 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; + 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterExtensions.swift; sourceTree = ""; }; + 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = ""; }; + 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtensions.swift; sourceTree = ""; }; + 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtensions.swift; sourceTree = ""; }; + 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; + 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleExtensions.swift; sourceTree = ""; }; + 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatExtensions.swift; sourceTree = ""; }; + 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingPointExtensions.swift; sourceTree = ""; }; + 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntExtensions.swift; sourceTree = ""; }; + 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleExtensions.swift; sourceTree = ""; }; + 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; + 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensions.swift; sourceTree = ""; }; + 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensions.swift; sourceTree = ""; }; + 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; + 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; }; + 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensions.swift; sourceTree = ""; }; + 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemExtensions.swift; sourceTree = ""; }; + 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; + 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = ""; }; + 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; + 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; + 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; + 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelExtensions.swift; sourceTree = ""; }; + 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensions.swift; sourceTree = ""; }; + 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensions.swift; sourceTree = ""; }; + 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensions.swift; sourceTree = ""; }; + 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensions.swift; sourceTree = ""; }; + 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensions.swift; sourceTree = ""; }; + 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISliderExtensions.swift; sourceTree = ""; }; + 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensions.swift; sourceTree = ""; }; + 07B7F18B1F5EB41600E6F910 /* UISwitchExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISwitchExtensions.swift; sourceTree = ""; }; + 07B7F18C1F5EB41600E6F910 /* UITabBarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarExtensions.swift; sourceTree = ""; }; + 07B7F18D1F5EB41600E6F910 /* UITableViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewExtensions.swift; sourceTree = ""; }; + 07B7F18E1F5EB41600E6F910 /* UITextFieldExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensions.swift; sourceTree = ""; }; + 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewExtensions.swift; sourceTree = ""; }; + 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensions.swift; sourceTree = ""; }; + 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtensions.swift; sourceTree = ""; }; + 07C50CC91F5EAF2700F46E5A /* SwifterSwift-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 07C50CCD1F5EAF2700F46E5A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 07C50CD81F5EAF4B00F46E5A /* SwifterSwift-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 07C50CE71F5EAF6300F46E5A /* SwifterSwift-macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwifterSwift-macOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwifterSwiftTests.swift; sourceTree = ""; }; + 07C50CFA1F5EB03200F46E5A /* ArrayExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayExtensionsTests.swift; sourceTree = ""; }; + 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; }; + 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterExtensionsTests.swift; sourceTree = ""; }; + 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensionsTests.swift; sourceTree = ""; }; + 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtensionsTests.swift; sourceTree = ""; }; + 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtensionsTests.swift; sourceTree = ""; }; + 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionsTests.swift; sourceTree = ""; }; + 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleExtensionsTests.swift; sourceTree = ""; }; + 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatExtensionsTests.swift; sourceTree = ""; }; + 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntExtensionsTests.swift; sourceTree = ""; }; + 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleExtensionsTests.swift; sourceTree = ""; }; + 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalExtensionsTests.swift; sourceTree = ""; }; + 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; }; + 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; }; + 07C50D091F5EB03200F46E5A /* TestImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestImage.png; sourceTree = ""; }; + 07C50D0A1F5EB03200F46E5A /* TestStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TestStoryboard.storyboard; sourceTree = ""; }; + 07C50D0B1F5EB03200F46E5A /* UITableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UITableViewCell.xib; sourceTree = ""; }; + 07C50D0C1F5EB03200F46E5A /* UITableViewHeaderFooterView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UITableViewHeaderFooterView.xib; sourceTree = ""; }; + 07C50D0E1F5EB03200F46E5A /* UIAlertControllerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtensionsTests.swift; sourceTree = ""; }; + 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonExtensionsTests.swift; sourceTree = ""; }; + 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonExtensionsTests.swift; sourceTree = ""; }; + 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; }; + 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; }; + 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtensionsTests.swift; sourceTree = ""; }; + 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensionsTests.swift; sourceTree = ""; }; + 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelExtensionsTests.swift; sourceTree = ""; }; + 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationBarExtensionTests.swift; sourceTree = ""; }; + 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationControllerExtensionsTests.swift; sourceTree = ""; }; + 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationItemExtensionsTests.swift; sourceTree = ""; }; + 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensionsTests.swift; sourceTree = ""; }; + 07C50D1A1F5EB03200F46E5A /* UISegmentedControlExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISegmentedControlExtensionsTests.swift; sourceTree = ""; }; + 07C50D1B1F5EB03200F46E5A /* UISliderExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISliderExtensionsTests.swift; sourceTree = ""; }; + 07C50D1C1F5EB03200F46E5A /* UIStoryboardExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStoryboardExtensionsTests.swift; sourceTree = ""; }; + 07C50D1D1F5EB03200F46E5A /* UISwitchExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISwitchExtensionsTests.swift; sourceTree = ""; }; + 07C50D1E1F5EB03200F46E5A /* UITabBarExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarExtensionsTests.swift; sourceTree = ""; }; + 07C50D1F1F5EB03200F46E5A /* UITableViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewExtensionsTests.swift; sourceTree = ""; }; + 07C50D201F5EB03200F46E5A /* UITextFieldExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextFieldExtensionsTests.swift; sourceTree = ""; }; + 07C50D211F5EB03200F46E5A /* UITextViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewExtensionsTests.swift; sourceTree = ""; }; + 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExtensionsTests.swift; sourceTree = ""; }; + 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtensionsTests.swift; sourceTree = ""; }; + 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGFloatExtensionsTests.swift; sourceTree = ""; }; + 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGPointExtensionsTests.swift; sourceTree = ""; }; + 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGSizeExtensionsTests.swift; sourceTree = ""; }; + 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; + 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; + 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 077AD1B21F13873600D3214D /* Frameworks */ = { + 07898B591F278D7600558C97 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 077AD1BA1F13873600D3214D /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1C11F13875100D3214D /* Frameworks */ = { + 07898B671F278D9700558C97 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 077AD1C91F13875100D3214D /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1D01F13876000D3214D /* Frameworks */ = { + 07898B741F278DBC00558C97 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 077AD1D81F13876000D3214D /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3AA1F1380F100D0C644 /* Frameworks */ = { + 07898B811F278DD200558C97 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3B81F13816200D0C644 /* Frameworks */ = { + 07C50CC61F5EAF2700F46E5A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 07C50CCE1F5EAF2700F46E5A /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3C51F13817200D0C644 /* Frameworks */ = { + 07C50CD51F5EAF4B00F46E5A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 07C50CDD1F5EAF4B00F46E5A /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3D21F13818700D0C644 /* Frameworks */ = { + 07C50CE41F5EAF6300F46E5A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 07C50CEC1F5EAF6300F46E5A /* SwifterSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0743F2771F611B62008386F7 /* AppKit */ = { + 077BA0871F6BE73000D9C4AC /* SwiftStdlib */ = { isa = PBXGroup; children = ( - 0743F2781F611B62008386F7 /* NSColorExtensions.swift */, - 0743F2791F611B62008386F7 /* NSViewExtensions.swift */, + 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */, + 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */, + 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */, + 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */, + 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */, + 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */, + 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */, + 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */, + 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */, + 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */, + 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */, + 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */, + 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */, ); - path = AppKit; + path = SwiftStdlib; sourceTree = ""; }; - 0743F27A1F611B62008386F7 /* CoreGraphics */ = { + 077BA0931F6BE93000D9C4AC /* SwiftStdlibTests */ = { isa = PBXGroup; children = ( - 0743F27B1F611B62008386F7 /* CGColorExtensions.swift */, - 0743F27C1F611B62008386F7 /* CGFloatExtensions.swift */, - 0743F27D1F611B62008386F7 /* CGPointExtensions.swift */, - 0743F27E1F611B62008386F7 /* CGSizeExtensions.swift */, - ); - path = CoreGraphics; + 07C50CFA1F5EB03200F46E5A /* ArrayExtensionsTests.swift */, + 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */, + 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */, + 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */, + 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */, + 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */, + 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */, + 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */, + 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */, + 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */, + ); + path = SwiftStdlibTests; sourceTree = ""; }; - 0743F27F1F611B62008386F7 /* CoreLocation */ = { + 07898B511F278CF900558C97 = { isa = PBXGroup; children = ( - 0743F2801F611B62008386F7 /* CLLocationExtensions.swift */, + 07898B8D1F278E6300558C97 /* Sources */, + 07C50CF21F5EAF7B00F46E5A /* Tests */, + 07898B5E1F278D7600558C97 /* Products */, ); - path = CoreLocation; sourceTree = ""; }; - 0743F2811F611B62008386F7 /* Deprecated */ = { + 07898B5E1F278D7600558C97 /* Products */ = { isa = PBXGroup; children = ( - 0743F2821F611B62008386F7 /* SwifterSwiftDeprecated.swift */, + 07898B5D1F278D7600558C97 /* SwifterSwift.framework */, + 07898B6B1F278D9700558C97 /* SwifterSwift.framework */, + 07898B781F278DBC00558C97 /* SwifterSwift.framework */, + 07898B851F278DD200558C97 /* SwifterSwift.framework */, + 07C50CC91F5EAF2700F46E5A /* SwifterSwift-iOSTests.xctest */, + 07C50CD81F5EAF4B00F46E5A /* SwifterSwift-tvOSTests.xctest */, + 07C50CE71F5EAF6300F46E5A /* SwifterSwift-macOSTests.xctest */, ); - path = Deprecated; + name = Products; sourceTree = ""; }; - 0743F2831F611B62008386F7 /* Foundation */ = { + 07898B8D1F278E6300558C97 /* Sources */ = { isa = PBXGroup; children = ( - 0743F2861F611B62008386F7 /* Deprecated */, - 0743F2841F611B62008386F7 /* DataExtensions.swift */, - 0743F2851F611B62008386F7 /* DateExtensions.swift */, - 0743F2881F611B62008386F7 /* LocaleExtensions.swift */, - 0743F2891F611B62008386F7 /* NSAttributedStringExtensions.swift */, - 0743F28A1F611B62008386F7 /* URLExtensions.swift */, - 0743F28B1F611B62008386F7 /* URLRequestExtensions.swift */, - 0743F28C1F611B62008386F7 /* UserDefaultsExtensions.swift */, + 07898B941F27904200558C97 /* Extensions */, + 07898B8E1F278E6300558C97 /* Info.plist */, + 07898B8F1F278E6300558C97 /* SwifterSwift.h */, ); - path = Foundation; + path = Sources; sourceTree = ""; }; - 0743F2861F611B62008386F7 /* Deprecated */ = { + 07898B941F27904200558C97 /* Extensions */ = { isa = PBXGroup; children = ( - 0743F2871F611B62008386F7 /* FoundationDeprecated.swift */, - ); - path = Deprecated; + 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, + 07B7F1651F5EB41600E6F910 /* Foundation */, + 07B7F1791F5EB41600E6F910 /* UIKit */, + 07D8960D1F5ED85400FC894D /* CoreGraphics */, + 07D8960C1F5ED84400FC894D /* CoreLocation */, + 07B7F15C1F5EB41600E6F910 /* AppKit */, + 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */, + ); + path = Extensions; sourceTree = ""; }; - 0743F28E1F611B62008386F7 /* SwiftStdlib */ = { + 07B7F15C1F5EB41600E6F910 /* AppKit */ = { isa = PBXGroup; children = ( - 0743F28F1F611B62008386F7 /* ArrayExtensions.swift */, - 0743F2901F611B62008386F7 /* BoolExtensions.swift */, - 0743F2911F611B62008386F7 /* CharacterExtensions.swift */, - 0743F2921F611B62008386F7 /* CollectionExtensions.swift */, - 0743F2931F611B62008386F7 /* DictionaryExtensions.swift */, - 0743F2941F611B62008386F7 /* DoubleExtensions.swift */, - 0743F2951F611B62008386F7 /* FloatExtensions.swift */, - 0743F2961F611B62008386F7 /* FloatingPointExtensions.swift */, - 0743F2971F611B62008386F7 /* IntExtensions.swift */, - 0743F2981F611B62008386F7 /* OptionalExtensions.swift */, - 0743F2991F611B62008386F7 /* SignedIntegerExtensions.swift */, - 0743F29A1F611B62008386F7 /* SignedNumericExtensions.swift */, - 0743F29B1F611B62008386F7 /* StringExtensions.swift */, + 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */, + 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */, ); - path = SwiftStdlib; + path = AppKit; sourceTree = ""; }; - 0743F29C1F611B62008386F7 /* UIKit */ = { + 07B7F1651F5EB41600E6F910 /* Foundation */ = { isa = PBXGroup; children = ( - 0743F29D1F611B62008386F7 /* Deprecated */, - 0743F29F1F611B62008386F7 /* UIAlertControllerExtensions.swift */, - 0743F2A01F611B62008386F7 /* UIBarButtonItemExtensions.swift */, - 0743F2A11F611B62008386F7 /* UIButtonExtensions.swift */, - 0743F2A21F611B62008386F7 /* UICollectionViewExtensions.swift */, - 0743F2A31F611B62008386F7 /* UIColorExtensions.swift */, - 0743F2A41F611B62008386F7 /* UIImageExtensions.swift */, - 0743F2A51F611B62008386F7 /* UIImageViewExtensions.swift */, - 0743F2A61F611B62008386F7 /* UILabelExtensions.swift */, - 0743F2A71F611B62008386F7 /* UINavigationBarExtensions.swift */, - 0743F2A81F611B62008386F7 /* UINavigationControllerExtensions.swift */, - 0743F2A91F611B62008386F7 /* UINavigationItemExtensions.swift */, - 0743F2AA1F611B62008386F7 /* UISearchBarExtensions.swift */, - 0743F2AB1F611B62008386F7 /* UISegmentedControlExtensions.swift */, - 0743F2AC1F611B62008386F7 /* UISliderExtensions.swift */, - 0743F2AD1F611B62008386F7 /* UIStoryboardExtensions.swift */, - 0743F2AE1F611B62008386F7 /* UISwitchExtensions.swift */, - 0743F2AF1F611B62008386F7 /* UITabBarExtensions.swift */, - 0743F2B01F611B62008386F7 /* UITableViewExtensions.swift */, - 0743F2B11F611B62008386F7 /* UITextFieldExtensions.swift */, - 0743F2B21F611B62008386F7 /* UITextViewExtensions.swift */, - 0743F2B31F611B62008386F7 /* UIViewControllerExtensions.swift */, - 0743F2B41F611B62008386F7 /* UIViewExtensions.swift */, - 0743F2B51F611B62008386F7 /* UIWebViewExtensions.swift */, + 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */, + 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */, + 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */, + 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */, + 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */, + 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */, + 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */, ); - path = UIKit; + path = Foundation; sourceTree = ""; }; - 0743F29D1F611B62008386F7 /* Deprecated */ = { + 07B7F1791F5EB41600E6F910 /* UIKit */ = { isa = PBXGroup; children = ( - 0743F29E1F611B62008386F7 /* UIKitDeprecated.swift */, + 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */, + 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */, + 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */, + 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */, + 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */, + 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */, + 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */, + 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */, + 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */, + 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */, + 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */, + 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */, + 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */, + 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */, + 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */, + 07B7F18B1F5EB41600E6F910 /* UISwitchExtensions.swift */, + 07B7F18C1F5EB41600E6F910 /* UITabBarExtensions.swift */, + 07B7F18D1F5EB41600E6F910 /* UITableViewExtensions.swift */, + 07B7F18E1F5EB41600E6F910 /* UITextFieldExtensions.swift */, + 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */, + 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */, + 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */, ); - path = Deprecated; + path = UIKit; sourceTree = ""; }; - 0743F38E1F611B87008386F7 /* AppKitTests */ = { + 07C50CF21F5EAF7B00F46E5A /* Tests */ = { isa = PBXGroup; children = ( - 0743F3901F611B87008386F7 /* NSViewExtensionsTests.swift */, - ); - name = AppKitTests; - path = Tests/AppKitTests; + 077BA0931F6BE93000D9C4AC /* SwiftStdlibTests */, + 07C50CF91F5EB03200F46E5A /* FoundationTests */, + 07C50D0D1F5EB03200F46E5A /* UIKitTests */, + 07D8960F1F5ED8AB00FC894D /* CoreLocationTests */, + 07D8960E1F5ED89A00FC894D /* CoreGraphicsTests */, + 07C50D241F5EB03200F46E5A /* AppKitTests */, + 07C50CCD1F5EAF2700F46E5A /* Info.plist */, + 07C50D081F5EB03200F46E5A /* Resources */, + 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */, + ); + path = Tests; sourceTree = ""; }; - 0743F3911F611B87008386F7 /* CoreGraphicsTests */ = { + 07C50CF91F5EB03200F46E5A /* FoundationTests */ = { isa = PBXGroup; children = ( - 0743F3921F611B87008386F7 /* CGFloatExtensionsTests.swift */, - 0743F3931F611B87008386F7 /* CGPointExtensionsTests.swift */, - 0743F3941F611B87008386F7 /* CGSizeExtensionsTests.swift */, - ); - name = CoreGraphicsTests; - path = Tests/CoreGraphicsTests; + 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */, + 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */, + 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */, + 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */, + 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */, + 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */, + 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */, + ); + path = FoundationTests; sourceTree = ""; }; - 0743F3951F611B87008386F7 /* CoreLocationTests */ = { + 07C50D081F5EB03200F46E5A /* Resources */ = { isa = PBXGroup; children = ( - 0743F3961F611B87008386F7 /* CLLocationExtensionsTests.swift */, + 07C50D091F5EB03200F46E5A /* TestImage.png */, + 07C50D0A1F5EB03200F46E5A /* TestStoryboard.storyboard */, + 07C50D0B1F5EB03200F46E5A /* UITableViewCell.xib */, + 07C50D0C1F5EB03200F46E5A /* UITableViewHeaderFooterView.xib */, ); - name = CoreLocationTests; - path = Tests/CoreLocationTests; + path = Resources; sourceTree = ""; }; - 0743F3971F611B87008386F7 /* FoundationTests */ = { + 07C50D0D1F5EB03200F46E5A /* UIKitTests */ = { isa = PBXGroup; children = ( - 0743F3981F611B87008386F7 /* DataExtensionsTests.swift */, - 0743F3991F611B87008386F7 /* DateExtensionsTests.swift */, - 0743F39A1F611B87008386F7 /* LocaleExtensionsTests.swift */, - 0743F38F1F611B87008386F7 /* NSAttributedStringExtensionsTests.swift */, - 0743F39B1F611B87008386F7 /* URLExtensionsTests.swift */, - 0743F39C1F611B87008386F7 /* URLRequestExtensionsTests.swift */, - 0743F39D1F611B87008386F7 /* UserDefaultsExtensionsTests.swift */, - ); - name = FoundationTests; - path = Tests/FoundationTests; + 07C50D0E1F5EB03200F46E5A /* UIAlertControllerExtensionsTests.swift */, + 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */, + 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */, + 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */, + 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */, + 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */, + 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */, + 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */, + 07C50D161F5EB03200F46E5A /* UINavigationBarExtensionTests.swift */, + 07C50D171F5EB03200F46E5A /* UINavigationControllerExtensionsTests.swift */, + 07C50D181F5EB03200F46E5A /* UINavigationItemExtensionsTests.swift */, + 07C50D191F5EB03200F46E5A /* UISearchBarExtensionsTests.swift */, + 07C50D1A1F5EB03200F46E5A /* UISegmentedControlExtensionsTests.swift */, + 07C50D1B1F5EB03200F46E5A /* UISliderExtensionsTests.swift */, + 07C50D1C1F5EB03200F46E5A /* UIStoryboardExtensionsTests.swift */, + 07C50D1D1F5EB03200F46E5A /* UISwitchExtensionsTests.swift */, + 07C50D1E1F5EB03200F46E5A /* UITabBarExtensionsTests.swift */, + 07C50D1F1F5EB03200F46E5A /* UITableViewExtensionsTests.swift */, + 07C50D201F5EB03200F46E5A /* UITextFieldExtensionsTests.swift */, + 07C50D211F5EB03200F46E5A /* UITextViewExtensionsTests.swift */, + 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */, + 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */, + ); + path = UIKitTests; sourceTree = ""; }; - 0743F39E1F611B87008386F7 /* SwiftStdlibTests */ = { + 07C50D241F5EB03200F46E5A /* AppKitTests */ = { isa = PBXGroup; children = ( - 0743F39F1F611B87008386F7 /* ArrayExtensionsTests.swift */, - 0743F3A01F611B87008386F7 /* BoolExtensionsTests.swift */, - 0743F3A11F611B87008386F7 /* CharacterExtensionsTests.swift */, - 0743F3A21F611B87008386F7 /* CollectionExtensionsTests.swift */, - 0743F3A31F611B87008386F7 /* DictionaryExtensionsTests.swift */, - 0743F3A41F611B87008386F7 /* DoubleExtensionsTests.swift */, - 0743F3A51F611B87008386F7 /* FloatExtensionsTests.swift */, - 0743F3A61F611B87008386F7 /* IntExtensionsTests.swift */, - 0743F3A71F611B87008386F7 /* OptionalExtensionsTests.swift */, - 0743F3A81F611B87008386F7 /* StringExtensionsTests.swift */, - ); - name = SwiftStdlibTests; - path = Tests/SwiftStdlibTests; - sourceTree = ""; - }; - 0743F3A91F611B87008386F7 /* UIKitTests */ = { - isa = PBXGroup; - children = ( - 0743F3AA1F611B87008386F7 /* UIAlertControllerExtensionsTests.swift */, - 0743F3AB1F611B87008386F7 /* UIBarButtonExtensionsTests.swift */, - 0743F3AC1F611B87008386F7 /* UIButtonExtensionsTests.swift */, - 0743F3AD1F611B87008386F7 /* UICollectionViewExtensionsTests.swift */, - 0743F3AE1F611B87008386F7 /* UIColorExtensionsTests.swift */, - 0743F3AF1F611B87008386F7 /* UIImageExtensionsTests.swift */, - 0743F3B01F611B87008386F7 /* UIImageViewExtensionsTests.swift */, - 0743F3B11F611B87008386F7 /* UILabelExtensionsTests.swift */, - 0743F3B21F611B87008386F7 /* UINavigationBarExtensionTests.swift */, - 0743F3B31F611B87008386F7 /* UINavigationControllerExtensionsTests.swift */, - 0743F3B41F611B87008386F7 /* UINavigationItemExtensionsTests.swift */, - 0743F3B51F611B87008386F7 /* UISearchBarExtensionsTests.swift */, - 0743F3B61F611B87008386F7 /* UISegmentedControlExtensionsTests.swift */, - 0743F3B71F611B87008386F7 /* UISliderExtensionsTests.swift */, - 0743F3B81F611B87008386F7 /* UIStoryboardExtensionsTests.swift */, - 0743F3B91F611B87008386F7 /* UISwitchExtensionsTests.swift */, - 0743F3BA1F611B87008386F7 /* UITabBarExtensionsTests.swift */, - 0743F3BB1F611B87008386F7 /* UITableViewExtensionsTests.swift */, - 0743F3BC1F611B87008386F7 /* UITextFieldExtensionsTests.swift */, - 0743F3BD1F611B87008386F7 /* UITextViewExtensionsTests.swift */, - 0743F3BE1F611B87008386F7 /* UIViewControllerExtensionsTests.swift */, - 0743F3BF1F611B87008386F7 /* UIViewExtensionsTests.swift */, - 0743F3C01F611B87008386F7 /* UIWebViewExtensionsTests.swift */, - ); - name = UIKitTests; - path = Tests/UIKitTests; - sourceTree = ""; - }; - 077AD1DE1F1387C100D3214D /* Tests */ = { - isa = PBXGroup; - children = ( - 078980DC1F138B0400A3A4E1 /* SwifterSwiftTests.swift */, - 0743F39E1F611B87008386F7 /* SwiftStdlibTests */, - 0743F3971F611B87008386F7 /* FoundationTests */, - 0743F3A91F611B87008386F7 /* UIKitTests */, - 0743F38E1F611B87008386F7 /* AppKitTests */, - 0743F3911F611B87008386F7 /* CoreGraphicsTests */, - 0743F3951F611B87008386F7 /* CoreLocationTests */, - 078980721F138AF000A3A4E1 /* Resources */, - 077AD1DF1F1387D600D3214D /* Info.plist */, - ); - name = Tests; - sourceTree = ""; - }; - 07897F401F138A3300A3A4E1 /* Extensions */ = { - isa = PBXGroup; - children = ( - 0743F28D1F611B62008386F7 /* SwifterSwift.swift */, - 0743F28E1F611B62008386F7 /* SwiftStdlib */, - 0743F2831F611B62008386F7 /* Foundation */, - 0743F29C1F611B62008386F7 /* UIKit */, - 0743F2771F611B62008386F7 /* AppKit */, - 0743F27A1F611B62008386F7 /* CoreGraphics */, - 0743F27F1F611B62008386F7 /* CoreLocation */, - 0743F2811F611B62008386F7 /* Deprecated */, - ); - name = Extensions; - path = Sources/Extensions; + 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */, + ); + path = AppKitTests; sourceTree = ""; }; - 078980721F138AF000A3A4E1 /* Resources */ = { + 07D8960C1F5ED84400FC894D /* CoreLocation */ = { isa = PBXGroup; children = ( - 078980731F138AF000A3A4E1 /* TestImage.png */, - 078980741F138AF000A3A4E1 /* TestStoryboard.storyboard */, - 078980751F138AF000A3A4E1 /* UITableViewCell.xib */, - 078980761F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib */, + 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */, ); - name = Resources; - path = Tests/Resources; + path = CoreLocation; sourceTree = ""; }; - 079412C41F137D5C006AA1F8 = { + 07D8960D1F5ED85400FC894D /* CoreGraphics */ = { isa = PBXGroup; children = ( - 07DFA3DE1F13824300D0C644 /* Sources */, - 077AD1DE1F1387C100D3214D /* Tests */, - 07DFA3AF1F1380F100D0C644 /* Products */, + 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */, + 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */, + 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */, + 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */, ); + path = CoreGraphics; sourceTree = ""; }; - 07DFA3AF1F1380F100D0C644 /* Products */ = { + 07D8960E1F5ED89A00FC894D /* CoreGraphicsTests */ = { isa = PBXGroup; children = ( - 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */, - 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */, - 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */, - 07DFA3D61F13818700D0C644 /* SwifterSwift.framework */, - 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */, - 077AD1C41F13875100D3214D /* SwifterSwift macOSTests.xctest */, - 077AD1D31F13876000D3214D /* SwifterSwift tvOSTests.xctest */, + 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */, + 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */, + 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */, ); - name = Products; + path = CoreGraphicsTests; sourceTree = ""; }; - 07DFA3DE1F13824300D0C644 /* Sources */ = { + 07D8960F1F5ED8AB00FC894D /* CoreLocationTests */ = { isa = PBXGroup; children = ( - 07897F401F138A3300A3A4E1 /* Extensions */, - 07DFA3E31F13844C00D0C644 /* SwifterSwift.h */, - 07DFA3DF1F13825700D0C644 /* Info.plist */, + 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */, ); - name = Sources; + path = CoreLocationTests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 07DFA3AB1F1380F100D0C644 /* Headers */ = { + 07898B5A1F278D7600558C97 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 07DFA3E41F13844C00D0C644 /* SwifterSwift.h in Headers */, + 07898B901F278F0800558C97 /* SwifterSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3B91F13816200D0C644 /* Headers */ = { + 07898B681F278D9700558C97 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 07DFA3E51F13844C00D0C644 /* SwifterSwift.h in Headers */, + 07898B911F278F0C00558C97 /* SwifterSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3C61F13817200D0C644 /* Headers */ = { + 07898B751F278DBC00558C97 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 07DFA3E61F13844C00D0C644 /* SwifterSwift.h in Headers */, + 07898B921F278F1000558C97 /* SwifterSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3D31F13818700D0C644 /* Headers */ = { + 07898B821F278DD200558C97 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 07DFA3E71F13844C00D0C644 /* SwifterSwift.h in Headers */, + 07898B931F278F1300558C97 /* SwifterSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 077AD1B41F13873600D3214D /* SwifterSwift iOSTests */ = { + 07898B5C1F278D7600558C97 /* SwifterSwift-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 077AD1BD1F13873600D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift iOSTests" */; + buildConfigurationList = 07898B631F278D7600558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-iOS" */; buildPhases = ( - 077AD1B11F13873600D3214D /* Sources */, - 077AD1B21F13873600D3214D /* Frameworks */, - 077AD1B31F13873600D3214D /* Resources */, + 07898B581F278D7600558C97 /* Sources */, + 07898B591F278D7600558C97 /* Frameworks */, + 07898B5A1F278D7600558C97 /* Headers */, + 07898B5B1F278D7600558C97 /* Resources */, ); buildRules = ( ); dependencies = ( - 077AD1BC1F13873600D3214D /* PBXTargetDependency */, ); - name = "SwifterSwift iOSTests"; - productName = "SwifterSwift iOSTests"; - productReference = 077AD1B51F13873600D3214D /* SwifterSwift iOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = "SwifterSwift-iOS"; + productName = "SwifterSwift-iOS"; + productReference = 07898B5D1F278D7600558C97 /* SwifterSwift.framework */; + productType = "com.apple.product-type.framework"; }; - 077AD1C31F13875100D3214D /* SwifterSwift macOSTests */ = { + 07898B6A1F278D9700558C97 /* SwifterSwift-tvOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 077AD1CC1F13875100D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift macOSTests" */; + buildConfigurationList = 07898B701F278D9700558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-tvOS" */; buildPhases = ( - 077AD1C01F13875100D3214D /* Sources */, - 077AD1C11F13875100D3214D /* Frameworks */, - 077AD1C21F13875100D3214D /* Resources */, + 07898B661F278D9700558C97 /* Sources */, + 07898B671F278D9700558C97 /* Frameworks */, + 07898B681F278D9700558C97 /* Headers */, + 07898B691F278D9700558C97 /* Resources */, ); buildRules = ( ); dependencies = ( - 077AD1CB1F13875100D3214D /* PBXTargetDependency */, ); - name = "SwifterSwift macOSTests"; - productName = "SwifterSwift macTests"; - productReference = 077AD1C41F13875100D3214D /* SwifterSwift macOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = "SwifterSwift-tvOS"; + productName = "SwifterSwift-tvOS"; + productReference = 07898B6B1F278D9700558C97 /* SwifterSwift.framework */; + productType = "com.apple.product-type.framework"; }; - 077AD1D21F13876000D3214D /* SwifterSwift tvOSTests */ = { + 07898B771F278DBC00558C97 /* SwifterSwift-watchOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 077AD1DB1F13876000D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift tvOSTests" */; + buildConfigurationList = 07898B7D1F278DBC00558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-watchOS" */; buildPhases = ( - 077AD1CF1F13876000D3214D /* Sources */, - 077AD1D01F13876000D3214D /* Frameworks */, - 077AD1D11F13876000D3214D /* Resources */, + 07898B731F278DBC00558C97 /* Sources */, + 07898B741F278DBC00558C97 /* Frameworks */, + 07898B751F278DBC00558C97 /* Headers */, + 07898B761F278DBC00558C97 /* Resources */, ); buildRules = ( ); dependencies = ( - 077AD1DA1F13876000D3214D /* PBXTargetDependency */, ); - name = "SwifterSwift tvOSTests"; - productName = "SwifterSwift tvTests"; - productReference = 077AD1D31F13876000D3214D /* SwifterSwift tvOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = "SwifterSwift-watchOS"; + productName = "SwifterSwift-watchOS"; + productReference = 07898B781F278DBC00558C97 /* SwifterSwift.framework */; + productType = "com.apple.product-type.framework"; }; - 07DFA3AD1F1380F100D0C644 /* SwifterSwift iOS */ = { + 07898B841F278DD200558C97 /* SwifterSwift-macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 07DFA3B61F1380F100D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift iOS" */; + buildConfigurationList = 07898B8A1F278DD200558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-macOS" */; buildPhases = ( - 07DFA3A91F1380F100D0C644 /* Sources */, - 07DFA3AA1F1380F100D0C644 /* Frameworks */, - 07DFA3AB1F1380F100D0C644 /* Headers */, - 07DFA3AC1F1380F100D0C644 /* Resources */, + 07898B801F278DD200558C97 /* Sources */, + 07898B811F278DD200558C97 /* Frameworks */, + 07898B821F278DD200558C97 /* Headers */, + 07898B831F278DD200558C97 /* Resources */, ); buildRules = ( ); dependencies = ( ); - name = "SwifterSwift iOS"; - productName = "SwifterSwift iOS"; - productReference = 07DFA3AE1F1380F100D0C644 /* SwifterSwift.framework */; + name = "SwifterSwift-macOS"; + productName = "SwifterSwift-macOS"; + productReference = 07898B851F278DD200558C97 /* SwifterSwift.framework */; productType = "com.apple.product-type.framework"; }; - 07DFA3BB1F13816200D0C644 /* SwifterSwift macOS */ = { + 07C50CC81F5EAF2700F46E5A /* SwifterSwift-iOSTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 07DFA3C11F13816200D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift macOS" */; + buildConfigurationList = 07C50CD31F5EAF2700F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-iOSTests" */; buildPhases = ( - 07DFA3B71F13816200D0C644 /* Sources */, - 07DFA3B81F13816200D0C644 /* Frameworks */, - 07DFA3B91F13816200D0C644 /* Headers */, - 07DFA3BA1F13816200D0C644 /* Resources */, + 07C50CC51F5EAF2700F46E5A /* Sources */, + 07C50CC61F5EAF2700F46E5A /* Frameworks */, + 07C50CC71F5EAF2700F46E5A /* Resources */, ); buildRules = ( ); dependencies = ( + 07C50CD01F5EAF2700F46E5A /* PBXTargetDependency */, ); - name = "SwifterSwift macOS"; - productName = "SwifterSwift macOS"; - productReference = 07DFA3BC1F13816200D0C644 /* SwifterSwift.framework */; - productType = "com.apple.product-type.framework"; + name = "SwifterSwift-iOSTests"; + productName = "SwifterSwift-iOSTests"; + productReference = 07C50CC91F5EAF2700F46E5A /* SwifterSwift-iOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; - 07DFA3C81F13817200D0C644 /* SwifterSwift tvOS */ = { + 07C50CD71F5EAF4B00F46E5A /* SwifterSwift-tvOSTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 07DFA3CE1F13817200D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift tvOS" */; + buildConfigurationList = 07C50CE01F5EAF4B00F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-tvOSTests" */; buildPhases = ( - 07DFA3C41F13817200D0C644 /* Sources */, - 07DFA3C51F13817200D0C644 /* Frameworks */, - 07DFA3C61F13817200D0C644 /* Headers */, - 07DFA3C71F13817200D0C644 /* Resources */, + 07C50CD41F5EAF4B00F46E5A /* Sources */, + 07C50CD51F5EAF4B00F46E5A /* Frameworks */, + 07C50CD61F5EAF4B00F46E5A /* Resources */, ); buildRules = ( ); dependencies = ( + 07C50CDF1F5EAF4B00F46E5A /* PBXTargetDependency */, ); - name = "SwifterSwift tvOS"; - productName = "SwifterSwift tvOS"; - productReference = 07DFA3C91F13817200D0C644 /* SwifterSwift.framework */; - productType = "com.apple.product-type.framework"; + name = "SwifterSwift-tvOSTests"; + productName = "SwifterSwift-tvOSTests"; + productReference = 07C50CD81F5EAF4B00F46E5A /* SwifterSwift-tvOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; - 07DFA3D51F13818700D0C644 /* SwifterSwift watchOS */ = { + 07C50CE61F5EAF6300F46E5A /* SwifterSwift-macOSTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 07DFA3DB1F13818700D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift watchOS" */; + buildConfigurationList = 07C50CEF1F5EAF6300F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-macOSTests" */; buildPhases = ( - 07DFA3D11F13818700D0C644 /* Sources */, - 07DFA3D21F13818700D0C644 /* Frameworks */, - 07DFA3D31F13818700D0C644 /* Headers */, - 07DFA3D41F13818700D0C644 /* Resources */, + 07C50CE31F5EAF6300F46E5A /* Sources */, + 07C50CE41F5EAF6300F46E5A /* Frameworks */, + 07C50CE51F5EAF6300F46E5A /* Resources */, ); buildRules = ( ); dependencies = ( + 07C50CEE1F5EAF6300F46E5A /* PBXTargetDependency */, ); - name = "SwifterSwift watchOS"; - productName = "SwifterSwift watchOS"; - productReference = 07DFA3D61F13818700D0C644 /* SwifterSwift.framework */; - productType = "com.apple.product-type.framework"; + name = "SwifterSwift-macOSTests"; + productName = "SwifterSwift-macOSTests"; + productReference = 07C50CE71F5EAF6300F46E5A /* SwifterSwift-macOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - 079412C51F137D5C006AA1F8 /* Project object */ = { + 07898B521F278CF900558C97 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0830; + LastSwiftUpdateCheck = 0900; LastUpgradeCheck = 0900; TargetAttributes = { - 077AD1B41F13873600D3214D = { - CreatedOnToolsVersion = 8.3.3; + 07898B5C1F278D7600558C97 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; - 077AD1C31F13875100D3214D = { - CreatedOnToolsVersion = 8.3.3; + 07898B6A1F278D9700558C97 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; - 077AD1D21F13876000D3214D = { - CreatedOnToolsVersion = 8.3.3; + 07898B771F278DBC00558C97 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; - 07DFA3AD1F1380F100D0C644 = { - CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0830; + 07898B841F278DD200558C97 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 0900; ProvisioningStyle = Automatic; }; - 07DFA3BB1F13816200D0C644 = { - CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0830; + 07C50CC81F5EAF2700F46E5A = { + CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; - 07DFA3C81F13817200D0C644 = { - CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0830; + 07C50CD71F5EAF4B00F46E5A = { + CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; - 07DFA3D51F13818700D0C644 = { - CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0830; + 07C50CE61F5EAF6300F46E5A = { + CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; }; }; - buildConfigurationList = 079412C81F137D5C006AA1F8 /* Build configuration list for PBXProject "SwifterSwift" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + buildConfigurationList = 07898B551F278CF900558C97 /* Build configuration list for PBXProject "SwifterSwift" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = 079412C41F137D5C006AA1F8; - productRefGroup = 07DFA3AF1F1380F100D0C644 /* Products */; + mainGroup = 07898B511F278CF900558C97; + productRefGroup = 07898B5E1F278D7600558C97 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 07DFA3AD1F1380F100D0C644 /* SwifterSwift iOS */, - 07DFA3BB1F13816200D0C644 /* SwifterSwift macOS */, - 07DFA3C81F13817200D0C644 /* SwifterSwift tvOS */, - 07DFA3D51F13818700D0C644 /* SwifterSwift watchOS */, - 077AD1B41F13873600D3214D /* SwifterSwift iOSTests */, - 077AD1C31F13875100D3214D /* SwifterSwift macOSTests */, - 077AD1D21F13876000D3214D /* SwifterSwift tvOSTests */, + 07898B5C1F278D7600558C97 /* SwifterSwift-iOS */, + 07898B6A1F278D9700558C97 /* SwifterSwift-tvOS */, + 07898B771F278DBC00558C97 /* SwifterSwift-watchOS */, + 07898B841F278DD200558C97 /* SwifterSwift-macOS */, + 07C50CC81F5EAF2700F46E5A /* SwifterSwift-iOSTests */, + 07C50CD71F5EAF4B00F46E5A /* SwifterSwift-tvOSTests */, + 07C50CE61F5EAF6300F46E5A /* SwifterSwift-macOSTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 077AD1B31F13873600D3214D /* Resources */ = { + 07898B5B1F278D7600558C97 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 078980971F138AF000A3A4E1 /* UITableViewHeaderFooterView.xib in Resources */, - 078980941F138AF000A3A4E1 /* UITableViewCell.xib in Resources */, - 0789808E1F138AF000A3A4E1 /* TestImage.png in Resources */, - 078980911F138AF000A3A4E1 /* TestStoryboard.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1C21F13875100D3214D /* Resources */ = { + 07898B691F278D9700558C97 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0789808F1F138AF000A3A4E1 /* TestImage.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1D11F13876000D3214D /* Resources */ = { + 07898B761F278DBC00558C97 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 078980901F138AF000A3A4E1 /* TestImage.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3AC1F1380F100D0C644 /* Resources */ = { + 07898B831F278DD200558C97 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3BA1F13816200D0C644 /* Resources */ = { + 07C50CC71F5EAF2700F46E5A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 07C50D911F5EB07400F46E5A /* TestImage.png in Resources */, + 07C50D981F5EB08200F46E5A /* TestStoryboard.storyboard in Resources */, + 07C50D951F5EB07D00F46E5A /* UITableViewHeaderFooterView.xib in Resources */, + 07C50D941F5EB07D00F46E5A /* UITableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3C71F13817200D0C644 /* Resources */ = { + 07C50CD61F5EAF4B00F46E5A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 07C50D921F5EB07500F46E5A /* TestImage.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3D41F13818700D0C644 /* Resources */ = { + 07C50CE51F5EAF6300F46E5A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 07C50D931F5EB07500F46E5A /* TestImage.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 077AD1B11F13873600D3214D /* Sources */ = { + 07898B581F278D7600558C97 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F3CA1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, - 0743F3E51F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, - 0743F41E1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, - 0743F4061F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, - 0743F4211F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, - 0743F3D91F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, - 0743F3D31F611B87008386F7 /* DataExtensionsTests.swift in Sources */, - 0743F3D61F611B87008386F7 /* DateExtensionsTests.swift in Sources */, - 0743F3F11F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, - 0743F4091F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, - 0743F42D1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, - 0743F3EE1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, - 078980DD1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 0743F4331F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, - 0743F3DF1F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, - 0743F40F1F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, - 0743F43F1F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, - 0743F4391F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, - 0743F4361F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, - 0743F3CD1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, - 0743F3F71F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, - 0743F4151F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, - 0743F3F41F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, - 0743F3FA1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, - 0743F4181F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, - 0743F4271F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, - 0743F4301F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, - 0743F40C1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, - 0743F3E81F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, - 0743F3EB1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, - 0743F3DC1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, - 0743F43C1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, - 0743F3D01F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, - 0743F3FD1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, - 0743F3C11F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, - 0743F41B1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, - 0743F42A1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, - 0743F4001F611B87008386F7 /* StringExtensionsTests.swift in Sources */, - 0743F4421F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, - 0743F4121F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, - 0743F3E21F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, - 0743F4451F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, - 0743F3C71F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, - 0743F4031F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, - 0743F4241F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, - 0743F3C41F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, + 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, + 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, + 07B7F1991F5EB42000E6F910 /* UILabelExtensions.swift in Sources */, + 07B7F20C1F5EB43C00E6F910 /* BoolExtensions.swift in Sources */, + 07B7F22F1F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */, + 07B7F1981F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */, + 07B7F2321F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */, + 07B7F20E1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */, + 07B7F2151F5EB43C00E6F910 /* IntExtensions.swift in Sources */, + 07B7F2111F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */, + 07B7F2301F5EB45100E6F910 /* CGPointExtensions.swift in Sources */, + 07B7F1951F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, + 07B7F1A31F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, + 077BA08F1F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, + 07B7F1A11F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, + 07B7F1A41F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */, + 07B7F20B1F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */, + 07B7F1A01F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */, + 07B7F19A1F5EB42000E6F910 /* UINavigationBarExtensions.swift in Sources */, + 07B7F1941F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */, + 07B7F21B1F5EB43C00E6F910 /* URLExtensions.swift in Sources */, + 07B7F19B1F5EB42000E6F910 /* UINavigationControllerExtensions.swift in Sources */, + 07B7F19F1F5EB42000E6F910 /* UISliderExtensions.swift in Sources */, + 07B7F1931F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */, + 07B7F1A21F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */, + 07B7F1A61F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */, + 07B7F2311F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */, + 07B7F20D1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */, + 07B7F19D1F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, + 07B7F21A1F5EB43C00E6F910 /* StringExtensions.swift in Sources */, + 07B7F2331F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, + 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 07B7F2131F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, + 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, + 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, + 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, + 07B7F22E1F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, + 07B7F21F1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 07B7F2161F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, + 07B7F2101F5EB43C00E6F910 /* DateExtensions.swift in Sources */, + 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, + 07B7F19E1F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, + 07B7F1961F5EB42000E6F910 /* UIColorExtensions.swift in Sources */, + 07B7F20F1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, + 07B7F19C1F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */, + 07B7F1A51F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1C01F13875100D3214D /* Sources */ = { + 07898B661F278D9700558C97 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F3CB1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, - 0743F3E61F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, - 0743F41F1F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, - 0743F4071F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, - 0743F4221F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, - 0743F3DA1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, - 0743F3D41F611B87008386F7 /* DataExtensionsTests.swift in Sources */, - 0743F3D71F611B87008386F7 /* DateExtensionsTests.swift in Sources */, - 0743F3F21F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, - 0743F40A1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, - 0743F42E1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, - 0743F3EF1F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, - 078980DE1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 0743F4341F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, - 0743F3E01F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, - 0743F4101F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, - 0743F4401F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, - 0743F43A1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, - 0743F4371F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, - 0743F3CE1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, - 0743F3F81F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, - 0743F4161F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, - 0743F3F51F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, - 0743F3FB1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, - 0743F4191F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, - 0743F4281F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, - 0743F4311F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, - 0743F40D1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, - 0743F3E91F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, - 0743F3EC1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, - 0743F3DD1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, - 0743F43D1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, - 0743F3D11F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, - 0743F3FE1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, - 0743F3C21F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, - 0743F41C1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, - 0743F42B1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, - 0743F4011F611B87008386F7 /* StringExtensionsTests.swift in Sources */, - 0743F4431F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, - 0743F4131F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, - 0743F3E31F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, - 0743F4461F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, - 0743F3C81F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, - 0743F4041F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, - 0743F4251F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, - 0743F3C51F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, + 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, + 07B7F1BD1F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, + 07B7F1AF1F5EB42000E6F910 /* UILabelExtensions.swift in Sources */, + 07B7F1FA1F5EB43C00E6F910 /* BoolExtensions.swift in Sources */, + 07B7F2351F5EB45200E6F910 /* CGFloatExtensions.swift in Sources */, + 07B7F1AE1F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */, + 07B7F2381F5EB45200E6F910 /* CLLocationExtensions.swift in Sources */, + 07B7F1FC1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */, + 07B7F2031F5EB43C00E6F910 /* IntExtensions.swift in Sources */, + 07B7F1FF1F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */, + 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */, + 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, + 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, + 077BA0901F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, + 07B7F1B71F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, + 07B7F1BA1F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */, + 07B7F1F91F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */, + 07B7F1B61F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */, + 07B7F1B01F5EB42000E6F910 /* UINavigationBarExtensions.swift in Sources */, + 07B7F1AA1F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */, + 07B7F2091F5EB43C00E6F910 /* URLExtensions.swift in Sources */, + 07B7F1B11F5EB42000E6F910 /* UINavigationControllerExtensions.swift in Sources */, + 07B7F1B51F5EB42000E6F910 /* UISliderExtensions.swift in Sources */, + 07B7F1A91F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */, + 07B7F1B81F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */, + 07B7F1BC1F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */, + 07B7F2371F5EB45200E6F910 /* CGSizeExtensions.swift in Sources */, + 07B7F1FB1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */, + 07B7F1B31F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, + 07B7F2081F5EB43C00E6F910 /* StringExtensions.swift in Sources */, + 07B7F2391F5EB45200E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, + 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 07B7F2011F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, + 07B7F2001F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, + 07B7F2051F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, + 07B7F1A81F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, + 07B7F2341F5EB45200E6F910 /* CGColorExtensions.swift in Sources */, + 07B7F21E1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 07B7F2041F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, + 07B7F1FE1F5EB43C00E6F910 /* DateExtensions.swift in Sources */, + 07B7F2021F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, + 07B7F1B41F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, + 07B7F1AC1F5EB42000E6F910 /* UIColorExtensions.swift in Sources */, + 07B7F1FD1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, + 07B7F1B21F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */, + 07B7F1BB1F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 077AD1CF1F13876000D3214D /* Sources */ = { + 07898B731F278DBC00558C97 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F3CC1F611B87008386F7 /* CGPointExtensionsTests.swift in Sources */, - 0743F3E71F611B87008386F7 /* ArrayExtensionsTests.swift in Sources */, - 0743F4201F611B87008386F7 /* UINavigationControllerExtensionsTests.swift in Sources */, - 0743F4081F611B87008386F7 /* UIBarButtonExtensionsTests.swift in Sources */, - 0743F4231F611B87008386F7 /* UINavigationItemExtensionsTests.swift in Sources */, - 0743F3DB1F611B87008386F7 /* LocaleExtensionsTests.swift in Sources */, - 0743F3D51F611B87008386F7 /* DataExtensionsTests.swift in Sources */, - 0743F3D81F611B87008386F7 /* DateExtensionsTests.swift in Sources */, - 0743F3F31F611B87008386F7 /* DictionaryExtensionsTests.swift in Sources */, - 0743F40B1F611B87008386F7 /* UIButtonExtensionsTests.swift in Sources */, - 0743F42F1F611B87008386F7 /* UIStoryboardExtensionsTests.swift in Sources */, - 0743F3F01F611B87008386F7 /* CollectionExtensionsTests.swift in Sources */, - 078980DF1F138B0400A3A4E1 /* SwifterSwiftTests.swift in Sources */, - 0743F4351F611B87008386F7 /* UITabBarExtensionsTests.swift in Sources */, - 0743F3E11F611B87008386F7 /* URLRequestExtensionsTests.swift in Sources */, - 0743F4111F611B87008386F7 /* UIColorExtensionsTests.swift in Sources */, - 0743F4411F611B87008386F7 /* UIViewControllerExtensionsTests.swift in Sources */, - 0743F43B1F611B87008386F7 /* UITextFieldExtensionsTests.swift in Sources */, - 0743F4381F611B87008386F7 /* UITableViewExtensionsTests.swift in Sources */, - 0743F3CF1F611B87008386F7 /* CGSizeExtensionsTests.swift in Sources */, - 0743F3F91F611B87008386F7 /* FloatExtensionsTests.swift in Sources */, - 0743F4171F611B87008386F7 /* UIImageViewExtensionsTests.swift in Sources */, - 0743F3F61F611B87008386F7 /* DoubleExtensionsTests.swift in Sources */, - 0743F3FC1F611B87008386F7 /* IntExtensionsTests.swift in Sources */, - 0743F41A1F611B87008386F7 /* UILabelExtensionsTests.swift in Sources */, - 0743F4291F611B87008386F7 /* UISegmentedControlExtensionsTests.swift in Sources */, - 0743F4321F611B87008386F7 /* UISwitchExtensionsTests.swift in Sources */, - 0743F40E1F611B87008386F7 /* UICollectionViewExtensionsTests.swift in Sources */, - 0743F3EA1F611B87008386F7 /* BoolExtensionsTests.swift in Sources */, - 0743F3ED1F611B87008386F7 /* CharacterExtensionsTests.swift in Sources */, - 0743F3DE1F611B87008386F7 /* URLExtensionsTests.swift in Sources */, - 0743F43E1F611B87008386F7 /* UITextViewExtensionsTests.swift in Sources */, - 0743F3D21F611B87008386F7 /* CLLocationExtensionsTests.swift in Sources */, - 0743F3FF1F611B87008386F7 /* OptionalExtensionsTests.swift in Sources */, - 0743F3C31F611B87008386F7 /* NSAttributedStringExtensionsTests.swift in Sources */, - 0743F41D1F611B87008386F7 /* UINavigationBarExtensionTests.swift in Sources */, - 0743F42C1F611B87008386F7 /* UISliderExtensionsTests.swift in Sources */, - 0743F4021F611B87008386F7 /* StringExtensionsTests.swift in Sources */, - 0743F4441F611B87008386F7 /* UIViewExtensionsTests.swift in Sources */, - 0743F4141F611B87008386F7 /* UIImageExtensionsTests.swift in Sources */, - 0743F3E41F611B87008386F7 /* UserDefaultsExtensionsTests.swift in Sources */, - 0743F4471F611B87008386F7 /* UIWebViewExtensionsTests.swift in Sources */, - 0743F3C91F611B87008386F7 /* CGFloatExtensionsTests.swift in Sources */, - 0743F4051F611B87008386F7 /* UIAlertControllerExtensionsTests.swift in Sources */, - 0743F4261F611B87008386F7 /* UISearchBarExtensionsTests.swift in Sources */, - 0743F3C61F611B87008386F7 /* NSViewExtensionsTests.swift in Sources */, + 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, + 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, + 07B7F1D31F5EB42200E6F910 /* UIViewExtensions.swift in Sources */, + 07B7F1C51F5EB42200E6F910 /* UILabelExtensions.swift in Sources */, + 07B7F1E81F5EB43B00E6F910 /* BoolExtensions.swift in Sources */, + 07B7F2291F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */, + 07B7F1C41F5EB42200E6F910 /* UIImageViewExtensions.swift in Sources */, + 07B7F22C1F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */, + 07B7F1EA1F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */, + 07B7F1F11F5EB43B00E6F910 /* IntExtensions.swift in Sources */, + 07B7F1ED1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */, + 07B7F22A1F5EB45100E6F910 /* CGPointExtensions.swift in Sources */, + 07B7F1C11F5EB42200E6F910 /* UICollectionViewExtensions.swift in Sources */, + 07B7F1CF1F5EB42200E6F910 /* UITableViewExtensions.swift in Sources */, + 077BA0911F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, + 07B7F1CD1F5EB42200E6F910 /* UISwitchExtensions.swift in Sources */, + 07B7F1D01F5EB42200E6F910 /* UITextFieldExtensions.swift in Sources */, + 07B7F1E71F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, + 07B7F1CC1F5EB42200E6F910 /* UIStoryboardExtensions.swift in Sources */, + 07B7F1C61F5EB42200E6F910 /* UINavigationBarExtensions.swift in Sources */, + 07B7F1C01F5EB42200E6F910 /* UIButtonExtensions.swift in Sources */, + 07B7F1F71F5EB43B00E6F910 /* URLExtensions.swift in Sources */, + 07B7F1C71F5EB42200E6F910 /* UINavigationControllerExtensions.swift in Sources */, + 07B7F1CB1F5EB42200E6F910 /* UISliderExtensions.swift in Sources */, + 07B7F1BF1F5EB42200E6F910 /* UIBarButtonItemExtensions.swift in Sources */, + 07B7F1CE1F5EB42200E6F910 /* UITabBarExtensions.swift in Sources */, + 07B7F1D21F5EB42200E6F910 /* UIViewControllerExtensions.swift in Sources */, + 07B7F22B1F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */, + 07B7F1E91F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */, + 07B7F1C91F5EB42200E6F910 /* UISearchBarExtensions.swift in Sources */, + 07B7F1F61F5EB43B00E6F910 /* StringExtensions.swift in Sources */, + 07B7F22D1F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 07B7F1C31F5EB42200E6F910 /* UIImageExtensions.swift in Sources */, + 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 07B7F1EF1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */, + 07B7F1EE1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */, + 07B7F1F31F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */, + 07B7F1BE1F5EB42200E6F910 /* UIAlertControllerExtensions.swift in Sources */, + 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, + 07B7F21D1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 07B7F1F21F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */, + 07B7F1EC1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, + 07B7F1F01F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */, + 07B7F1CA1F5EB42200E6F910 /* UISegmentedControlExtensions.swift in Sources */, + 07B7F1C21F5EB42200E6F910 /* UIColorExtensions.swift in Sources */, + 07B7F1EB1F5EB43B00E6F910 /* DataExtensions.swift in Sources */, + 07B7F1C81F5EB42200E6F910 /* UINavigationItemExtensions.swift in Sources */, + 07B7F1D11F5EB42200E6F910 /* UITextViewExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3A91F1380F100D0C644 /* Sources */ = { + 07898B801F278DD200558C97 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F34A1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, - 0743F36A1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, - 0743F3061F611B63008386F7 /* CollectionExtensions.swift in Sources */, - 0743F3021F611B63008386F7 /* CharacterExtensions.swift in Sources */, - 0743F2EE1F611B63008386F7 /* URLRequestExtensions.swift in Sources */, - 0743F2DA1F611B63008386F7 /* DateExtensions.swift in Sources */, - 0743F2D21F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, - 0743F3661F611B63008386F7 /* UISliderExtensions.swift in Sources */, - 0743F2BE1F611B63008386F7 /* CGColorExtensions.swift in Sources */, - 0743F3361F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, - 0743F38A1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, - 0743F31A1F611B63008386F7 /* IntExtensions.swift in Sources */, - 0743F36E1F611B63008386F7 /* UISwitchExtensions.swift in Sources */, - 0743F3721F611B63008386F7 /* UITabBarExtensions.swift in Sources */, - 0743F35E1F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, - 0743F33A1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, - 0743F3821F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, - 0743F33E1F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, - 0743F2C61F611B63008386F7 /* CGPointExtensions.swift in Sources */, - 0743F2C21F611B63008386F7 /* CGFloatExtensions.swift in Sources */, - 0743F2FA1F611B63008386F7 /* ArrayExtensions.swift in Sources */, - 0743F2D61F611B63008386F7 /* DataExtensions.swift in Sources */, - 0743F32A1F611B63008386F7 /* StringExtensions.swift in Sources */, - 0743F2EA1F611B63008386F7 /* URLExtensions.swift in Sources */, - 0743F2DE1F611B63008386F7 /* FoundationDeprecated.swift in Sources */, - 0743F32E1F611B63008386F7 /* UIKitDeprecated.swift in Sources */, - 0743F30A1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, - 0743F3521F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, - 0743F37A1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, - 0743F3121F611B63008386F7 /* FloatExtensions.swift in Sources */, - 0743F3321F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, - 0743F31E1F611B63008386F7 /* OptionalExtensions.swift in Sources */, - 0743F2FE1F611B63008386F7 /* BoolExtensions.swift in Sources */, - 0743F3461F611B63008386F7 /* UIImageExtensions.swift in Sources */, - 0743F3861F611B63008386F7 /* UIViewExtensions.swift in Sources */, - 0743F3621F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3261F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, - 0743F37E1F611B63008386F7 /* UITextViewExtensions.swift in Sources */, - 0743F3161F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, - 0743F30E1F611B63008386F7 /* DoubleExtensions.swift in Sources */, - 0743F35A1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, - 0743F34E1F611B63008386F7 /* UILabelExtensions.swift in Sources */, - 0743F3421F611B63008386F7 /* UIColorExtensions.swift in Sources */, - 0743F3221F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, - 0743F2E61F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, - 0743F2CE1F611B63008386F7 /* CLLocationExtensions.swift in Sources */, - 0743F3761F611B63008386F7 /* UITableViewExtensions.swift in Sources */, - 0743F2E21F611B63008386F7 /* LocaleExtensions.swift in Sources */, - 0743F2F61F611B63008386F7 /* SwifterSwift.swift in Sources */, - 0743F2CA1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, - 0743F2F21F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, - 0743F3561F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, + 07B7F1E01F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */, + 07B7F1DA1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, + 07B7F1D81F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */, + 07B7F1DD1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */, + 07B7F1D61F5EB43B00E6F910 /* BoolExtensions.swift in Sources */, + 07B7F1DE1F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */, + 07B7F1DB1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */, + 07B7F1DC1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */, + 07B7F1D71F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */, + 07B7F2231F5EB44600E6F910 /* CGSizeExtensions.swift in Sources */, + 07B7F1E11F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */, + 07B7F2221F5EB44600E6F910 /* CGPointExtensions.swift in Sources */, + 07B7F2251F5EB44600E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 077BA08D1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, + 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, + 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, + 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */, + 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, + 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */, + 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, + 07B7F2261F5EB44600E6F910 /* NSColorExtensions.swift in Sources */, + 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, + 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, + 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */, + 07B7F1E41F5EB43B00E6F910 /* StringExtensions.swift in Sources */, + 07B7F2271F5EB44600E6F910 /* NSViewExtensions.swift in Sources */, + 07B7F2211F5EB44600E6F910 /* CGFloatExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3B71F13816200D0C644 /* Sources */ = { + 07C50CC51F5EAF2700F46E5A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F2B71F611B63008386F7 /* NSColorExtensions.swift in Sources */, - 0743F3071F611B63008386F7 /* CollectionExtensions.swift in Sources */, - 0743F3031F611B63008386F7 /* CharacterExtensions.swift in Sources */, - 0743F2EF1F611B63008386F7 /* URLRequestExtensions.swift in Sources */, - 0743F2DB1F611B63008386F7 /* DateExtensions.swift in Sources */, - 0743F2D31F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, - 0743F2BF1F611B63008386F7 /* CGColorExtensions.swift in Sources */, - 0743F31B1F611B63008386F7 /* IntExtensions.swift in Sources */, - 0743F2C71F611B63008386F7 /* CGPointExtensions.swift in Sources */, - 0743F2C31F611B63008386F7 /* CGFloatExtensions.swift in Sources */, - 0743F2FB1F611B63008386F7 /* ArrayExtensions.swift in Sources */, - 0743F2D71F611B63008386F7 /* DataExtensions.swift in Sources */, - 0743F32B1F611B63008386F7 /* StringExtensions.swift in Sources */, - 0743F2EB1F611B63008386F7 /* URLExtensions.swift in Sources */, - 0743F2DF1F611B63008386F7 /* FoundationDeprecated.swift in Sources */, - 0743F30B1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, - 0743F3131F611B63008386F7 /* FloatExtensions.swift in Sources */, - 0743F31F1F611B63008386F7 /* OptionalExtensions.swift in Sources */, - 0743F2FF1F611B63008386F7 /* BoolExtensions.swift in Sources */, - 0743F3271F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, - 0743F3171F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, - 0743F30F1F611B63008386F7 /* DoubleExtensions.swift in Sources */, - 0743F3231F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, - 0743F2E71F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, - 0743F2CF1F611B63008386F7 /* CLLocationExtensions.swift in Sources */, - 0743F2E31F611B63008386F7 /* LocaleExtensions.swift in Sources */, - 0743F2F71F611B63008386F7 /* SwifterSwift.swift in Sources */, - 0743F2CB1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, - 0743F2F31F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, - 0743F2BB1F611B63008386F7 /* NSViewExtensions.swift in Sources */, + 07C50D321F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */, + 07C50D621F5EB05000F46E5A /* OptionalExtensionsTests.swift in Sources */, + 07C50D601F5EB05000F46E5A /* IntExtensionsTests.swift in Sources */, + 07C50D631F5EB05000F46E5A /* StringExtensionsTests.swift in Sources */, + 07C50D5C1F5EB05000F46E5A /* DateExtensionsTests.swift in Sources */, + 077BA09E1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, + 07C50D2E1F5EB04600F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, + 07C50D3C1F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, + 07C50D381F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, + 07C50D2F1F5EB04600F46E5A /* UIColorExtensionsTests.swift in Sources */, + 07C50D331F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, + 07C50D401F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, + 07C50D311F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, + 07C50D2C1F5EB04600F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, + 077BA0B91F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, + 07C50D591F5EB05000F46E5A /* CharacterExtensionsTests.swift in Sources */, + 07C50D571F5EB05000F46E5A /* ArrayExtensionsTests.swift in Sources */, + 07C50D5F1F5EB05000F46E5A /* FloatExtensionsTests.swift in Sources */, + 07C50D371F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, + 07C50D8E1F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */, + 07C50D581F5EB05000F46E5A /* BoolExtensionsTests.swift in Sources */, + 07C50D391F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, + 07C50D361F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, + 07C50D8C1F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, + 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */, + 07C50D3E1F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */, + 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, + 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, + 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, + 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */, + 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, + 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, + 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, + 07C50D3F1F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, + 07C50D3D1F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */, + 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, + 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, + 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, + 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, + 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, + 07C50D611F5EB05000F46E5A /* LocaleExtensionsTests.swift in Sources */, + 07C50D901F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, + 07C50D3B1F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3C41F13817200D0C644 /* Sources */ = { + 07C50CD41F5EAF4B00F46E5A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F34C1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, - 0743F36C1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, - 0743F3081F611B63008386F7 /* CollectionExtensions.swift in Sources */, - 0743F3041F611B63008386F7 /* CharacterExtensions.swift in Sources */, - 0743F2F01F611B63008386F7 /* URLRequestExtensions.swift in Sources */, - 0743F2DC1F611B63008386F7 /* DateExtensions.swift in Sources */, - 0743F2D41F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, - 0743F3681F611B63008386F7 /* UISliderExtensions.swift in Sources */, - 0743F2C01F611B63008386F7 /* CGColorExtensions.swift in Sources */, - 0743F3381F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, - 0743F38C1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, - 0743F31C1F611B63008386F7 /* IntExtensions.swift in Sources */, - 0743F3701F611B63008386F7 /* UISwitchExtensions.swift in Sources */, - 0743F3741F611B63008386F7 /* UITabBarExtensions.swift in Sources */, - 0743F3601F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, - 0743F33C1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, - 0743F3841F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, - 0743F3401F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, - 0743F2C81F611B63008386F7 /* CGPointExtensions.swift in Sources */, - 0743F2C41F611B63008386F7 /* CGFloatExtensions.swift in Sources */, - 0743F2FC1F611B63008386F7 /* ArrayExtensions.swift in Sources */, - 0743F2D81F611B63008386F7 /* DataExtensions.swift in Sources */, - 0743F32C1F611B63008386F7 /* StringExtensions.swift in Sources */, - 0743F2EC1F611B63008386F7 /* URLExtensions.swift in Sources */, - 0743F2E01F611B63008386F7 /* FoundationDeprecated.swift in Sources */, - 0743F3301F611B63008386F7 /* UIKitDeprecated.swift in Sources */, - 0743F30C1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, - 0743F3541F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, - 0743F37C1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, - 0743F3141F611B63008386F7 /* FloatExtensions.swift in Sources */, - 0743F3341F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, - 0743F3201F611B63008386F7 /* OptionalExtensions.swift in Sources */, - 0743F3001F611B63008386F7 /* BoolExtensions.swift in Sources */, - 0743F3481F611B63008386F7 /* UIImageExtensions.swift in Sources */, - 0743F3881F611B63008386F7 /* UIViewExtensions.swift in Sources */, - 0743F3641F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3281F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, - 0743F3801F611B63008386F7 /* UITextViewExtensions.swift in Sources */, - 0743F3181F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, - 0743F3101F611B63008386F7 /* DoubleExtensions.swift in Sources */, - 0743F35C1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, - 0743F3501F611B63008386F7 /* UILabelExtensions.swift in Sources */, - 0743F3441F611B63008386F7 /* UIColorExtensions.swift in Sources */, - 0743F3241F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, - 0743F2E81F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, - 0743F2D01F611B63008386F7 /* CLLocationExtensions.swift in Sources */, - 0743F3781F611B63008386F7 /* UITableViewExtensions.swift in Sources */, - 0743F2E41F611B63008386F7 /* LocaleExtensions.swift in Sources */, - 0743F2F81F611B63008386F7 /* SwifterSwift.swift in Sources */, - 0743F2CC1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, - 0743F2F41F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, - 0743F3581F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, + 07C50D481F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */, + 07C50D701F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */, + 07C50D6E1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */, + 07C50D711F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, + 07C50D6A1F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, + 077BA09F1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, + 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, + 07C50D521F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, + 07C50D4E1F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, + 07C50D451F5EB04700F46E5A /* UIColorExtensionsTests.swift in Sources */, + 07C50D491F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, + 07C50D561F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, + 07C50D471F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, + 07C50D421F5EB04700F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, + 077BA0BA1F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, + 07C50D671F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, + 07C50D651F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */, + 07C50D6D1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, + 07C50D4D1F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, + 07C50D891F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */, + 07C50D661F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */, + 07C50D4F1F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, + 07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, + 07C50D871F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, + 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */, + 07C50D541F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */, + 07C50D461F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, + 07C50D501F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, + 07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, + 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, + 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, + 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 07C50D8A1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, + 07C50D881F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, + 07C50D551F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, + 07C50D531F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */, + 07C50D721F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, + 07C50D411F5EB04700F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, + 07C50D6C1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 07C50D6B1F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, + 07C50D691F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, + 07C50D6F1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, + 07C50D8B1F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, + 07C50D511F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 07DFA3D11F13818700D0C644 /* Sources */ = { + 07C50CE31F5EAF6300F46E5A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0743F34D1F611B63008386F7 /* UIImageViewExtensions.swift in Sources */, - 0743F36D1F611B63008386F7 /* UIStoryboardExtensions.swift in Sources */, - 0743F3091F611B63008386F7 /* CollectionExtensions.swift in Sources */, - 0743F3051F611B63008386F7 /* CharacterExtensions.swift in Sources */, - 0743F2F11F611B63008386F7 /* URLRequestExtensions.swift in Sources */, - 0743F2DD1F611B63008386F7 /* DateExtensions.swift in Sources */, - 0743F2D51F611B63008386F7 /* SwifterSwiftDeprecated.swift in Sources */, - 0743F3691F611B63008386F7 /* UISliderExtensions.swift in Sources */, - 0743F2C11F611B63008386F7 /* CGColorExtensions.swift in Sources */, - 0743F3391F611B63008386F7 /* UIBarButtonItemExtensions.swift in Sources */, - 0743F38D1F611B63008386F7 /* UIWebViewExtensions.swift in Sources */, - 0743F31D1F611B63008386F7 /* IntExtensions.swift in Sources */, - 0743F3711F611B63008386F7 /* UISwitchExtensions.swift in Sources */, - 0743F3751F611B63008386F7 /* UITabBarExtensions.swift in Sources */, - 0743F3611F611B63008386F7 /* UISearchBarExtensions.swift in Sources */, - 0743F33D1F611B63008386F7 /* UIButtonExtensions.swift in Sources */, - 0743F3851F611B63008386F7 /* UIViewControllerExtensions.swift in Sources */, - 0743F3411F611B63008386F7 /* UICollectionViewExtensions.swift in Sources */, - 0743F2C91F611B63008386F7 /* CGPointExtensions.swift in Sources */, - 0743F2C51F611B63008386F7 /* CGFloatExtensions.swift in Sources */, - 0743F2FD1F611B63008386F7 /* ArrayExtensions.swift in Sources */, - 0743F2D91F611B63008386F7 /* DataExtensions.swift in Sources */, - 0743F32D1F611B63008386F7 /* StringExtensions.swift in Sources */, - 0743F2ED1F611B63008386F7 /* URLExtensions.swift in Sources */, - 0743F2E11F611B63008386F7 /* FoundationDeprecated.swift in Sources */, - 0743F3311F611B63008386F7 /* UIKitDeprecated.swift in Sources */, - 0743F30D1F611B63008386F7 /* DictionaryExtensions.swift in Sources */, - 0743F3551F611B63008386F7 /* UINavigationBarExtensions.swift in Sources */, - 0743F37D1F611B63008386F7 /* UITextFieldExtensions.swift in Sources */, - 0743F3151F611B63008386F7 /* FloatExtensions.swift in Sources */, - 0743F3351F611B63008386F7 /* UIAlertControllerExtensions.swift in Sources */, - 0743F3211F611B63008386F7 /* OptionalExtensions.swift in Sources */, - 0743F3011F611B63008386F7 /* BoolExtensions.swift in Sources */, - 0743F3491F611B63008386F7 /* UIImageExtensions.swift in Sources */, - 0743F3891F611B63008386F7 /* UIViewExtensions.swift in Sources */, - 0743F3651F611B63008386F7 /* UISegmentedControlExtensions.swift in Sources */, - 0743F3291F611B63008386F7 /* SignedNumericExtensions.swift in Sources */, - 0743F3811F611B63008386F7 /* UITextViewExtensions.swift in Sources */, - 0743F3191F611B63008386F7 /* FloatingPointExtensions.swift in Sources */, - 0743F3111F611B63008386F7 /* DoubleExtensions.swift in Sources */, - 0743F35D1F611B63008386F7 /* UINavigationItemExtensions.swift in Sources */, - 0743F3511F611B63008386F7 /* UILabelExtensions.swift in Sources */, - 0743F3451F611B63008386F7 /* UIColorExtensions.swift in Sources */, - 0743F3251F611B63008386F7 /* SignedIntegerExtensions.swift in Sources */, - 0743F2E91F611B63008386F7 /* NSAttributedStringExtensions.swift in Sources */, - 0743F2D11F611B63008386F7 /* CLLocationExtensions.swift in Sources */, - 0743F3791F611B63008386F7 /* UITableViewExtensions.swift in Sources */, - 0743F2E51F611B63008386F7 /* LocaleExtensions.swift in Sources */, - 0743F2F91F611B63008386F7 /* SwifterSwift.swift in Sources */, - 0743F2CD1F611B63008386F7 /* CGSizeExtensions.swift in Sources */, - 0743F2F51F611B63008386F7 /* UserDefaultsExtensions.swift in Sources */, - 0743F3591F611B63008386F7 /* UINavigationControllerExtensions.swift in Sources */, + 07C50D731F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */, + 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */, + 07C50D7E1F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */, + 07C50D761F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, + 07C50D841F5EB05800F46E5A /* CLLocationExtensionsTests.swift in Sources */, + 07C50D741F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */, + 07C50D861F5EB05800F46E5A /* NSViewExtensionsTests.swift in Sources */, + 07C50D851F5EB05800F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, + 07C50D7C1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */, + 07C50D791F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, + 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, + 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, + 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, + 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, + 07C50D771F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, + 07C50D831F5EB05800F46E5A /* CGSizeExtensionsTests.swift in Sources */, + 077BA0BB1F6BEA6B00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, + 07C50D751F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, + 07C50D7D1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, + 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, + 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */, + 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 077AD1BC1F13873600D3214D /* PBXTargetDependency */ = { + 07C50CD01F5EAF2700F46E5A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 07DFA3AD1F1380F100D0C644 /* SwifterSwift iOS */; - targetProxy = 077AD1BB1F13873600D3214D /* PBXContainerItemProxy */; + target = 07898B5C1F278D7600558C97 /* SwifterSwift-iOS */; + targetProxy = 07C50CCF1F5EAF2700F46E5A /* PBXContainerItemProxy */; }; - 077AD1CB1F13875100D3214D /* PBXTargetDependency */ = { + 07C50CDF1F5EAF4B00F46E5A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 07DFA3BB1F13816200D0C644 /* SwifterSwift macOS */; - targetProxy = 077AD1CA1F13875100D3214D /* PBXContainerItemProxy */; + target = 07898B6A1F278D9700558C97 /* SwifterSwift-tvOS */; + targetProxy = 07C50CDE1F5EAF4B00F46E5A /* PBXContainerItemProxy */; }; - 077AD1DA1F13876000D3214D /* PBXTargetDependency */ = { + 07C50CEE1F5EAF6300F46E5A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 07DFA3C81F13817200D0C644 /* SwifterSwift tvOS */; - targetProxy = 077AD1D91F13876000D3214D /* PBXContainerItemProxy */; + target = 07898B841F278DD200558C97 /* SwifterSwift-macOS */; + targetProxy = 07C50CED1F5EAF6300F46E5A /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 077AD1BE1F13873600D3214D /* Debug */ = { + 07898B561F278CF900558C97 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.10; + SWIFT_VERSION = 4.0; + }; + name = Debug; + }; + 07898B571F278CF900558C97 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.10; + SWIFT_VERSION = 4.0; + }; + name = Release; + }; + 07898B641F278D7600558C97 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1533,16 +1428,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1556,32 +1464,39 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOSTests"; - PRODUCT_NAME = "SwifterSwift iOSTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 077AD1BF1F13873600D3214D /* Release */ = { + 07898B651F278D7600558C97 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1589,16 +1504,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -1606,31 +1534,38 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOSTests"; - PRODUCT_NAME = "SwifterSwift iOSTests"; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = iphoneos; + SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Release; }; - 077AD1CD1F13875100D3214D /* Debug */ = { + 07898B711F278D9700558C97 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1638,17 +1573,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1662,32 +1609,39 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOSTests"; - PRODUCT_NAME = "SwifterSwift macOSTests"; - SDKROOT = macosx; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = appletvos; + SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 077AD1CE1F13875100D3214D /* Release */ = { + 07898B721F278D9700558C97 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1695,17 +1649,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -1713,30 +1679,39 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOSTests"; - PRODUCT_NAME = "SwifterSwift macOSTests"; - SDKROOT = macosx; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = appletvos; + SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.0; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Release; }; - 077AD1DC1F13876000D3214D /* Debug */ = { + 07898B7E1F278DBC00558C97 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1744,15 +1719,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1766,32 +1755,40 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOSTests"; - PRODUCT_NAME = "SwifterSwift tvOSTests"; - SDKROOT = appletvos; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-watchOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = watchos; + SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TVOS_DEPLOYMENT_TARGET = 10.2; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 4; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; - 077AD1DD1F13876000D3214D /* Release */ = { + 07898B7F1F278DBC00558C97 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1799,15 +1796,29 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -1815,96 +1826,38 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Tests/Info.plist; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOSTests"; - PRODUCT_NAME = "SwifterSwift tvOSTests"; - SDKROOT = appletvos; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-watchOS"; + PRODUCT_NAME = SwifterSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = watchos; + SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; - TVOS_DEPLOYMENT_TARGET = 10.2; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 4; VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; - 079412C91F137D5C006AA1F8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - ONLY_ACTIVE_ARCH = YES; - SWIFT_VERSION = 3.0; - }; - name = Debug; - }; - 079412CA1F137D5C006AA1F8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - SWIFT_VERSION = 3.0; - }; - name = Release; - }; - 07DFA3B41F1380F100D0C644 /* Debug */ = { + 07898B8B1F278DD200558C97 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1912,22 +1865,30 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1943,34 +1904,36 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOS"; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOS"; PRODUCT_NAME = SwifterSwift; - SDKROOT = iphoneos; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; + SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 07DFA3B51F1380F100D0C644 /* Release */ = { + 07898B8C1F278DD200558C97 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -1978,22 +1941,30 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2003,33 +1974,35 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOS"; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOS"; PRODUCT_NAME = SwifterSwift; - SDKROOT = iphoneos; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; + SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - 07DFA3C21F13816200D0C644 /* Debug */ = { + 07C50CD11F5EAF2700F46E5A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2037,23 +2010,24 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - FRAMEWORK_VERSION = A; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -2067,35 +2041,36 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOS"; - PRODUCT_NAME = SwifterSwift; - SDKROOT = macosx; - SKIP_INSTALL = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 07DFA3C31F13816200D0C644 /* Release */ = { + 07C50CD21F5EAF2700F46E5A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2103,23 +2078,24 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2127,33 +2103,35 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOS"; - PRODUCT_NAME = SwifterSwift; - SDKROOT = macosx; - SKIP_INSTALL = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-iOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; name = Release; }; - 07DFA3CF1F13817200D0C644 /* Debug */ = { + 07C50CE11F5EAF4B00F46E5A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2161,21 +2139,23 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -2189,36 +2169,36 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOS"; - PRODUCT_NAME = SwifterSwift; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = appletvos; - SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + TVOS_DEPLOYMENT_TARGET = 11.0; }; name = Debug; }; - 07DFA3D01F13817200D0C644 /* Release */ = { + 07C50CE21F5EAF4B00F46E5A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2226,21 +2206,23 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2248,36 +2230,35 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOS"; - PRODUCT_NAME = SwifterSwift; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = appletvos; - SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; + TVOS_DEPLOYMENT_TARGET = 11.0; VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; }; name = Release; }; - 07DFA3DC1F13818700D0C644 /* Debug */ = { + 07C50CF01F5EAF6300F46E5A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; - APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2285,21 +2266,24 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -2313,37 +2297,35 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-watchOS"; - PRODUCT_NAME = SwifterSwift; - SDKROOT = watchos; - SKIP_INSTALL = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = 4; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 2.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; - 07DFA3DD1F13818700D0C644 /* Release */ = { + 07C50CF11F5EAF6300F46E5A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; - APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; @@ -2351,21 +2333,24 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -2373,100 +2358,95 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-watchOS"; - PRODUCT_NAME = SwifterSwift; - SDKROOT = watchos; - SKIP_INSTALL = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.swifterswift.SwifterSwift-macOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = 4; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - WATCHOS_DEPLOYMENT_TARGET = 2.0; + SWIFT_VERSION = 4.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 077AD1BD1F13873600D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift iOSTests" */ = { + 07898B551F278CF900558C97 /* Build configuration list for PBXProject "SwifterSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 077AD1BE1F13873600D3214D /* Debug */, - 077AD1BF1F13873600D3214D /* Release */, + 07898B561F278CF900558C97 /* Debug */, + 07898B571F278CF900558C97 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 077AD1CC1F13875100D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift macOSTests" */ = { + 07898B631F278D7600558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 077AD1CD1F13875100D3214D /* Debug */, - 077AD1CE1F13875100D3214D /* Release */, + 07898B641F278D7600558C97 /* Debug */, + 07898B651F278D7600558C97 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 077AD1DB1F13876000D3214D /* Build configuration list for PBXNativeTarget "SwifterSwift tvOSTests" */ = { + 07898B701F278D9700558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 077AD1DC1F13876000D3214D /* Debug */, - 077AD1DD1F13876000D3214D /* Release */, + 07898B711F278D9700558C97 /* Debug */, + 07898B721F278D9700558C97 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 079412C81F137D5C006AA1F8 /* Build configuration list for PBXProject "SwifterSwift" */ = { + 07898B7D1F278DBC00558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-watchOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 079412C91F137D5C006AA1F8 /* Debug */, - 079412CA1F137D5C006AA1F8 /* Release */, + 07898B7E1F278DBC00558C97 /* Debug */, + 07898B7F1F278DBC00558C97 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 07DFA3B61F1380F100D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift iOS" */ = { + 07898B8A1F278DD200558C97 /* Build configuration list for PBXNativeTarget "SwifterSwift-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 07DFA3B41F1380F100D0C644 /* Debug */, - 07DFA3B51F1380F100D0C644 /* Release */, + 07898B8B1F278DD200558C97 /* Debug */, + 07898B8C1F278DD200558C97 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 07DFA3C11F13816200D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift macOS" */ = { + 07C50CD31F5EAF2700F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-iOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 07DFA3C21F13816200D0C644 /* Debug */, - 07DFA3C31F13816200D0C644 /* Release */, + 07C50CD11F5EAF2700F46E5A /* Debug */, + 07C50CD21F5EAF2700F46E5A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 07DFA3CE1F13817200D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift tvOS" */ = { + 07C50CE01F5EAF4B00F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-tvOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 07DFA3CF1F13817200D0C644 /* Debug */, - 07DFA3D01F13817200D0C644 /* Release */, + 07C50CE11F5EAF4B00F46E5A /* Debug */, + 07C50CE21F5EAF4B00F46E5A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 07DFA3DB1F13818700D0C644 /* Build configuration list for PBXNativeTarget "SwifterSwift watchOS" */ = { + 07C50CEF1F5EAF6300F46E5A /* Build configuration list for PBXNativeTarget "SwifterSwift-macOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 07DFA3DC1F13818700D0C644 /* Debug */, - 07DFA3DD1F13818700D0C644 /* Release */, + 07C50CF01F5EAF6300F46E5A /* Debug */, + 07C50CF11F5EAF6300F46E5A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = 079412C51F137D5C006AA1F8 /* Project object */; + rootObject = 07898B521F278CF900558C97 /* Project object */; } diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme deleted file mode 100644 index 3c60d93f9..000000000 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOSTests.xcscheme +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme deleted file mode 100644 index fbe50179e..000000000 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOSTests.xcscheme +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme deleted file mode 100644 index 3cce66a03..000000000 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOSTests.xcscheme +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme similarity index 83% rename from SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme rename to SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme index b71c1648b..92d2f72a2 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift iOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> @@ -34,9 +34,9 @@ skipped = "NO"> @@ -44,9 +44,9 @@ @@ -67,9 +67,9 @@ @@ -85,9 +85,9 @@ diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme similarity index 83% rename from SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOS.xcscheme rename to SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme index bbe9dde90..cbb282437 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift macOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> @@ -34,9 +34,9 @@ skipped = "NO"> @@ -44,9 +44,9 @@ @@ -67,9 +67,9 @@ @@ -85,9 +85,9 @@ diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme similarity index 83% rename from SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOS.xcscheme rename to SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme index 61e954421..7c0f45c67 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift tvOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> @@ -34,9 +34,9 @@ skipped = "NO"> @@ -44,9 +44,9 @@ @@ -67,9 +67,9 @@ @@ -85,9 +85,9 @@ diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift watchOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme similarity index 88% rename from SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift watchOS.xcscheme rename to SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme index c4a31e2c2..fcb306f8d 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift watchOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> @@ -47,9 +47,9 @@ @@ -65,9 +65,9 @@ diff --git a/Tests/FoundationTests/DataExtensionsTests.swift b/Tests/FoundationTests/DataExtensionsTests.swift index 86bbc50be..c3d6234e0 100644 --- a/Tests/FoundationTests/DataExtensionsTests.swift +++ b/Tests/FoundationTests/DataExtensionsTests.swift @@ -11,11 +11,6 @@ import XCTest class DataExtensionsTests: XCTestCase { - func testAttributedString() { - let attrString = "Hello".colored(with: .orange) - XCTAssertNotEqual(Data().attributedString, attrString) - } - func testString() { let dataFromString = "hello".data(using: .utf8) XCTAssertNotNil(dataFromString) diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 352c6a75c..f36272ec2 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 8/27/16. // Copyright © 2016 Omar Albeik. All rights reserved. // - import XCTest @testable import SwifterSwift @@ -237,33 +236,33 @@ class DateExtensionsTests: XCTestCase { let date = Date() XCTAssertEqual(date.isInWeekend, Calendar.current.isDateInWeekend(date)) } - - func testIsInWeekday() { - let date = Date() - XCTAssertEqual(date.isInWeekday, !Calendar.current.isDateInWeekend(date)) - } - - func testIsInThisWeek() { - let date = Date() - XCTAssert(date.isInThisWeek) - let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisWeek) - } - - func testIsInThisMonth() { - let date = Date() - XCTAssert(date.isInThisMonth) - let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisMonth) - } - - func testIsInThisYear() { - let date = Date() - XCTAssert(date.isInThisYear) - let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisYear) - } - + + func testIsInWeekday() { + let date = Date() + XCTAssertEqual(date.isInWeekday, !Calendar.current.isDateInWeekend(date)) + } + + func testIsInThisWeek() { + let date = Date() + XCTAssert(date.isInThisWeek) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisWeek) + } + + func testIsInThisMonth() { + let date = Date() + XCTAssert(date.isInThisMonth) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisMonth) + } + + func testIsInThisYear() { + let date = Date() + XCTAssert(date.isInThisYear) + let dateOneYearFromNow = date.adding(.year, value: 1) + XCTAssertFalse(dateOneYearFromNow.isInThisYear) + } + func testIso8601String() { let date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z XCTAssertEqual(date.iso8601String, "1970-01-01T00:08:32.000Z") @@ -683,29 +682,4 @@ class DateExtensionsTests: XCTestCase { XCTAssertEqual(date, dateFromUnixTimestamp) } - func testIfDateIsBetween() { - var date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z - let startDate = Date(timeIntervalSince1970: 511) - let endDate = Date(timeIntervalSince1970: 513) - XCTAssertTrue(date.isBetween(startDate, endDate)) - - date = Date(timeIntervalSince1970: 511) - XCTAssertTrue(date.isBetween(startDate, endDate, includeBounds: true)) - - date = Date(timeIntervalSince1970: 513) - XCTAssertTrue(date.isBetween(startDate, endDate, includeBounds: true)) - - date = Date(timeIntervalSince1970: 511) - XCTAssertFalse(date.isBetween(startDate, endDate)) - - date = Date(timeIntervalSince1970: 513) - XCTAssertFalse(date.isBetween(startDate, endDate)) - - date = Date(timeIntervalSince1970: 230) - XCTAssertFalse(date.isBetween(startDate, endDate)) - - date = Date(timeIntervalSince1970: 550) - XCTAssertFalse(date.isBetween(startDate, endDate)) - } - } diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index 3f09eeb6c..37e7c5a59 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -17,8 +17,8 @@ class NSAttributedStringExtensionsTests: XCTestCase { let out = string.bolded let attributes = out.attributes(at: 0, effectiveRange: nil) - let filterClosure: (String, Any) -> Bool = {key, value in - return (key == NSFontAttributeName && ((value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize))) + let filterClosure: (NSAttributedStringKey, Any) -> Bool = {key, value in + return (key == NSAttributedStringKey.font && ((value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize))) } let filteredAttributes = attributes.filter { filterClosure($0, $1) } @@ -32,7 +32,7 @@ class NSAttributedStringExtensionsTests: XCTestCase { let out = string.underlined let attributes = out.attributes(at: 0, effectiveRange: nil) let filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSUnderlineStyleAttributeName && (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) + return (key == NSAttributedStringKey.underlineStyle && (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) } XCTAssertEqual(filteredAttributes.count, 1) @@ -45,7 +45,7 @@ class NSAttributedStringExtensionsTests: XCTestCase { let out = string.italicized let attributes = out.attributes(at: 0, effectiveRange: nil) let filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSFontAttributeName && (value as? UIFont) == .italicSystemFont(ofSize: UIFont.systemFontSize)) + return (key == NSAttributedStringKey.font && (value as? UIFont) == .italicSystemFont(ofSize: UIFont.systemFontSize)) } XCTAssertEqual(filteredAttributes.count, 1) @@ -58,7 +58,7 @@ class NSAttributedStringExtensionsTests: XCTestCase { let out = string.struckthrough let attributes = out.attributes(at: 0, effectiveRange: nil) let filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSStrikethroughStyleAttributeName && (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) + return (key == NSAttributedStringKey.strikethroughStyle && (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) } XCTAssertEqual(filteredAttributes.count, 1) @@ -72,21 +72,21 @@ class NSAttributedStringExtensionsTests: XCTestCase { var out = string.colored(with: .red) var attributes = out.attributes(at: 0, effectiveRange: nil) let filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSForegroundColorAttributeName && (value as? UIColor) == .red) + return (key == NSAttributedStringKey.foregroundColor && (value as? UIColor) == .red) } XCTAssertEqual(filteredAttributes.count, 1) out = out.colored(with: .blue) attributes = out.attributes(at: 0, effectiveRange: nil) - XCTAssertEqual(attributes[NSForegroundColorAttributeName] as? UIColor, UIColor.blue) - XCTAssertNotEqual(attributes[NSForegroundColorAttributeName] as? UIColor, .red) + XCTAssertEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, UIColor.blue) + XCTAssertNotEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, .red) } #endif #if !os(macOS) && !os(tvOS) // MARK: - Operators - func testPlusEqual() { + func testAppending() { var string = NSAttributedString(string: "Test").italicized.underlined.struckthrough string += NSAttributedString(string: " Appending").bolded @@ -95,13 +95,13 @@ class NSAttributedStringExtensionsTests: XCTestCase { var attributes = string.attributes(at: 0, effectiveRange: nil) var filteredAttributes = attributes.filter { (key, value) -> Bool in var valid = false - if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { + if key == NSAttributedStringKey.font, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { valid = true } - if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + if key == NSAttributedStringKey.underlineStyle, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { valid = true } - if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { + if key == NSAttributedStringKey.strikethroughStyle, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { valid = true } @@ -112,108 +112,10 @@ class NSAttributedStringExtensionsTests: XCTestCase { attributes = string.attributes(at: 5, effectiveRange: nil) filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) + return (key == NSAttributedStringKey.font && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) } XCTAssertEqual(filteredAttributes.count, 1) } - - func testPlusAttributedString() { - let a : NSAttributedString = NSAttributedString(string: "Test").italicized.underlined.struckthrough - let b : NSAttributedString = NSAttributedString(string: " Appending").bolded - let result = a + b - - XCTAssertEqual(result.string, "Test Appending") - - var attributes = result.attributes(at: 0, effectiveRange: nil) - var filteredAttributes = attributes.filter { (key, value) -> Bool in - var valid = false - if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { - valid = true - } - if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - - return valid - } - - XCTAssertEqual(filteredAttributes.count, 3) - - attributes = result.attributes(at: 5, effectiveRange: nil) - filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) - } - - XCTAssertEqual(filteredAttributes.count, 1) - } - - func testPlusEqualString() { - var string = NSAttributedString(string: "Test").italicized.underlined.struckthrough - string += " Appending" - - XCTAssertEqual(string.string, "Test Appending") - - var attributes = string.attributes(at: 0, effectiveRange: nil) - var filteredAttributes = attributes.filter { (key, value) -> Bool in - var valid = false - if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { - valid = true - } - if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - - return valid - } - - XCTAssertEqual(filteredAttributes.count, 3) - - attributes = string.attributes(at: 5, effectiveRange: nil) - filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) - } - - XCTAssertEqual(filteredAttributes.count, 0) - } - - func testPlusString() { - let a : NSAttributedString = NSAttributedString(string: "Test").italicized.underlined.struckthrough - let b : String = " Appending" - let result = a + b - - XCTAssertEqual(result.string, "Test Appending") - - var attributes = result.attributes(at: 0, effectiveRange: nil) - var filteredAttributes = attributes.filter { (key, value) -> Bool in - var valid = false - if key == NSFontAttributeName, let value = value as? UIFont, value == .italicSystemFont(ofSize: UIFont.systemFontSize) { - valid = true - } - if key == NSUnderlineStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - if key == NSStrikethroughStyleAttributeName, let value = value as? NSUnderlineStyle.RawValue, value == NSUnderlineStyle.styleSingle.rawValue { - valid = true - } - - return valid - } - - XCTAssertEqual(filteredAttributes.count, 3) - - attributes = result.attributes(at: 5, effectiveRange: nil) - filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSFontAttributeName && (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize)) - } - - XCTAssertEqual(filteredAttributes.count, 0) - } #endif } diff --git a/Tests/FoundationTests/URLRequestExtensionsTests.swift b/Tests/FoundationTests/URLRequestExtensionsTests.swift index 549477229..4999c7c8e 100644 --- a/Tests/FoundationTests/URLRequestExtensionsTests.swift +++ b/Tests/FoundationTests/URLRequestExtensionsTests.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 9/6/17. // // - import XCTest @testable import SwifterSwift diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift index fd43e65b9..6a498352a 100644 --- a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 9/6/17. // // - import XCTest @testable import SwifterSwift diff --git a/Tests/Info.plist b/Tests/Info.plist index 6c6c23c43..6c40a6cd0 100644 --- a/Tests/Info.plist +++ b/Tests/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/Tests/Resources/TestStoryboard.storyboard b/Tests/Resources/TestStoryboard.storyboard index 66377e793..16065be93 100644 --- a/Tests/Resources/TestStoryboard.storyboard +++ b/Tests/Resources/TestStoryboard.storyboard @@ -1,11 +1,10 @@ - + - - + diff --git a/Tests/SwiftStdlibTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift index 6fc110935..bc3cff984 100644 --- a/Tests/SwiftStdlibTests/IntExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/IntExtensionsTests.swift @@ -82,17 +82,6 @@ class IntExtensionsTests: XCTestCase { func testRadiansToDegrees() { XCTAssertEqual(Int(3.radiansToDegrees), 171) } - - func testIsPrime() { - XCTAssert(2.isPrime()) - XCTAssert(3.isPrime()) - XCTAssert(5.isPrime()) - XCTAssert(997.isPrime()) - XCTAssertFalse(1.isPrime()) - XCTAssertFalse(9.isPrime()) - XCTAssertFalse(55.isPrime()) - XCTAssertFalse(108.isPrime()) - } func testRandomBetween() { XCTAssertGreaterThan(Int.random(between: 1, and: 5), 0) diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 206ba357f..b003c04b4 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -174,8 +174,8 @@ class StringExtensionsTests: XCTestCase { } func testMostCommonCharacter() { - let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter() - XCTAssertEqual(mostCommonCharacter, "e") + let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter + XCTAssertEqual(mostCommonCharacter(), "e") XCTAssertEqual("".mostCommonCharacter(), "") } @@ -435,7 +435,7 @@ class StringExtensionsTests: XCTestCase { #elseif os(macOS) str.copyToPasteboard() - let strFromPasteboard = NSPasteboard.general().string(forType: NSPasteboardTypeString) + let strFromPasteboard = NSPasteboard.general.string(forType: .string) XCTAssertEqual(strFromPasteboard, str) #endif } @@ -510,12 +510,12 @@ class StringExtensionsTests: XCTestCase { func testBold() { let boldString = "hello".bold let attrs = boldString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, boldString.length)) - XCTAssertNotNil(attrs[NSFontAttributeName]) + XCTAssertNotNil(attrs[NSAttributedStringKey.font]) #if os(macOS) - XCTAssertEqual(attrs[NSFontAttributeName] as! NSFont, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize())) + XCTAssertEqual(attrs[.font] as! NSFont, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)) #elseif os(iOS) - XCTAssertEqual(attrs[NSFontAttributeName] as! UIFont, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) + XCTAssertEqual(attrs[NSAttributedStringKey.font] as! UIFont, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) #endif } #endif @@ -523,35 +523,35 @@ class StringExtensionsTests: XCTestCase { func testUnderline() { let underlinedString = "hello".underline let attrs = underlinedString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, underlinedString.length)) - XCTAssertNotNil(attrs[NSUnderlineStyleAttributeName]) - XCTAssertEqual(attrs[NSUnderlineStyleAttributeName] as! Int, NSUnderlineStyle.styleSingle.rawValue) + XCTAssertNotNil(attrs[NSAttributedStringKey.underlineStyle]) + XCTAssertEqual(attrs[NSAttributedStringKey.underlineStyle] as! Int, NSUnderlineStyle.styleSingle.rawValue) } func testStrikethrough() { let strikedthroughString = "hello".strikethrough let attrs = strikedthroughString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, strikedthroughString.length)) - XCTAssertNotNil(attrs[NSStrikethroughStyleAttributeName]) - XCTAssertEqual(attrs[NSStrikethroughStyleAttributeName] as! NSNumber, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) + XCTAssertNotNil(attrs[NSAttributedStringKey.strikethroughStyle]) + XCTAssertEqual(attrs[NSAttributedStringKey.strikethroughStyle] as! NSNumber, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) } #if os(iOS) func testItalic() { let italicString = "hello".italic let attrs = italicString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, italicString.length)) - XCTAssertNotNil(attrs[NSFontAttributeName]) - XCTAssertEqual(attrs[NSFontAttributeName] as! UIFont, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) + XCTAssertNotNil(attrs[NSAttributedStringKey.font]) + XCTAssertEqual(attrs[NSAttributedStringKey.font] as! UIFont, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) } #endif func testColored() { let coloredString = "hello".colored(with: .orange) let attrs = coloredString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, coloredString.length)) - XCTAssertNotNil(attrs[NSForegroundColorAttributeName]) + XCTAssertNotNil(attrs[NSAttributedStringKey.foregroundColor]) #if os(macOS) - XCTAssertEqual(attrs[NSForegroundColorAttributeName] as! NSColor, NSColor.orange) + XCTAssertEqual(attrs[.foregroundColor] as! NSColor, NSColor.orange) #else - XCTAssertEqual(attrs[NSForegroundColorAttributeName] as! UIColor, UIColor.orange) + XCTAssertEqual(attrs[NSAttributedStringKey.foregroundColor] as! UIColor, UIColor.orange) #endif } diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index cb5a10081..691471935 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 8/27/16. // Copyright © 2016 Omar Albeik. All rights reserved. // - import XCTest @testable import SwifterSwift diff --git a/Tests/UIKitTests/UIColorExtensionsTests.swift b/Tests/UIKitTests/UIColorExtensionsTests.swift index 76357fe72..ed63a0ff7 100644 --- a/Tests/UIKitTests/UIColorExtensionsTests.swift +++ b/Tests/UIKitTests/UIColorExtensionsTests.swift @@ -124,73 +124,35 @@ class UIColorExtensionsTests: XCTestCase { } - func testCoreImageColor() { - var color = UIColor(hex: 0xFF0000, transparency: 1.0) - var coreImageTestColor = CIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - - color = UIColor(hex: 0x00FF00, transparency: 1.0) - coreImageTestColor = CIColor(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - - color = UIColor(hex: 0x0000FF, transparency: 1.0) - coreImageTestColor = CIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - - color = UIColor(hex: 0x000000, transparency: 1.0) - coreImageTestColor = CIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - - color = UIColor(hex: 0xFFFFFF, transparency: 1.0) - coreImageTestColor = CIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - - color = UIColor(hex: 0x0000FF, transparency: 0.5) - coreImageTestColor = CIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 0.5) - XCTAssertEqual([color!.coreImageColor!.red, color!.coreImageColor!.green, color!.coreImageColor!.blue, color!.coreImageColor!.alpha], [coreImageTestColor.red, coreImageTestColor.green, coreImageTestColor.blue, coreImageTestColor.alpha]) - } - func testHexString() { var color = UIColor.red - XCTAssertEqual(color.hexString(), "#FF0000") - + XCTAssertEqual(color.hexString, "#FF0000") + color = UIColor.blue - XCTAssertEqual(color.hexString(), "#0000FF") + XCTAssertEqual(color.hexString, "#0000FF") color = UIColor(hex: 0xABCDEF)! - XCTAssertEqual(color.hexString(), "#ABCDEF") + XCTAssertEqual(color.hexString, "#ABCDEF") color = UIColor(hex: 0xABC)! - XCTAssertEqual(color.hexString(), "#000ABC") + XCTAssertEqual(color.hexString, "#000ABC") color = UIColor.black - XCTAssertEqual(color.hexString(), "#000000") - - color = UIColor.clear - XCTAssertEqual(color.hexString(withAlpha: true), "#00000000") - - color = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) - XCTAssertEqual(color.hexString(withAlpha: true), "#7F7F7F7F") + XCTAssertEqual(color.hexString, "#000000") } func testShortHexString() { var color: UIColor? = UIColor.red - XCTAssertEqual(color?.shortHexString(), "#F00") + XCTAssertEqual(color?.shortHexString, "#F00") color = UIColor.blue - XCTAssertEqual(color?.shortHexString(), "#00F") + XCTAssertEqual(color?.shortHexString, "#00F") color = UIColor(hexString: "#0F120F") - XCTAssertNil(color?.shortHexString()) + XCTAssertNil(color?.shortHexString) color = UIColor(hexString: "#8FFFF") - XCTAssertNil(color?.shortHexString()) - - color = UIColor.red - XCTAssertEqual(color?.shortHexString(withAlpha: true), "#FF00") - - color = UIColor.blue - XCTAssertEqual(color?.shortHexString(withAlpha: true), "#F00F") + XCTAssertNil(color?.shortHexString) } func testShortHexOrHexString() { diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index 8655a37de..e0cebe08d 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -5,60 +5,61 @@ // Created by Steven on 2/19/17. // Copyright © 2017 omaralbeik. All rights reserved. // + #if os(iOS) || os(tvOS) - import XCTest - @testable import SwifterSwift +import XCTest +@testable import SwifterSwift + +class UIImageViewExtensionsTests: XCTestCase { - class UIImageViewExtensionsTests: XCTestCase { - - func testDownload() { - // Success - let imageView = UIImageView() - let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! - let placeHolder = UIImage() - let downloadExpectation = expectation(description: "Download success") - imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in - XCTAssertEqual(imageView.image, image) - downloadExpectation.fulfill() - } - XCTAssertEqual(imageView.image, placeHolder) - XCTAssertEqual(imageView.contentMode, .scaleAspectFill) - - // Failure - let failImageView = UIImageView() - let failingURL = URL(string: "https://developer.apple.com/")! - let failExpectation = expectation(description: "Download failure") - failImageView.image = nil - failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in - XCTAssertNil(image) - DispatchQueue.main.async { - XCTAssertNil(failImageView.image) - } - failExpectation.fulfill() - } - XCTAssertEqual(failImageView.contentMode, .center) - XCTAssertNil(failImageView.image) - waitForExpectations(timeout: 15, handler: nil) + func testDownload() { + // Success + let imageView = UIImageView() + let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! + let placeHolder = UIImage() + let downloadExpectation = expectation(description: "Download success") + imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in + XCTAssertEqual(imageView.image, image) + downloadExpectation.fulfill() } - - func testBlur() { - let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100)) - imageView.blur(withStyle: .dark) - - let blurView = imageView.subviews.first as? UIVisualEffectView - XCTAssertNotNil(blurView) - XCTAssertNotNil(blurView?.effect) - XCTAssertEqual(blurView?.frame, imageView.bounds) - XCTAssertEqual(blurView?.autoresizingMask, [.flexibleWidth, .flexibleHeight]) - XCTAssert(imageView.clipsToBounds) - } - - func testBlurred() { - let imageView = UIImageView() - let blurredImageView = imageView.blurred(withStyle: .extraLight) - XCTAssertEqual(blurredImageView, imageView) + XCTAssertEqual(imageView.image, placeHolder) + XCTAssertEqual(imageView.contentMode, .scaleAspectFill) + + // Failure + let failImageView = UIImageView() + let failingURL = URL(string: "https://developer.apple.com/")! + let failExpectation = expectation(description: "Download failure") + failImageView.image = nil + failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in + XCTAssertNil(image) + DispatchQueue.main.async { + XCTAssertNil(failImageView.image) + } + failExpectation.fulfill() } + XCTAssertEqual(failImageView.contentMode, .center) + XCTAssertNil(failImageView.image) + waitForExpectations(timeout: 15, handler: nil) + } + + func testBlur() { + let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100)) + imageView.blur(withStyle: .dark) + let blurView = imageView.subviews.first as? UIVisualEffectView + XCTAssertNotNil(blurView) + XCTAssertNotNil(blurView?.effect) + XCTAssertEqual(blurView?.frame, imageView.bounds) + XCTAssertEqual(blurView?.autoresizingMask, [.flexibleWidth, .flexibleHeight]) + XCTAssert(imageView.clipsToBounds) } + + func testBlurred() { + let imageView = UIImageView() + let blurredImageView = imageView.blurred(withStyle: .extraLight) + XCTAssertEqual(blurredImageView, imageView) + } + +} #endif diff --git a/Tests/UIKitTests/UINavigationBarExtensionTests.swift b/Tests/UIKitTests/UINavigationBarExtensionTests.swift index 00accfb36..733a1bd68 100644 --- a/Tests/UIKitTests/UINavigationBarExtensionTests.swift +++ b/Tests/UIKitTests/UINavigationBarExtensionTests.swift @@ -17,13 +17,13 @@ class UINavigationBarExtensionsTests: XCTestCase { let navigationBar = UINavigationBar() let helveticaFont = UIFont(name: "HelveticaNeue", size: 14)! navigationBar.setTitleFont(helveticaFont, color: .green) - let color = navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor XCTAssertEqual(color, .green) - let font = navigationBar.titleTextAttributes?[NSFontAttributeName] as? UIFont + let font = navigationBar.titleTextAttributes?[NSAttributedStringKey.font] as? UIFont XCTAssertEqual(font, helveticaFont) navigationBar.setTitleFont(helveticaFont) - let defaultColor = navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + let defaultColor = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor XCTAssertEqual(defaultColor, .black) } @@ -34,11 +34,11 @@ class UINavigationBarExtensionsTests: XCTestCase { XCTAssertNotNil(navigationBar.shadowImage) XCTAssert(navigationBar.isTranslucent) XCTAssertEqual(navigationBar.tintColor, .red) - let color = navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor XCTAssertEqual(color, .red) navigationBar.makeTransparent() - let defaultColor = navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + let defaultColor = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor XCTAssertEqual(defaultColor, .white) } @@ -50,7 +50,7 @@ class UINavigationBarExtensionsTests: XCTestCase { XCTAssertEqual(navigationBar.barTintColor, .blue) XCTAssertNotNil(navigationBar.backgroundImage(for: .default)) XCTAssertEqual(navigationBar.tintColor, .green) - let color = navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor + let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor XCTAssertEqual(color, .green) } } diff --git a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift index 5c7699ecf..abfab3298 100644 --- a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift @@ -44,15 +44,15 @@ class UINavigationControllerExtensionsTests: XCTestCase { } - func testMakeTransparent() { - let navigationController = UINavigationController() - navigationController.makeTransparent(withTint: .red) - XCTAssertNotNil(navigationController.navigationBar.backgroundImage(for: .default)) - XCTAssertNotNil(navigationController.navigationBar.shadowImage) - XCTAssert(navigationController.navigationBar.isTranslucent) - XCTAssertEqual(navigationController.navigationBar.tintColor, .red) - let titleColor = navigationController.navigationBar.titleTextAttributes?[NSForegroundColorAttributeName] as? UIColor - XCTAssertEqual(titleColor, .red) - } +// func testMakeTransparent() { +// let navigationController = UINavigationController() +// navigationController.makeTransparent(withTint: .red) +// XCTAssertNotNil(navigationController.navigationBar.backgroundImage(for: .default)) +// XCTAssertNotNil(navigationController.navigationBar.shadowImage) +// XCTAssert(navigationController.navigationBar.isTranslucent) +// XCTAssertEqual(navigationController.navigationBar.tintColor, .red) +// let titleColor = navigationController.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor +// XCTAssertEqual(titleColor, .red) +// } } #endif diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index 2244bf86f..ef809c7fd 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -29,13 +29,15 @@ class UISliderExtensionsTests: XCTestCase { let slider = UISlider() slider.minimumValue = 0 slider.maximumValue = 100 + var completionCalled = false - let exp = expectation(description: "calledCompletion") slider.setValue(99) { - exp.fulfill() - XCTAssertEqual(slider.value, 99) + completionCalled = true + XCTAssert(completionCalled) } - waitForExpectations(timeout: 1, handler: nil) + XCTAssertFalse(completionCalled) + XCTAssertEqual(slider.value, 99) + } func testCompletionCalled() { diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 00e547c03..08152d1e3 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -17,8 +17,8 @@ class UITableViewExtensionsTests: XCTestCase { override func setUp() { super.setUp() - - tableView.dataSource = self + // Put setup code here. This method is called before the invocation of each test method in the class. + tableView.dataSource = self emptyTableView.dataSource = self tableView.reloadData() } diff --git a/Tests/UIKitTests/UITextFieldExtensionsTests.swift b/Tests/UIKitTests/UITextFieldExtensionsTests.swift index 2d0cec97e..98178ab14 100644 --- a/Tests/UIKitTests/UITextFieldExtensionsTests.swift +++ b/Tests/UIKitTests/UITextFieldExtensionsTests.swift @@ -121,12 +121,12 @@ class UITextFieldExtensionsTests: XCTestCase { let textField = UITextField() textField.attributedPlaceholder = NSAttributedString(string: "Attributed Placeholder") textField.setPlaceHolderTextColor(.blue) - let color = textField.attributedPlaceholder?.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: nil) as? UIColor + let color = textField.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor XCTAssertEqual(color, .blue) textField.placeholder = nil textField.setPlaceHolderTextColor(.yellow) - let emptyColor = textField.attributedPlaceholder?.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: nil) as? UIColor + let emptyColor = textField.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor XCTAssertNil(emptyColor) } diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index 6346c906e..14fdd80a9 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -16,7 +16,7 @@ class UIViewControllerExtensionsTests: XCTestCase { class MockNotificationViewController: UIViewController { var notificationFired = false - func testSelector() { + @objc func testSelector() { notificationFired = true } } diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 8cbc75e20..34ac71131 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -5,7 +5,6 @@ // Created by Omar Albeik on 2/15/17. // Copyright © 2017 omaralbeik. All rights reserved. // - import XCTest @testable import SwifterSwift diff --git a/Tests/UIKitTests/UIWebViewExtensionsTests.swift b/Tests/UIKitTests/UIWebViewExtensionsTests.swift deleted file mode 100644 index 8f7c8e02b..000000000 --- a/Tests/UIKitTests/UIWebViewExtensionsTests.swift +++ /dev/null @@ -1,69 +0,0 @@ -// -// UIWebViewExtensionsTests.swift -// SwifterSwift -// -// Created by Omar Albeik on 9/6/17. -// -// - -import XCTest -@testable import SwifterSwift - -#if os(iOS) - class UIWebViewExtensionsTests: XCTestCase { - - var webView = UIWebView() - let successExpectation = XCTestExpectation(description: "Correct URL") - - override func setUp() { - webView = UIWebView() - } - - func testLoadURL() { - let url = URL(string: "https://www.w3schools.com/")! - webView.loadURL(url) - - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - guard let _ = self.webView.request?.url else { - XCTFail("No URL in webView") - return - } - self.successExpectation.fulfill() - } - wait(for: [successExpectation], timeout: 2.5) - - } - - func testLoadURLString() { - let urlString = "https://www.w3schools.com/" - webView.loadURLString(urlString) - - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - guard let _ = self.webView.request?.url?.absoluteString else { - XCTFail("No URL in webView") - return - } - self.successExpectation.fulfill() - } - wait(for: [successExpectation], timeout: 2.5) - } - - func testLoadInvalidURLString() { - let invalidURLString = "invalid url" - webView.loadURLString(invalidURLString) - - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - if let _ = self.webView.request?.url?.absoluteString { - XCTFail("Request was made by an invalid URL :(") - return - } - self.successExpectation.fulfill() - } - wait(for: [successExpectation], timeout: 2.5) - - } - - - } - -#endif diff --git a/Tests/build.sh b/Tests/build.sh deleted file mode 100644 index 81decb98b..000000000 --- a/Tests/build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# Builds all targets and runs tests. - -DERIVED_DATA=${1:-/tmp/SwifterSwift} -echo "Derived data location: $DERIVED_DATA"; - -set -o pipefail && -rm -rf $DERIVED_DATA && -time xcodebuild clean test \ - -project SwifterSwift.xcodeproj \ - -scheme 'SwifterSwift macOS' \ - -sdk macosx10.13 \ - -derivedDataPath $DERIVED_DATA \ - | tee build.log \ - | xcpretty && -cat build.log && -rm -rf $DERIVED_DATA && -time xcodebuild clean test \ - -project SwifterSwift.xcodeproj \ - -scheme 'SwifterSwift tvOS' \ - -sdk appletvsimulator11.0 \ - -derivedDataPath $DERIVED_DATA \ - -destination 'platform=tvOS Simulator,name=Apple TV 1080p' \ - | tee build.log \ - | xcpretty && -cat build.log && -rm -rf $DERIVED_DATA && -time xcodebuild clean test \ - -project SwifterSwift.xcodeproj \ - -scheme 'SwifterSwift iOS' \ - -sdk iphonesimulator11.0 \ - -derivedDataPath $DERIVED_DATA \ - -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.0' \ - | tee build.log \ - | xcpretty && -cat build.log From 8e5750f4017d76b2b857d25419de864ca0cd253f Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 27 Sep 2017 12:19:49 +0300 Subject: [PATCH 023/201] v4.0.0 --- .swiftlint.yml | 11 +++ CHANGELOG.md | 47 ++++++++++- README.md | 1 + .../Extensions/AppKit/NSColorExtensions.swift | 40 ++-------- .../Extensions/AppKit/NSViewExtensions.swift | 22 ++---- .../CoreGraphics/CGColorExtensions.swift | 1 - .../CoreGraphics/CGFloatExtensions.swift | 2 - .../CoreGraphics/CGPointExtensions.swift | 3 - .../CoreGraphics/CGSizeExtensions.swift | 1 - .../CoreLocation/CLLocationExtensions.swift | 2 - .../Foundation/DataExtensions.swift | 2 - .../Foundation/DateExtensions.swift | 12 +-- .../Foundation/LocaleExtensions.swift | 1 - .../NSAttributedStringExtensions.swift | 1 - .../Extensions/Foundation/URLExtensions.swift | 1 - .../Foundation/URLRequestExtensions.swift | 1 - .../Foundation/UserDefaultsExtensions.swift | 1 - .../SwiftStdlib/ArrayExtensions.swift | 58 ++++++-------- .../SwiftStdlib/BoolExtensions.swift | 1 - .../SwiftStdlib/CharacterExtensions.swift | 4 +- .../SwiftStdlib/CollectionExtensions.swift | 6 +- .../SwiftStdlib/DictionaryExtensions.swift | 21 +++-- .../SwiftStdlib/DoubleExtensions.swift | 2 - .../SwiftStdlib/FloatExtensions.swift | 2 - .../SwiftStdlib/FloatingPointExtensions.swift | 4 - .../SwiftStdlib/IntExtensions.swift | 13 +--- .../SwiftStdlib/OptionalExtensions.swift | 1 - .../SwiftStdlib/SignedIntegerExtensions.swift | 4 - .../SwiftStdlib/SignedNumericExtensions.swift | 3 +- .../SwiftStdlib/StringExtensions.swift | 15 +--- Sources/Extensions/SwifterSwift.swift | 12 ++- .../UIKit/UIAlertControllerExtensions.swift | 6 +- .../UIKit/UIBarButtonItemExtensions.swift | 1 - .../Extensions/UIKit/UIButtonExtensions.swift | 38 +++------ .../UIKit/UICollectionViewExtensions.swift | 10 +-- .../Extensions/UIKit/UIColorExtensions.swift | 54 ++++--------- .../Extensions/UIKit/UIImageExtensions.swift | 5 +- .../UIKit/UIImageViewExtensions.swift | 3 +- .../Extensions/UIKit/UILabelExtensions.swift | 1 - .../UIKit/UINavigationBarExtensions.swift | 1 - .../UINavigationControllerExtensions.swift | 5 +- .../UIKit/UINavigationItemExtensions.swift | 1 - .../UIKit/UISearchBarExtensions.swift | 2 - .../UIKit/UISegmentedControlExtensions.swift | 1 - .../Extensions/UIKit/UISliderExtensions.swift | 3 +- .../UIKit/UIStoryboardExtensions.swift | 4 +- .../Extensions/UIKit/UISwitchExtensions.swift | 1 - .../Extensions/UIKit/UITabBarExtensions.swift | 5 +- .../UIKit/UITableViewExtensions.swift | 6 +- .../UIKit/UITextFieldExtensions.swift | 12 +-- .../UIKit/UITextViewExtensions.swift | 2 +- .../UIKit/UIViewControllerExtensions.swift | 1 - .../Extensions/UIKit/UIViewExtensions.swift | 45 ++++------- SwifterSwift.xcodeproj/project.pbxproj | 77 ++++++++++++++++++- Tests/AppKitTests/NSViewExtensionsTests.swift | 1 - .../CLLocationExtensionsTests.swift | 1 - .../FoundationTests/DateExtensionsTests.swift | 4 +- .../UserDefaultsExtensionsTests.swift | 4 +- .../ArrayExtensionsTests.swift | 49 ++++++------ .../CollectionExtensionsTests.swift | 1 - .../DictionaryExtensionsTests.swift | 23 +++--- .../StringExtensionsTests.swift | 44 +++++++++-- .../UIAlertControllerExtensionsTests.swift | 4 +- Tests/UIKitTests/UIFontExtensionsTest.swift | 9 ++- Tests/UIKitTests/UIImageExtensionsTests.swift | 1 - .../UIKitTests/UISliderExtensionsTests.swift | 1 - .../UIKitTests/UITabBarExtensionsTests.swift | 1 - .../UITextFieldExtensionsTests.swift | 2 - Tests/UIKitTests/UIViewExtensionsTests.swift | 1 - 69 files changed, 341 insertions(+), 384 deletions(-) create mode 100644 .swiftlint.yml diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 000000000..1a9461f92 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,11 @@ +disabled_rules: +- identifier_name +- trailing_whitespace +- line_length +- type_body_length +- file_length +- cyclomatic_complexity +- function_body_length +- large_tuple +- legacy_constructor +- shorthand_operator diff --git a/CHANGELOG.md b/CHANGELOG.md index 935c3d1a8..c1d0d763a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,13 +11,52 @@ All notable changes to this project will be documented in this file. > N/A > > ### Enhancements -> - New **Date** extensions -> - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. -> - New **UIFont** extensions -> - added `asMonospacedDigitFont() -> UIFont` method to get the current font as monospaced digit font. [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) +> N/A +> > ### Bugfixes > N/A + +# v4.0.0 + +### API Breaking +- **Swift4 / Xcode9 🎉** + - This version brings support for Swift4 and Xcode9. [Looking for Swift3 / 3.2 ?](https://github.com/SwifterSwift/SwifterSwift#looking-for-swift-3) +- **UIColor** + - `social` has been renamed to `Social` to match Apple Swift guidelines + - `material` has been renamed to `Material` to match Apple Swift guidelines + - `flatUI` has been renamed to `FlatUI` to match Apple Swift guidelines + - `css` has been renamed to `CSS` to match Apple Swift guidelines +- **NSColor** + - `social` has been renamed to `Social` to match Apple Swift guidelines + - `material` has been renamed to `Material` to match Apple Swift guidelines + - `flatUI` has been renamed to `FlatUI` to match Apple Swift guidelines + - `css` has been renamed to `CSS` to match Apple Swift guidelines + +### Enhancements +- **SwiftLint** + - Added [SwiftLint](https://github.com/realm/SwiftLint) to enforce Swift style and conventions. +- **Danger** + - Added Danger to continuous integration. [#252](https://github.com/SwifterSwift/SwifterSwift/pull/252) by [SD10](https://github.com/SD10). +- New **Date** extensions + - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. [#248](https://github.com/SwifterSwift/SwifterSwift/pull/248) by [BennX](https://github.com/BennX). +- New **UIFont** extensions + - added `asMonospacedDigitFont() -> UIFont` method to get the current font as monospaced digit font. [#250](https://github.com/SwifterSwift/SwifterSwift/pull/250) by [BennX](https://github.com/BennX), [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) + +- **UITableView** + - `dequeueReusableCell` now returns an optional + - `dequeueReusableHeaderFooterView` now returns an optional +- **UICollectionView** + - `dequeueReusableCell` now returns an optional + - `dequeueReusableSupplementaryView` now returns an optional +- **UIAlertController** + - Added `preferredStyle: UIAlertControllerStyle = .alert` to `init from error`. + +### Bugfixes +- **SwifterSwift** + - `didTakeScreenShot` now returns the notification, make sure to remove listener when you don't need it anymore. + + # v3.2.0 ### API Breaking diff --git a/README.md b/README.md index a58405257..86fa501a4 100755 --- a/README.md +++ b/README.md @@ -242,3 +242,4 @@ Special thanks to: - [Paweł Urbanek](https://github.com/pawurb) for adding tvOS, watchOS and macOS initial support and helping with extensions. - [Mert Akengin](https://github.com/PvtMert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swiftierswift.com) and logo. - [Abdul Rahman Dabbour](https://github.com/thedabbour) for helping document the project. +- Many thanks to all other [contributors](https://github.com/SwifterSwift/SwifterSwift/graphs/contributors) of this project. diff --git a/Sources/Extensions/AppKit/NSColorExtensions.swift b/Sources/Extensions/AppKit/NSColorExtensions.swift index e0a5be02a..79ae49056 100644 --- a/Sources/Extensions/AppKit/NSColorExtensions.swift +++ b/Sources/Extensions/AppKit/NSColorExtensions.swift @@ -9,7 +9,6 @@ #if os(macOS) import Cocoa - public extension NSColor { /// SwifterSwift: Create NSColor from hexadecimal value with optional transparency. @@ -83,13 +82,11 @@ public extension NSColor { } - - -//MARK: - Social Colors +// MARK: - Social Colors public extension NSColor { /// SwifterSwift: Brand identity color of popular social media platform. - public struct social { + public struct Social { // https://www.lockedowndesign.com/social-media-colors/ /// red: 59, green: 89, blue: 152 @@ -173,12 +170,11 @@ public extension NSColor { } } - -//MARK: - Material colors +// MARK: - Material colors public extension NSColor { /// SwifterSwift: Google Material design colors palette. - public struct material { + public struct Material { // https://material.google.com/style/color.html /// SwifterSwift: color red500 @@ -226,7 +222,6 @@ public extension NSColor { /// SwifterSwift: hex #D50000 public static let redA700 = NSColor(hex: 0xD50000) - /// SwifterSwift: color pink500 public static let pink = pink500 @@ -272,7 +267,6 @@ public extension NSColor { /// SwifterSwift: hex #C51162 public static let pinkA700 = NSColor(hex: 0xC51162) - /// SwifterSwift: color purple500 public static let purple = purple500 @@ -318,7 +312,6 @@ public extension NSColor { /// SwifterSwift: hex #AA00FF public static let purpleA700 = NSColor(hex: 0xAA00FF) - /// SwifterSwift: color deepPurple500 public static let deepPurple = deepPurple500 @@ -364,7 +357,6 @@ public extension NSColor { /// SwifterSwift: hex #6200EA public static let deepPurpleA700 = NSColor(hex: 0x6200EA) - /// SwifterSwift: color indigo500 public static let indigo = indigo500 @@ -410,7 +402,6 @@ public extension NSColor { /// SwifterSwift: hex #304FFE public static let indigoA700 = NSColor(hex: 0x304FFE) - /// SwifterSwift: color blue500 public static let blue = blue500 @@ -456,7 +447,6 @@ public extension NSColor { /// SwifterSwift: hex #2962FF public static let blueA700 = NSColor(hex: 0x2962FF) - /// SwifterSwift: color lightBlue500 public static let lightBlue = lightBlue500 @@ -502,7 +492,6 @@ public extension NSColor { /// SwifterSwift: hex #0091EA public static let lightBlueA700 = NSColor(hex: 0x0091EA) - /// SwifterSwift: color cyan500 public static let cyan = cyan500 @@ -548,7 +537,6 @@ public extension NSColor { /// SwifterSwift: hex #00B8D4 public static let cyanA700 = NSColor(hex: 0x00B8D4) - /// SwifterSwift: color teal500 public static let teal = teal500 @@ -594,7 +582,6 @@ public extension NSColor { /// SwifterSwift: hex #00BFA5 public static let tealA700 = NSColor(hex: 0x00BFA5) - /// SwifterSwift: color green500 public static let green = green500 @@ -640,7 +627,6 @@ public extension NSColor { /// SwifterSwift: hex #00C853 public static let greenA700 = NSColor(hex: 0x00C853) - /// SwifterSwift: color lightGreen500 public static let lightGreen = lightGreen500 @@ -686,7 +672,6 @@ public extension NSColor { /// SwifterSwift: hex #64DD17 public static let lightGreenA700 = NSColor(hex: 0x64DD17) - /// SwifterSwift: color lime500 public static let lime = lime500 @@ -732,7 +717,6 @@ public extension NSColor { /// SwifterSwift: hex #AEEA00 public static let limeA700 = NSColor(hex: 0xAEEA00) - /// SwifterSwift: color yellow500 public static let yellow = yellow500 @@ -778,7 +762,6 @@ public extension NSColor { /// SwifterSwift: hex #FFD600 public static let yellowA700 = NSColor(hex: 0xFFD600) - /// SwifterSwift: color amber500 public static let amber = amber500 @@ -824,7 +807,6 @@ public extension NSColor { /// SwifterSwift: hex #FFAB00 public static let amberA700 = NSColor(hex: 0xFFAB00) - /// SwifterSwift: color orange500 public static let orange = orange500 @@ -870,7 +852,6 @@ public extension NSColor { /// SwifterSwift: hex #FF6D00 public static let orangeA700 = NSColor(hex: 0xFF6D00) - /// SwifterSwift: color deepOrange500 public static let deepOrange = deepOrange500 @@ -916,7 +897,6 @@ public extension NSColor { /// SwifterSwift: hex #DD2C00 public static let deepOrangeA700 = NSColor(hex: 0xDD2C00) - /// SwifterSwift: color brown500 public static let brown = brown500 @@ -950,7 +930,6 @@ public extension NSColor { /// SwifterSwift: hex #3E2723 public static let brown900 = NSColor(hex: 0x3E2723) - /// SwifterSwift: color grey500 public static let grey = grey500 @@ -984,7 +963,6 @@ public extension NSColor { /// SwifterSwift: hex #212121 public static let grey900 = NSColor(hex: 0x212121) - /// SwifterSwift: color blueGrey500 public static let blueGrey = blueGrey500 @@ -1018,7 +996,6 @@ public extension NSColor { /// SwifterSwift: hex #263238 public static let blueGrey900 = NSColor(hex: 0x263238) - /// SwifterSwift: hex #000000 public static let black = NSColor(hex: 0x000000) @@ -1029,13 +1006,11 @@ public extension NSColor { } - -//MARK: - CSS colors - +// MARK: - CSS colors public extension NSColor { /// SwifterSwift: CSS colors. - public struct css { + public struct CSS { // http://www.w3schools.com/colors/colors_names.asp /// SwifterSwift: hex #F0F8FF @@ -1487,11 +1462,10 @@ public extension NSColor { } // MARK: - Flat UI colors - public extension NSColor { /// SwifterSwift: Flat UI colors - public struct flatUI { + public struct FlatUI { // http://flatuicolors.com. /// SwifterSwift: hex #1ABC9C diff --git a/Sources/Extensions/AppKit/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift index 42f3f946d..017933f37 100644 --- a/Sources/Extensions/AppKit/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -12,9 +12,8 @@ import Cocoa // MARK: - Properties public extension NSView { - @IBInspectable /// SwifterSwift: Border color of view; also inspectable from Storyboard. - public var borderColor: NSColor? { + @IBInspectable public var borderColor: NSColor? { get { return layer?.borderColor?.nsColor } @@ -24,9 +23,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Border width of view; also inspectable from Storyboard. - public var borderWidth: CGFloat { + @IBInspectable public var borderWidth: CGFloat { get { return layer?.borderWidth ?? 0 } @@ -36,9 +34,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Corner radius of view; also inspectable from Storyboard. - public var cornerRadius: CGFloat { + @IBInspectable public var cornerRadius: CGFloat { get { return layer?.cornerRadius ?? 0 } @@ -59,9 +56,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. - public var shadowColor: NSColor? { + @IBInspectable public var shadowColor: NSColor? { get { return layer?.shadowColor?.nsColor } @@ -71,9 +67,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Shadow offset of view; also inspectable from Storyboard. - public var shadowOffset: CGSize { + @IBInspectable public var shadowOffset: CGSize { get { return layer?.shadowOffset ?? CGSize.zero } @@ -83,9 +78,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Shadow opacity of view; also inspectable from Storyboard. - public var shadowOpacity: Float { + @IBInspectable public var shadowOpacity: Float { get { return layer?.shadowOpacity ?? 0 } @@ -95,9 +89,8 @@ public extension NSView { } } - @IBInspectable /// SwifterSwift: Shadow radius of view; also inspectable from Storyboard. - public var shadowRadius: CGFloat { + @IBInspectable public var shadowRadius: CGFloat { get { return layer?.shadowRadius ?? 0 } @@ -130,7 +123,6 @@ public extension NSView { } - // MARK: - Methods extension NSView { diff --git a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift index cc7fb03b2..8c11d5c22 100644 --- a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - public extension CGColor { #if !os(macOS) diff --git a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift index cc07f8539..d1e4833b8 100644 --- a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - // MARK: - Properties public extension CGFloat { @@ -68,7 +67,6 @@ public extension CGFloat { } - // MARK: - Methods public extension CGFloat { diff --git a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift index 7bf235442..de812cdb7 100644 --- a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - // MARK: - Methods public extension CGPoint { @@ -47,7 +46,6 @@ public extension CGPoint { } - // MARK: - Operators public extension CGPoint { @@ -152,4 +150,3 @@ public extension CGPoint { } } - diff --git a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift index 9e5704048..db19d69a8 100644 --- a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - // MARK: - Methods public extension CGSize { diff --git a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift index c5b7b7bca..ba8ef1f00 100644 --- a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift +++ b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift @@ -8,7 +8,6 @@ import CoreLocation - // MARK: - Methods public extension CLLocation { @@ -70,4 +69,3 @@ public extension CLLocation { } } - diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index a6da5b70a..b77acbb1a 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - // MARK: - Properties public extension Data { @@ -35,4 +34,3 @@ public extension Data { } } - diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 6b5e9201b..25d7eb15b 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -8,7 +8,6 @@ import Foundation - public extension Date { /// SwifterSwift: Day name format. @@ -35,7 +34,6 @@ public extension Date { } - // MARK: - Properties public extension Date { @@ -313,7 +311,7 @@ public extension Date { /// date.nearestFiveMinutes // "5:45 PM" /// public var nearestFiveMinutes: Date { - var components = Calendar.current.dateComponents([.year, .month , .day , .hour , .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) let min = components.minute! components.minute! = min % 5 < 3 ? min - min % 5 : min + 5 - (min % 5) components.second = 0 @@ -330,7 +328,7 @@ public extension Date { /// date.nearestTenMinutes // "5:50 PM" /// public var nearestTenMinutes: Date { - var components = Calendar.current.dateComponents([.year, .month , .day , .hour , .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) let min = components.minute! components.minute? = min % 10 < 6 ? min - min % 10 : min + 10 - (min % 10) components.second = 0 @@ -347,7 +345,7 @@ public extension Date { /// date.nearestQuarterHour // "5:45 PM" /// public var nearestQuarterHour: Date { - var components = Calendar.current.dateComponents([.year, .month , .day , .hour , .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) let min = components.minute! components.minute! = min % 15 < 8 ? min - min % 15 : min + 15 - (min % 15) components.second = 0 @@ -364,7 +362,7 @@ public extension Date { /// date.nearestHalfHour // "7:00 PM" /// public var nearestHalfHour: Date { - var components = Calendar.current.dateComponents([.year, .month , .day , .hour , .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) let min = components.minute! components.minute! = min % 30 < 15 ? min - min % 30 : min + 30 - (min % 30) components.second = 0 @@ -404,7 +402,6 @@ public extension Date { } - // MARK: - Methods public extension Date { @@ -719,7 +716,6 @@ public extension Date { } } - // MARK: - Initializers public extension Date { diff --git a/Sources/Extensions/Foundation/LocaleExtensions.swift b/Sources/Extensions/Foundation/LocaleExtensions.swift index fc9507499..7c17aa928 100644 --- a/Sources/Extensions/Foundation/LocaleExtensions.swift +++ b/Sources/Extensions/Foundation/LocaleExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Properties public extension Locale { diff --git a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift index 615fe193a..251ade26a 100644 --- a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift @@ -12,7 +12,6 @@ import UIKit #endif - // MARK: - Properties public extension NSAttributedString { diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 2e1aecba3..678cd5beb 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -8,7 +8,6 @@ import Foundation - public extension URL { /// SwifterSwift: URL with appending query parameters. diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift index cda4f1665..be4c7cd90 100644 --- a/Sources/Extensions/Foundation/URLRequestExtensions.swift +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -7,7 +7,6 @@ // import Foundation - // MARK: - Initializers public extension URLRequest { diff --git a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift index 6c3d8519c..7e050f7af 100644 --- a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift +++ b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift @@ -7,7 +7,6 @@ // import Foundation - // MARK: - Methods public extension UserDefaults { diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index ba943f923..a5832ba0a 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Methods (Integer) public extension Array where Element: Numeric { @@ -25,7 +24,6 @@ public extension Array where Element: Numeric { } - // MARK: - Methods (FloatingPoint) public extension Array where Element: FloatingPoint { @@ -35,13 +33,12 @@ public extension Array where Element: FloatingPoint { /// /// - Returns: average of the array's elements. public func average() -> Element { - guard isEmpty == false else { return 0 } + guard !isEmpty else { return 0 } var total: Element = 0 forEach { total += $0 } return total / Element(count) } - } // MARK: - Methods @@ -98,11 +95,11 @@ public extension Array { /// - Parameters: /// - index: index of first element. /// - otherIndex: index of other element. - public mutating func safeSwap(from index: Int, to otherIndex: Int) { + public mutating func safeSwap(from index: Int, to otherIndex: Int) { guard index != otherIndex, startIndex.. //print: 0, 2, 4 + /// [0, 2, 4, 7].forEach(where: {$0 % 2 == 0}, body: { print($0)}) -> //print: 0, 2, 4 /// /// - Parameters: /// - condition: condition to evaluate each element against. @@ -271,7 +268,6 @@ public extension Array { }) } - /// SwifterSwift: Keep elements of Array while condition is true. /// /// [0, 2, 4, 7].keep( where: {$0 % 2 == 0}) -> [0, 2, 4] @@ -324,17 +320,16 @@ public extension Array { /// - Parameters: /// - slice: size of array in each interation. /// - body: a closure that takes an array of slice size as a parameter. - public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { + public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { guard slice > 0, !isEmpty else { return } - var value : Int = 0 + var value: Int = 0 while value < count { - try body(Array(self[Swift.max(value,startIndex).. [[0, 2], [4, 7]] @@ -345,10 +340,10 @@ public extension Array { public func group(by size: Int) -> [[Element]]? { //Inspired by: https://lodash.com/docs/4.17.4#chunk guard size > 0, !isEmpty else { return nil } - var value : Int = 0 - var slices : [[Element]] = [] + var value: Int = 0 + var slices: [[Element]] = [] while value < count { - slices.append(Array(self[Swift.max(value,startIndex)..(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { - var group : [K: [Element]] = [:] + var group = [K: [Element]]() for value in self { let key = try keyForValue(value) group[key] = (group[key] ?? []) + [value] @@ -382,7 +377,7 @@ public extension Array { guard places != 0 && places < count else { return self } - var array : [Element] = self + var array: [Element] = self if places > 0 { let range = (array.count - places).. 1 else { return } for index in startIndex.. Bool { - guard !elements.isEmpty else { // elements array is empty - return true - } + guard !elements.isEmpty else { return true } var found = true for element in elements { if !contains(element) { @@ -468,10 +460,8 @@ public extension Array where Element: Equatable { /// - Returns: an array with all indexes of the given item. public func indexes(of item: Element) -> [Int] { var indexes: [Int] = [] - for index in startIndex.. [Element] { // Thanks to https://github.com/sairamkotha for improving the property - return reduce([]){ ($0 as [Element]).contains($1) ? $0 : $0 + [$1] } + return reduce([]) { ($0 as [Element]).contains($1) ? $0 : $0 + [$1] } } /// SwifterSwift: First index of a given item in an array. @@ -527,8 +517,8 @@ public extension Array where Element: Equatable { /// - Parameter item: item to check. /// - Returns: first index of item in array (if exists). public func firstIndex(of item: Element) -> Int? { - for (index, value) in lazy.enumerated() { - if value == item { return index } + for (index, value) in lazy.enumerated() where value == item { + return index } return nil } @@ -542,8 +532,8 @@ public extension Array where Element: Equatable { /// - Parameter item: item to check. /// - Returns: last index of item in array (if exists). public func lastIndex(of item: Element) -> Int? { - for (index, value) in lazy.enumerated().reversed() { - if value == item { return index } + for (index, value) in lazy.enumerated().reversed() where value == item { + return index } return nil } diff --git a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift index c29fceabf..f1c747efd 100644 --- a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Properties public extension Bool { diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index 05f3c4ac9..050b87991 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Properties public extension Character { @@ -20,7 +19,7 @@ public extension Character { // http://stackoverflow.com/questions/30757193/find-out-if-character-in-string-is-emoji let scalarValue = String(self).unicodeScalars.first!.value switch scalarValue { - case 0x3030, 0x00AE, 0x00A9,// Special Characters + case 0x3030, 0x00AE, 0x00A9, // Special Characters 0x1D000...0x1F77F, // Emoticons 0x2100...0x27BF, // Misc symbols and Dingbats 0xFE00...0xFE0F, // Variation Selectors @@ -111,7 +110,6 @@ public extension Character { } - // MARK: - Operators public extension Character { diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index 609918dc5..b4fcd877e 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Methods public extension Collection { @@ -29,7 +28,7 @@ public extension Collection { /// } /// /// - Parameter each: closure to run for each element. - public func forEachInParallel(_ each: (Self.Iterator.Element) -> ()) { + public func forEachInParallel(_ each: (Self.Iterator.Element) -> Void) { let indices = indicesArray() DispatchQueue.concurrentPerform(iterations: indices.count) { (index) in @@ -49,7 +48,7 @@ public extension Collection { /// arr[safe: 10] -> nil /// /// - Parameter index: index of element to access element. - public subscript (safe index: Index) -> Iterator.Element? { + public subscript(safe index: Index) -> Iterator.Element? { return indices.contains(index) ? self[index] : nil } @@ -77,4 +76,3 @@ public extension Collection where Iterator.Element == Int, Index == Int { } } - diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index ed5c0d52a..870494bbe 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -84,8 +84,8 @@ public extension Dictionary { /// /// - Parameter where: condition to evaluate each tuple entry against. /// - Returns: Count of entries that matches the where clousure. - public func count(where condition: @escaping ((key: Key, value: Value)) throws -> Bool ) rethrows -> Int { - var count : Int = 0 + public func count(where condition: @escaping ((key: Key, value: Value)) throws -> Bool) rethrows -> Int { + var count: Int = 0 try self.forEach { if try condition($0) { count += 1 @@ -112,9 +112,9 @@ public extension Dictionary { /// - lhs: dictionary /// - rhs: dictionary /// - Returns: An dictionary with keys and values from both. - public static func +(lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] { + public static func + (lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] { var result = lhs - rhs.forEach{ result[$0] = $1 } + rhs.forEach { result[$0] = $1 } return result } @@ -131,11 +131,10 @@ public extension Dictionary { /// - Parameters: /// - lhs: dictionary /// - rhs: dictionary - public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) { - rhs.forEach({ lhs[$0] = $1}) + public static func += (lhs: inout [Key: Value], rhs: [Key: Value]) { + rhs.forEach { lhs[$0] = $1} } - - + /// SwifterSwift: Remove contained in the array from the dictionary /// /// let dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] @@ -148,7 +147,7 @@ public extension Dictionary { /// - lhs: dictionary /// - rhs: array with the keys to be removed. /// - Returns: a new dictionary with keys removed. - public static func -(lhs: [Key: Value], keys: [Key]) -> [Key: Value]{ + public static func - (lhs: [Key: Value], keys: [Key]) -> [Key: Value] { var result = lhs result.removeAll(keys: keys) return result @@ -165,13 +164,12 @@ public extension Dictionary { /// - Parameters: /// - lhs: dictionary /// - rhs: array with the keys to be removed. - public static func -=(lhs: inout [Key: Value], keys: [Key]) { + public static func -= (lhs: inout [Key: Value], keys: [Key]) { lhs.removeAll(keys: keys) } } - // MARK: - Methods (ExpressibleByStringLiteral) public extension Dictionary where Key: ExpressibleByStringLiteral { @@ -191,4 +189,3 @@ public extension Dictionary where Key: ExpressibleByStringLiteral { } } - diff --git a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift index 1479d22e9..b6bfde58c 100755 --- a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift @@ -13,7 +13,6 @@ import Foundation import UIKit #endif - // MARK: - Properties public extension Double { @@ -34,7 +33,6 @@ public extension Double { } - // MARK: - Operators precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence } diff --git a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift index 6d08e80d6..f46afca6e 100755 --- a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift @@ -13,7 +13,6 @@ import Foundation import UIKit #endif - // MARK: - Properties public extension Float { @@ -34,7 +33,6 @@ public extension Float { } - // MARK: - Operators precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence } diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index 7eafaca34..37db0af69 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -8,7 +8,6 @@ import Foundation - // MARK: - Properties public extension FloatingPoint { @@ -49,7 +48,6 @@ public extension FloatingPoint { } - // MARK: - Methods public extension FloatingPoint { @@ -77,7 +75,6 @@ public extension FloatingPoint { } - // MARK: - Initializers public extension FloatingPoint { @@ -103,7 +100,6 @@ public extension FloatingPoint { } - // MARK: - Operators infix operator ± /// SwifterSwift: Tuple of plus-minus operation. diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 3d618e860..1d0c27c7a 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -13,11 +13,9 @@ import Foundation import UIKit #endif - // MARK: - Properties public extension Int { - /// SwifterSwift: CountableRange 0.. { return 0.. 0) { + if div > 0 { for _ in 0..
    ) -> String? { - guard let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) else { + guard let lowerIndex = index(startIndex, offsetBy: max(0, range.lowerBound), limitedBy: endIndex) else { return nil } guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) else { @@ -464,7 +462,7 @@ public extension String { /// /// - Parameter range: Closed range. public subscript(safe range: ClosedRange) -> String? { - guard let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) else { + guard let lowerIndex = index(startIndex, offsetBy: max(0, range.lowerBound), limitedBy: endIndex) else { return nil } guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound + 1, limitedBy: endIndex) else { @@ -703,7 +701,7 @@ public extension String { /// - Parameter separator: separator to split string by. /// - Returns: array of strings separated by given string. public func splitted(by separator: Character) -> [String] { - return characters.split{$0 == separator}.map(String.init) + return characters.split { $0 == separator }.map(String.init) } /// SwifterSwift: Check if string starts with substring. @@ -813,7 +811,6 @@ public extension String { } - // MARK: - Operators public extension String { @@ -849,7 +846,6 @@ public extension String { } - // MARK: - Initializers public extension String { @@ -877,8 +873,6 @@ public extension String { } - - // MARK: - NSAttributedString extensions public extension String { @@ -934,8 +928,7 @@ public extension String { } - -//MARK: - NSString extensions +// MARK: - NSString extensions public extension String { /// SwifterSwift: NSString from a string. diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 73f45fdad..2cb4c5417 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -84,7 +84,6 @@ public struct SwifterSwift { } #endif - #if !os(macOS) /// SwifterSwift: Screen height. public static var screenHeight: CGFloat { @@ -267,7 +266,7 @@ public extension SwifterSwift { /// - queue: a queue that completion closure should be executed on (default is DispatchQueue.main). /// - completion: closure to be executed after delay. /// - Returns: DispatchWorkItem task. You can call .cancel() on it to cancel delayed execution. - @discardableResult public static func delay(milliseconds: Double, queue: DispatchQueue = .main, completion: @escaping ()-> Void) -> DispatchWorkItem { + @discardableResult public static func delay(milliseconds: Double, queue: DispatchQueue = .main, completion: @escaping () -> Void) -> DispatchWorkItem { let task = DispatchWorkItem { completion() } queue.asyncAfter(deadline: .now() + (milliseconds/1000), execute: task) return task @@ -279,7 +278,7 @@ public extension SwifterSwift { /// - millisecondsOffset: allow execution of method if it was not called since millisecondsOffset. /// - queue: a queue that action closure should be executed on (default is DispatchQueue.main). /// - action: closure to be executed in a debounced way. - public static func debounce(millisecondsDelay: Int, queue: DispatchQueue = .main, action: @escaping (()->())) -> ()->() { + public static func debounce(millisecondsDelay: Int, queue: DispatchQueue = .main, action: @escaping (() -> Void)) -> () -> Void { //http://stackoverflow.com/questions/27116684/how-can-i-debounce-a-method-call var lastFireTime = DispatchTime.now() let dispatchDelay = DispatchTimeInterval.milliseconds(millisecondsDelay) @@ -301,11 +300,10 @@ public extension SwifterSwift { /// SwifterSwift: Called when user takes a screenshot /// /// - Parameter action: a closure to run when user takes a screenshot - public static func didTakeScreenShot(_ action: @escaping () -> ()) { + public static func didTakeScreenShot(_ action: @escaping (_ notification: Notification) -> Void) { // http://stackoverflow.com/questions/13484516/ios-detection-of-screenshot - let mainQueue = OperationQueue.main - NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in - action() + _ = NotificationCenter.default.addObserver(forName: Notification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: OperationQueue.main) { notification in + action(notification) } } #endif diff --git a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift index 2441b0206..c785675e3 100644 --- a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift @@ -10,7 +10,6 @@ import UIKit import AudioToolbox - // MARK: - Methods public extension UIAlertController { @@ -61,7 +60,6 @@ public extension UIAlertController { } - // MARK: - Initializers public extension UIAlertController { @@ -88,8 +86,8 @@ public extension UIAlertController { /// - error: error to set alert controller's message to it's localizedDescription. /// - defaultActionButtonTitle: default action button title (default is "OK") /// - tintColor: alert controller's tint color (default is nil) - public convenience init(title: String = "Error", error: Error, defaultActionButtonTitle: String = "OK", tintColor: UIColor? = nil) { - self.init(title: title, message: error.localizedDescription, preferredStyle: .alert) + public convenience init(title: String = "Error", error: Error, defaultActionButtonTitle: String = "OK", preferredStyle: UIAlertControllerStyle = .alert, tintColor: UIColor? = nil) { + self.init(title: title, message: error.localizedDescription, preferredStyle: preferredStyle) let defaultAction = UIAlertAction(title: defaultActionButtonTitle, style: .default, handler: nil) addAction(defaultAction) if let color = tintColor { diff --git a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift index f80fe5179..881d891fe 100644 --- a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift +++ b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UIBarButtonItem { diff --git a/Sources/Extensions/UIKit/UIButtonExtensions.swift b/Sources/Extensions/UIKit/UIButtonExtensions.swift index 34da08c4f..0095b25a8 100644 --- a/Sources/Extensions/UIKit/UIButtonExtensions.swift +++ b/Sources/Extensions/UIKit/UIButtonExtensions.swift @@ -9,13 +9,11 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UIButton { - @IBInspectable /// SwifterSwift: Image of disabled state for button; also inspectable from Storyboard. - public var imageForDisabled: UIImage? { + @IBInspectable public var imageForDisabled: UIImage? { get { return image(for: .disabled) } @@ -24,9 +22,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Image of highlighted state for button; also inspectable from Storyboard. - public var imageForHighlighted: UIImage? { + @IBInspectable public var imageForHighlighted: UIImage? { get { return image(for: .highlighted) } @@ -35,9 +32,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Image of normal state for button; also inspectable from Storyboard. - public var imageForNormal: UIImage? { + @IBInspectable public var imageForNormal: UIImage? { get { return image(for: .normal) } @@ -46,9 +42,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Image of selected state for button; also inspectable from Storyboard. - public var imageForSelected: UIImage? { + @IBInspectable public var imageForSelected: UIImage? { get { return image(for: .selected) } @@ -57,9 +52,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title color of disabled state for button; also inspectable from Storyboard. - public var titleColorForDisabled: UIColor? { + @IBInspectable public var titleColorForDisabled: UIColor? { get { return titleColor(for: .disabled) } @@ -68,9 +62,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title color of highlighted state for button; also inspectable from Storyboard. - public var titleColorForHighlighted: UIColor? { + @IBInspectable public var titleColorForHighlighted: UIColor? { get { return titleColor(for: .highlighted) } @@ -79,9 +72,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title color of normal state for button; also inspectable from Storyboard. - public var titleColorForNormal: UIColor? { + @IBInspectable public var titleColorForNormal: UIColor? { get { return titleColor(for: .normal) } @@ -90,9 +82,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title color of selected state for button; also inspectable from Storyboard. - public var titleColorForSelected: UIColor? { + @IBInspectable public var titleColorForSelected: UIColor? { get { return titleColor(for: .selected) } @@ -101,9 +92,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title of disabled state for button; also inspectable from Storyboard. - public var titleForDisabled: String? { + @IBInspectable public var titleForDisabled: String? { get { return title(for: .disabled) } @@ -112,9 +102,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title of highlighted state for button; also inspectable from Storyboard. - public var titleForHighlighted: String? { + @IBInspectable public var titleForHighlighted: String? { get { return title(for: .highlighted) } @@ -123,9 +112,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title of normal state for button; also inspectable from Storyboard. - public var titleForNormal: String? { + @IBInspectable public var titleForNormal: String? { get { return title(for: .normal) } @@ -134,9 +122,8 @@ public extension UIButton { } } - @IBInspectable /// SwifterSwift: Title of selected state for button; also inspectable from Storyboard. - public var titleForSelected: String? { + @IBInspectable public var titleForSelected: String? { get { return title(for: .selected) } @@ -147,7 +134,6 @@ public extension UIButton { } - // MARK: - Methods public extension UIButton { diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index 86fda512b..0dc9fd468 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UICollectionView { @@ -25,7 +24,6 @@ public extension UICollectionView { } - // MARK: - Methods public extension UICollectionView { @@ -76,8 +74,8 @@ public extension UICollectionView { /// - name: UICollectionViewCell type. /// - indexPath: location of cell in collectionView. /// - Returns: UICollectionViewCell object with associated class name. - public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T { - return dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as! T + public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { + return dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as? T } /// SwifterSwift: Dequeue reusable UICollectionReusableView using class name. @@ -87,8 +85,8 @@ public extension UICollectionView { /// - name: UICollectionReusableView type. /// - indexPath: location of cell in collectionView. /// - Returns: UICollectionReusableView object with associated class name. - public func dequeueReusableSupplementaryView(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T { - return dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as! T + public func dequeueReusableSupplementaryView(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T? { + return dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as? T } /// SwifterSwift: Register UICollectionReusableView using class name. diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift index 61feeb505..3c9a14522 100755 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ b/Sources/Extensions/UIKit/UIColorExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) || os(watchOS) import UIKit - // MARK: - Properties public extension UIColor { @@ -44,10 +43,10 @@ public extension UIColor { /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { - var hue: CGFloat = 0.0 - var sat: CGFloat = 0.0 - var bri: CGFloat = 0.0 - var alpha: CGFloat = 0.0 + var hue: CGFloat = 0.0 + var sat: CGFloat = 0.0 + var bri: CGFloat = 0.0 + var alpha: CGFloat = 0.0 self.getHue(&hue, saturation: &sat, brightness: &bri, alpha: &alpha) return (hue:hue, saturation:sat, brightness:bri, alpha:alpha) @@ -113,7 +112,6 @@ public extension UIColor { } - // MARK: - Methods public extension UIColor { @@ -141,7 +139,6 @@ public extension UIColor { } - // MARK: - Initializers public extension UIColor { @@ -189,7 +186,6 @@ public extension UIColor { self.init(hex: Int(hexValue), transparency: transparency) } - /// SwifterSwift: Create UIColor from RGB values with optional transparency. /// /// - Parameters: @@ -218,15 +214,14 @@ public extension UIColor { /// - Parameter color: color of which opposite color is desired. public convenience init?(complementaryFor color: UIColor) { let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() - let convertColorToRGBSpace : ((_ color : UIColor) -> UIColor?) = { (color) -> UIColor? in + let convertColorToRGBSpace: ((_ color: UIColor) -> UIColor?) = { color -> UIColor? in if color.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { let oldComponents = color.cgColor.components - let components : [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1] ] + let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) let colorOut = UIColor(cgColor: colorRef!) return colorOut - } - else { + } else { return color } } @@ -244,12 +239,11 @@ public extension UIColor { } - -//MARK: - Social Colors +// MARK: - Social Colors public extension UIColor { /// SwifterSwift: Brand identity color of popular social media platform. - public struct social { + public struct Social { // https://www.lockedowndesign.com/social-media-colors/ /// SwifterSwift: red: 59, green: 89, blue: 152 @@ -333,12 +327,11 @@ public extension UIColor { } } - -//MARK: - Material colors +// MARK: - Material colors public extension UIColor { /// SwifterSwift: Google Material design colors palette. - public struct material { + public struct Material { // https://material.google.com/style/color.html /// SwifterSwift: color red500 @@ -386,7 +379,6 @@ public extension UIColor { /// SwifterSwift: hex #D50000 public static let redA700 = UIColor(hex: 0xD50000) - /// SwifterSwift: color pink500 public static let pink = pink500 @@ -432,7 +424,6 @@ public extension UIColor { /// SwifterSwift: hex #C51162 public static let pinkA700 = UIColor(hex: 0xC51162) - /// SwifterSwift: color purple500 public static let purple = purple500 @@ -478,7 +469,6 @@ public extension UIColor { /// SwifterSwift: hex #AA00FF public static let purpleA700 = UIColor(hex: 0xAA00FF) - /// SwifterSwift: color deepPurple500 public static let deepPurple = deepPurple500 @@ -524,7 +514,6 @@ public extension UIColor { /// SwifterSwift: hex #6200EA public static let deepPurpleA700 = UIColor(hex: 0x6200EA) - /// SwifterSwift: color indigo500 public static let indigo = indigo500 @@ -570,7 +559,6 @@ public extension UIColor { /// SwifterSwift: hex #304FFE public static let indigoA700 = UIColor(hex: 0x304FFE) - /// SwifterSwift: color blue500 public static let blue = blue500 @@ -616,7 +604,6 @@ public extension UIColor { /// SwifterSwift: hex #2962FF public static let blueA700 = UIColor(hex: 0x2962FF) - /// SwifterSwift: color lightBlue500 public static let lightBlue = lightBlue500 @@ -662,7 +649,6 @@ public extension UIColor { /// SwifterSwift: hex #0091EA public static let lightBlueA700 = UIColor(hex: 0x0091EA) - /// SwifterSwift: color cyan500 public static let cyan = cyan500 @@ -708,7 +694,6 @@ public extension UIColor { /// SwifterSwift: hex #00B8D4 public static let cyanA700 = UIColor(hex: 0x00B8D4) - /// SwifterSwift: color teal500 public static let teal = teal500 @@ -754,7 +739,6 @@ public extension UIColor { /// SwifterSwift: hex #00BFA5 public static let tealA700 = UIColor(hex: 0x00BFA5) - /// SwifterSwift: color green500 public static let green = green500 @@ -800,7 +784,6 @@ public extension UIColor { /// SwifterSwift: hex #00C853 public static let greenA700 = UIColor(hex: 0x00C853) - /// SwifterSwift: color lightGreen500 public static let lightGreen = lightGreen500 @@ -846,7 +829,6 @@ public extension UIColor { /// SwifterSwift: hex #64DD17 public static let lightGreenA700 = UIColor(hex: 0x64DD17) - /// SwifterSwift: color lime500 public static let lime = lime500 @@ -892,7 +874,6 @@ public extension UIColor { /// SwifterSwift: hex #AEEA00 public static let limeA700 = UIColor(hex: 0xAEEA00) - /// SwifterSwift: color yellow500 public static let yellow = yellow500 @@ -938,7 +919,6 @@ public extension UIColor { /// SwifterSwift: hex #FFD600 public static let yellowA700 = UIColor(hex: 0xFFD600) - /// SwifterSwift: color amber500 public static let amber = amber500 @@ -984,7 +964,6 @@ public extension UIColor { /// SwifterSwift: hex #FFAB00 public static let amberA700 = UIColor(hex: 0xFFAB00) - /// SwifterSwift: color orange500 public static let orange = orange500 @@ -1030,7 +1009,6 @@ public extension UIColor { /// SwifterSwift: hex #FF6D00 public static let orangeA700 = UIColor(hex: 0xFF6D00) - /// SwifterSwift: color deepOrange500 public static let deepOrange = deepOrange500 @@ -1076,7 +1054,6 @@ public extension UIColor { /// SwifterSwift: hex #DD2C00 public static let deepOrangeA700 = UIColor(hex: 0xDD2C00) - /// SwifterSwift: color brown500 public static let brown = brown500 @@ -1110,7 +1087,6 @@ public extension UIColor { /// SwifterSwift: hex #3E2723 public static let brown900 = UIColor(hex: 0x3E2723) - /// SwifterSwift: color grey500 public static let grey = grey500 @@ -1144,7 +1120,6 @@ public extension UIColor { /// SwifterSwift: hex #212121 public static let grey900 = UIColor(hex: 0x212121) - /// SwifterSwift: color blueGrey500 public static let blueGrey = blueGrey500 @@ -1178,7 +1153,6 @@ public extension UIColor { /// SwifterSwift: hex #263238 public static let blueGrey900 = UIColor(hex: 0x263238) - /// SwifterSwift: hex #000000 public static let black = UIColor(hex: 0x000000) @@ -1188,12 +1162,11 @@ public extension UIColor { } - // MARK: - CSS colors public extension UIColor { /// SwifterSwift: CSS colors. - public struct css { + public struct CSS { // http://www.w3schools.com/colors/colors_names.asp /// SwifterSwift: hex #F0F8FF @@ -1645,11 +1618,10 @@ public extension UIColor { } // MARK: - Flat UI colors - public extension UIColor { /// SwifterSwift: Flat UI colors - public struct flatUI { + public struct FlatUI { // http://flatuicolors.com. /// SwifterSwift: hex #1ABC9C diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index f02cc1140..936375380 100755 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) || os(watchOS) import UIKit - // MARK: - Properties public extension UIImage { @@ -35,7 +34,6 @@ public extension UIImage { } - // MARK: - Methods public extension UIImage { @@ -116,7 +114,7 @@ public extension UIImage { } context.translateBy(x: 0, y: size.height) - context.scaleBy(x: 1.0, y: -1.0); + context.scaleBy(x: 1.0, y: -1.0) context.setBlendMode(CGBlendMode.normal) let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) @@ -151,7 +149,6 @@ public extension UIImage { } } - // MARK: - Initializers public extension UIImage { diff --git a/Sources/Extensions/UIKit/UIImageViewExtensions.swift b/Sources/Extensions/UIKit/UIImageViewExtensions.swift index 074660515..8dda49cc9 100644 --- a/Sources/Extensions/UIKit/UIImageViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageViewExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UIImageView { @@ -27,7 +26,7 @@ public extension UIImageView { image = placeholder self.contentMode = contentMode - URLSession.shared.dataTask(with: url) { (data, response, error) in + URLSession.shared.dataTask(with: url) { (data, response, _) in guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, let mimeType = response?.mimeType, mimeType.hasPrefix("image"), diff --git a/Sources/Extensions/UIKit/UILabelExtensions.swift b/Sources/Extensions/UIKit/UILabelExtensions.swift index bc3975df3..7b11e7a2b 100644 --- a/Sources/Extensions/UIKit/UILabelExtensions.swift +++ b/Sources/Extensions/UIKit/UILabelExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UILabel { diff --git a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift index e93c4250b..9b64d027d 100644 --- a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UINavigationBar { diff --git a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift index 5aa41b9e1..4459064fe 100755 --- a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift @@ -9,14 +9,13 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UINavigationController { /// SwifterSwift: Pop ViewController with completion handler. /// /// - Parameter completion: optional completion handler (default is nil). - public func popViewController(_ completion: (()->Void)? = nil) { + public func popViewController(_ completion: (() -> Void)? = nil) { // https://github.com/cotkjaer/UserInterface/blob/master/UserInterface/UIViewController.swift CATransaction.begin() CATransaction.setCompletionBlock(completion) @@ -29,7 +28,7 @@ public extension UINavigationController { /// - Parameters: /// - viewController: viewController to push. /// - completion: optional completion handler (default is nil). - public func pushViewController(_ viewController: UIViewController, completion: (()->Void)? = nil) { + public func pushViewController(_ viewController: UIViewController, completion: (() -> Void)? = nil) { // https://github.com/cotkjaer/UserInterface/blob/master/UserInterface/UIViewController.swift CATransaction.begin() CATransaction.setCompletionBlock(completion) diff --git a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift index 7185ef521..799df8d71 100644 --- a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UINavigationItem { diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index d0044b92b..673d56816 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UISearchBar { @@ -29,7 +28,6 @@ public extension UISearchBar { } - // MARK: - Methods public extension UISearchBar { diff --git a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift index f31d151b2..fef598625 100644 --- a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift +++ b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UISegmentedControl { diff --git a/Sources/Extensions/UIKit/UISliderExtensions.swift b/Sources/Extensions/UIKit/UISliderExtensions.swift index d26cc9638..d3c224e65 100644 --- a/Sources/Extensions/UIKit/UISliderExtensions.swift +++ b/Sources/Extensions/UIKit/UISliderExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) import UIKit - // MARK: - Methods public extension UISlider { @@ -24,7 +23,7 @@ public extension UISlider { if animated { UIView.animate(withDuration: duration, animations: { self.setValue(value, animated: true) - }, completion: { finished in + }, completion: { _ in completion?() }) } else { diff --git a/Sources/Extensions/UIKit/UIStoryboardExtensions.swift b/Sources/Extensions/UIKit/UIStoryboardExtensions.swift index 73d87e8d4..d3820714d 100644 --- a/Sources/Extensions/UIKit/UIStoryboardExtensions.swift +++ b/Sources/Extensions/UIKit/UIStoryboardExtensions.swift @@ -23,8 +23,8 @@ public extension UIStoryboard { /// /// - Parameter name: UIViewController type /// - Returns: The view controller corresponding to specified class name - public func instantiateViewController(withClass name: T.Type) -> T { - return instantiateViewController(withIdentifier: String(describing: name)) as! T + public func instantiateViewController(withClass name: T.Type) -> T? { + return instantiateViewController(withIdentifier: String(describing: name)) as? T } } #endif diff --git a/Sources/Extensions/UIKit/UISwitchExtensions.swift b/Sources/Extensions/UIKit/UISwitchExtensions.swift index 0f033f0cc..78c65cf05 100644 --- a/Sources/Extensions/UIKit/UISwitchExtensions.swift +++ b/Sources/Extensions/UIKit/UISwitchExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) import UIKit - // MARK: - Methods public extension UISwitch { diff --git a/Sources/Extensions/UIKit/UITabBarExtensions.swift b/Sources/Extensions/UIKit/UITabBarExtensions.swift index b38aac29b..7dbcbf5ed 100644 --- a/Sources/Extensions/UIKit/UITabBarExtensions.swift +++ b/Sources/Extensions/UIKit/UITabBarExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UITabBar { @@ -51,9 +50,9 @@ public extension UITabBar { continue } barItem.image = image.filled(withColor: itemColor).withRenderingMode(.alwaysOriginal) - barItem.setTitleTextAttributes([.foregroundColor : itemColor], for: .normal) + barItem.setTitleTextAttributes([.foregroundColor: itemColor], for: .normal) if let selected = selectedItem { - barItem.setTitleTextAttributes([.foregroundColor : selected], for: .selected) + barItem.setTitleTextAttributes([.foregroundColor: selected], for: .selected) } } } diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index c8c269fcc..52ce2e0bc 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UITableView { @@ -76,7 +75,6 @@ public extension UITableView { tableHeaderView = nil } - /// SwifterSwift: Scroll to bottom of TableView. /// /// - Parameter animated: set true to animate scroll (default is true). @@ -106,8 +104,8 @@ public extension UITableView { /// - name: UITableViewCell type. /// - indexPath: location of cell in tableView. /// - Returns: UITableViewCell object with associated class name. - public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T { - return dequeueReusableCell(withIdentifier: String(describing: name), for: indexPath) as! T + public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { + return dequeueReusableCell(withIdentifier: String(describing: name), for: indexPath) as? T } /// SwiferSwift: Dequeue reusable UITableViewHeaderFooterView using class name diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index 40651f9d2..faabf9642 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -24,8 +24,7 @@ public extension UITextField { } } - - + // MARK: - Properties public extension UITextField { @@ -62,7 +61,6 @@ public extension UITextField { } } - /// SwifterSwift: Check if text field is empty. public var isEmpty: Bool { return text?.isEmpty == true @@ -88,9 +86,8 @@ public extension UITextField { range: nil, locale: nil) != nil } - @IBInspectable /// SwifterSwift: Left view tint color. - public var leftViewTintColor: UIColor? { + @IBInspectable public var leftViewTintColor: UIColor? { get { guard let iconView = leftView as? UIImageView else { return nil @@ -105,10 +102,9 @@ public extension UITextField { iconView.tintColor = newValue } } - - @IBInspectable + /// SwifterSwift: Right view tint color. - public var rightViewTintColor: UIColor? { + @IBInspectable public var rightViewTintColor: UIColor? { get { guard let iconView = rightView as? UIImageView else { return nil diff --git a/Sources/Extensions/UIKit/UITextViewExtensions.swift b/Sources/Extensions/UIKit/UITextViewExtensions.swift index 592a2421b..41a385e91 100644 --- a/Sources/Extensions/UIKit/UITextViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITextViewExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Methods public extension UITextView { @@ -23,6 +22,7 @@ public extension UITextView { public func scrollToBottom() { let range = NSMakeRange((text as NSString).length - 1, 1) scrollRangeToVisible(range) + } /// SwifterSwift: Scroll to the top of text view diff --git a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift index 9b3428fcf..469904f14 100755 --- a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - Properties public extension UIViewController { diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index dc27de995..42bf40077 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -9,7 +9,6 @@ #if os(iOS) || os(tvOS) import UIKit - // MARK: - enums /// SwifterSwift: Shake directions of a view. @@ -43,13 +42,11 @@ public enum ShakeAnimationType { case easeInOut } - // MARK: - Properties public extension UIView { - @IBInspectable /// SwifterSwift: Border color of view; also inspectable from Storyboard. - public var borderColor: UIColor? { + @IBInspectable public var borderColor: UIColor? { get { guard let color = layer.borderColor else { return nil @@ -65,9 +62,8 @@ public extension UIView { } } - @IBInspectable /// SwifterSwift: Border width of view; also inspectable from Storyboard. - public var borderWidth: CGFloat { + @IBInspectable public var borderWidth: CGFloat { get { return layer.borderWidth } @@ -76,9 +72,8 @@ public extension UIView { } } - @IBInspectable /// SwifterSwift: Corner radius of view; also inspectable from Storyboard. - public var cornerRadius: CGFloat { + @IBInspectable public var cornerRadius: CGFloat { get { return layer.cornerRadius } @@ -93,10 +88,8 @@ public extension UIView { guard !isFirstResponder else { return self } - for subView in subviews { - if subView.isFirstResponder { - return subView - } + for subView in subviews where subView.isFirstResponder { + return subView } return nil } @@ -122,7 +115,7 @@ public extension UIView { /// SwifterSwift: Take screenshot of view (if applicable). public var screenshot: UIImage? { - UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, 0.0); + UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, 0) defer { UIGraphicsEndImageContext() } @@ -133,9 +126,8 @@ public extension UIView { return UIGraphicsGetImageFromCurrentImageContext() } - @IBInspectable /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. - public var shadowColor: UIColor? { + @IBInspectable public var shadowColor: UIColor? { get { guard let color = layer.shadowColor else { return nil @@ -147,9 +139,8 @@ public extension UIView { } } - @IBInspectable /// SwifterSwift: Shadow offset of view; also inspectable from Storyboard. - public var shadowOffset: CGSize { + @IBInspectable public var shadowOffset: CGSize { get { return layer.shadowOffset } @@ -158,9 +149,8 @@ public extension UIView { } } - @IBInspectable /// SwifterSwift: Shadow opacity of view; also inspectable from Storyboard. - public var shadowOpacity: Float { + @IBInspectable public var shadowOpacity: Float { get { return layer.shadowOpacity } @@ -169,9 +159,8 @@ public extension UIView { } } - @IBInspectable /// SwifterSwift: Shadow radius of view; also inspectable from Storyboard. - public var shadowRadius: CGFloat { + @IBInspectable public var shadowRadius: CGFloat { get { return layer.shadowRadius } @@ -235,7 +224,6 @@ public extension UIView { } - // MARK: - Methods public extension UIView { @@ -260,10 +248,7 @@ public extension UIView { /// - radius: shadow radius (default is 3). /// - offset: shadow offset (default is .zero). /// - opacity: shadow opacity (default is 0.5). - public func addShadow(ofColor color: UIColor = UIColor(hex: 0x137992)!, - radius: CGFloat = 3, - offset: CGSize = .zero, - opacity: Float = 0.5) { + public func addShadow(ofColor color: UIColor = UIColor(hex: 0x137992)!, radius: CGFloat = 3, offset: CGSize = .zero, opacity: Float = 0.5) { layer.shadowColor = color.cgColor layer.shadowOffset = offset layer.shadowRadius = radius @@ -312,7 +297,7 @@ public extension UIView { /// - name: nib name. /// - bundle: bundle of nib (default is nil). /// - Returns: optional UIView (if applicable). - public class func loadFromNib(named name: String, bundle : Bundle? = nil) -> UIView? { + public class func loadFromNib(named name: String, bundle: Bundle? = nil) -> UIView? { return UINib(nibName: name, bundle: bundle).instantiate(withOwner: nil, options: nil)[0] as? UIView } @@ -334,7 +319,7 @@ public extension UIView { /// - animated: set true to animate rotation (default is true). /// - duration: animation duration in seconds (default is 1 second). /// - completion: optional completion handler to run with animation finishes (default is nil). - public func rotate(byAngle angle : CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion:((Bool) -> Void)? = nil) { + public func rotate(byAngle angle: CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion: ((Bool) -> Void)? = nil) { let angleWithType = (type == .degrees) ? CGFloat.pi * angle / 180.0 : angle let aDuration = animated ? duration : 0 UIView.animate(withDuration: aDuration, delay: 0, options: .curveLinear, animations: { () -> Void in @@ -350,7 +335,7 @@ public extension UIView { /// - animated: set true to animate rotation (default is false). /// - duration: animation duration in seconds (default is 1 second). /// - completion: optional completion handler to run with animation finishes (default is nil). - public func rotate(toAngle angle: CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion:((Bool) -> Void)? = nil) { + public func rotate(toAngle angle: CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion: ((Bool) -> Void)? = nil) { let angleWithType = (type == .degrees) ? CGFloat.pi * angle / 180.0 : angle let aDuration = animated ? duration : 0 UIView.animate(withDuration: aDuration, animations: { @@ -365,7 +350,7 @@ public extension UIView { /// - animated: set true to animate scaling (default is false). /// - duration: animation duration in seconds (default is 1 second). /// - completion: optional completion handler to run with animation finishes (default is nil). - public func scale(by offset: CGPoint, animated: Bool = false, duration: TimeInterval = 1, completion:((Bool) -> Void)? = nil) { + public func scale(by offset: CGPoint, animated: Bool = false, duration: TimeInterval = 1, completion: ((Bool) -> Void)? = nil) { if animated { UIView.animate(withDuration: duration, delay: 0, options: .curveLinear, animations: { () -> Void in self.transform = self.transform.scaledBy(x: offset.x, y: offset.y) diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 2047fc150..bf0bec615 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -794,6 +794,7 @@ 07898B591F278D7600558C97 /* Frameworks */, 07898B5A1F278D7600558C97 /* Headers */, 07898B5B1F278D7600558C97 /* Resources */, + 074EAF161F7B859500C74636 /* ShellScript */, ); buildRules = ( ); @@ -812,6 +813,7 @@ 07898B671F278D9700558C97 /* Frameworks */, 07898B681F278D9700558C97 /* Headers */, 07898B691F278D9700558C97 /* Resources */, + 074EAF171F7B859A00C74636 /* ShellScript */, ); buildRules = ( ); @@ -830,6 +832,7 @@ 07898B741F278DBC00558C97 /* Frameworks */, 07898B751F278DBC00558C97 /* Headers */, 07898B761F278DBC00558C97 /* Resources */, + 074EAF181F7B85C600C74636 /* ShellScript */, ); buildRules = ( ); @@ -848,6 +851,7 @@ 07898B811F278DD200558C97 /* Frameworks */, 07898B821F278DD200558C97 /* Headers */, 07898B831F278DD200558C97 /* Resources */, + 074EAF191F7B85CB00C74636 /* ShellScript */, ); buildRules = ( ); @@ -883,6 +887,7 @@ 07C50CD41F5EAF4B00F46E5A /* Sources */, 07C50CD51F5EAF4B00F46E5A /* Frameworks */, 07C50CD61F5EAF4B00F46E5A /* Resources */, + 074EAF151F7B845A00C74636 /* ShellScript */, ); buildRules = ( ); @@ -1036,6 +1041,74 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 074EAF151F7B845A00C74636 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = ""; + }; + 074EAF161F7B859500C74636 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; + 074EAF171F7B859A00C74636 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; + 074EAF181F7B85C600C74636 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; + 074EAF191F7B85CB00C74636 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 07898B581F278D7600558C97 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -2280,7 +2353,7 @@ COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = C3VKVFB3SA; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2347,7 +2420,7 @@ COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = C3VKVFB3SA; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; diff --git a/Tests/AppKitTests/NSViewExtensionsTests.swift b/Tests/AppKitTests/NSViewExtensionsTests.swift index c79673f1a..211e6c6a2 100644 --- a/Tests/AppKitTests/NSViewExtensionsTests.swift +++ b/Tests/AppKitTests/NSViewExtensionsTests.swift @@ -11,7 +11,6 @@ import XCTest @testable import SwifterSwift - class NSViewExtensionsTests: XCTestCase { func testBorderColor() { diff --git a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift index ee7731f51..46e3834bf 100644 --- a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift +++ b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift @@ -9,7 +9,6 @@ import XCTest import CoreLocation - class CLLocationExtensionsTests: XCTestCase { func testMidLocation() { diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index f36272ec2..7c16c7905 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -502,7 +502,7 @@ class DateExtensionsTests: XCTestCase { func testEnd() { let date = Date(timeIntervalSince1970: 512) // January 1, 1970 at 2:08:32 AM GMT+2 - XCTAssertEqual(date.end(of: .second)?.second , 32) + XCTAssertEqual(date.end(of: .second)?.second, 32) XCTAssertEqual(date.end(of: .hour)?.minute, 59) XCTAssertEqual(date.end(of: .minute)?.second, 59) @@ -656,7 +656,6 @@ class DateExtensionsTests: XCTestCase { XCTAssertEqual(date1.daysSince(date2), -1) } - func testNewDateFromComponenets() { let date = Date(calendar: Date().calendar, timeZone: Date().timeZone, era: Date().era, year: Date().year, month: Date().month, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNotNil(date) @@ -664,7 +663,6 @@ class DateExtensionsTests: XCTestCase { XCTAssertEqual(date?.timeIntervalSince1970, date1.timeIntervalSince1970) - let date2 = Date(calendar: nil, timeZone: Date().timeZone, era: Date().era, year: nil, month: nil, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNil(date2) } diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift index 6a498352a..226005b5f 100644 --- a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -14,12 +14,12 @@ class UserDefaultsExtensionsTests: XCTestCase { let key = "testKey" UserDefaults.standard.set(true, forKey: key) XCTAssertNotNil(UserDefaults.standard[key]) - XCTAssert(UserDefaults.standard[key] as! Bool) + XCTAssert(UserDefaults.standard[key] as? Bool ?? false) UserDefaults.standard.removeObject(forKey: key) UserDefaults.standard[key] = false XCTAssertNotNil(UserDefaults.standard[key]) - XCTAssertFalse(UserDefaults.standard[key] as! Bool) + XCTAssertFalse(UserDefaults.standard[key] as? Bool ?? false) } func testFloat() { diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index 1bab63276..cdd213c8e 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -76,7 +76,6 @@ class ArrayExtensionsTests: XCTestCase { newArray.safeSwap(from: 1, to: 1) XCTAssertEqual(newArray, array) - newArray = array newArray.safeSwap(from: 1, to: 12) XCTAssertEqual(newArray, array) @@ -99,7 +98,7 @@ class ArrayExtensionsTests: XCTestCase { func testRemoveAllItems() { var arr = [0, 1, 2, 2, 0, 3, 4, 5, 0, 0] - arr.removeAll([0,2]) + arr.removeAll([0, 2]) XCTAssertEqual(arr, [1, 3, 4, 5]) arr.removeAll([]) XCTAssertEqual(arr, [1, 3, 4, 5]) @@ -107,8 +106,7 @@ class ArrayExtensionsTests: XCTestCase { arr.removeAll([]) XCTAssertEqual(arr, []) } - - + func testShuffle() { var arr = ["a"] arr.shuffle() @@ -228,7 +226,7 @@ class ArrayExtensionsTests: XCTestCase { func testForEachWhere() { let input = [1, 2, 2, 2, 1, 4, 1] var output: [Int] = [] - input.forEach(where: {$0 % 2 == 0}) { output.append($0 * 2) } + input.forEach(where: {$0 % 2 == 0}, body: { output.append($0 * 2) }) XCTAssertEqual(output, [4, 4, 4, 8]) } @@ -239,8 +237,8 @@ class ArrayExtensionsTests: XCTestCase { } func testFilteredMap() { - let input = [1,2,3,4,5] - let result = input.filtered({ $0 % 2 == 0 }) { $0.string } + let input = [1, 2, 3, 4, 5] + let result = input.filtered({ $0 % 2 == 0 }, map: { $0.string }) XCTAssertEqual(result.count, 2) XCTAssertEqual(["2", "4"], result) } @@ -278,11 +276,10 @@ class ArrayExtensionsTests: XCTestCase { XCTAssertEqual([].skip(while: { $0 % 2 == 0}), []) } - - + func testGroupBy() { - let array : [String] = [ "james", "irving", "jordan", "jonshon", "iverson"] - let grouped = array.groupByKey { (element) -> String in + let array: [String] = ["james", "irving", "jordan", "jonshon", "iverson"] + let grouped = array.groupByKey { element -> String in return String(element.characters.first ?? Character("")) } XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) @@ -290,11 +287,11 @@ class ArrayExtensionsTests: XCTestCase { } func testForEachSlice() { - var iterations : Int = 0 + var iterations: Int = 0 // A slice with value zero - var array : [String] = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] - array.forEach(slice: 0) { (sliceArray) in + var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] + array.forEach(slice: 0) { _ in iterations += 1 } XCTAssertEqual(iterations, 0) @@ -347,7 +344,7 @@ class ArrayExtensionsTests: XCTestCase { func testGroupBySize() { // A slice with value zero - var array : [String] = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] + var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] var slices = array.group(by: 0) XCTAssertNil(slices) @@ -372,23 +369,23 @@ class ArrayExtensionsTests: XCTestCase { } func testRotated() { - let array : [Int] = [1,2,3,4] - XCTAssertEqual(array.rotated(by: 0), [1,2,3,4]) - XCTAssertEqual(array.rotated(by: 4), [1,2,3,4]) - XCTAssertEqual(array.rotated(by: 1), [4,1,2,3]) - XCTAssertEqual(array.rotated(by: 3), [2,3,4,1]) - XCTAssertEqual(array.rotated(by: -1), [2,3,4,1]) - XCTAssertEqual(array.rotated(by: -3), [4,1,2,3]) + let array: [Int] = [1, 2, 3, 4] + XCTAssertEqual(array.rotated(by: 0), [1, 2, 3, 4]) + XCTAssertEqual(array.rotated(by: 4), [1, 2, 3, 4]) + XCTAssertEqual(array.rotated(by: 1), [4, 1, 2, 3]) + XCTAssertEqual(array.rotated(by: 3), [2, 3, 4, 1]) + XCTAssertEqual(array.rotated(by: -1), [2, 3, 4, 1]) + XCTAssertEqual(array.rotated(by: -3), [4, 1, 2, 3]) } func testRotate() { - var array : [Int] = [1,2,3,4] + var array: [Int] = [1, 2, 3, 4] array.rotate(by: 0) - XCTAssertEqual(array, [1,2,3,4]) + XCTAssertEqual(array, [1, 2, 3, 4]) array.rotate(by: 2) - XCTAssertEqual(array, [3,4,1,2]) + XCTAssertEqual(array, [3, 4, 1, 2]) array.rotate(by: -1) - XCTAssertEqual(array, [4,1,2,3]) + XCTAssertEqual(array, [4, 1, 2, 3]) } diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index 7685b73b9..c6ba009de 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -25,5 +25,4 @@ class CollectionExtensionsTests: XCTestCase { XCTAssertNil(collection[safe: 10]) } - } diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index d865599fb..c448d1643 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -19,7 +19,7 @@ class DictionaryExtensionsTests: XCTestCase { } func testRemoveAll() { - var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + var dict: [String : String] = ["key1": "value1", "key2": "value2", "key3": "value3"] dict.removeAll(keys: ["key1", "key2"]) XCTAssertTrue(dict.keys.contains("key3")) XCTAssertFalse(dict.keys.contains("key1")) @@ -34,7 +34,7 @@ class DictionaryExtensionsTests: XCTestCase { XCTAssertEqual(testDict.jsonString(prettify: true)?.contains("[\n 1,\n 2,\n 3,\n 4,\n 5\n ]"), true) XCTAssertNil(["key": NSObject()].jsonString()) - XCTAssertNil([1:2].jsonString()) + XCTAssertNil([1: 2].jsonString()) } func testJsonData() { @@ -50,7 +50,7 @@ class DictionaryExtensionsTests: XCTestCase { XCTAssertEqual(dict.jsonData(prettify: true), prettyJsonData) XCTAssertNil(["key": NSObject()].jsonData()) - XCTAssertNil([1:2].jsonData()) + XCTAssertNil([1: 2].jsonData()) } func testLowercaseAllKeys() { @@ -60,18 +60,17 @@ class DictionaryExtensionsTests: XCTestCase { } func testCountFiltered() { - let dict: [String: String] = ["key1" : "value", "key2" : "value", "key3" : "value3"] + let dict: [String: String] = ["key1": "value", "key2": "value", "key3": "value3"] let count = dict.count { (tuple) -> Bool in return tuple.0 == "key1" || tuple.1 == "value" } XCTAssertEqual(count, 2) } - //MARK: Test Operators - + // MARK: - Test Operators func testOperatorPlus() { - let dict : [String : String] = ["key1" : "value1"] - let dict2 : [String : String] = ["key2" : "value2"] + let dict: [String: String] = ["key1": "value1"] + let dict2: [String: String] = ["key2": "value2"] let result = dict + dict2 XCTAssertTrue(result.keys.contains("key1")) XCTAssertTrue(result.keys.contains("key2")) @@ -79,7 +78,7 @@ class DictionaryExtensionsTests: XCTestCase { } func testOperatorMinus() { - let dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + let dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] let result = dict-["key1", "key2"] XCTAssertTrue(result.keys.contains("key3")) XCTAssertFalse(result.keys.contains("key1")) @@ -87,15 +86,15 @@ class DictionaryExtensionsTests: XCTestCase { } func testOperatorPlusEqual() { - var dict : [String : String] = ["key1" : "value1"] - let dict2 : [String : String] = ["key2" : "value2"] + var dict: [String: String] = ["key1": "value1"] + let dict2: [String: String] = ["key2": "value2"] dict += dict2 XCTAssertTrue(dict.keys.contains("key1")) XCTAssertTrue(dict.keys.contains("key2")) } func testOperatorRemoveKeys() { - var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + var dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] dict-=["key1", "key2"] XCTAssertTrue(dict.keys.contains("key3")) XCTAssertFalse(dict.keys.contains("key1")) diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index b003c04b4..450c62383 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -55,7 +55,7 @@ class StringExtensionsTests: XCTestCase { func testCount() { XCTAssertEqual("Hello This Tests".count(of: "T"), 2) XCTAssertEqual("Hello This Tests".count(of: "t"), 1) - XCTAssertEqual("Hello This Tests".count(of: "T", caseSensitive: false) , 3) + XCTAssertEqual("Hello This Tests".count(of: "T", caseSensitive: false), 3) XCTAssertEqual("Hello This Tests".count(of: "t", caseSensitive: false), 3) } @@ -513,9 +513,17 @@ class StringExtensionsTests: XCTestCase { XCTAssertNotNil(attrs[NSAttributedStringKey.font]) #if os(macOS) - XCTAssertEqual(attrs[.font] as! NSFont, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)) + guard let font = attrs[.font] as? NSFont else { + XCTFail() + return + } + XCTAssertEqual(font, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)) #elseif os(iOS) - XCTAssertEqual(attrs[NSAttributedStringKey.font] as! UIFont, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) + guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { + XCTFail() + return + } + XCTAssertEqual(font, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) #endif } #endif @@ -524,14 +532,22 @@ class StringExtensionsTests: XCTestCase { let underlinedString = "hello".underline let attrs = underlinedString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, underlinedString.length)) XCTAssertNotNil(attrs[NSAttributedStringKey.underlineStyle]) - XCTAssertEqual(attrs[NSAttributedStringKey.underlineStyle] as! Int, NSUnderlineStyle.styleSingle.rawValue) + guard let style = attrs[NSAttributedStringKey.underlineStyle] as? Int else { + XCTFail() + return + } + XCTAssertEqual(style, NSUnderlineStyle.styleSingle.rawValue) } func testStrikethrough() { let strikedthroughString = "hello".strikethrough let attrs = strikedthroughString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, strikedthroughString.length)) XCTAssertNotNil(attrs[NSAttributedStringKey.strikethroughStyle]) - XCTAssertEqual(attrs[NSAttributedStringKey.strikethroughStyle] as! NSNumber, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) + guard let style = attrs[NSAttributedStringKey.strikethroughStyle] as? NSNumber else { + XCTFail() + return + } + XCTAssertEqual(style, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) } #if os(iOS) @@ -539,7 +555,11 @@ class StringExtensionsTests: XCTestCase { let italicString = "hello".italic let attrs = italicString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, italicString.length)) XCTAssertNotNil(attrs[NSAttributedStringKey.font]) - XCTAssertEqual(attrs[NSAttributedStringKey.font] as! UIFont, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) + guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { + XCTFail() + return + } + XCTAssertEqual(font, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) } #endif @@ -549,9 +569,17 @@ class StringExtensionsTests: XCTestCase { XCTAssertNotNil(attrs[NSAttributedStringKey.foregroundColor]) #if os(macOS) - XCTAssertEqual(attrs[.foregroundColor] as! NSColor, NSColor.orange) + guard let color = attrs[.foregroundColor] as? NSColor else { + XCTFail() + return + } + XCTAssertEqual(color, NSColor.orange) #else - XCTAssertEqual(attrs[NSAttributedStringKey.foregroundColor] as! UIColor, UIColor.orange) + guard let color = attrs[NSAttributedStringKey.foregroundColor] as? UIColor else { + XCTFail() + return + } + XCTAssertEqual(color, UIColor.orange) #endif } diff --git a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift index 8d9b5fba5..7b3ef8128 100644 --- a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift @@ -67,9 +67,9 @@ class UIAlertControllerExtensionsTests: XCTestCase { XCTAssertEqual(defaultAction?.style, .default) } + enum TestError: Error { case error } + func testErrorInit() { - - enum TestError: Error { case error } let error = TestError.error let alertController = UIAlertController(title: "Title", error: error, defaultActionButtonTitle: "Ok", tintColor: .red) diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index 5cf258f75..8706e9b60 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -4,14 +4,18 @@ // // Created by Benjamin Meyer on 9/16/17. // -#if os(iOS) || os(tvOS) || os(watchOS) +#if !os(macOS) import XCTest @testable import SwifterSwift + class UIFontExtension: XCTestCase { func testMonospacedDigitFont() { let font = UIFont.preferredFont(forTextStyle: .body) let monoFont = font.asMonospacedDigitFont() - let attributes: [[String: Int]] = monoFont.fontDescriptor.fontAttributes[UIFontDescriptorFeatureSettingsAttribute] as! [[String: Int]] + guard let attributes: [[String: Int]] = monoFont.fontDescriptor.fontAttributes[UIFontDescriptorFeatureSettingsAttribute] as? [[String: Int]] else { + XCFail() + return + } XCTAssertEqual(attributes[0][UIFontFeatureTypeIdentifierKey], kNumberSpacingType) XCTAssertEqual(attributes[0][UIFontFeatureSelectorIdentifierKey], kMonospacedNumbersSelector) XCTAssertEqual(font.fontName, monoFont.fontName) @@ -21,4 +25,3 @@ class UIFontExtension: XCTestCase { } #endif - diff --git a/Tests/UIKitTests/UIImageExtensionsTests.swift b/Tests/UIKitTests/UIImageExtensionsTests.swift index 18f2e38bb..f5bf71561 100644 --- a/Tests/UIKitTests/UIImageExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageExtensionsTests.swift @@ -86,7 +86,6 @@ class UIImageExtensionsTests: XCTestCase { filledImage = emptyImage.filled(withColor: .red) XCTAssertEqual(emptyImage, filledImage) } - func testTinted() { let baseImage = UIImage(color: .white, size: CGSize(width: 20, height: 20)) diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index ef809c7fd..ecd9d5a0e 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -54,6 +54,5 @@ class UISliderExtensionsTests: XCTestCase { } - } #endif diff --git a/Tests/UIKitTests/UITabBarExtensionsTests.swift b/Tests/UIKitTests/UITabBarExtensionsTests.swift index 636b6a531..f8d3c560c 100644 --- a/Tests/UIKitTests/UITabBarExtensionsTests.swift +++ b/Tests/UIKitTests/UITabBarExtensionsTests.swift @@ -37,6 +37,5 @@ class UITabBarExtensionsTests: XCTestCase { } - } #endif diff --git a/Tests/UIKitTests/UITextFieldExtensionsTests.swift b/Tests/UIKitTests/UITextFieldExtensionsTests.swift index 98178ab14..a0b247daf 100644 --- a/Tests/UIKitTests/UITextFieldExtensionsTests.swift +++ b/Tests/UIKitTests/UITextFieldExtensionsTests.swift @@ -53,7 +53,6 @@ class UITextFieldExtensionsTests: XCTestCase { XCTAssertEqual(tf3.textType, .generic) XCTAssertFalse(tf3.isSecureTextEntry) - } func testHasValidEmail() { @@ -108,7 +107,6 @@ class UITextFieldExtensionsTests: XCTestCase { XCTAssertNil(textField.rightViewTintColor) } - func testClear() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let textField = UITextField(frame: frame) diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 34ac71131..c42ad121b 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -254,6 +254,5 @@ class UIViewExtensionsTests: XCTestCase { XCTAssertNotNil(subview.centerYAnchor) } - } #endif From bbeed8d813e180657846b423ef7a630c80650d9b Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 27 Sep 2017 12:25:26 +0300 Subject: [PATCH 024/201] Update CHANGELOG --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1d0d763a..cea659916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,6 @@ All notable changes to this project will be documented in this file. - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. [#248](https://github.com/SwifterSwift/SwifterSwift/pull/248) by [BennX](https://github.com/BennX). - New **UIFont** extensions - added `asMonospacedDigitFont() -> UIFont` method to get the current font as monospaced digit font. [#250](https://github.com/SwifterSwift/SwifterSwift/pull/250) by [BennX](https://github.com/BennX), [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) - - **UITableView** - `dequeueReusableCell` now returns an optional - `dequeueReusableHeaderFooterView` now returns an optional @@ -51,6 +50,10 @@ All notable changes to this project will be documented in this file. - `dequeueReusableSupplementaryView` now returns an optional - **UIAlertController** - Added `preferredStyle: UIAlertControllerStyle = .alert` to `init from error`. +- **UIStoryboard** + - `instantiateViewController` now returns an optional. +- **Continuous Integration** + - Travis now builds `watchOS` target. ### Bugfixes - **SwifterSwift** From 0500fc9b6e6cd33211d2ef32b84159890f063331 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 27 Sep 2017 14:01:28 +0300 Subject: [PATCH 025/201] FIx AppKit subspec dependencies - Update UIFontExtensions and tests to Swift 4 --- CHANGELOG.md | 2 +- .../Extensions/AppKit/NSViewExtensions.swift | 6 ++- .../SwiftStdlib/DictionaryExtensions.swift | 4 +- .../Extensions/UIKit/UIFontExtensions.swift | 16 ++++---- SwifterSwift.xcodeproj/project.pbxproj | 14 +++++++ Tests/UIKitTests/UIFontExtensionsTest.swift | 40 +++++++++++++------ 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cea659916..db90fddc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ All notable changes to this project will be documented in this file. - New **Date** extensions - added `isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool` method to check if a date is between two other dates. [#248](https://github.com/SwifterSwift/SwifterSwift/pull/248) by [BennX](https://github.com/BennX). - New **UIFont** extensions - - added `asMonospacedDigitFont() -> UIFont` method to get the current font as monospaced digit font. [#250](https://github.com/SwifterSwift/SwifterSwift/pull/250) by [BennX](https://github.com/BennX), [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) + - added `monospaced -> UIFont` method to get the current font as monospaced font. [#250](https://github.com/SwifterSwift/SwifterSwift/pull/250) by [BennX](https://github.com/BennX), [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) - **UITableView** - `dequeueReusableCell` now returns an optional - `dequeueReusableHeaderFooterView` now returns an optional diff --git a/Sources/Extensions/AppKit/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift index 017933f37..1cc4ed44d 100644 --- a/Sources/Extensions/AppKit/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -15,7 +15,8 @@ public extension NSView { /// SwifterSwift: Border color of view; also inspectable from Storyboard. @IBInspectable public var borderColor: NSColor? { get { - return layer?.borderColor?.nsColor + guard let color = layer?.borderColor else { return nil } + return NSColor(cgColor: color) } set { wantsLayer = true @@ -59,7 +60,8 @@ public extension NSView { /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. @IBInspectable public var shadowColor: NSColor? { get { - return layer?.shadowColor?.nsColor + guard let color = layer?.shadowColor else { return nil } + return NSColor(cgColor: color) } set { wantsLayer = true diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 870494bbe..0d1429c83 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -76,8 +76,8 @@ public extension Dictionary { return nil } let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() - let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) - return jsonData?.string(encoding: .utf8) + guard let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) else { return nil } + return String(data: jsonData, encoding: .utf8) } /// SwifterSwift: Count dictionary entries that where function returns true. diff --git a/Sources/Extensions/UIKit/UIFontExtensions.swift b/Sources/Extensions/UIKit/UIFontExtensions.swift index ee160a062..5c20202ff 100644 --- a/Sources/Extensions/UIKit/UIFontExtensions.swift +++ b/Sources/Extensions/UIKit/UIFontExtensions.swift @@ -10,15 +10,17 @@ import UIKit // MARK: - Properties public extension UIFont { - /// SwifterSwift: Font as monospaced digit font. [Monospaced Font explanation](https://en.wikipedia.org/wiki/Monospaced_font) + + /// SwifterSwift: Font as monospaced font /// - /// UIFont.preferredFont(forTextStyle: .body).asMonospacedDigitFont() + /// UIFont.preferredFont(forTextStyle: .body).monospaced /// - public func asMonospacedDigitFont() -> UIFont { - let fontDescriptorFeatureSettings = [[UIFontFeatureTypeIdentifierKey: kNumberSpacingType, UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector]] - let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings] - let newFontDescriptor = fontDescriptor.addingAttributes(fontDescriptorAttributes) - return UIFont(descriptor: newFontDescriptor, size: 0) + public var monospaced: UIFont { + let settings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType, UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector]] + + let attributes = [UIFontDescriptor.AttributeName.featureSettings: settings] + let newDescriptor = fontDescriptor.addingAttributes(attributes) + return UIFont(descriptor: newDescriptor, size: 0) } } #endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index bf0bec615..201541e0a 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,6 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 074EAF1B1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; + 074EAF1C1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; + 074EAF1D1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; + 074EAF1F1F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */; }; + 074EAF201F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */; }; 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; @@ -330,6 +335,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; + 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; @@ -612,6 +619,7 @@ 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */, 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */, 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */, + 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */, 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */, 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */, 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */, @@ -682,6 +690,7 @@ 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */, 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */, 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */, + 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */, 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */, 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */, 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */, @@ -1151,6 +1160,7 @@ 07B7F2131F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, + 074EAF1B1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F22E1F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21F1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, @@ -1206,6 +1216,7 @@ 07B7F2011F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, 07B7F2001F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2051F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, + 074EAF1C1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, 07B7F1A81F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2341F5EB45200E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21E1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, @@ -1261,6 +1272,7 @@ 07B7F1EF1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */, 07B7F1EE1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F1F31F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */, + 074EAF1D1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, 07B7F1BE1F5EB42200E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21D1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, @@ -1340,6 +1352,7 @@ 07C50D8C1F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */, 07C50D3E1F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */, + 074EAF1F1F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */, 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, @@ -1391,6 +1404,7 @@ 07C50D871F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */, 07C50D541F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */, + 074EAF201F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */, 07C50D461F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, 07C50D501F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index 8706e9b60..9e5c861d7 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -4,24 +4,38 @@ // // Created by Benjamin Meyer on 9/16/17. // -#if !os(macOS) + +#if os(iOS) || os(tvOS) || os(watchOS) import XCTest @testable import SwifterSwift class UIFontExtension: XCTestCase { - func testMonospacedDigitFont() { - let font = UIFont.preferredFont(forTextStyle: .body) - let monoFont = font.asMonospacedDigitFont() - guard let attributes: [[String: Int]] = monoFont.fontDescriptor.fontAttributes[UIFontDescriptorFeatureSettingsAttribute] as? [[String: Int]] else { - XCFail() + + func testMonospacedDigitFont() { + let font = UIFont.preferredFont(forTextStyle: .body) + let monoFont = font.monospaced + + let attributes = monoFont.fontDescriptor.fontAttributes + guard let settings = attributes[UIFontDescriptor.AttributeName.featureSettings] as? [[UIFontDescriptor.AttributeName :Int]] else { + XCTFail("Unable to get settings from font") + return + } + + guard let selector = settings.first?[.init("CTFeatureSelectorIdentifier")] else { + XCTFail("Unable to get selector from font") return } - XCTAssertEqual(attributes[0][UIFontFeatureTypeIdentifierKey], kNumberSpacingType) - XCTAssertEqual(attributes[0][UIFontFeatureSelectorIdentifierKey], kMonospacedNumbersSelector) - XCTAssertEqual(font.fontName, monoFont.fontName) - XCTAssertEqual(font.familyName, monoFont.familyName) - XCTAssertEqual(font.lineHeight, monoFont.lineHeight) - } + + guard let space = settings.first?[.init("CTFeatureTypeIdentifier")] else { + XCTFail("Unable to get space from font") + return + } + + XCTAssertEqual(selector, kMonospacedNumbersSelector) + XCTAssertEqual(space, kNumberSpacingType) + XCTAssertEqual(font.fontName, monoFont.fontName) + XCTAssertEqual(font.familyName, monoFont.familyName) + XCTAssertEqual(font.lineHeight, monoFont.lineHeight) + } } - #endif From a9f3ecf44c9cc6900c1a4a313c6e3ac985cc6f32 Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Wed, 27 Sep 2017 06:08:30 -0500 Subject: [PATCH 026/201] [Added] Danger to continuous integration (#252) --- .travis.yml | 6 +++++- Dangerfile | 22 ++++++++++++++++++++++ Gemfile | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Dangerfile create mode 100644 Gemfile diff --git a/.travis.yml b/.travis.yml index 105fa7370..e11b4422e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,12 @@ env: before_install: + - bundle install - brew update - brew outdated xctool || brew upgrade xctool - - gem install xcpretty + +before_script: + - bundle exec danger script: - set -o pipefail @@ -28,3 +31,4 @@ script: after_success: - bash <(curl -s https://codecov.io/bash) + diff --git a/Dangerfile b/Dangerfile new file mode 100644 index 000000000..46be46921 --- /dev/null +++ b/Dangerfile @@ -0,0 +1,22 @@ +message(“Thank you for submitting a pull request to SwifterSwift. The team will review your submission as soon as possible.“) + +# Checks for modified source files +source_changes_exist = !git.modified_files.grep(/Sources/).empty? + +# Checks for changelog entry +no_changelog_entry = !git.modified_files.include?("CHANGELOG.md") + +# Checks for tests +no_test_changes = !git.modified_files.grep(/Tests/).empty? + +if source_changes_exist && no_test_changes + warn(“Consider adding tests for new extensions or updating existing tests for a modified SwifterSwift extension”) +end + +if source_changes_exist && no_changelog_entry + warn(“The source files have been modified. Please consider adding a CHANGELOG entry if necessary.“) +end + +# Checks if pull request is labeled as [WIP] +warn(“This pull request is marked as Work in Progress. DO NOT MERGE!“) if github.pr_title.include? “[WIP]” + diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..a414cca43 --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'xcpretty' +gem 'danger' +gem 'danger-swiftlint' From de108fda819f18dd42f7eb76b6e63e7ab51aed06 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 28 Sep 2017 00:04:06 +0300 Subject: [PATCH 027/201] Add ColorExtensions --- CHANGELOG.md | 14 + .../Extensions/AppKit/NSColorExtensions.swift | 1533 ---------------- .../Extensions/Shared/ColorExtensions.swift | 1620 +++++++++++++++++ .../Extensions/UIKit/UIColorExtensions.swift | 1590 ---------------- SwifterSwift.podspec | 6 +- SwifterSwift.xcodeproj/project.pbxproj | 20 +- 6 files changed, 1655 insertions(+), 3128 deletions(-) delete mode 100644 Sources/Extensions/AppKit/NSColorExtensions.swift create mode 100644 Sources/Extensions/Shared/ColorExtensions.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index db90fddc4..852738f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,20 @@ All notable changes to this project will be documented in this file. > N/A +# v4.0.1 + +### API Breaking +N/A + +### Enhancements +- **Color** + - Refactored duplicated code from `UIColorExtensions` and `NSColorExtensions` into `ColorExtensions`. thanks to [SD10](https://github.com/SD10). + +### Bugfixes +- **Color** + - Fixed a bug in `rgbComponenets`, `shortHexString`, and `shortHexOrHexString` where an exception was raised when color is white or black. + + # v4.0.0 ### API Breaking diff --git a/Sources/Extensions/AppKit/NSColorExtensions.swift b/Sources/Extensions/AppKit/NSColorExtensions.swift deleted file mode 100644 index 79ae49056..000000000 --- a/Sources/Extensions/AppKit/NSColorExtensions.swift +++ /dev/null @@ -1,1533 +0,0 @@ -// -// NSColorExtensions.swift -// SwifterSwift -// -// Created by Omar Albeik on 03/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. -// - -#if os(macOS) -import Cocoa - -public extension NSColor { - - /// SwifterSwift: Create NSColor from hexadecimal value with optional transparency. - /// - /// - Parameters: - /// - hex: hex Int (example: 0xDECEB5). - /// - transparency: optional transparency value (default is 1). - public convenience init(hex: Int, transparency: CGFloat = 1) { - var trans: CGFloat { - if transparency > 1 { - return 1 - } else if transparency < 0 { - return 0 - } else { - return transparency - } - } - self.init(red:(hex >> 16) & 0xff, green:(hex >> 8) & 0xff, blue:hex & 0xff, transparency: trans) - } - - /// SwifterSwift: Create NSColor from hexadecimal string with optional transparency (if applicable). - /// - /// - Parameters: - /// - hexString: hexadecimal string (examples: EDE7F6, 0xEDE7F6, #EDE7F6, #0ff, 0xF0F, ..). - /// - transparency: optional transparency value (default is 1). - public convenience init?(hexString: String, transparency: CGFloat = 1) { - var string = "" - if hexString.lowercased().hasPrefix("0x") { - string = hexString.replacingOccurrences(of: "0x", with: "") - } else if hexString.hasPrefix("#") { - string = hexString.replacingOccurrences(of: "#", with: "") - } else { - string = hexString - } - - if string.characters.count == 3 { // convert hex to 6 digit format if in short format - var str = "" - string.characters.forEach({ str.append(String(repeating: String($0), count: 2)) }) - string = str - } - - guard let hexValue = Int(string, radix: 16) else { - return nil - } - - self.init(hex: Int(hexValue), transparency: transparency) - } - - /// SwifterSwift: Create NSColor from RGB values with optional transparency. - /// - /// - Parameters: - /// - red: red component. - /// - green: green component. - /// - blue: blue component. - /// - transparency: optional transparency value (default is 1). - public convenience init(red: Int, green: Int, blue: Int, transparency: CGFloat = 1) { - assert(red >= 0 && red <= 255, "Invalid red component") - assert(green >= 0 && green <= 255, "Invalid green component") - assert(blue >= 0 && blue <= 255, "Invalid blue component") - var trans: CGFloat { - if transparency > 1 { - return 1 - } else if transparency < 0 { - return 0 - } else { - return transparency - } - } - self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) - } - -} - -// MARK: - Social Colors -public extension NSColor { - - /// SwifterSwift: Brand identity color of popular social media platform. - public struct Social { - // https://www.lockedowndesign.com/social-media-colors/ - - /// red: 59, green: 89, blue: 152 - public static let facebook = NSColor(red: 59, green: 89, blue: 152) - - /// red: 0, green: 182, blue: 241 - public static let twitter = NSColor(red: 0, green: 182, blue: 241) - - /// red: 223, green: 74, blue: 50 - public static let googlePlus = NSColor(red: 223, green: 74, blue: 50) - - /// red: 0, green: 123, blue: 182 - public static let linkedIn = NSColor(red: 0, green: 123, blue: 182) - - /// red: 69, green: 187, blue: 255 - public static let vimeo = NSColor(red: 69, green: 187, blue: 255) - - /// red: 179, green: 18, blue: 23 - public static let youtube = NSColor(red: 179, green: 18, blue: 23) - - /// red: 195, green: 42, blue: 163 - public static let instagram = NSColor(red: 195, green: 42, blue: 163) - - /// red: 203, green: 32, blue: 39 - public static let pinterest = NSColor(red: 203, green: 32, blue: 39) - - /// red: 244, green: 0, blue: 131 - public static let flickr = NSColor(red: 244, green: 0, blue: 131) - - /// red: 67, green: 2, blue: 151 - public static let yahoo = NSColor(red: 67, green: 2, blue: 151) - - /// red: 67, green: 2, blue: 151 - public static let soundCloud = NSColor(red: 67, green: 2, blue: 151) - - /// red: 44, green: 71, blue: 98 - public static let tumblr = NSColor(red: 44, green: 71, blue: 98) - - /// red: 252, green: 69, blue: 117 - public static let foursquare = NSColor(red: 252, green: 69, blue: 117) - - /// red: 255, green: 176, blue: 0 - public static let swarm = NSColor(red: 255, green: 176, blue: 0) - - /// red: 234, green: 76, blue: 137 - public static let dribbble = NSColor(red: 234, green: 76, blue: 137) - - /// red: 255, green: 87, blue: 0 - public static let reddit = NSColor(red: 255, green: 87, blue: 0) - - /// red: 74, green: 93, blue: 78 - public static let devianArt = NSColor(red: 74, green: 93, blue: 78) - - /// red: 238, green: 64, blue: 86 - public static let pocket = NSColor(red: 238, green: 64, blue: 86) - - /// red: 170, green: 34, blue: 182 - public static let quora = NSColor(red: 170, green: 34, blue: 182) - - /// red: 247, green: 146, blue: 30 - public static let slideShare = NSColor(red: 247, green: 146, blue: 30) - - /// red: 0, green: 153, blue: 229 - public static let px500 = NSColor(red: 0, green: 153, blue: 229) - - /// red: 223, green: 109, blue: 70 - public static let listly = NSColor(red: 223, green: 109, blue: 70) - - /// red: 0, green: 180, blue: 137 - public static let vine = NSColor(red: 0, green: 180, blue: 137) - - /// red: 0, green: 175, blue: 240 - public static let skype = NSColor(red: 0, green: 175, blue: 240) - - /// red: 235, green: 73, blue: 36 - public static let stumbleUpon = NSColor(red: 235, green: 73, blue: 36) - - /// red: 255, green: 252, blue: 0 - public static let snapchat = NSColor(red: 255, green: 252, blue: 0) - - } -} - -// MARK: - Material colors -public extension NSColor { - - /// SwifterSwift: Google Material design colors palette. - public struct Material { - // https://material.google.com/style/color.html - - /// SwifterSwift: color red500 - public static let red = red500 - - /// SwifterSwift: hex #FFEBEE - public static let red50 = NSColor(hex: 0xFFEBEE) - - /// SwifterSwift: hex #FFCDD2 - public static let red100 = NSColor(hex: 0xFFCDD2) - - /// SwifterSwift: hex #EF9A9A - public static let red200 = NSColor(hex: 0xEF9A9A) - - /// SwifterSwift: hex #E57373 - public static let red300 = NSColor(hex: 0xE57373) - - /// SwifterSwift: hex #EF5350 - public static let red400 = NSColor(hex: 0xEF5350) - - /// SwifterSwift: hex #F44336 - public static let red500 = NSColor(hex: 0xF44336) - - /// SwifterSwift: hex #E53935 - public static let red600 = NSColor(hex: 0xE53935) - - /// SwifterSwift: hex #D32F2F - public static let red700 = NSColor(hex: 0xD32F2F) - - /// SwifterSwift: hex #C62828 - public static let red800 = NSColor(hex: 0xC62828) - - /// SwifterSwift: hex #B71C1C - public static let red900 = NSColor(hex: 0xB71C1C) - - /// SwifterSwift: hex #FF8A80 - public static let redA100 = NSColor(hex: 0xFF8A80) - - /// SwifterSwift: hex #FF5252 - public static let redA200 = NSColor(hex: 0xFF5252) - - /// SwifterSwift: hex #FF1744 - public static let redA400 = NSColor(hex: 0xFF1744) - - /// SwifterSwift: hex #D50000 - public static let redA700 = NSColor(hex: 0xD50000) - - /// SwifterSwift: color pink500 - public static let pink = pink500 - - /// SwifterSwift: hex #FCE4EC - public static let pink50 = NSColor(hex: 0xFCE4EC) - - /// SwifterSwift: hex #F8BBD0 - public static let pink100 = NSColor(hex: 0xF8BBD0) - - /// SwifterSwift: hex #F48FB1 - public static let pink200 = NSColor(hex: 0xF48FB1) - - /// SwifterSwift: hex #F06292 - public static let pink300 = NSColor(hex: 0xF06292) - - /// SwifterSwift: hex #EC407A - public static let pink400 = NSColor(hex: 0xEC407A) - - /// SwifterSwift: hex #E91E63 - public static let pink500 = NSColor(hex: 0xE91E63) - - /// SwifterSwift: hex #D81B60 - public static let pink600 = NSColor(hex: 0xD81B60) - - /// SwifterSwift: hex #C2185B - public static let pink700 = NSColor(hex: 0xC2185B) - - /// SwifterSwift: hex #AD1457 - public static let pink800 = NSColor(hex: 0xAD1457) - - /// SwifterSwift: hex #880E4F - public static let pink900 = NSColor(hex: 0x880E4F) - - /// SwifterSwift: hex #FF80AB - public static let pinkA100 = NSColor(hex: 0xFF80AB) - - /// SwifterSwift: hex #FF4081 - public static let pinkA200 = NSColor(hex: 0xFF4081) - - /// SwifterSwift: hex #F50057 - public static let pinkA400 = NSColor(hex: 0xF50057) - - /// SwifterSwift: hex #C51162 - public static let pinkA700 = NSColor(hex: 0xC51162) - - /// SwifterSwift: color purple500 - public static let purple = purple500 - - /// SwifterSwift: hex #F3E5F5 - public static let purple50 = NSColor(hex: 0xF3E5F5) - - /// SwifterSwift: hex #E1BEE7 - public static let purple100 = NSColor(hex: 0xE1BEE7) - - /// SwifterSwift: hex #CE93D8 - public static let purple200 = NSColor(hex: 0xCE93D8) - - /// SwifterSwift: hex #BA68C8 - public static let purple300 = NSColor(hex: 0xBA68C8) - - /// SwifterSwift: hex #AB47BC - public static let purple400 = NSColor(hex: 0xAB47BC) - - /// SwifterSwift: hex #9C27B0 - public static let purple500 = NSColor(hex: 0x9C27B0) - - /// SwifterSwift: hex #8E24AA - public static let purple600 = NSColor(hex: 0x8E24AA) - - /// SwifterSwift: hex #7B1FA2 - public static let purple700 = NSColor(hex: 0x7B1FA2) - - /// SwifterSwift: hex #6A1B9A - public static let purple800 = NSColor(hex: 0x6A1B9A) - - /// SwifterSwift: hex #4A148C - public static let purple900 = NSColor(hex: 0x4A148C) - - /// SwifterSwift: hex #EA80FC - public static let purpleA100 = NSColor(hex: 0xEA80FC) - - /// SwifterSwift: hex #E040FB - public static let purpleA200 = NSColor(hex: 0xE040FB) - - /// SwifterSwift: hex #D500F9 - public static let purpleA400 = NSColor(hex: 0xD500F9) - - /// SwifterSwift: hex #AA00FF - public static let purpleA700 = NSColor(hex: 0xAA00FF) - - /// SwifterSwift: color deepPurple500 - public static let deepPurple = deepPurple500 - - /// SwifterSwift: hex #EDE7F6 - public static let deepPurple50 = NSColor(hex: 0xEDE7F6) - - /// SwifterSwift: hex #D1C4E9 - public static let deepPurple100 = NSColor(hex: 0xD1C4E9) - - /// SwifterSwift: hex #B39DDB - public static let deepPurple200 = NSColor(hex: 0xB39DDB) - - /// SwifterSwift: hex #9575CD - public static let deepPurple300 = NSColor(hex: 0x9575CD) - - /// SwifterSwift: hex #7E57C2 - public static let deepPurple400 = NSColor(hex: 0x7E57C2) - - /// SwifterSwift: hex #673AB7 - public static let deepPurple500 = NSColor(hex: 0x673AB7) - - /// SwifterSwift: hex #5E35B1 - public static let deepPurple600 = NSColor(hex: 0x5E35B1) - - /// SwifterSwift: hex #512DA8 - public static let deepPurple700 = NSColor(hex: 0x512DA8) - - /// SwifterSwift: hex #4527A0 - public static let deepPurple800 = NSColor(hex: 0x4527A0) - - /// SwifterSwift: hex #311B92 - public static let deepPurple900 = NSColor(hex: 0x311B92) - - /// SwifterSwift: hex #B388FF - public static let deepPurpleA100 = NSColor(hex: 0xB388FF) - - /// SwifterSwift: hex #7C4DFF - public static let deepPurpleA200 = NSColor(hex: 0x7C4DFF) - - /// SwifterSwift: hex #651FFF - public static let deepPurpleA400 = NSColor(hex: 0x651FFF) - - /// SwifterSwift: hex #6200EA - public static let deepPurpleA700 = NSColor(hex: 0x6200EA) - - /// SwifterSwift: color indigo500 - public static let indigo = indigo500 - - /// SwifterSwift: hex #E8EAF6 - public static let indigo50 = NSColor(hex: 0xE8EAF6) - - /// SwifterSwift: hex #C5CAE9 - public static let indigo100 = NSColor(hex: 0xC5CAE9) - - /// SwifterSwift: hex #9FA8DA - public static let indigo200 = NSColor(hex: 0x9FA8DA) - - /// SwifterSwift: hex #7986CB - public static let indigo300 = NSColor(hex: 0x7986CB) - - /// SwifterSwift: hex #5C6BC0 - public static let indigo400 = NSColor(hex: 0x5C6BC0) - - /// SwifterSwift: hex #3F51B5 - public static let indigo500 = NSColor(hex: 0x3F51B5) - - /// SwifterSwift: hex #3949AB - public static let indigo600 = NSColor(hex: 0x3949AB) - - /// SwifterSwift: hex #303F9F - public static let indigo700 = NSColor(hex: 0x303F9F) - - /// SwifterSwift: hex #283593 - public static let indigo800 = NSColor(hex: 0x283593) - - /// SwifterSwift: hex #1A237E - public static let indigo900 = NSColor(hex: 0x1A237E) - - /// SwifterSwift: hex #8C9EFF - public static let indigoA100 = NSColor(hex: 0x8C9EFF) - - /// SwifterSwift: hex #536DFE - public static let indigoA200 = NSColor(hex: 0x536DFE) - - /// SwifterSwift: hex #3D5AFE - public static let indigoA400 = NSColor(hex: 0x3D5AFE) - - /// SwifterSwift: hex #304FFE - public static let indigoA700 = NSColor(hex: 0x304FFE) - - /// SwifterSwift: color blue500 - public static let blue = blue500 - - /// SwifterSwift: hex #E3F2FD - public static let blue50 = NSColor(hex: 0xE3F2FD) - - /// SwifterSwift: hex #BBDEFB - public static let blue100 = NSColor(hex: 0xBBDEFB) - - /// SwifterSwift: hex #90CAF9 - public static let blue200 = NSColor(hex: 0x90CAF9) - - /// SwifterSwift: hex #64B5F6 - public static let blue300 = NSColor(hex: 0x64B5F6) - - /// SwifterSwift: hex #42A5F5 - public static let blue400 = NSColor(hex: 0x42A5F5) - - /// SwifterSwift: hex #2196F3 - public static let blue500 = NSColor(hex: 0x2196F3) - - /// SwifterSwift: hex #1E88E5 - public static let blue600 = NSColor(hex: 0x1E88E5) - - /// SwifterSwift: hex #1976D2 - public static let blue700 = NSColor(hex: 0x1976D2) - - /// SwifterSwift: hex #1565C0 - public static let blue800 = NSColor(hex: 0x1565C0) - - /// SwifterSwift: hex #0D47A1 - public static let blue900 = NSColor(hex: 0x0D47A1) - - /// SwifterSwift: hex #82B1FF - public static let blueA100 = NSColor(hex: 0x82B1FF) - - /// SwifterSwift: hex #448AFF - public static let blueA200 = NSColor(hex: 0x448AFF) - - /// SwifterSwift: hex #2979FF - public static let blueA400 = NSColor(hex: 0x2979FF) - - /// SwifterSwift: hex #2962FF - public static let blueA700 = NSColor(hex: 0x2962FF) - - /// SwifterSwift: color lightBlue500 - public static let lightBlue = lightBlue500 - - /// SwifterSwift: hex #E1F5FE - public static let lightBlue50 = NSColor(hex: 0xE1F5FE) - - /// SwifterSwift: hex #B3E5FC - public static let lightBlue100 = NSColor(hex: 0xB3E5FC) - - /// SwifterSwift: hex #81D4FA - public static let lightBlue200 = NSColor(hex: 0x81D4FA) - - /// SwifterSwift: hex #4FC3F7 - public static let lightBlue300 = NSColor(hex: 0x4FC3F7) - - /// SwifterSwift: hex #29B6F6 - public static let lightBlue400 = NSColor(hex: 0x29B6F6) - - /// SwifterSwift: hex #03A9F4 - public static let lightBlue500 = NSColor(hex: 0x03A9F4) - - /// SwifterSwift: hex #039BE5 - public static let lightBlue600 = NSColor(hex: 0x039BE5) - - /// SwifterSwift: hex #0288D1 - public static let lightBlue700 = NSColor(hex: 0x0288D1) - - /// SwifterSwift: hex #0277BD - public static let lightBlue800 = NSColor(hex: 0x0277BD) - - /// SwifterSwift: hex #01579B - public static let lightBlue900 = NSColor(hex: 0x01579B) - - /// SwifterSwift: hex #80D8FF - public static let lightBlueA100 = NSColor(hex: 0x80D8FF) - - /// SwifterSwift: hex #40C4FF - public static let lightBlueA200 = NSColor(hex: 0x40C4FF) - - /// SwifterSwift: hex #00B0FF - public static let lightBlueA400 = NSColor(hex: 0x00B0FF) - - /// SwifterSwift: hex #0091EA - public static let lightBlueA700 = NSColor(hex: 0x0091EA) - - /// SwifterSwift: color cyan500 - public static let cyan = cyan500 - - /// SwifterSwift: hex #E0F7FA - public static let cyan50 = NSColor(hex: 0xE0F7FA) - - /// SwifterSwift: hex #B2EBF2 - public static let cyan100 = NSColor(hex: 0xB2EBF2) - - /// SwifterSwift: hex #80DEEA - public static let cyan200 = NSColor(hex: 0x80DEEA) - - /// SwifterSwift: hex #4DD0E1 - public static let cyan300 = NSColor(hex: 0x4DD0E1) - - /// SwifterSwift: hex #26C6DA - public static let cyan400 = NSColor(hex: 0x26C6DA) - - /// SwifterSwift: hex #00BCD4 - public static let cyan500 = NSColor(hex: 0x00BCD4) - - /// SwifterSwift: hex #00ACC1 - public static let cyan600 = NSColor(hex: 0x00ACC1) - - /// SwifterSwift: hex #0097A7 - public static let cyan700 = NSColor(hex: 0x0097A7) - - /// SwifterSwift: hex #00838F - public static let cyan800 = NSColor(hex: 0x00838F) - - /// SwifterSwift: hex #006064 - public static let cyan900 = NSColor(hex: 0x006064) - - /// SwifterSwift: hex #84FFFF - public static let cyanA100 = NSColor(hex: 0x84FFFF) - - /// SwifterSwift: hex #18FFFF - public static let cyanA200 = NSColor(hex: 0x18FFFF) - - /// SwifterSwift: hex #00E5FF - public static let cyanA400 = NSColor(hex: 0x00E5FF) - - /// SwifterSwift: hex #00B8D4 - public static let cyanA700 = NSColor(hex: 0x00B8D4) - - /// SwifterSwift: color teal500 - public static let teal = teal500 - - /// SwifterSwift: hex #E0F2F1 - public static let teal50 = NSColor(hex: 0xE0F2F1) - - /// SwifterSwift: hex #B2DFDB - public static let teal100 = NSColor(hex: 0xB2DFDB) - - /// SwifterSwift: hex #80CBC4 - public static let teal200 = NSColor(hex: 0x80CBC4) - - /// SwifterSwift: hex #4DB6AC - public static let teal300 = NSColor(hex: 0x4DB6AC) - - /// SwifterSwift: hex #26A69A - public static let teal400 = NSColor(hex: 0x26A69A) - - /// SwifterSwift: hex #009688 - public static let teal500 = NSColor(hex: 0x009688) - - /// SwifterSwift: hex #00897B - public static let teal600 = NSColor(hex: 0x00897B) - - /// SwifterSwift: hex #00796B - public static let teal700 = NSColor(hex: 0x00796B) - - /// SwifterSwift: hex #00695C - public static let teal800 = NSColor(hex: 0x00695C) - - /// SwifterSwift: hex #004D40 - public static let teal900 = NSColor(hex: 0x004D40) - - /// SwifterSwift: hex #A7FFEB - public static let tealA100 = NSColor(hex: 0xA7FFEB) - - /// SwifterSwift: hex #64FFDA - public static let tealA200 = NSColor(hex: 0x64FFDA) - - /// SwifterSwift: hex #1DE9B6 - public static let tealA400 = NSColor(hex: 0x1DE9B6) - - /// SwifterSwift: hex #00BFA5 - public static let tealA700 = NSColor(hex: 0x00BFA5) - - /// SwifterSwift: color green500 - public static let green = green500 - - /// SwifterSwift: hex #E8F5E9 - public static let green50 = NSColor(hex: 0xE8F5E9) - - /// SwifterSwift: hex #C8E6C9 - public static let green100 = NSColor(hex: 0xC8E6C9) - - /// SwifterSwift: hex #A5D6A7 - public static let green200 = NSColor(hex: 0xA5D6A7) - - /// SwifterSwift: hex #81C784 - public static let green300 = NSColor(hex: 0x81C784) - - /// SwifterSwift: hex #66BB6A - public static let green400 = NSColor(hex: 0x66BB6A) - - /// SwifterSwift: hex #4CAF50 - public static let green500 = NSColor(hex: 0x4CAF50) - - /// SwifterSwift: hex #43A047 - public static let green600 = NSColor(hex: 0x43A047) - - /// SwifterSwift: hex #388E3C - public static let green700 = NSColor(hex: 0x388E3C) - - /// SwifterSwift: hex #2E7D32 - public static let green800 = NSColor(hex: 0x2E7D32) - - /// SwifterSwift: hex #1B5E20 - public static let green900 = NSColor(hex: 0x1B5E20) - - /// SwifterSwift: hex #B9F6CA - public static let greenA100 = NSColor(hex: 0xB9F6CA) - - /// SwifterSwift: hex #69F0AE - public static let greenA200 = NSColor(hex: 0x69F0AE) - - /// SwifterSwift: hex #00E676 - public static let greenA400 = NSColor(hex: 0x00E676) - - /// SwifterSwift: hex #00C853 - public static let greenA700 = NSColor(hex: 0x00C853) - - /// SwifterSwift: color lightGreen500 - public static let lightGreen = lightGreen500 - - /// SwifterSwift: hex #F1F8E9 - public static let lightGreen50 = NSColor(hex: 0xF1F8E9) - - /// SwifterSwift: hex #DCEDC8 - public static let lightGreen100 = NSColor(hex: 0xDCEDC8) - - /// SwifterSwift: hex #C5E1A5 - public static let lightGreen200 = NSColor(hex: 0xC5E1A5) - - /// SwifterSwift: hex #AED581 - public static let lightGreen300 = NSColor(hex: 0xAED581) - - /// SwifterSwift: hex #9CCC65 - public static let lightGreen400 = NSColor(hex: 0x9CCC65) - - /// SwifterSwift: hex #8BC34A - public static let lightGreen500 = NSColor(hex: 0x8BC34A) - - /// SwifterSwift: hex #7CB342 - public static let lightGreen600 = NSColor(hex: 0x7CB342) - - /// SwifterSwift: hex #689F38 - public static let lightGreen700 = NSColor(hex: 0x689F38) - - /// SwifterSwift: hex #558B2F - public static let lightGreen800 = NSColor(hex: 0x558B2F) - - /// SwifterSwift: hex #33691E - public static let lightGreen900 = NSColor(hex: 0x33691E) - - /// SwifterSwift: hex #CCFF90 - public static let lightGreenA100 = NSColor(hex: 0xCCFF90) - - /// SwifterSwift: hex #B2FF59 - public static let lightGreenA200 = NSColor(hex: 0xB2FF59) - - /// SwifterSwift: hex #76FF03 - public static let lightGreenA400 = NSColor(hex: 0x76FF03) - - /// SwifterSwift: hex #64DD17 - public static let lightGreenA700 = NSColor(hex: 0x64DD17) - - /// SwifterSwift: color lime500 - public static let lime = lime500 - - /// SwifterSwift: hex #F9FBE7 - public static let lime50 = NSColor(hex: 0xF9FBE7) - - /// SwifterSwift: hex #F0F4C3 - public static let lime100 = NSColor(hex: 0xF0F4C3) - - /// SwifterSwift: hex #E6EE9C - public static let lime200 = NSColor(hex: 0xE6EE9C) - - /// SwifterSwift: hex #DCE775 - public static let lime300 = NSColor(hex: 0xDCE775) - - /// SwifterSwift: hex #D4E157 - public static let lime400 = NSColor(hex: 0xD4E157) - - /// SwifterSwift: hex #CDDC39 - public static let lime500 = NSColor(hex: 0xCDDC39) - - /// SwifterSwift: hex #C0CA33 - public static let lime600 = NSColor(hex: 0xC0CA33) - - /// SwifterSwift: hex #AFB42B - public static let lime700 = NSColor(hex: 0xAFB42B) - - /// SwifterSwift: hex #9E9D24 - public static let lime800 = NSColor(hex: 0x9E9D24) - - /// SwifterSwift: hex #827717 - public static let lime900 = NSColor(hex: 0x827717) - - /// SwifterSwift: hex #F4FF81 - public static let limeA100 = NSColor(hex: 0xF4FF81) - - /// SwifterSwift: hex #EEFF41 - public static let limeA200 = NSColor(hex: 0xEEFF41) - - /// SwifterSwift: hex #C6FF00 - public static let limeA400 = NSColor(hex: 0xC6FF00) - - /// SwifterSwift: hex #AEEA00 - public static let limeA700 = NSColor(hex: 0xAEEA00) - - /// SwifterSwift: color yellow500 - public static let yellow = yellow500 - - /// SwifterSwift: hex #FFFDE7 - public static let yellow50 = NSColor(hex: 0xFFFDE7) - - /// SwifterSwift: hex #FFF9C4 - public static let yellow100 = NSColor(hex: 0xFFF9C4) - - /// SwifterSwift: hex #FFF59D - public static let yellow200 = NSColor(hex: 0xFFF59D) - - /// SwifterSwift: hex #FFF176 - public static let yellow300 = NSColor(hex: 0xFFF176) - - /// SwifterSwift: hex #FFEE58 - public static let yellow400 = NSColor(hex: 0xFFEE58) - - /// SwifterSwift: hex #FFEB3B - public static let yellow500 = NSColor(hex: 0xFFEB3B) - - /// SwifterSwift: hex #FDD835 - public static let yellow600 = NSColor(hex: 0xFDD835) - - /// SwifterSwift: hex #FBC02D - public static let yellow700 = NSColor(hex: 0xFBC02D) - - /// SwifterSwift: hex #F9A825 - public static let yellow800 = NSColor(hex: 0xF9A825) - - /// SwifterSwift: hex #F57F17 - public static let yellow900 = NSColor(hex: 0xF57F17) - - /// SwifterSwift: hex #FFFF8D - public static let yellowA100 = NSColor(hex: 0xFFFF8D) - - /// SwifterSwift: hex #FFFF00 - public static let yellowA200 = NSColor(hex: 0xFFFF00) - - /// SwifterSwift: hex #FFEA00 - public static let yellowA400 = NSColor(hex: 0xFFEA00) - - /// SwifterSwift: hex #FFD600 - public static let yellowA700 = NSColor(hex: 0xFFD600) - - /// SwifterSwift: color amber500 - public static let amber = amber500 - - /// SwifterSwift: hex #FFF8E1 - public static let amber50 = NSColor(hex: 0xFFF8E1) - - /// SwifterSwift: hex #FFECB3 - public static let amber100 = NSColor(hex: 0xFFECB3) - - /// SwifterSwift: hex #FFE082 - public static let amber200 = NSColor(hex: 0xFFE082) - - /// SwifterSwift: hex #FFD54F - public static let amber300 = NSColor(hex: 0xFFD54F) - - /// SwifterSwift: hex #FFCA28 - public static let amber400 = NSColor(hex: 0xFFCA28) - - /// SwifterSwift: hex #FFC107 - public static let amber500 = NSColor(hex: 0xFFC107) - - /// SwifterSwift: hex #FFB300 - public static let amber600 = NSColor(hex: 0xFFB300) - - /// SwifterSwift: hex #FFA000 - public static let amber700 = NSColor(hex: 0xFFA000) - - /// SwifterSwift: hex #FF8F00 - public static let amber800 = NSColor(hex: 0xFF8F00) - - /// SwifterSwift: hex #FF6F00 - public static let amber900 = NSColor(hex: 0xFF6F00) - - /// SwifterSwift: hex #FFE57F - public static let amberA100 = NSColor(hex: 0xFFE57F) - - /// SwifterSwift: hex #FFD740 - public static let amberA200 = NSColor(hex: 0xFFD740) - - /// SwifterSwift: hex #FFC400 - public static let amberA400 = NSColor(hex: 0xFFC400) - - /// SwifterSwift: hex #FFAB00 - public static let amberA700 = NSColor(hex: 0xFFAB00) - - /// SwifterSwift: color orange500 - public static let orange = orange500 - - /// SwifterSwift: hex #FFF3E0 - public static let orange50 = NSColor(hex: 0xFFF3E0) - - /// SwifterSwift: hex #FFE0B2 - public static let orange100 = NSColor(hex: 0xFFE0B2) - - /// SwifterSwift: hex #FFCC80 - public static let orange200 = NSColor(hex: 0xFFCC80) - - /// SwifterSwift: hex #FFB74D - public static let orange300 = NSColor(hex: 0xFFB74D) - - /// SwifterSwift: hex #FFA726 - public static let orange400 = NSColor(hex: 0xFFA726) - - /// SwifterSwift: hex #FF9800 - public static let orange500 = NSColor(hex: 0xFF9800) - - /// SwifterSwift: hex #FB8C00 - public static let orange600 = NSColor(hex: 0xFB8C00) - - /// SwifterSwift: hex #F57C00 - public static let orange700 = NSColor(hex: 0xF57C00) - - /// SwifterSwift: hex #EF6C00 - public static let orange800 = NSColor(hex: 0xEF6C00) - - /// SwifterSwift: hex #E65100 - public static let orange900 = NSColor(hex: 0xE65100) - - /// SwifterSwift: hex #FFD180 - public static let orangeA100 = NSColor(hex: 0xFFD180) - - /// SwifterSwift: hex #FFAB40 - public static let orangeA200 = NSColor(hex: 0xFFAB40) - - /// SwifterSwift: hex #FF9100 - public static let orangeA400 = NSColor(hex: 0xFF9100) - - /// SwifterSwift: hex #FF6D00 - public static let orangeA700 = NSColor(hex: 0xFF6D00) - - /// SwifterSwift: color deepOrange500 - public static let deepOrange = deepOrange500 - - /// SwifterSwift: hex #FBE9E7 - public static let deepOrange50 = NSColor(hex: 0xFBE9E7) - - /// SwifterSwift: hex #FFCCBC - public static let deepOrange100 = NSColor(hex: 0xFFCCBC) - - /// SwifterSwift: hex #FFAB91 - public static let deepOrange200 = NSColor(hex: 0xFFAB91) - - /// SwifterSwift: hex #FF8A65 - public static let deepOrange300 = NSColor(hex: 0xFF8A65) - - /// SwifterSwift: hex #FF7043 - public static let deepOrange400 = NSColor(hex: 0xFF7043) - - /// SwifterSwift: hex #FF5722 - public static let deepOrange500 = NSColor(hex: 0xFF5722) - - /// SwifterSwift: hex #F4511E - public static let deepOrange600 = NSColor(hex: 0xF4511E) - - /// SwifterSwift: hex #E64A19 - public static let deepOrange700 = NSColor(hex: 0xE64A19) - - /// SwifterSwift: hex #D84315 - public static let deepOrange800 = NSColor(hex: 0xD84315) - - /// SwifterSwift: hex #BF360C - public static let deepOrange900 = NSColor(hex: 0xBF360C) - - /// SwifterSwift: hex #FF9E80 - public static let deepOrangeA100 = NSColor(hex: 0xFF9E80) - - /// SwifterSwift: hex #FF6E40 - public static let deepOrangeA200 = NSColor(hex: 0xFF6E40) - - /// SwifterSwift: hex #FF3D00 - public static let deepOrangeA400 = NSColor(hex: 0xFF3D00) - - /// SwifterSwift: hex #DD2C00 - public static let deepOrangeA700 = NSColor(hex: 0xDD2C00) - - /// SwifterSwift: color brown500 - public static let brown = brown500 - - /// SwifterSwift: hex #EFEBE9 - public static let brown50 = NSColor(hex: 0xEFEBE9) - - /// SwifterSwift: hex #D7CCC8 - public static let brown100 = NSColor(hex: 0xD7CCC8) - - /// SwifterSwift: hex #BCAAA4 - public static let brown200 = NSColor(hex: 0xBCAAA4) - - /// SwifterSwift: hex #A1887F - public static let brown300 = NSColor(hex: 0xA1887F) - - /// SwifterSwift: hex #8D6E63 - public static let brown400 = NSColor(hex: 0x8D6E63) - - /// SwifterSwift: hex #795548 - public static let brown500 = NSColor(hex: 0x795548) - - /// SwifterSwift: hex #6D4C41 - public static let brown600 = NSColor(hex: 0x6D4C41) - - /// SwifterSwift: hex #5D4037 - public static let brown700 = NSColor(hex: 0x5D4037) - - /// SwifterSwift: hex #4E342E - public static let brown800 = NSColor(hex: 0x4E342E) - - /// SwifterSwift: hex #3E2723 - public static let brown900 = NSColor(hex: 0x3E2723) - - /// SwifterSwift: color grey500 - public static let grey = grey500 - - /// SwifterSwift: hex #FAFAFA - public static let grey50 = NSColor(hex: 0xFAFAFA) - - /// SwifterSwift: hex #F5F5F5 - public static let grey100 = NSColor(hex: 0xF5F5F5) - - /// SwifterSwift: hex #EEEEEE - public static let grey200 = NSColor(hex: 0xEEEEEE) - - /// SwifterSwift: hex #E0E0E0 - public static let grey300 = NSColor(hex: 0xE0E0E0) - - /// SwifterSwift: hex #BDBDBD - public static let grey400 = NSColor(hex: 0xBDBDBD) - - /// SwifterSwift: hex #9E9E9E - public static let grey500 = NSColor(hex: 0x9E9E9E) - - /// SwifterSwift: hex #757575 - public static let grey600 = NSColor(hex: 0x757575) - - /// SwifterSwift: hex #616161 - public static let grey700 = NSColor(hex: 0x616161) - - /// SwifterSwift: hex #424242 - public static let grey800 = NSColor(hex: 0x424242) - - /// SwifterSwift: hex #212121 - public static let grey900 = NSColor(hex: 0x212121) - - /// SwifterSwift: color blueGrey500 - public static let blueGrey = blueGrey500 - - /// SwifterSwift: hex #ECEFF1 - public static let blueGrey50 = NSColor(hex: 0xECEFF1) - - /// SwifterSwift: hex #CFD8DC - public static let blueGrey100 = NSColor(hex: 0xCFD8DC) - - /// SwifterSwift: hex #B0BEC5 - public static let blueGrey200 = NSColor(hex: 0xB0BEC5) - - /// SwifterSwift: hex #90A4AE - public static let blueGrey300 = NSColor(hex: 0x90A4AE) - - /// SwifterSwift: hex #78909C - public static let blueGrey400 = NSColor(hex: 0x78909C) - - /// SwifterSwift: hex #607D8B - public static let blueGrey500 = NSColor(hex: 0x607D8B) - - /// SwifterSwift: hex #546E7A - public static let blueGrey600 = NSColor(hex: 0x546E7A) - - /// SwifterSwift: hex #455A64 - public static let blueGrey700 = NSColor(hex: 0x455A64) - - /// SwifterSwift: hex #37474F - public static let blueGrey800 = NSColor(hex: 0x37474F) - - /// SwifterSwift: hex #263238 - public static let blueGrey900 = NSColor(hex: 0x263238) - - /// SwifterSwift: hex #000000 - public static let black = NSColor(hex: 0x000000) - - /// SwifterSwift: hex #FFFFFF - public static let white = NSColor(hex: 0xFFFFFF) - - } - -} - -// MARK: - CSS colors -public extension NSColor { - - /// SwifterSwift: CSS colors. - public struct CSS { - // http://www.w3schools.com/colors/colors_names.asp - - /// SwifterSwift: hex #F0F8FF - public static let aliceBlue = NSColor(hex: 0xF0F8FF) - - /// SwifterSwift: hex #FAEBD7 - public static let antiqueWhite = NSColor(hex: 0xFAEBD7) - - /// SwifterSwift: hex #00FFFF - public static let aqua = NSColor(hex: 0x00FFFF) - - /// SwifterSwift: hex #7FFFD4 - public static let aquamarine = NSColor(hex: 0x7FFFD4) - - /// SwifterSwift: hex #F0FFFF - public static let azure = NSColor(hex: 0xF0FFFF) - - /// SwifterSwift: hex #F5F5DC - public static let beige = NSColor(hex: 0xF5F5DC) - - /// SwifterSwift: hex #FFE4C4 - public static let bisque = NSColor(hex: 0xFFE4C4) - - /// SwifterSwift: hex #000000 - public static let black = NSColor(hex: 0x000000) - - /// SwifterSwift: hex #FFEBCD - public static let blanchedAlmond = NSColor(hex: 0xFFEBCD) - - /// SwifterSwift: hex #0000FF - public static let blue = NSColor(hex: 0x0000FF) - - /// SwifterSwift: hex #8A2BE2 - public static let blueViolet = NSColor(hex: 0x8A2BE2) - - /// SwifterSwift: hex #A52A2A - public static let brown = NSColor(hex: 0xA52A2A) - - /// SwifterSwift: hex #DEB887 - public static let burlyWood = NSColor(hex: 0xDEB887) - - /// SwifterSwift: hex #5F9EA0 - public static let cadetBlue = NSColor(hex: 0x5F9EA0) - - /// SwifterSwift: hex #7FFF00 - public static let chartreuse = NSColor(hex: 0x7FFF00) - - /// SwifterSwift: hex #D2691E - public static let chocolate = NSColor(hex: 0xD2691E) - - /// SwifterSwift: hex #FF7F50 - public static let coral = NSColor(hex: 0xFF7F50) - - /// SwifterSwift: hex #6495ED - public static let cornflowerBlue = NSColor(hex: 0x6495ED) - - /// SwifterSwift: hex #FFF8DC - public static let cornsilk = NSColor(hex: 0xFFF8DC) - - /// SwifterSwift: hex #DC143C - public static let crimson = NSColor(hex: 0xDC143C) - - /// SwifterSwift: hex #00FFFF - public static let cyan = NSColor(hex: 0x00FFFF) - - /// SwifterSwift: hex #00008B - public static let darkBlue = NSColor(hex: 0x00008B) - - /// SwifterSwift: hex #008B8B - public static let darkCyan = NSColor(hex: 0x008B8B) - - /// SwifterSwift: hex #B8860B - public static let darkGoldenRod = NSColor(hex: 0xB8860B) - - /// SwifterSwift: hex #A9A9A9 - public static let darkGray = NSColor(hex: 0xA9A9A9) - - /// SwifterSwift: hex #A9A9A9 - public static let darkGrey = NSColor(hex: 0xA9A9A9) - - /// SwifterSwift: hex #006400 - public static let darkGreen = NSColor(hex: 0x006400) - - /// SwifterSwift: hex #BDB76B - public static let darkKhaki = NSColor(hex: 0xBDB76B) - - /// SwifterSwift: hex #8B008B - public static let darkMagenta = NSColor(hex: 0x8B008B) - - /// SwifterSwift: hex #556B2F - public static let darkOliveGreen = NSColor(hex: 0x556B2F) - - /// SwifterSwift: hex #FF8C00 - public static let darkOrange = NSColor(hex: 0xFF8C00) - - /// SwifterSwift: hex #9932CC - public static let darkOrchid = NSColor(hex: 0x9932CC) - - /// SwifterSwift: hex #8B0000 - public static let darkRed = NSColor(hex: 0x8B0000) - - /// SwifterSwift: hex #E9967A - public static let darkSalmon = NSColor(hex: 0xE9967A) - - /// SwifterSwift: hex #8FBC8F - public static let darkSeaGreen = NSColor(hex: 0x8FBC8F) - - /// SwifterSwift: hex #483D8B - public static let darkSlateBlue = NSColor(hex: 0x483D8B) - - /// SwifterSwift: hex #2F4F4F - public static let darkSlateGray = NSColor(hex: 0x2F4F4F) - - /// SwifterSwift: hex #2F4F4F - public static let darkSlateGrey = NSColor(hex: 0x2F4F4F) - - /// SwifterSwift: hex #00CED1 - public static let darkTurquoise = NSColor(hex: 0x00CED1) - - /// SwifterSwift: hex #9400D3 - public static let darkViolet = NSColor(hex: 0x9400D3) - - /// SwifterSwift: hex #FF1493 - public static let deepPink = NSColor(hex: 0xFF1493) - - /// SwifterSwift: hex #00BFFF - public static let deepSkyBlue = NSColor(hex: 0x00BFFF) - - /// SwifterSwift: hex #696969 - public static let dimGray = NSColor(hex: 0x696969) - - /// SwifterSwift: hex #696969 - public static let dimGrey = NSColor(hex: 0x696969) - - /// SwifterSwift: hex #1E90FF - public static let dodgerBlue = NSColor(hex: 0x1E90FF) - - /// SwifterSwift: hex #B22222 - public static let fireBrick = NSColor(hex: 0xB22222) - - /// SwifterSwift: hex #FFFAF0 - public static let floralWhite = NSColor(hex: 0xFFFAF0) - - /// SwifterSwift: hex #228B22 - public static let forestGreen = NSColor(hex: 0x228B22) - - /// SwifterSwift: hex #FF00FF - public static let fuchsia = NSColor(hex: 0xFF00FF) - - /// SwifterSwift: hex #DCDCDC - public static let gainsboro = NSColor(hex: 0xDCDCDC) - - /// SwifterSwift: hex #F8F8FF - public static let ghostWhite = NSColor(hex: 0xF8F8FF) - - /// SwifterSwift: hex #FFD700 - public static let gold = NSColor(hex: 0xFFD700) - - /// SwifterSwift: hex #DAA520 - public static let goldenRod = NSColor(hex: 0xDAA520) - - /// SwifterSwift: hex #808080 - public static let gray = NSColor(hex: 0x808080) - - /// SwifterSwift: hex #808080 - public static let grey = NSColor(hex: 0x808080) - - /// SwifterSwift: hex #008000 - public static let green = NSColor(hex: 0x008000) - - /// SwifterSwift: hex #ADFF2F - public static let greenYellow = NSColor(hex: 0xADFF2F) - - /// SwifterSwift: hex #F0FFF0 - public static let honeyDew = NSColor(hex: 0xF0FFF0) - - /// SwifterSwift: hex #FF69B4 - public static let hotPink = NSColor(hex: 0xFF69B4) - - /// SwifterSwift: hex #CD5C5C - public static let indianRed = NSColor(hex: 0xCD5C5C) - - /// SwifterSwift: hex #4B0082 - public static let indigo = NSColor(hex: 0x4B0082) - - /// SwifterSwift: hex #FFFFF0 - public static let ivory = NSColor(hex: 0xFFFFF0) - - /// SwifterSwift: hex #F0E68C - public static let khaki = NSColor(hex: 0xF0E68C) - - /// SwifterSwift: hex #E6E6FA - public static let lavender = NSColor(hex: 0xE6E6FA) - - /// SwifterSwift: hex #FFF0F5 - public static let lavenderBlush = NSColor(hex: 0xFFF0F5) - - /// SwifterSwift: hex #7CFC00 - public static let lawnGreen = NSColor(hex: 0x7CFC00) - - /// SwifterSwift: hex #FFFACD - public static let lemonChiffon = NSColor(hex: 0xFFFACD) - - /// SwifterSwift: hex #ADD8E6 - public static let lightBlue = NSColor(hex: 0xADD8E6) - - /// SwifterSwift: hex #F08080 - public static let lightCoral = NSColor(hex: 0xF08080) - - /// SwifterSwift: hex #E0FFFF - public static let lightCyan = NSColor(hex: 0xE0FFFF) - - /// SwifterSwift: hex #FAFAD2 - public static let lightGoldenRodYellow = NSColor(hex: 0xFAFAD2) - - /// SwifterSwift: hex #D3D3D3 - public static let lightGray = NSColor(hex: 0xD3D3D3) - - /// SwifterSwift: hex #D3D3D3 - public static let lightGrey = NSColor(hex: 0xD3D3D3) - - /// SwifterSwift: hex #90EE90 - public static let lightGreen = NSColor(hex: 0x90EE90) - - /// SwifterSwift: hex #FFB6C1 - public static let lightPink = NSColor(hex: 0xFFB6C1) - - /// SwifterSwift: hex #FFA07A - public static let lightSalmon = NSColor(hex: 0xFFA07A) - - /// SwifterSwift: hex #20B2AA - public static let lightSeaGreen = NSColor(hex: 0x20B2AA) - - /// SwifterSwift: hex #87CEFA - public static let lightSkyBlue = NSColor(hex: 0x87CEFA) - - /// SwifterSwift: hex #778899 - public static let lightSlateGray = NSColor(hex: 0x778899) - - /// SwifterSwift: hex #778899 - public static let lightSlateGrey = NSColor(hex: 0x778899) - - /// SwifterSwift: hex #B0C4DE - public static let lightSteelBlue = NSColor(hex: 0xB0C4DE) - - /// SwifterSwift: hex #FFFFE0 - public static let lightYellow = NSColor(hex: 0xFFFFE0) - - /// SwifterSwift: hex #00FF00 - public static let lime = NSColor(hex: 0x00FF00) - - /// SwifterSwift: hex #32CD32 - public static let limeGreen = NSColor(hex: 0x32CD32) - - /// SwifterSwift: hex #FAF0E6 - public static let linen = NSColor(hex: 0xFAF0E6) - - /// SwifterSwift: hex #FF00FF - public static let magenta = NSColor(hex: 0xFF00FF) - - /// SwifterSwift: hex #800000 - public static let maroon = NSColor(hex: 0x800000) - - /// SwifterSwift: hex #66CDAA - public static let mediumAquaMarine = NSColor(hex: 0x66CDAA) - - /// SwifterSwift: hex #0000CD - public static let mediumBlue = NSColor(hex: 0x0000CD) - - /// SwifterSwift: hex #BA55D3 - public static let mediumOrchid = NSColor(hex: 0xBA55D3) - - /// SwifterSwift: hex #9370DB - public static let mediumPurple = NSColor(hex: 0x9370DB) - - /// SwifterSwift: hex #3CB371 - public static let mediumSeaGreen = NSColor(hex: 0x3CB371) - - /// SwifterSwift: hex #7B68EE - public static let mediumSlateBlue = NSColor(hex: 0x7B68EE) - - /// SwifterSwift: hex #00FA9A - public static let mediumSpringGreen = NSColor(hex: 0x00FA9A) - - /// SwifterSwift: hex #48D1CC - public static let mediumTurquoise = NSColor(hex: 0x48D1CC) - - /// SwifterSwift: hex #C71585 - public static let mediumVioletRed = NSColor(hex: 0xC71585) - - /// SwifterSwift: hex #191970 - public static let midnightBlue = NSColor(hex: 0x191970) - - /// SwifterSwift: hex #F5FFFA - public static let mintCream = NSColor(hex: 0xF5FFFA) - - /// SwifterSwift: hex #FFE4E1 - public static let mistyRose = NSColor(hex: 0xFFE4E1) - - /// SwifterSwift: hex #FFE4B5 - public static let moccasin = NSColor(hex: 0xFFE4B5) - - /// SwifterSwift: hex #FFDEAD - public static let navajoWhite = NSColor(hex: 0xFFDEAD) - - /// SwifterSwift: hex #000080 - public static let navy = NSColor(hex: 0x000080) - - /// SwifterSwift: hex #FDF5E6 - public static let oldLace = NSColor(hex: 0xFDF5E6) - - /// SwifterSwift: hex #808000 - public static let olive = NSColor(hex: 0x808000) - - /// SwifterSwift: hex #6B8E23 - public static let oliveDrab = NSColor(hex: 0x6B8E23) - - /// SwifterSwift: hex #FFA500 - public static let orange = NSColor(hex: 0xFFA500) - - /// SwifterSwift: hex #FF4500 - public static let orangeRed = NSColor(hex: 0xFF4500) - - /// SwifterSwift: hex #DA70D6 - public static let orchid = NSColor(hex: 0xDA70D6) - - /// SwifterSwift: hex #EEE8AA - public static let paleGoldenRod = NSColor(hex: 0xEEE8AA) - - /// SwifterSwift: hex #98FB98 - public static let paleGreen = NSColor(hex: 0x98FB98) - - /// SwifterSwift: hex #AFEEEE - public static let paleTurquoise = NSColor(hex: 0xAFEEEE) - - /// SwifterSwift: hex #DB7093 - public static let paleVioletRed = NSColor(hex: 0xDB7093) - - /// SwifterSwift: hex #FFEFD5 - public static let papayaWhip = NSColor(hex: 0xFFEFD5) - - /// SwifterSwift: hex #FFDAB9 - public static let peachPuff = NSColor(hex: 0xFFDAB9) - - /// SwifterSwift: hex #CD853F - public static let peru = NSColor(hex: 0xCD853F) - - /// SwifterSwift: hex #FFC0CB - public static let pink = NSColor(hex: 0xFFC0CB) - - /// SwifterSwift: hex #DDA0DD - public static let plum = NSColor(hex: 0xDDA0DD) - - /// SwifterSwift: hex #B0E0E6 - public static let powderBlue = NSColor(hex: 0xB0E0E6) - - /// SwifterSwift: hex #800080 - public static let purple = NSColor(hex: 0x800080) - - /// SwifterSwift: hex #663399 - public static let rebeccaPurple = NSColor(hex: 0x663399) - - /// SwifterSwift: hex #FF0000 - public static let red = NSColor(hex: 0xFF0000) - - /// SwifterSwift: hex #BC8F8F - public static let rosyBrown = NSColor(hex: 0xBC8F8F) - - /// SwifterSwift: hex #4169E1 - public static let royalBlue = NSColor(hex: 0x4169E1) - - /// SwifterSwift: hex #8B4513 - public static let saddleBrown = NSColor(hex: 0x8B4513) - - /// SwifterSwift: hex #FA8072 - public static let salmon = NSColor(hex: 0xFA8072) - - /// SwifterSwift: hex #F4A460 - public static let sandyBrown = NSColor(hex: 0xF4A460) - - /// SwifterSwift: hex #2E8B57 - public static let seaGreen = NSColor(hex: 0x2E8B57) - - /// SwifterSwift: hex #FFF5EE - public static let seaShell = NSColor(hex: 0xFFF5EE) - - /// SwifterSwift: hex #A0522D - public static let sienna = NSColor(hex: 0xA0522D) - - /// SwifterSwift: hex #C0C0C0 - public static let silver = NSColor(hex: 0xC0C0C0) - - /// SwifterSwift: hex #87CEEB - public static let skyBlue = NSColor(hex: 0x87CEEB) - - /// SwifterSwift: hex #6A5ACD - public static let slateBlue = NSColor(hex: 0x6A5ACD) - - /// SwifterSwift: hex #708090 - public static let slateGray = NSColor(hex: 0x708090) - - /// SwifterSwift: hex #708090 - public static let slateGrey = NSColor(hex: 0x708090) - - /// SwifterSwift: hex #FFFAFA - public static let snow = NSColor(hex: 0xFFFAFA) - - /// SwifterSwift: hex #00FF7F - public static let springGreen = NSColor(hex: 0x00FF7F) - - /// SwifterSwift: hex #4682B4 - public static let steelBlue = NSColor(hex: 0x4682B4) - - /// SwifterSwift: hex #D2B48C - public static let tan = NSColor(hex: 0xD2B48C) - - /// SwifterSwift: hex #008080 - public static let teal = NSColor(hex: 0x008080) - - /// SwifterSwift: hex #D8BFD8 - public static let thistle = NSColor(hex: 0xD8BFD8) - - /// SwifterSwift: hex #FF6347 - public static let tomato = NSColor(hex: 0xFF6347) - - /// SwifterSwift: hex #40E0D0 - public static let turquoise = NSColor(hex: 0x40E0D0) - - /// SwifterSwift: hex #EE82EE - public static let violet = NSColor(hex: 0xEE82EE) - - /// SwifterSwift: hex #F5DEB3 - public static let wheat = NSColor(hex: 0xF5DEB3) - - /// SwifterSwift: hex #FFFFFF - public static let white = NSColor(hex: 0xFFFFFF) - - /// SwifterSwift: hex #F5F5F5 - public static let whiteSmoke = NSColor(hex: 0xF5F5F5) - - /// SwifterSwift: hex #FFFF00 - public static let yellow = NSColor(hex: 0xFFFF00) - - /// SwifterSwift: hex #9ACD32 - public static let yellowGreen = NSColor(hex: 0x9ACD32) - - } - -} - -// MARK: - Flat UI colors -public extension NSColor { - - /// SwifterSwift: Flat UI colors - public struct FlatUI { - // http://flatuicolors.com. - - /// SwifterSwift: hex #1ABC9C - public static let turquoise = NSColor(hex: 0x1abc9c) - - /// SwifterSwift: hex #16A085 - public static let greenSea = NSColor(hex: 0x16a085) - - /// SwifterSwift: hex #2ECC71 - public static let emerald = NSColor(hex: 0x2ecc71) - - /// SwifterSwift: hex #27AE60 - public static let nephritis = NSColor(hex: 0x27ae60) - - /// SwifterSwift: hex #3498DB - public static let peterRiver = NSColor(hex: 0x3498db) - - /// SwifterSwift: hex #2980B9 - public static let belizeHole = NSColor(hex: 0x2980b9) - - /// SwifterSwift: hex #9B59B6 - public static let amethyst = NSColor(hex: 0x9b59b6) - - /// SwifterSwift: hex #8E44AD - public static let wisteria = NSColor(hex: 0x8e44ad) - - /// SwifterSwift: hex #34495E - public static let wetAsphalt = NSColor(hex: 0x34495e) - - /// SwifterSwift: hex #2C3E50 - public static let midnightBlue = NSColor(hex: 0x2c3e50) - - /// SwifterSwift: hex #F1C40F - public static let sunFlower = NSColor(hex: 0xf1c40f) - - /// SwifterSwift: hex #F39C12 - public static let flatOrange = NSColor(hex: 0xf39c12) - - /// SwifterSwift: hex #E67E22 - public static let carrot = NSColor(hex: 0xe67e22) - - /// SwifterSwift: hex #D35400 - public static let pumkin = NSColor(hex: 0xd35400) - - /// SwifterSwift: hex #E74C3C - public static let alizarin = NSColor(hex: 0xe74c3c) - - /// SwifterSwift: hex #C0392B - public static let pomegranate = NSColor(hex: 0xc0392b) - - /// SwifterSwift: hex #ECF0F1 - public static let clouds = NSColor(hex: 0xecf0f1) - - /// SwifterSwift: hex #BDC3C7 - public static let silver = NSColor(hex: 0xbdc3c7) - - /// SwifterSwift: hex #7F8C8D - public static let asbestos = NSColor(hex: 0x7f8c8d) - - /// SwifterSwift: hex #95A5A6 - public static let concerte = NSColor(hex: 0x95a5a6) - } -} - -#endif diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift new file mode 100644 index 000000000..75fed3868 --- /dev/null +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -0,0 +1,1620 @@ +// +// ColorExtensions.swift +// SwifterSwift-iOS +// +// Created by Omar Albeik on 9/27/17. +// + +#if os(macOS) + import Cocoa + public typealias Color = NSColor +#else + import UIKit + public typealias Color = UIColor +#endif + +#if !os(watchOS) + import CoreImage +#endif + +// MARK: - Properties +public extension Color { + + /// SwifterSwift: Random color. + public static var random: Color { + let r = Int(arc4random_uniform(255)) + let g = Int(arc4random_uniform(255)) + let b = Int(arc4random_uniform(255)) + #if os(macOS) + return NSColor(red: r, green: g, blue: b)! + #else + return UIColor(red: r, green: g, blue: b)! + #endif + } + + /// SwifterSwift: RGB components for a UIColor + /// + /// UIColor.red.rgbComponenets.red -> 255 + /// UIColor.green.rgbComponenets.green -> 255 + /// UIColor.blue.rgbComponenets.blue -> 255 + /// + public var rgbComponenets: (red: Int, green: Int, blue: Int) { + var components: [CGFloat] { + let c = cgColor.components! + if c.count == 4 { + return c + } + return [c[0], c[0], c[0], c[1]] + } + let r = components[0] + let g = components[1] + let b = components[2] + return (red: Int(r * 255.0), green: Int(g * 255.0), blue: Int(b * 255.0)) + } + + /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). + public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { + var hue: CGFloat = 0.0 + var sat: CGFloat = 0.0 + var bri: CGFloat = 0.0 + var alpha: CGFloat = 0.0 + self.getHue(&hue, saturation: &sat, brightness: &bri, alpha: &alpha) + + return (hue:hue, saturation:sat, brightness:bri, alpha:alpha) + } + + /// SwifterSwift: Hexadecimal value string (read-only). + public var hexString: String { + let r = rgbComponenets.red + let g = rgbComponenets.green + let b = rgbComponenets.blue + return String(format: "#%02X%02X%02X", r, g, b) + } + + /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). + public var shortHexString: String? { + let string = hexString.replacingOccurrences(of: "#", with: "") + let chrs = Array(string.characters) + guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return nil } + return "#\(chrs[0])\(chrs[2])\(chrs[4])" + } + + /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). + public var shortHexOrHexString: String { + return shortHexString ?? hexString + } + + /// SwifterSwift: Alpha of UIColor (read-only). + public var alpha: CGFloat { + return cgColor.alpha + } + + #if !os(watchOS) + /// SwifterSwift: CoreImage.CIColor (read-only) + public var coreImageColor: CoreImage.CIColor? { + return CoreImage.CIColor(color: self) + } + #endif + +} + +// MARK: - Initializers +public extension Color { + + /// SwifterSwift: Create NSColor from RGB values with optional transparency. + /// + /// - Parameters: + /// - red: red component. + /// - green: green component. + /// - blue: blue component. + /// - transparency: optional transparency value (default is 1). + public convenience init?(red: Int, green: Int, blue: Int, transparency: CGFloat = 1) { + guard red >= 0 && red <= 255 else { return nil } + guard green >= 0 && green <= 255 else { return nil } + guard blue >= 0 && blue <= 255 else { return nil } + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + #if os(macOS) + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) + #else + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) + #endif + } + + /// SwifterSwift: Create NSColor from hexadecimal value with optional transparency. + /// + /// - Parameters: + /// - hex: hex Int (example: 0xDECEB5). + /// - transparency: optional transparency value (default is 1). + public convenience init?(hex: Int, transparency: CGFloat = 1) { + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + let red = (hex >> 16) & 0xff + let green = (hex >> 8) & 0xff + let blue = hex & 0xff + self.init(red: red, green: green, blue: blue, transparency: trans) + } + + /// SwifterSwift: Create UIColor from hexadecimal string with optional transparency (if applicable). + /// + /// - Parameters: + /// - hexString: hexadecimal string (examples: EDE7F6, 0xEDE7F6, #EDE7F6, #0ff, 0xF0F, ..). + /// - transparency: optional transparency value (default is 1). + public convenience init?(hexString: String, transparency: CGFloat = 1) { + var string = "" + if hexString.lowercased().hasPrefix("0x") { + string = hexString.replacingOccurrences(of: "0x", with: "") + } else if hexString.hasPrefix("#") { + string = hexString.replacingOccurrences(of: "#", with: "") + } else { + string = hexString + } + + if string.characters.count == 3 { // convert hex to 6 digit format if in short format + var str = "" + string.characters.forEach { str.append(String(repeating: String($0), count: 2)) } + string = str + } + + guard let hexValue = Int(string, radix: 16) else { return nil } + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + self.init(hex: Int(hexValue), transparency: trans) + } + +} + +// MARK: - Social +public extension Color { + + /// SwifterSwift: Brand identity color of popular social media platform. + public struct Social { + // https://www.lockedowndesign.com/social-media-colors/ + + /// red: 59, green: 89, blue: 152 + public static let facebook = Color(red: 59, green: 89, blue: 152)! + + /// red: 0, green: 182, blue: 241 + public static let twitter = Color(red: 0, green: 182, blue: 241)! + + /// red: 223, green: 74, blue: 50 + public static let googlePlus = Color(red: 223, green: 74, blue: 50)! + + /// red: 0, green: 123, blue: 182 + public static let linkedIn = Color(red: 0, green: 123, blue: 182)! + + /// red: 69, green: 187, blue: 255 + public static let vimeo = Color(red: 69, green: 187, blue: 255)! + + /// red: 179, green: 18, blue: 23 + public static let youtube = Color(red: 179, green: 18, blue: 23)! + + /// red: 195, green: 42, blue: 163 + public static let instagram = Color(red: 195, green: 42, blue: 163)! + + /// red: 203, green: 32, blue: 39 + public static let pinterest = Color(red: 203, green: 32, blue: 39)! + + /// red: 244, green: 0, blue: 131 + public static let flickr = Color(red: 244, green: 0, blue: 131)! + + /// red: 67, green: 2, blue: 151 + public static let yahoo = Color(red: 67, green: 2, blue: 151)! + + /// red: 67, green: 2, blue: 151 + public static let soundCloud = Color(red: 67, green: 2, blue: 151)! + + /// red: 44, green: 71, blue: 98 + public static let tumblr = Color(red: 44, green: 71, blue: 98)! + + /// red: 252, green: 69, blue: 117 + public static let foursquare = Color(red: 252, green: 69, blue: 117)! + + /// red: 255, green: 176, blue: 0 + public static let swarm = Color(red: 255, green: 176, blue: 0)! + + /// red: 234, green: 76, blue: 137 + public static let dribbble = Color(red: 234, green: 76, blue: 137)! + + /// red: 255, green: 87, blue: 0 + public static let reddit = Color(red: 255, green: 87, blue: 0)! + + /// red: 74, green: 93, blue: 78 + public static let devianArt = Color(red: 74, green: 93, blue: 78)! + + /// red: 238, green: 64, blue: 86 + public static let pocket = Color(red: 238, green: 64, blue: 86)! + + /// red: 170, green: 34, blue: 182 + public static let quora = Color(red: 170, green: 34, blue: 182)! + + /// red: 247, green: 146, blue: 30 + public static let slideShare = Color(red: 247, green: 146, blue: 30)! + + /// red: 0, green: 153, blue: 229 + public static let px500 = Color(red: 0, green: 153, blue: 229)! + + /// red: 223, green: 109, blue: 70 + public static let listly = Color(red: 223, green: 109, blue: 70)! + + /// red: 0, green: 180, blue: 137 + public static let vine = Color(red: 0, green: 180, blue: 137)! + + /// red: 0, green: 175, blue: 240 + public static let skype = Color(red: 0, green: 175, blue: 240)! + + /// red: 235, green: 73, blue: 36 + public static let stumbleUpon = Color(red: 235, green: 73, blue: 36)! + + /// red: 255, green: 252, blue: 0 + public static let snapchat = Color(red: 255, green: 252, blue: 0)! + } + +} + +// MARK: - Material colors +public extension Color { + + /// SwifterSwift: Google Material design colors palette. + public struct Material { + // https://material.google.com/style/color.html + + /// SwifterSwift: color red500 + public static let red = red500 + + /// SwifterSwift: hex #FFEBEE + public static let red50 = Color(hex: 0xFFEBEE)! + + /// SwifterSwift: hex #FFCDD2 + public static let red100 = Color(hex: 0xFFCDD2)! + + /// SwifterSwift: hex #EF9A9A + public static let red200 = Color(hex: 0xEF9A9A)! + + /// SwifterSwift: hex #E57373 + public static let red300 = Color(hex: 0xE57373)! + + /// SwifterSwift: hex #EF5350 + public static let red400 = Color(hex: 0xEF5350)! + + /// SwifterSwift: hex #F44336 + public static let red500 = Color(hex: 0xF44336)! + + /// SwifterSwift: hex #E53935 + public static let red600 = Color(hex: 0xE53935)! + + /// SwifterSwift: hex #D32F2F + public static let red700 = Color(hex: 0xD32F2F)! + + /// SwifterSwift: hex #C62828 + public static let red800 = Color(hex: 0xC62828)! + + /// SwifterSwift: hex #B71C1C + public static let red900 = Color(hex: 0xB71C1C)! + + /// SwifterSwift: hex #FF8A80 + public static let redA100 = Color(hex: 0xFF8A80)! + + /// SwifterSwift: hex #FF5252 + public static let redA200 = Color(hex: 0xFF5252)! + + /// SwifterSwift: hex #FF1744 + public static let redA400 = Color(hex: 0xFF1744)! + + /// SwifterSwift: hex #D50000 + public static let redA700 = Color(hex: 0xD50000)! + + /// SwifterSwift: color pink500 + public static let pink = pink500 + + /// SwifterSwift: hex #FCE4EC + public static let pink50 = Color(hex: 0xFCE4EC)! + + /// SwifterSwift: hex #F8BBD0 + public static let pink100 = Color(hex: 0xF8BBD0)! + + /// SwifterSwift: hex #F48FB1 + public static let pink200 = Color(hex: 0xF48FB1)! + + /// SwifterSwift: hex #F06292 + public static let pink300 = Color(hex: 0xF06292)! + + /// SwifterSwift: hex #EC407A + public static let pink400 = Color(hex: 0xEC407A)! + + /// SwifterSwift: hex #E91E63 + public static let pink500 = Color(hex: 0xE91E63)! + + /// SwifterSwift: hex #D81B60 + public static let pink600 = Color(hex: 0xD81B60)! + + /// SwifterSwift: hex #C2185B + public static let pink700 = Color(hex: 0xC2185B)! + + /// SwifterSwift: hex #AD1457 + public static let pink800 = Color(hex: 0xAD1457)! + + /// SwifterSwift: hex #880E4F + public static let pink900 = Color(hex: 0x880E4F)! + + /// SwifterSwift: hex #FF80AB + public static let pinkA100 = Color(hex: 0xFF80AB)! + + /// SwifterSwift: hex #FF4081 + public static let pinkA200 = Color(hex: 0xFF4081)! + + /// SwifterSwift: hex #F50057 + public static let pinkA400 = Color(hex: 0xF50057)! + + /// SwifterSwift: hex #C51162 + public static let pinkA700 = Color(hex: 0xC51162)! + + /// SwifterSwift: color purple500 + public static let purple = purple500 + + /// SwifterSwift: hex #F3E5F5 + public static let purple50 = Color(hex: 0xF3E5F5)! + + /// SwifterSwift: hex #E1BEE7 + public static let purple100 = Color(hex: 0xE1BEE7)! + + /// SwifterSwift: hex #CE93D8 + public static let purple200 = Color(hex: 0xCE93D8)! + + /// SwifterSwift: hex #BA68C8 + public static let purple300 = Color(hex: 0xBA68C8)! + + /// SwifterSwift: hex #AB47BC + public static let purple400 = Color(hex: 0xAB47BC)! + + /// SwifterSwift: hex #9C27B0 + public static let purple500 = Color(hex: 0x9C27B0)! + + /// SwifterSwift: hex #8E24AA + public static let purple600 = Color(hex: 0x8E24AA)! + + /// SwifterSwift: hex #7B1FA2 + public static let purple700 = Color(hex: 0x7B1FA2)! + + /// SwifterSwift: hex #6A1B9A + public static let purple800 = Color(hex: 0x6A1B9A)! + + /// SwifterSwift: hex #4A148C + public static let purple900 = Color(hex: 0x4A148C)! + + /// SwifterSwift: hex #EA80FC + public static let purpleA100 = Color(hex: 0xEA80FC)! + + /// SwifterSwift: hex #E040FB + public static let purpleA200 = Color(hex: 0xE040FB)! + + /// SwifterSwift: hex #D500F9 + public static let purpleA400 = Color(hex: 0xD500F9)! + + /// SwifterSwift: hex #AA00FF + public static let purpleA700 = Color(hex: 0xAA00FF)! + + /// SwifterSwift: color deepPurple500 + public static let deepPurple = deepPurple500 + + /// SwifterSwift: hex #EDE7F6 + public static let deepPurple50 = Color(hex: 0xEDE7F6)! + + /// SwifterSwift: hex #D1C4E9 + public static let deepPurple100 = Color(hex: 0xD1C4E9)! + + /// SwifterSwift: hex #B39DDB + public static let deepPurple200 = Color(hex: 0xB39DDB)! + + /// SwifterSwift: hex #9575CD + public static let deepPurple300 = Color(hex: 0x9575CD)! + + /// SwifterSwift: hex #7E57C2 + public static let deepPurple400 = Color(hex: 0x7E57C2)! + + /// SwifterSwift: hex #673AB7 + public static let deepPurple500 = Color(hex: 0x673AB7)! + + /// SwifterSwift: hex #5E35B1 + public static let deepPurple600 = Color(hex: 0x5E35B1)! + + /// SwifterSwift: hex #512DA8 + public static let deepPurple700 = Color(hex: 0x512DA8)! + + /// SwifterSwift: hex #4527A0 + public static let deepPurple800 = Color(hex: 0x4527A0)! + + /// SwifterSwift: hex #311B92 + public static let deepPurple900 = Color(hex: 0x311B92)! + + /// SwifterSwift: hex #B388FF + public static let deepPurpleA100 = Color(hex: 0xB388FF)! + + /// SwifterSwift: hex #7C4DFF + public static let deepPurpleA200 = Color(hex: 0x7C4DFF)! + + /// SwifterSwift: hex #651FFF + public static let deepPurpleA400 = Color(hex: 0x651FFF)! + + /// SwifterSwift: hex #6200EA + public static let deepPurpleA700 = Color(hex: 0x6200EA)! + + /// SwifterSwift: color indigo500 + public static let indigo = indigo500 + + /// SwifterSwift: hex #E8EAF6 + public static let indigo50 = Color(hex: 0xE8EAF6)! + + /// SwifterSwift: hex #C5CAE9 + public static let indigo100 = Color(hex: 0xC5CAE9)! + + /// SwifterSwift: hex #9FA8DA + public static let indigo200 = Color(hex: 0x9FA8DA)! + + /// SwifterSwift: hex #7986CB + public static let indigo300 = Color(hex: 0x7986CB)! + + /// SwifterSwift: hex #5C6BC0 + public static let indigo400 = Color(hex: 0x5C6BC0)! + + /// SwifterSwift: hex #3F51B5 + public static let indigo500 = Color(hex: 0x3F51B5)! + + /// SwifterSwift: hex #3949AB + public static let indigo600 = Color(hex: 0x3949AB)! + + /// SwifterSwift: hex #303F9F + public static let indigo700 = Color(hex: 0x303F9F)! + + /// SwifterSwift: hex #283593 + public static let indigo800 = Color(hex: 0x283593)! + + /// SwifterSwift: hex #1A237E + public static let indigo900 = Color(hex: 0x1A237E)! + + /// SwifterSwift: hex #8C9EFF + public static let indigoA100 = Color(hex: 0x8C9EFF)! + + /// SwifterSwift: hex #536DFE + public static let indigoA200 = Color(hex: 0x536DFE)! + + /// SwifterSwift: hex #3D5AFE + public static let indigoA400 = Color(hex: 0x3D5AFE)! + + /// SwifterSwift: hex #304FFE + public static let indigoA700 = Color(hex: 0x304FFE)! + + /// SwifterSwift: color blue500 + public static let blue = blue500 + + /// SwifterSwift: hex #E3F2FD + public static let blue50 = Color(hex: 0xE3F2FD)! + + /// SwifterSwift: hex #BBDEFB + public static let blue100 = Color(hex: 0xBBDEFB)! + + /// SwifterSwift: hex #90CAF9 + public static let blue200 = Color(hex: 0x90CAF9)! + + /// SwifterSwift: hex #64B5F6 + public static let blue300 = Color(hex: 0x64B5F6)! + + /// SwifterSwift: hex #42A5F5 + public static let blue400 = Color(hex: 0x42A5F5)! + + /// SwifterSwift: hex #2196F3 + public static let blue500 = Color(hex: 0x2196F3)! + + /// SwifterSwift: hex #1E88E5 + public static let blue600 = Color(hex: 0x1E88E5)! + + /// SwifterSwift: hex #1976D2 + public static let blue700 = Color(hex: 0x1976D2)! + + /// SwifterSwift: hex #1565C0 + public static let blue800 = Color(hex: 0x1565C0)! + + /// SwifterSwift: hex #0D47A1 + public static let blue900 = Color(hex: 0x0D47A1)! + + /// SwifterSwift: hex #82B1FF + public static let blueA100 = Color(hex: 0x82B1FF)! + + /// SwifterSwift: hex #448AFF + public static let blueA200 = Color(hex: 0x448AFF)! + + /// SwifterSwift: hex #2979FF + public static let blueA400 = Color(hex: 0x2979FF)! + + /// SwifterSwift: hex #2962FF + public static let blueA700 = Color(hex: 0x2962FF)! + + /// SwifterSwift: color lightBlue500 + public static let lightBlue = lightBlue500 + + /// SwifterSwift: hex #E1F5FE + public static let lightBlue50 = Color(hex: 0xE1F5FE)! + + /// SwifterSwift: hex #B3E5FC + public static let lightBlue100 = Color(hex: 0xB3E5FC)! + + /// SwifterSwift: hex #81D4FA + public static let lightBlue200 = Color(hex: 0x81D4FA)! + + /// SwifterSwift: hex #4FC3F7 + public static let lightBlue300 = Color(hex: 0x4FC3F7)! + + /// SwifterSwift: hex #29B6F6 + public static let lightBlue400 = Color(hex: 0x29B6F6)! + + /// SwifterSwift: hex #03A9F4 + public static let lightBlue500 = Color(hex: 0x03A9F4)! + + /// SwifterSwift: hex #039BE5 + public static let lightBlue600 = Color(hex: 0x039BE5)! + + /// SwifterSwift: hex #0288D1 + public static let lightBlue700 = Color(hex: 0x0288D1)! + + /// SwifterSwift: hex #0277BD + public static let lightBlue800 = Color(hex: 0x0277BD)! + + /// SwifterSwift: hex #01579B + public static let lightBlue900 = Color(hex: 0x01579B)! + + /// SwifterSwift: hex #80D8FF + public static let lightBlueA100 = Color(hex: 0x80D8FF)! + + /// SwifterSwift: hex #40C4FF + public static let lightBlueA200 = Color(hex: 0x40C4FF)! + + /// SwifterSwift: hex #00B0FF + public static let lightBlueA400 = Color(hex: 0x00B0FF)! + + /// SwifterSwift: hex #0091EA + public static let lightBlueA700 = Color(hex: 0x0091EA)! + + /// SwifterSwift: color cyan500 + public static let cyan = cyan500 + + /// SwifterSwift: hex #E0F7FA + public static let cyan50 = Color(hex: 0xE0F7FA)! + + /// SwifterSwift: hex #B2EBF2 + public static let cyan100 = Color(hex: 0xB2EBF2)! + + /// SwifterSwift: hex #80DEEA + public static let cyan200 = Color(hex: 0x80DEEA)! + + /// SwifterSwift: hex #4DD0E1 + public static let cyan300 = Color(hex: 0x4DD0E1)! + + /// SwifterSwift: hex #26C6DA + public static let cyan400 = Color(hex: 0x26C6DA)! + + /// SwifterSwift: hex #00BCD4 + public static let cyan500 = Color(hex: 0x00BCD4)! + + /// SwifterSwift: hex #00ACC1 + public static let cyan600 = Color(hex: 0x00ACC1)! + + /// SwifterSwift: hex #0097A7 + public static let cyan700 = Color(hex: 0x0097A7)! + + /// SwifterSwift: hex #00838F + public static let cyan800 = Color(hex: 0x00838F)! + + /// SwifterSwift: hex #006064 + public static let cyan900 = Color(hex: 0x006064)! + + /// SwifterSwift: hex #84FFFF + public static let cyanA100 = Color(hex: 0x84FFFF)! + + /// SwifterSwift: hex #18FFFF + public static let cyanA200 = Color(hex: 0x18FFFF)! + + /// SwifterSwift: hex #00E5FF + public static let cyanA400 = Color(hex: 0x00E5FF)! + + /// SwifterSwift: hex #00B8D4 + public static let cyanA700 = Color(hex: 0x00B8D4)! + + /// SwifterSwift: color teal500 + public static let teal = teal500 + + /// SwifterSwift: hex #E0F2F1 + public static let teal50 = Color(hex: 0xE0F2F1)! + + /// SwifterSwift: hex #B2DFDB + public static let teal100 = Color(hex: 0xB2DFDB)! + + /// SwifterSwift: hex #80CBC4 + public static let teal200 = Color(hex: 0x80CBC4)! + + /// SwifterSwift: hex #4DB6AC + public static let teal300 = Color(hex: 0x4DB6AC)! + + /// SwifterSwift: hex #26A69A + public static let teal400 = Color(hex: 0x26A69A)! + + /// SwifterSwift: hex #009688 + public static let teal500 = Color(hex: 0x009688)! + + /// SwifterSwift: hex #00897B + public static let teal600 = Color(hex: 0x00897B)! + + /// SwifterSwift: hex #00796B + public static let teal700 = Color(hex: 0x00796B)! + + /// SwifterSwift: hex #00695C + public static let teal800 = Color(hex: 0x00695C)! + + /// SwifterSwift: hex #004D40 + public static let teal900 = Color(hex: 0x004D40)! + + /// SwifterSwift: hex #A7FFEB + public static let tealA100 = Color(hex: 0xA7FFEB)! + + /// SwifterSwift: hex #64FFDA + public static let tealA200 = Color(hex: 0x64FFDA)! + + /// SwifterSwift: hex #1DE9B6 + public static let tealA400 = Color(hex: 0x1DE9B6)! + + /// SwifterSwift: hex #00BFA5 + public static let tealA700 = Color(hex: 0x00BFA5)! + + /// SwifterSwift: color green500 + public static let green = green500 + + /// SwifterSwift: hex #E8F5E9 + public static let green50 = Color(hex: 0xE8F5E9)! + + /// SwifterSwift: hex #C8E6C9 + public static let green100 = Color(hex: 0xC8E6C9)! + + /// SwifterSwift: hex #A5D6A7 + public static let green200 = Color(hex: 0xA5D6A7)! + + /// SwifterSwift: hex #81C784 + public static let green300 = Color(hex: 0x81C784)! + + /// SwifterSwift: hex #66BB6A + public static let green400 = Color(hex: 0x66BB6A)! + + /// SwifterSwift: hex #4CAF50 + public static let green500 = Color(hex: 0x4CAF50)! + + /// SwifterSwift: hex #43A047 + public static let green600 = Color(hex: 0x43A047)! + + /// SwifterSwift: hex #388E3C + public static let green700 = Color(hex: 0x388E3C)! + + /// SwifterSwift: hex #2E7D32 + public static let green800 = Color(hex: 0x2E7D32)! + + /// SwifterSwift: hex #1B5E20 + public static let green900 = Color(hex: 0x1B5E20)! + + /// SwifterSwift: hex #B9F6CA + public static let greenA100 = Color(hex: 0xB9F6CA)! + + /// SwifterSwift: hex #69F0AE + public static let greenA200 = Color(hex: 0x69F0AE)! + + /// SwifterSwift: hex #00E676 + public static let greenA400 = Color(hex: 0x00E676)! + + /// SwifterSwift: hex #00C853 + public static let greenA700 = Color(hex: 0x00C853)! + + /// SwifterSwift: color lightGreen500 + public static let lightGreen = lightGreen500 + + /// SwifterSwift: hex #F1F8E9 + public static let lightGreen50 = Color(hex: 0xF1F8E9)! + + /// SwifterSwift: hex #DCEDC8 + public static let lightGreen100 = Color(hex: 0xDCEDC8)! + + /// SwifterSwift: hex #C5E1A5 + public static let lightGreen200 = Color(hex: 0xC5E1A5)! + + /// SwifterSwift: hex #AED581 + public static let lightGreen300 = Color(hex: 0xAED581)! + + /// SwifterSwift: hex #9CCC65 + public static let lightGreen400 = Color(hex: 0x9CCC65)! + + /// SwifterSwift: hex #8BC34A + public static let lightGreen500 = Color(hex: 0x8BC34A)! + + /// SwifterSwift: hex #7CB342 + public static let lightGreen600 = Color(hex: 0x7CB342)! + + /// SwifterSwift: hex #689F38 + public static let lightGreen700 = Color(hex: 0x689F38)! + + /// SwifterSwift: hex #558B2F + public static let lightGreen800 = Color(hex: 0x558B2F)! + + /// SwifterSwift: hex #33691E + public static let lightGreen900 = Color(hex: 0x33691E)! + + /// SwifterSwift: hex #CCFF90 + public static let lightGreenA100 = Color(hex: 0xCCFF90)! + + /// SwifterSwift: hex #B2FF59 + public static let lightGreenA200 = Color(hex: 0xB2FF59)! + + /// SwifterSwift: hex #76FF03 + public static let lightGreenA400 = Color(hex: 0x76FF03)! + + /// SwifterSwift: hex #64DD17 + public static let lightGreenA700 = Color(hex: 0x64DD17)! + + /// SwifterSwift: color lime500 + public static let lime = lime500 + + /// SwifterSwift: hex #F9FBE7 + public static let lime50 = Color(hex: 0xF9FBE7)! + + /// SwifterSwift: hex #F0F4C3 + public static let lime100 = Color(hex: 0xF0F4C3)! + + /// SwifterSwift: hex #E6EE9C + public static let lime200 = Color(hex: 0xE6EE9C)! + + /// SwifterSwift: hex #DCE775 + public static let lime300 = Color(hex: 0xDCE775)! + + /// SwifterSwift: hex #D4E157 + public static let lime400 = Color(hex: 0xD4E157)! + + /// SwifterSwift: hex #CDDC39 + public static let lime500 = Color(hex: 0xCDDC39)! + + /// SwifterSwift: hex #C0CA33 + public static let lime600 = Color(hex: 0xC0CA33)! + + /// SwifterSwift: hex #AFB42B + public static let lime700 = Color(hex: 0xAFB42B)! + + /// SwifterSwift: hex #9E9D24 + public static let lime800 = Color(hex: 0x9E9D24)! + + /// SwifterSwift: hex #827717 + public static let lime900 = Color(hex: 0x827717)! + + /// SwifterSwift: hex #F4FF81 + public static let limeA100 = Color(hex: 0xF4FF81)! + + /// SwifterSwift: hex #EEFF41 + public static let limeA200 = Color(hex: 0xEEFF41)! + + /// SwifterSwift: hex #C6FF00 + public static let limeA400 = Color(hex: 0xC6FF00)! + + /// SwifterSwift: hex #AEEA00 + public static let limeA700 = Color(hex: 0xAEEA00)! + + /// SwifterSwift: color yellow500 + public static let yellow = yellow500 + + /// SwifterSwift: hex #FFFDE7 + public static let yellow50 = Color(hex: 0xFFFDE7)! + + /// SwifterSwift: hex #FFF9C4 + public static let yellow100 = Color(hex: 0xFFF9C4)! + + /// SwifterSwift: hex #FFF59D + public static let yellow200 = Color(hex: 0xFFF59D)! + + /// SwifterSwift: hex #FFF176 + public static let yellow300 = Color(hex: 0xFFF176)! + + /// SwifterSwift: hex #FFEE58 + public static let yellow400 = Color(hex: 0xFFEE58)! + + /// SwifterSwift: hex #FFEB3B + public static let yellow500 = Color(hex: 0xFFEB3B)! + + /// SwifterSwift: hex #FDD835 + public static let yellow600 = Color(hex: 0xFDD835)! + + /// SwifterSwift: hex #FBC02D + public static let yellow700 = Color(hex: 0xFBC02D)! + + /// SwifterSwift: hex #F9A825 + public static let yellow800 = Color(hex: 0xF9A825)! + + /// SwifterSwift: hex #F57F17 + public static let yellow900 = Color(hex: 0xF57F17)! + + /// SwifterSwift: hex #FFFF8D + public static let yellowA100 = Color(hex: 0xFFFF8D)! + + /// SwifterSwift: hex #FFFF00 + public static let yellowA200 = Color(hex: 0xFFFF00)! + + /// SwifterSwift: hex #FFEA00 + public static let yellowA400 = Color(hex: 0xFFEA00)! + + /// SwifterSwift: hex #FFD600 + public static let yellowA700 = Color(hex: 0xFFD600)! + + /// SwifterSwift: color amber500 + public static let amber = amber500 + + /// SwifterSwift: hex #FFF8E1 + public static let amber50 = Color(hex: 0xFFF8E1)! + + /// SwifterSwift: hex #FFECB3 + public static let amber100 = Color(hex: 0xFFECB3)! + + /// SwifterSwift: hex #FFE082 + public static let amber200 = Color(hex: 0xFFE082)! + + /// SwifterSwift: hex #FFD54F + public static let amber300 = Color(hex: 0xFFD54F)! + + /// SwifterSwift: hex #FFCA28 + public static let amber400 = Color(hex: 0xFFCA28)! + + /// SwifterSwift: hex #FFC107 + public static let amber500 = Color(hex: 0xFFC107)! + + /// SwifterSwift: hex #FFB300 + public static let amber600 = Color(hex: 0xFFB300)! + + /// SwifterSwift: hex #FFA000 + public static let amber700 = Color(hex: 0xFFA000)! + + /// SwifterSwift: hex #FF8F00 + public static let amber800 = Color(hex: 0xFF8F00)! + + /// SwifterSwift: hex #FF6F00 + public static let amber900 = Color(hex: 0xFF6F00)! + + /// SwifterSwift: hex #FFE57F + public static let amberA100 = Color(hex: 0xFFE57F)! + + /// SwifterSwift: hex #FFD740 + public static let amberA200 = Color(hex: 0xFFD740)! + + /// SwifterSwift: hex #FFC400 + public static let amberA400 = Color(hex: 0xFFC400)! + + /// SwifterSwift: hex #FFAB00 + public static let amberA700 = Color(hex: 0xFFAB00)! + + /// SwifterSwift: color orange500 + public static let orange = orange500 + + /// SwifterSwift: hex #FFF3E0 + public static let orange50 = Color(hex: 0xFFF3E0)! + + /// SwifterSwift: hex #FFE0B2 + public static let orange100 = Color(hex: 0xFFE0B2)! + + /// SwifterSwift: hex #FFCC80 + public static let orange200 = Color(hex: 0xFFCC80)! + + /// SwifterSwift: hex #FFB74D + public static let orange300 = Color(hex: 0xFFB74D)! + + /// SwifterSwift: hex #FFA726 + public static let orange400 = Color(hex: 0xFFA726)! + + /// SwifterSwift: hex #FF9800 + public static let orange500 = Color(hex: 0xFF9800)! + + /// SwifterSwift: hex #FB8C00 + public static let orange600 = Color(hex: 0xFB8C00)! + + /// SwifterSwift: hex #F57C00 + public static let orange700 = Color(hex: 0xF57C00)! + + /// SwifterSwift: hex #EF6C00 + public static let orange800 = Color(hex: 0xEF6C00)! + + /// SwifterSwift: hex #E65100 + public static let orange900 = Color(hex: 0xE65100)! + + /// SwifterSwift: hex #FFD180 + public static let orangeA100 = Color(hex: 0xFFD180)! + + /// SwifterSwift: hex #FFAB40 + public static let orangeA200 = Color(hex: 0xFFAB40)! + + /// SwifterSwift: hex #FF9100 + public static let orangeA400 = Color(hex: 0xFF9100)! + + /// SwifterSwift: hex #FF6D00 + public static let orangeA700 = Color(hex: 0xFF6D00)! + + /// SwifterSwift: color deepOrange500 + public static let deepOrange = deepOrange500 + + /// SwifterSwift: hex #FBE9E7 + public static let deepOrange50 = Color(hex: 0xFBE9E7)! + + /// SwifterSwift: hex #FFCCBC + public static let deepOrange100 = Color(hex: 0xFFCCBC)! + + /// SwifterSwift: hex #FFAB91 + public static let deepOrange200 = Color(hex: 0xFFAB91)! + + /// SwifterSwift: hex #FF8A65 + public static let deepOrange300 = Color(hex: 0xFF8A65)! + + /// SwifterSwift: hex #FF7043 + public static let deepOrange400 = Color(hex: 0xFF7043)! + + /// SwifterSwift: hex #FF5722 + public static let deepOrange500 = Color(hex: 0xFF5722)! + + /// SwifterSwift: hex #F4511E + public static let deepOrange600 = Color(hex: 0xF4511E)! + + /// SwifterSwift: hex #E64A19 + public static let deepOrange700 = Color(hex: 0xE64A19)! + + /// SwifterSwift: hex #D84315 + public static let deepOrange800 = Color(hex: 0xD84315)! + + /// SwifterSwift: hex #BF360C + public static let deepOrange900 = Color(hex: 0xBF360C)! + + /// SwifterSwift: hex #FF9E80 + public static let deepOrangeA100 = Color(hex: 0xFF9E80)! + + /// SwifterSwift: hex #FF6E40 + public static let deepOrangeA200 = Color(hex: 0xFF6E40)! + + /// SwifterSwift: hex #FF3D00 + public static let deepOrangeA400 = Color(hex: 0xFF3D00)! + + /// SwifterSwift: hex #DD2C00 + public static let deepOrangeA700 = Color(hex: 0xDD2C00)! + + /// SwifterSwift: color brown500 + public static let brown = brown500 + + /// SwifterSwift: hex #EFEBE9 + public static let brown50 = Color(hex: 0xEFEBE9)! + + /// SwifterSwift: hex #D7CCC8 + public static let brown100 = Color(hex: 0xD7CCC8)! + + /// SwifterSwift: hex #BCAAA4 + public static let brown200 = Color(hex: 0xBCAAA4)! + + /// SwifterSwift: hex #A1887F + public static let brown300 = Color(hex: 0xA1887F)! + + /// SwifterSwift: hex #8D6E63 + public static let brown400 = Color(hex: 0x8D6E63)! + + /// SwifterSwift: hex #795548 + public static let brown500 = Color(hex: 0x795548)! + + /// SwifterSwift: hex #6D4C41 + public static let brown600 = Color(hex: 0x6D4C41)! + + /// SwifterSwift: hex #5D4037 + public static let brown700 = Color(hex: 0x5D4037)! + + /// SwifterSwift: hex #4E342E + public static let brown800 = Color(hex: 0x4E342E)! + + /// SwifterSwift: hex #3E2723 + public static let brown900 = Color(hex: 0x3E2723)! + + /// SwifterSwift: color grey500 + public static let grey = grey500 + + /// SwifterSwift: hex #FAFAFA + public static let grey50 = Color(hex: 0xFAFAFA)! + + /// SwifterSwift: hex #F5F5F5 + public static let grey100 = Color(hex: 0xF5F5F5)! + + /// SwifterSwift: hex #EEEEEE + public static let grey200 = Color(hex: 0xEEEEEE)! + + /// SwifterSwift: hex #E0E0E0 + public static let grey300 = Color(hex: 0xE0E0E0)! + + /// SwifterSwift: hex #BDBDBD + public static let grey400 = Color(hex: 0xBDBDBD)! + + /// SwifterSwift: hex #9E9E9E + public static let grey500 = Color(hex: 0x9E9E9E)! + + /// SwifterSwift: hex #757575 + public static let grey600 = Color(hex: 0x757575)! + + /// SwifterSwift: hex #616161 + public static let grey700 = Color(hex: 0x616161)! + + /// SwifterSwift: hex #424242 + public static let grey800 = Color(hex: 0x424242)! + + /// SwifterSwift: hex #212121 + public static let grey900 = Color(hex: 0x212121)! + + /// SwifterSwift: color blueGrey500 + public static let blueGrey = blueGrey500 + + /// SwifterSwift: hex #ECEFF1 + public static let blueGrey50 = Color(hex: 0xECEFF1)! + + /// SwifterSwift: hex #CFD8DC + public static let blueGrey100 = Color(hex: 0xCFD8DC)! + + /// SwifterSwift: hex #B0BEC5 + public static let blueGrey200 = Color(hex: 0xB0BEC5)! + + /// SwifterSwift: hex #90A4AE + public static let blueGrey300 = Color(hex: 0x90A4AE)! + + /// SwifterSwift: hex #78909C + public static let blueGrey400 = Color(hex: 0x78909C)! + + /// SwifterSwift: hex #607D8B + public static let blueGrey500 = Color(hex: 0x607D8B)! + + /// SwifterSwift: hex #546E7A + public static let blueGrey600 = Color(hex: 0x546E7A)! + + /// SwifterSwift: hex #455A64 + public static let blueGrey700 = Color(hex: 0x455A64)! + + /// SwifterSwift: hex #37474F + public static let blueGrey800 = Color(hex: 0x37474F)! + + /// SwifterSwift: hex #263238 + public static let blueGrey900 = Color(hex: 0x263238)! + + /// SwifterSwift: hex #000000 + public static let black = Color(hex: 0x000000)! + + /// SwifterSwift: hex #FFFFFF + public static let white = Color(hex: 0xFFFFFF)! + } + +} + +// MARK: - CSS colors +public extension Color { + + /// SwifterSwift: CSS colors. + public struct CSS { + // http://www.w3schools.com/colors/colors_names.asp + + /// SwifterSwift: hex #F0F8FF + public static let aliceBlue = Color(hex: 0xF0F8FF)! + + /// SwifterSwift: hex #FAEBD7 + public static let antiqueWhite = Color(hex: 0xFAEBD7)! + + /// SwifterSwift: hex #00FFFF + public static let aqua = Color(hex: 0x00FFFF)! + + /// SwifterSwift: hex #7FFFD4 + public static let aquamarine = Color(hex: 0x7FFFD4)! + + /// SwifterSwift: hex #F0FFFF + public static let azure = Color(hex: 0xF0FFFF)! + + /// SwifterSwift: hex #F5F5DC + public static let beige = Color(hex: 0xF5F5DC)! + + /// SwifterSwift: hex #FFE4C4 + public static let bisque = Color(hex: 0xFFE4C4)! + + /// SwifterSwift: hex #000000 + public static let black = Color(hex: 0x000000)! + + /// SwifterSwift: hex #FFEBCD + public static let blanchedAlmond = Color(hex: 0xFFEBCD)! + + /// SwifterSwift: hex #0000FF + public static let blue = Color(hex: 0x0000FF)! + + /// SwifterSwift: hex #8A2BE2 + public static let blueViolet = Color(hex: 0x8A2BE2)! + + /// SwifterSwift: hex #A52A2A + public static let brown = Color(hex: 0xA52A2A)! + + /// SwifterSwift: hex #DEB887 + public static let burlyWood = Color(hex: 0xDEB887)! + + /// SwifterSwift: hex #5F9EA0 + public static let cadetBlue = Color(hex: 0x5F9EA0)! + + /// SwifterSwift: hex #7FFF00 + public static let chartreuse = Color(hex: 0x7FFF00)! + + /// SwifterSwift: hex #D2691E + public static let chocolate = Color(hex: 0xD2691E)! + + /// SwifterSwift: hex #FF7F50 + public static let coral = Color(hex: 0xFF7F50)! + + /// SwifterSwift: hex #6495ED + public static let cornflowerBlue = Color(hex: 0x6495ED)! + + /// SwifterSwift: hex #FFF8DC + public static let cornsilk = Color(hex: 0xFFF8DC)! + + /// SwifterSwift: hex #DC143C + public static let crimson = Color(hex: 0xDC143C)! + + /// SwifterSwift: hex #00FFFF + public static let cyan = Color(hex: 0x00FFFF)! + + /// SwifterSwift: hex #00008B + public static let darkBlue = Color(hex: 0x00008B)! + + /// SwifterSwift: hex #008B8B + public static let darkCyan = Color(hex: 0x008B8B)! + + /// SwifterSwift: hex #B8860B + public static let darkGoldenRod = Color(hex: 0xB8860B)! + + /// SwifterSwift: hex #A9A9A9 + public static let darkGray = Color(hex: 0xA9A9A9)! + + /// SwifterSwift: hex #A9A9A9 + public static let darkGrey = Color(hex: 0xA9A9A9)! + + /// SwifterSwift: hex #006400 + public static let darkGreen = Color(hex: 0x006400)! + + /// SwifterSwift: hex #BDB76B + public static let darkKhaki = Color(hex: 0xBDB76B)! + + /// SwifterSwift: hex #8B008B + public static let darkMagenta = Color(hex: 0x8B008B)! + + /// SwifterSwift: hex #556B2F + public static let darkOliveGreen = Color(hex: 0x556B2F)! + + /// SwifterSwift: hex #FF8C00 + public static let darkOrange = Color(hex: 0xFF8C00)! + + /// SwifterSwift: hex #9932CC + public static let darkOrchid = Color(hex: 0x9932CC)! + + /// SwifterSwift: hex #8B0000 + public static let darkRed = Color(hex: 0x8B0000)! + + /// SwifterSwift: hex #E9967A + public static let darkSalmon = Color(hex: 0xE9967A)! + + /// SwifterSwift: hex #8FBC8F + public static let darkSeaGreen = Color(hex: 0x8FBC8F)! + + /// SwifterSwift: hex #483D8B + public static let darkSlateBlue = Color(hex: 0x483D8B)! + + /// SwifterSwift: hex #2F4F4F + public static let darkSlateGray = Color(hex: 0x2F4F4F)! + + /// SwifterSwift: hex #2F4F4F + public static let darkSlateGrey = Color(hex: 0x2F4F4F)! + + /// SwifterSwift: hex #00CED1 + public static let darkTurquoise = Color(hex: 0x00CED1)! + + /// SwifterSwift: hex #9400D3 + public static let darkViolet = Color(hex: 0x9400D3)! + + /// SwifterSwift: hex #FF1493 + public static let deepPink = Color(hex: 0xFF1493)! + + /// SwifterSwift: hex #00BFFF + public static let deepSkyBlue = Color(hex: 0x00BFFF)! + + /// SwifterSwift: hex #696969 + public static let dimGray = Color(hex: 0x696969)! + + /// SwifterSwift: hex #696969 + public static let dimGrey = Color(hex: 0x696969)! + + /// SwifterSwift: hex #1E90FF + public static let dodgerBlue = Color(hex: 0x1E90FF)! + + /// SwifterSwift: hex #B22222 + public static let fireBrick = Color(hex: 0xB22222)! + + /// SwifterSwift: hex #FFFAF0 + public static let floralWhite = Color(hex: 0xFFFAF0)! + + /// SwifterSwift: hex #228B22 + public static let forestGreen = Color(hex: 0x228B22)! + + /// SwifterSwift: hex #FF00FF + public static let fuchsia = Color(hex: 0xFF00FF)! + + /// SwifterSwift: hex #DCDCDC + public static let gainsboro = Color(hex: 0xDCDCDC)! + + /// SwifterSwift: hex #F8F8FF + public static let ghostWhite = Color(hex: 0xF8F8FF)! + + /// SwifterSwift: hex #FFD700 + public static let gold = Color(hex: 0xFFD700)! + + /// SwifterSwift: hex #DAA520 + public static let goldenRod = Color(hex: 0xDAA520)! + + /// SwifterSwift: hex #808080 + public static let gray = Color(hex: 0x808080)! + + /// SwifterSwift: hex #808080 + public static let grey = Color(hex: 0x808080)! + + /// SwifterSwift: hex #008000 + public static let green = Color(hex: 0x008000)! + + /// SwifterSwift: hex #ADFF2F + public static let greenYellow = Color(hex: 0xADFF2F)! + + /// SwifterSwift: hex #F0FFF0 + public static let honeyDew = Color(hex: 0xF0FFF0)! + + /// SwifterSwift: hex #FF69B4 + public static let hotPink = Color(hex: 0xFF69B4)! + + /// SwifterSwift: hex #CD5C5C + public static let indianRed = Color(hex: 0xCD5C5C)! + + /// SwifterSwift: hex #4B0082 + public static let indigo = Color(hex: 0x4B0082)! + + /// SwifterSwift: hex #FFFFF0 + public static let ivory = Color(hex: 0xFFFFF0)! + + /// SwifterSwift: hex #F0E68C + public static let khaki = Color(hex: 0xF0E68C)! + + /// SwifterSwift: hex #E6E6FA + public static let lavender = Color(hex: 0xE6E6FA)! + + /// SwifterSwift: hex #FFF0F5 + public static let lavenderBlush = Color(hex: 0xFFF0F5)! + + /// SwifterSwift: hex #7CFC00 + public static let lawnGreen = Color(hex: 0x7CFC00)! + + /// SwifterSwift: hex #FFFACD + public static let lemonChiffon = Color(hex: 0xFFFACD)! + + /// SwifterSwift: hex #ADD8E6 + public static let lightBlue = Color(hex: 0xADD8E6)! + + /// SwifterSwift: hex #F08080 + public static let lightCoral = Color(hex: 0xF08080)! + + /// SwifterSwift: hex #E0FFFF + public static let lightCyan = Color(hex: 0xE0FFFF)! + + /// SwifterSwift: hex #FAFAD2 + public static let lightGoldenRodYellow = Color(hex: 0xFAFAD2)! + + /// SwifterSwift: hex #D3D3D3 + public static let lightGray = Color(hex: 0xD3D3D3)! + + /// SwifterSwift: hex #D3D3D3 + public static let lightGrey = Color(hex: 0xD3D3D3)! + + /// SwifterSwift: hex #90EE90 + public static let lightGreen = Color(hex: 0x90EE90)! + + /// SwifterSwift: hex #FFB6C1 + public static let lightPink = Color(hex: 0xFFB6C1)! + + /// SwifterSwift: hex #FFA07A + public static let lightSalmon = Color(hex: 0xFFA07A)! + + /// SwifterSwift: hex #20B2AA + public static let lightSeaGreen = Color(hex: 0x20B2AA)! + + /// SwifterSwift: hex #87CEFA + public static let lightSkyBlue = Color(hex: 0x87CEFA)! + + /// SwifterSwift: hex #778899 + public static let lightSlateGray = Color(hex: 0x778899)! + + /// SwifterSwift: hex #778899 + public static let lightSlateGrey = Color(hex: 0x778899)! + + /// SwifterSwift: hex #B0C4DE + public static let lightSteelBlue = Color(hex: 0xB0C4DE)! + + /// SwifterSwift: hex #FFFFE0 + public static let lightYellow = Color(hex: 0xFFFFE0)! + + /// SwifterSwift: hex #00FF00 + public static let lime = Color(hex: 0x00FF00)! + + /// SwifterSwift: hex #32CD32 + public static let limeGreen = Color(hex: 0x32CD32)! + + /// SwifterSwift: hex #FAF0E6 + public static let linen = Color(hex: 0xFAF0E6)! + + /// SwifterSwift: hex #FF00FF + public static let magenta = Color(hex: 0xFF00FF)! + + /// SwifterSwift: hex #800000 + public static let maroon = Color(hex: 0x800000)! + + /// SwifterSwift: hex #66CDAA + public static let mediumAquaMarine = Color(hex: 0x66CDAA)! + + /// SwifterSwift: hex #0000CD + public static let mediumBlue = Color(hex: 0x0000CD)! + + /// SwifterSwift: hex #BA55D3 + public static let mediumOrchid = Color(hex: 0xBA55D3)! + + /// SwifterSwift: hex #9370DB + public static let mediumPurple = Color(hex: 0x9370DB)! + + /// SwifterSwift: hex #3CB371 + public static let mediumSeaGreen = Color(hex: 0x3CB371)! + + /// SwifterSwift: hex #7B68EE + public static let mediumSlateBlue = Color(hex: 0x7B68EE)! + + /// SwifterSwift: hex #00FA9A + public static let mediumSpringGreen = Color(hex: 0x00FA9A)! + + /// SwifterSwift: hex #48D1CC + public static let mediumTurquoise = Color(hex: 0x48D1CC)! + + /// SwifterSwift: hex #C71585 + public static let mediumVioletRed = Color(hex: 0xC71585)! + + /// SwifterSwift: hex #191970 + public static let midnightBlue = Color(hex: 0x191970)! + + /// SwifterSwift: hex #F5FFFA + public static let mintCream = Color(hex: 0xF5FFFA)! + + /// SwifterSwift: hex #FFE4E1 + public static let mistyRose = Color(hex: 0xFFE4E1)! + + /// SwifterSwift: hex #FFE4B5 + public static let moccasin = Color(hex: 0xFFE4B5)! + + /// SwifterSwift: hex #FFDEAD + public static let navajoWhite = Color(hex: 0xFFDEAD)! + + /// SwifterSwift: hex #000080 + public static let navy = Color(hex: 0x000080)! + + /// SwifterSwift: hex #FDF5E6 + public static let oldLace = Color(hex: 0xFDF5E6)! + + /// SwifterSwift: hex #808000 + public static let olive = Color(hex: 0x808000)! + + /// SwifterSwift: hex #6B8E23 + public static let oliveDrab = Color(hex: 0x6B8E23)! + + /// SwifterSwift: hex #FFA500 + public static let orange = Color(hex: 0xFFA500)! + + /// SwifterSwift: hex #FF4500 + public static let orangeRed = Color(hex: 0xFF4500)! + + /// SwifterSwift: hex #DA70D6 + public static let orchid = Color(hex: 0xDA70D6)! + + /// SwifterSwift: hex #EEE8AA + public static let paleGoldenRod = Color(hex: 0xEEE8AA)! + + /// SwifterSwift: hex #98FB98 + public static let paleGreen = Color(hex: 0x98FB98)! + + /// SwifterSwift: hex #AFEEEE + public static let paleTurquoise = Color(hex: 0xAFEEEE)! + + /// SwifterSwift: hex #DB7093 + public static let paleVioletRed = Color(hex: 0xDB7093)! + + /// SwifterSwift: hex #FFEFD5 + public static let papayaWhip = Color(hex: 0xFFEFD5)! + + /// SwifterSwift: hex #FFDAB9 + public static let peachPuff = Color(hex: 0xFFDAB9)! + + /// SwifterSwift: hex #CD853F + public static let peru = Color(hex: 0xCD853F)! + + /// SwifterSwift: hex #FFC0CB + public static let pink = Color(hex: 0xFFC0CB)! + + /// SwifterSwift: hex #DDA0DD + public static let plum = Color(hex: 0xDDA0DD)! + + /// SwifterSwift: hex #B0E0E6 + public static let powderBlue = Color(hex: 0xB0E0E6)! + + /// SwifterSwift: hex #800080 + public static let purple = Color(hex: 0x800080)! + + /// SwifterSwift: hex #663399 + public static let rebeccaPurple = Color(hex: 0x663399)! + + /// SwifterSwift: hex #FF0000 + public static let red = Color(hex: 0xFF0000)! + + /// SwifterSwift: hex #BC8F8F + public static let rosyBrown = Color(hex: 0xBC8F8F)! + + /// SwifterSwift: hex #4169E1 + public static let royalBlue = Color(hex: 0x4169E1)! + + /// SwifterSwift: hex #8B4513 + public static let saddleBrown = Color(hex: 0x8B4513)! + + /// SwifterSwift: hex #FA8072 + public static let salmon = Color(hex: 0xFA8072)! + + /// SwifterSwift: hex #F4A460 + public static let sandyBrown = Color(hex: 0xF4A460)! + + /// SwifterSwift: hex #2E8B57 + public static let seaGreen = Color(hex: 0x2E8B57)! + + /// SwifterSwift: hex #FFF5EE + public static let seaShell = Color(hex: 0xFFF5EE)! + + /// SwifterSwift: hex #A0522D + public static let sienna = Color(hex: 0xA0522D)! + + /// SwifterSwift: hex #C0C0C0 + public static let silver = Color(hex: 0xC0C0C0)! + + /// SwifterSwift: hex #87CEEB + public static let skyBlue = Color(hex: 0x87CEEB)! + + /// SwifterSwift: hex #6A5ACD + public static let slateBlue = Color(hex: 0x6A5ACD)! + + /// SwifterSwift: hex #708090 + public static let slateGray = Color(hex: 0x708090)! + + /// SwifterSwift: hex #708090 + public static let slateGrey = Color(hex: 0x708090)! + + /// SwifterSwift: hex #FFFAFA + public static let snow = Color(hex: 0xFFFAFA)! + + /// SwifterSwift: hex #00FF7F + public static let springGreen = Color(hex: 0x00FF7F)! + + /// SwifterSwift: hex #4682B4 + public static let steelBlue = Color(hex: 0x4682B4)! + + /// SwifterSwift: hex #D2B48C + public static let tan = Color(hex: 0xD2B48C)! + + /// SwifterSwift: hex #008080 + public static let teal = Color(hex: 0x008080)! + + /// SwifterSwift: hex #D8BFD8 + public static let thistle = Color(hex: 0xD8BFD8)! + + /// SwifterSwift: hex #FF6347 + public static let tomato = Color(hex: 0xFF6347)! + + /// SwifterSwift: hex #40E0D0 + public static let turquoise = Color(hex: 0x40E0D0)! + + /// SwifterSwift: hex #EE82EE + public static let violet = Color(hex: 0xEE82EE)! + + /// SwifterSwift: hex #F5DEB3 + public static let wheat = Color(hex: 0xF5DEB3)! + + /// SwifterSwift: hex #FFFFFF + public static let white = Color(hex: 0xFFFFFF)! + + /// SwifterSwift: hex #F5F5F5 + public static let whiteSmoke = Color(hex: 0xF5F5F5)! + + /// SwifterSwift: hex #FFFF00 + public static let yellow = Color(hex: 0xFFFF00)! + + /// SwifterSwift: hex #9ACD32 + public static let yellowGreen = Color(hex: 0x9ACD32)! + } + +} + +// MARK: - Flat UI colors +public extension Color { + + /// SwifterSwift: Flat UI colors + public struct FlatUI { + // http://flatuicolors.com. + + /// SwifterSwift: hex #1ABC9C + public static let turquoise = Color(hex: 0x1abc9c)! + + /// SwifterSwift: hex #16A085 + public static let greenSea = Color(hex: 0x16a085)! + + /// SwifterSwift: hex #2ECC71 + public static let emerald = Color(hex: 0x2ecc71)! + + /// SwifterSwift: hex #27AE60 + public static let nephritis = Color(hex: 0x27ae60)! + + /// SwifterSwift: hex #3498DB + public static let peterRiver = Color(hex: 0x3498db)! + + /// SwifterSwift: hex #2980B9 + public static let belizeHole = Color(hex: 0x2980b9)! + + /// SwifterSwift: hex #9B59B6 + public static let amethyst = Color(hex: 0x9b59b6)! + + /// SwifterSwift: hex #8E44AD + public static let wisteria = Color(hex: 0x8e44ad)! + + /// SwifterSwift: hex #34495E + public static let wetAsphalt = Color(hex: 0x34495e)! + + /// SwifterSwift: hex #2C3E50 + public static let midnightBlue = Color(hex: 0x2c3e50)! + + /// SwifterSwift: hex #F1C40F + public static let sunFlower = Color(hex: 0xf1c40f)! + + /// SwifterSwift: hex #F39C12 + public static let flatOrange = Color(hex: 0xf39c12)! + + /// SwifterSwift: hex #E67E22 + public static let carrot = Color(hex: 0xe67e22)! + + /// SwifterSwift: hex #D35400 + public static let pumkin = Color(hex: 0xd35400)! + + /// SwifterSwift: hex #E74C3C + public static let alizarin = Color(hex: 0xe74c3c)! + + /// SwifterSwift: hex #C0392B + public static let pomegranate = Color(hex: 0xc0392b)! + + /// SwifterSwift: hex #ECF0F1 + public static let clouds = Color(hex: 0xecf0f1)! + + /// SwifterSwift: hex #BDC3C7 + public static let silver = Color(hex: 0xbdc3c7)! + + /// SwifterSwift: hex #7F8C8D + public static let asbestos = Color(hex: 0x7f8c8d)! + + /// SwifterSwift: hex #95A5A6 + public static let concerte = Color(hex: 0x95a5a6)! + } + +} diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift index 3c9a14522..4f466ddf5 100755 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ b/Sources/Extensions/UIKit/UIColorExtensions.swift @@ -12,46 +12,6 @@ import UIKit // MARK: - Properties public extension UIColor { - /// SwifterSwift: RGB components for a UIColor - /// - /// UIColor.red.rgbComponenets.red -> 255 - /// UIColor.green.rgbComponenets.green -> 255 - /// UIColor.blue.rgbComponenets.blue -> 255 - /// - public var rgbComponenets: (red: Int, green: Int, blue: Int) { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - getRed(&red, green: &green, blue: &blue, alpha: nil) - - return (red: Int(red * 255.0), green: Int(green * 255.0), blue: Int(blue * 255.0)) - } - - /// SwifterSwift: Alpha of UIColor (read-only). - public var alpha: CGFloat { - var a: CGFloat = 0.0 - getRed(nil, green: nil, blue: nil, alpha: &a) - return a - } - - #if os(iOS) || os(tvOS) - /// SwifterSwift: CoreImage.CIColor (read-only). Only available on iOS and tvOS - public var coreImageColor: CoreImage.CIColor? { - return CoreImage.CIColor(color: self) // The resulting Core Image color, or nil - } - #endif - - /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). - public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { - var hue: CGFloat = 0.0 - var sat: CGFloat = 0.0 - var bri: CGFloat = 0.0 - var alpha: CGFloat = 0.0 - self.getHue(&hue, saturation: &sat, brightness: &bri, alpha: &alpha) - - return (hue:hue, saturation:sat, brightness:bri, alpha:alpha) - } - /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var uInt: UInt { var colorAsUInt32: UInt32 = 0 @@ -69,47 +29,11 @@ public extension UIColor { return UInt(colorAsUInt32) } - /// SwifterSwift: Hexadecimal value string (read-only). - public var hexString: String { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - - getRed(&red, green: &green, blue: &blue, alpha: &alpha) - let rgb: Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0 - return NSString(format:"#%06x", rgb).uppercased as String - } - - /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). - public var shortHexString: String? { - let string = hexString.replacingOccurrences(of: "#", with: "") - let chrs = Array(string.characters) - guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { - return nil - } - return "#" + "\(chrs[0])\(chrs[2])\(chrs[4])" - } - - /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). - public var shortHexOrHexString: String { - return shortHexString ?? hexString - } - /// SwifterSwift: Get color complementary (read-only, if applicable). public var complementary: UIColor? { return UIColor.init(complementaryFor: self) } - /// SwifterSwift: Random color. - public static var random: UIColor { - let r = Int(arc4random_uniform(255)) - let g = Int(arc4random_uniform(255)) - let b = Int(arc4random_uniform(255)) - return UIColor(red: r, green: g, blue: b)! - - } - } // MARK: - Methods @@ -142,73 +66,6 @@ public extension UIColor { // MARK: - Initializers public extension UIColor { - /// SwifterSwift: Create UIColor from hexadecimal value with optional transparency. - /// - /// - Parameters: - /// - hex: hex Int (example: 0xDECEB5). - /// - transparency: optional transparency value (default is 1). - public convenience init?(hex: Int, transparency: CGFloat = 1) { - var trans = transparency - if trans < 0 { trans = 0 } - if trans > 1 { trans = 1 } - - let red = (hex >> 16) & 0xff - let green = (hex >> 8) & 0xff - let blue = hex & 0xff - self.init(red: red, green: green, blue: blue, transparency: trans) - } - - /// SwifterSwift: Create UIColor from hexadecimal string with optional transparency (if applicable). - /// - /// - Parameters: - /// - hexString: hexadecimal string (examples: EDE7F6, 0xEDE7F6, #EDE7F6, #0ff, 0xF0F, ..). - /// - transparency: optional transparency value (default is 1). - public convenience init?(hexString: String, transparency: CGFloat = 1) { - var string = "" - if hexString.lowercased().hasPrefix("0x") { - string = hexString.replacingOccurrences(of: "0x", with: "") - } else if hexString.hasPrefix("#") { - string = hexString.replacingOccurrences(of: "#", with: "") - } else { - string = hexString - } - - if string.characters.count == 3 { // convert hex to 6 digit format if in short format - var str = "" - string.characters.forEach({ str.append(String(repeating: String($0), count: 2)) }) - string = str - } - - guard let hexValue = Int(string, radix: 16) else { - return nil - } - - self.init(hex: Int(hexValue), transparency: transparency) - } - - /// SwifterSwift: Create UIColor from RGB values with optional transparency. - /// - /// - Parameters: - /// - red: red component. - /// - green: green component. - /// - blue: blue component. - /// - transparency: optional transparency value (default is 1). - public convenience init?(red: Int, green: Int, blue: Int, transparency: CGFloat = 1) { - guard red >= 0 && red <= 255 else { - return nil - } - guard green >= 0 && green <= 255 else { - return nil - } - guard blue >= 0 && blue <= 255 else { - return nil - } - var trans = transparency - if trans < 0 { trans = 0 } - if trans > 1 { trans = 1 } - self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) - } - /// SwifterSwift: Create UIColor from a complementary of a UIColor (if applicable). /// /// - Parameter color: color of which opposite color is desired. @@ -238,1451 +95,4 @@ public extension UIColor { } } - -// MARK: - Social Colors -public extension UIColor { - - /// SwifterSwift: Brand identity color of popular social media platform. - public struct Social { - // https://www.lockedowndesign.com/social-media-colors/ - - /// SwifterSwift: red: 59, green: 89, blue: 152 - public static let facebook = UIColor(red: 59, green: 89, blue: 152) - - /// SwifterSwift: red: 0, green: 182, blue: 241 - public static let twitter = UIColor(red: 0, green: 182, blue: 241) - - /// SwifterSwift: red: 223, green: 74, blue: 50 - public static let googlePlus = UIColor(red: 223, green: 74, blue: 50) - - /// SwifterSwift: red: 0, green: 123, blue: 182 - public static let linkedIn = UIColor(red: 0, green: 123, blue: 182) - - /// SwifterSwift: red: 69, green: 187, blue: 255 - public static let vimeo = UIColor(red: 69, green: 187, blue: 255) - - /// SwifterSwift: red: 179, green: 18, blue: 23 - public static let youtube = UIColor(red: 179, green: 18, blue: 23) - - /// SwifterSwift: red: 195, green: 42, blue: 163 - public static let instagram = UIColor(red: 195, green: 42, blue: 163) - - /// SwifterSwift: red: 203, green: 32, blue: 39 - public static let pinterest = UIColor(red: 203, green: 32, blue: 39) - - /// SwifterSwift: red: 244, green: 0, blue: 131 - public static let flickr = UIColor(red: 244, green: 0, blue: 131) - - /// SwifterSwift: red: 67, green: 2, blue: 151 - public static let yahoo = UIColor(red: 67, green: 2, blue: 151) - - /// SwifterSwift: red: 67, green: 2, blue: 151 - public static let soundCloud = UIColor(red: 67, green: 2, blue: 151) - - /// SwifterSwift: red: 44, green: 71, blue: 98 - public static let tumblr = UIColor(red: 44, green: 71, blue: 98) - - /// SwifterSwift: red: 252, green: 69, blue: 117 - public static let foursquare = UIColor(red: 252, green: 69, blue: 117) - - /// SwifterSwift: red: 255, green: 176, blue: 0 - public static let swarm = UIColor(red: 255, green: 176, blue: 0) - - /// SwifterSwift: red: 234, green: 76, blue: 137 - public static let dribbble = UIColor(red: 234, green: 76, blue: 137) - - /// SwifterSwift: red: 255, green: 87, blue: 0 - public static let reddit = UIColor(red: 255, green: 87, blue: 0) - - /// SwifterSwift: red: 74, green: 93, blue: 78 - public static let devianArt = UIColor(red: 74, green: 93, blue: 78) - - /// SwifterSwift: red: 238, green: 64, blue: 86 - public static let pocket = UIColor(red: 238, green: 64, blue: 86) - - /// SwifterSwift: red: 170, green: 34, blue: 182 - public static let quora = UIColor(red: 170, green: 34, blue: 182) - - /// SwifterSwift: red: 247, green: 146, blue: 30 - public static let slideShare = UIColor(red: 247, green: 146, blue: 30) - - /// SwifterSwift: red: 0, green: 153, blue: 229 - public static let px500 = UIColor(red: 0, green: 153, blue: 229) - - /// SwifterSwift: red: 223, green: 109, blue: 70 - public static let listly = UIColor(red: 223, green: 109, blue: 70) - - /// SwifterSwift: red: 0, green: 180, blue: 137 - public static let vine = UIColor(red: 0, green: 180, blue: 137) - - /// SwifterSwift: red: 0, green: 175, blue: 240 - public static let skype = UIColor(red: 0, green: 175, blue: 240) - - /// SwifterSwift: red: 235, green: 73, blue: 36 - public static let stumbleUpon = UIColor(red: 235, green: 73, blue: 36) - - /// SwifterSwift: red: 255, green: 252, blue: 0 - public static let snapchat = UIColor(red: 255, green: 252, blue: 0) - - } -} - -// MARK: - Material colors -public extension UIColor { - - /// SwifterSwift: Google Material design colors palette. - public struct Material { - // https://material.google.com/style/color.html - - /// SwifterSwift: color red500 - public static let red = red500 - - /// SwifterSwift: hex #FFEBEE - public static let red50 = UIColor(hex: 0xFFEBEE) - - /// SwifterSwift: hex #FFCDD2 - public static let red100 = UIColor(hex: 0xFFCDD2) - - /// SwifterSwift: hex #EF9A9A - public static let red200 = UIColor(hex: 0xEF9A9A) - - /// SwifterSwift: hex #E57373 - public static let red300 = UIColor(hex: 0xE57373) - - /// SwifterSwift: hex #EF5350 - public static let red400 = UIColor(hex: 0xEF5350) - - /// SwifterSwift: hex #F44336 - public static let red500 = UIColor(hex: 0xF44336) - - /// SwifterSwift: hex #E53935 - public static let red600 = UIColor(hex: 0xE53935) - - /// SwifterSwift: hex #D32F2F - public static let red700 = UIColor(hex: 0xD32F2F) - - /// SwifterSwift: hex #C62828 - public static let red800 = UIColor(hex: 0xC62828) - - /// SwifterSwift: hex #B71C1C - public static let red900 = UIColor(hex: 0xB71C1C) - - /// SwifterSwift: hex #FF8A80 - public static let redA100 = UIColor(hex: 0xFF8A80) - - /// SwifterSwift: hex #FF5252 - public static let redA200 = UIColor(hex: 0xFF5252) - - /// SwifterSwift: hex #FF1744 - public static let redA400 = UIColor(hex: 0xFF1744) - - /// SwifterSwift: hex #D50000 - public static let redA700 = UIColor(hex: 0xD50000) - - /// SwifterSwift: color pink500 - public static let pink = pink500 - - /// SwifterSwift: hex #FCE4EC - public static let pink50 = UIColor(hex: 0xFCE4EC) - - /// SwifterSwift: hex #F8BBD0 - public static let pink100 = UIColor(hex: 0xF8BBD0) - - /// SwifterSwift: hex #F48FB1 - public static let pink200 = UIColor(hex: 0xF48FB1) - - /// SwifterSwift: hex #F06292 - public static let pink300 = UIColor(hex: 0xF06292) - - /// SwifterSwift: hex #EC407A - public static let pink400 = UIColor(hex: 0xEC407A) - - /// SwifterSwift: hex #E91E63 - public static let pink500 = UIColor(hex: 0xE91E63) - - /// SwifterSwift: hex #D81B60 - public static let pink600 = UIColor(hex: 0xD81B60) - - /// SwifterSwift: hex #C2185B - public static let pink700 = UIColor(hex: 0xC2185B) - - /// SwifterSwift: hex #AD1457 - public static let pink800 = UIColor(hex: 0xAD1457) - - /// SwifterSwift: hex #880E4F - public static let pink900 = UIColor(hex: 0x880E4F) - - /// SwifterSwift: hex #FF80AB - public static let pinkA100 = UIColor(hex: 0xFF80AB) - - /// SwifterSwift: hex #FF4081 - public static let pinkA200 = UIColor(hex: 0xFF4081) - - /// SwifterSwift: hex #F50057 - public static let pinkA400 = UIColor(hex: 0xF50057) - - /// SwifterSwift: hex #C51162 - public static let pinkA700 = UIColor(hex: 0xC51162) - - /// SwifterSwift: color purple500 - public static let purple = purple500 - - /// SwifterSwift: hex #F3E5F5 - public static let purple50 = UIColor(hex: 0xF3E5F5) - - /// SwifterSwift: hex #E1BEE7 - public static let purple100 = UIColor(hex: 0xE1BEE7) - - /// SwifterSwift: hex #CE93D8 - public static let purple200 = UIColor(hex: 0xCE93D8) - - /// SwifterSwift: hex #BA68C8 - public static let purple300 = UIColor(hex: 0xBA68C8) - - /// SwifterSwift: hex #AB47BC - public static let purple400 = UIColor(hex: 0xAB47BC) - - /// SwifterSwift: hex #9C27B0 - public static let purple500 = UIColor(hex: 0x9C27B0) - - /// SwifterSwift: hex #8E24AA - public static let purple600 = UIColor(hex: 0x8E24AA) - - /// SwifterSwift: hex #7B1FA2 - public static let purple700 = UIColor(hex: 0x7B1FA2) - - /// SwifterSwift: hex #6A1B9A - public static let purple800 = UIColor(hex: 0x6A1B9A) - - /// SwifterSwift: hex #4A148C - public static let purple900 = UIColor(hex: 0x4A148C) - - /// SwifterSwift: hex #EA80FC - public static let purpleA100 = UIColor(hex: 0xEA80FC) - - /// SwifterSwift: hex #E040FB - public static let purpleA200 = UIColor(hex: 0xE040FB) - - /// SwifterSwift: hex #D500F9 - public static let purpleA400 = UIColor(hex: 0xD500F9) - - /// SwifterSwift: hex #AA00FF - public static let purpleA700 = UIColor(hex: 0xAA00FF) - - /// SwifterSwift: color deepPurple500 - public static let deepPurple = deepPurple500 - - /// SwifterSwift: hex #EDE7F6 - public static let deepPurple50 = UIColor(hex: 0xEDE7F6) - - /// SwifterSwift: hex #D1C4E9 - public static let deepPurple100 = UIColor(hex: 0xD1C4E9) - - /// SwifterSwift: hex #B39DDB - public static let deepPurple200 = UIColor(hex: 0xB39DDB) - - /// SwifterSwift: hex #9575CD - public static let deepPurple300 = UIColor(hex: 0x9575CD) - - /// SwifterSwift: hex #7E57C2 - public static let deepPurple400 = UIColor(hex: 0x7E57C2) - - /// SwifterSwift: hex #673AB7 - public static let deepPurple500 = UIColor(hex: 0x673AB7) - - /// SwifterSwift: hex #5E35B1 - public static let deepPurple600 = UIColor(hex: 0x5E35B1) - - /// SwifterSwift: hex #512DA8 - public static let deepPurple700 = UIColor(hex: 0x512DA8) - - /// SwifterSwift: hex #4527A0 - public static let deepPurple800 = UIColor(hex: 0x4527A0) - - /// SwifterSwift: hex #311B92 - public static let deepPurple900 = UIColor(hex: 0x311B92) - - /// SwifterSwift: hex #B388FF - public static let deepPurpleA100 = UIColor(hex: 0xB388FF) - - /// SwifterSwift: hex #7C4DFF - public static let deepPurpleA200 = UIColor(hex: 0x7C4DFF) - - /// SwifterSwift: hex #651FFF - public static let deepPurpleA400 = UIColor(hex: 0x651FFF) - - /// SwifterSwift: hex #6200EA - public static let deepPurpleA700 = UIColor(hex: 0x6200EA) - - /// SwifterSwift: color indigo500 - public static let indigo = indigo500 - - /// SwifterSwift: hex #E8EAF6 - public static let indigo50 = UIColor(hex: 0xE8EAF6) - - /// SwifterSwift: hex #C5CAE9 - public static let indigo100 = UIColor(hex: 0xC5CAE9) - - /// SwifterSwift: hex #9FA8DA - public static let indigo200 = UIColor(hex: 0x9FA8DA) - - /// SwifterSwift: hex #7986CB - public static let indigo300 = UIColor(hex: 0x7986CB) - - /// SwifterSwift: hex #5C6BC0 - public static let indigo400 = UIColor(hex: 0x5C6BC0) - - /// SwifterSwift: hex #3F51B5 - public static let indigo500 = UIColor(hex: 0x3F51B5) - - /// SwifterSwift: hex #3949AB - public static let indigo600 = UIColor(hex: 0x3949AB) - - /// SwifterSwift: hex #303F9F - public static let indigo700 = UIColor(hex: 0x303F9F) - - /// SwifterSwift: hex #283593 - public static let indigo800 = UIColor(hex: 0x283593) - - /// SwifterSwift: hex #1A237E - public static let indigo900 = UIColor(hex: 0x1A237E) - - /// SwifterSwift: hex #8C9EFF - public static let indigoA100 = UIColor(hex: 0x8C9EFF) - - /// SwifterSwift: hex #536DFE - public static let indigoA200 = UIColor(hex: 0x536DFE) - - /// SwifterSwift: hex #3D5AFE - public static let indigoA400 = UIColor(hex: 0x3D5AFE) - - /// SwifterSwift: hex #304FFE - public static let indigoA700 = UIColor(hex: 0x304FFE) - - /// SwifterSwift: color blue500 - public static let blue = blue500 - - /// SwifterSwift: hex #E3F2FD - public static let blue50 = UIColor(hex: 0xE3F2FD) - - /// SwifterSwift: hex #BBDEFB - public static let blue100 = UIColor(hex: 0xBBDEFB) - - /// SwifterSwift: hex #90CAF9 - public static let blue200 = UIColor(hex: 0x90CAF9) - - /// SwifterSwift: hex #64B5F6 - public static let blue300 = UIColor(hex: 0x64B5F6) - - /// SwifterSwift: hex #42A5F5 - public static let blue400 = UIColor(hex: 0x42A5F5) - - /// SwifterSwift: hex #2196F3 - public static let blue500 = UIColor(hex: 0x2196F3) - - /// SwifterSwift: hex #1E88E5 - public static let blue600 = UIColor(hex: 0x1E88E5) - - /// SwifterSwift: hex #1976D2 - public static let blue700 = UIColor(hex: 0x1976D2) - - /// SwifterSwift: hex #1565C0 - public static let blue800 = UIColor(hex: 0x1565C0) - - /// SwifterSwift: hex #0D47A1 - public static let blue900 = UIColor(hex: 0x0D47A1) - - /// SwifterSwift: hex #82B1FF - public static let blueA100 = UIColor(hex: 0x82B1FF) - - /// SwifterSwift: hex #448AFF - public static let blueA200 = UIColor(hex: 0x448AFF) - - /// SwifterSwift: hex #2979FF - public static let blueA400 = UIColor(hex: 0x2979FF) - - /// SwifterSwift: hex #2962FF - public static let blueA700 = UIColor(hex: 0x2962FF) - - /// SwifterSwift: color lightBlue500 - public static let lightBlue = lightBlue500 - - /// SwifterSwift: hex #E1F5FE - public static let lightBlue50 = UIColor(hex: 0xE1F5FE) - - /// SwifterSwift: hex #B3E5FC - public static let lightBlue100 = UIColor(hex: 0xB3E5FC) - - /// SwifterSwift: hex #81D4FA - public static let lightBlue200 = UIColor(hex: 0x81D4FA) - - /// SwifterSwift: hex #4FC3F7 - public static let lightBlue300 = UIColor(hex: 0x4FC3F7) - - /// SwifterSwift: hex #29B6F6 - public static let lightBlue400 = UIColor(hex: 0x29B6F6) - - /// SwifterSwift: hex #03A9F4 - public static let lightBlue500 = UIColor(hex: 0x03A9F4) - - /// SwifterSwift: hex #039BE5 - public static let lightBlue600 = UIColor(hex: 0x039BE5) - - /// SwifterSwift: hex #0288D1 - public static let lightBlue700 = UIColor(hex: 0x0288D1) - - /// SwifterSwift: hex #0277BD - public static let lightBlue800 = UIColor(hex: 0x0277BD) - - /// SwifterSwift: hex #01579B - public static let lightBlue900 = UIColor(hex: 0x01579B) - - /// SwifterSwift: hex #80D8FF - public static let lightBlueA100 = UIColor(hex: 0x80D8FF) - - /// SwifterSwift: hex #40C4FF - public static let lightBlueA200 = UIColor(hex: 0x40C4FF) - - /// SwifterSwift: hex #00B0FF - public static let lightBlueA400 = UIColor(hex: 0x00B0FF) - - /// SwifterSwift: hex #0091EA - public static let lightBlueA700 = UIColor(hex: 0x0091EA) - - /// SwifterSwift: color cyan500 - public static let cyan = cyan500 - - /// SwifterSwift: hex #E0F7FA - public static let cyan50 = UIColor(hex: 0xE0F7FA) - - /// SwifterSwift: hex #B2EBF2 - public static let cyan100 = UIColor(hex: 0xB2EBF2) - - /// SwifterSwift: hex #80DEEA - public static let cyan200 = UIColor(hex: 0x80DEEA) - - /// SwifterSwift: hex #4DD0E1 - public static let cyan300 = UIColor(hex: 0x4DD0E1) - - /// SwifterSwift: hex #26C6DA - public static let cyan400 = UIColor(hex: 0x26C6DA) - - /// SwifterSwift: hex #00BCD4 - public static let cyan500 = UIColor(hex: 0x00BCD4) - - /// SwifterSwift: hex #00ACC1 - public static let cyan600 = UIColor(hex: 0x00ACC1) - - /// SwifterSwift: hex #0097A7 - public static let cyan700 = UIColor(hex: 0x0097A7) - - /// SwifterSwift: hex #00838F - public static let cyan800 = UIColor(hex: 0x00838F) - - /// SwifterSwift: hex #006064 - public static let cyan900 = UIColor(hex: 0x006064) - - /// SwifterSwift: hex #84FFFF - public static let cyanA100 = UIColor(hex: 0x84FFFF) - - /// SwifterSwift: hex #18FFFF - public static let cyanA200 = UIColor(hex: 0x18FFFF) - - /// SwifterSwift: hex #00E5FF - public static let cyanA400 = UIColor(hex: 0x00E5FF) - - /// SwifterSwift: hex #00B8D4 - public static let cyanA700 = UIColor(hex: 0x00B8D4) - - /// SwifterSwift: color teal500 - public static let teal = teal500 - - /// SwifterSwift: hex #E0F2F1 - public static let teal50 = UIColor(hex: 0xE0F2F1) - - /// SwifterSwift: hex #B2DFDB - public static let teal100 = UIColor(hex: 0xB2DFDB) - - /// SwifterSwift: hex #80CBC4 - public static let teal200 = UIColor(hex: 0x80CBC4) - - /// SwifterSwift: hex #4DB6AC - public static let teal300 = UIColor(hex: 0x4DB6AC) - - /// SwifterSwift: hex #26A69A - public static let teal400 = UIColor(hex: 0x26A69A) - - /// SwifterSwift: hex #009688 - public static let teal500 = UIColor(hex: 0x009688) - - /// SwifterSwift: hex #00897B - public static let teal600 = UIColor(hex: 0x00897B) - - /// SwifterSwift: hex #00796B - public static let teal700 = UIColor(hex: 0x00796B) - - /// SwifterSwift: hex #00695C - public static let teal800 = UIColor(hex: 0x00695C) - - /// SwifterSwift: hex #004D40 - public static let teal900 = UIColor(hex: 0x004D40) - - /// SwifterSwift: hex #A7FFEB - public static let tealA100 = UIColor(hex: 0xA7FFEB) - - /// SwifterSwift: hex #64FFDA - public static let tealA200 = UIColor(hex: 0x64FFDA) - - /// SwifterSwift: hex #1DE9B6 - public static let tealA400 = UIColor(hex: 0x1DE9B6) - - /// SwifterSwift: hex #00BFA5 - public static let tealA700 = UIColor(hex: 0x00BFA5) - - /// SwifterSwift: color green500 - public static let green = green500 - - /// SwifterSwift: hex #E8F5E9 - public static let green50 = UIColor(hex: 0xE8F5E9) - - /// SwifterSwift: hex #C8E6C9 - public static let green100 = UIColor(hex: 0xC8E6C9) - - /// SwifterSwift: hex #A5D6A7 - public static let green200 = UIColor(hex: 0xA5D6A7) - - /// SwifterSwift: hex #81C784 - public static let green300 = UIColor(hex: 0x81C784) - - /// SwifterSwift: hex #66BB6A - public static let green400 = UIColor(hex: 0x66BB6A) - - /// SwifterSwift: hex #4CAF50 - public static let green500 = UIColor(hex: 0x4CAF50) - - /// SwifterSwift: hex #43A047 - public static let green600 = UIColor(hex: 0x43A047) - - /// SwifterSwift: hex #388E3C - public static let green700 = UIColor(hex: 0x388E3C) - - /// SwifterSwift: hex #2E7D32 - public static let green800 = UIColor(hex: 0x2E7D32) - - /// SwifterSwift: hex #1B5E20 - public static let green900 = UIColor(hex: 0x1B5E20) - - /// SwifterSwift: hex #B9F6CA - public static let greenA100 = UIColor(hex: 0xB9F6CA) - - /// SwifterSwift: hex #69F0AE - public static let greenA200 = UIColor(hex: 0x69F0AE) - - /// SwifterSwift: hex #00E676 - public static let greenA400 = UIColor(hex: 0x00E676) - - /// SwifterSwift: hex #00C853 - public static let greenA700 = UIColor(hex: 0x00C853) - - /// SwifterSwift: color lightGreen500 - public static let lightGreen = lightGreen500 - - /// SwifterSwift: hex #F1F8E9 - public static let lightGreen50 = UIColor(hex: 0xF1F8E9) - - /// SwifterSwift: hex #DCEDC8 - public static let lightGreen100 = UIColor(hex: 0xDCEDC8) - - /// SwifterSwift: hex #C5E1A5 - public static let lightGreen200 = UIColor(hex: 0xC5E1A5) - - /// SwifterSwift: hex #AED581 - public static let lightGreen300 = UIColor(hex: 0xAED581) - - /// SwifterSwift: hex #9CCC65 - public static let lightGreen400 = UIColor(hex: 0x9CCC65) - - /// SwifterSwift: hex #8BC34A - public static let lightGreen500 = UIColor(hex: 0x8BC34A) - - /// SwifterSwift: hex #7CB342 - public static let lightGreen600 = UIColor(hex: 0x7CB342) - - /// SwifterSwift: hex #689F38 - public static let lightGreen700 = UIColor(hex: 0x689F38) - - /// SwifterSwift: hex #558B2F - public static let lightGreen800 = UIColor(hex: 0x558B2F) - - /// SwifterSwift: hex #33691E - public static let lightGreen900 = UIColor(hex: 0x33691E) - - /// SwifterSwift: hex #CCFF90 - public static let lightGreenA100 = UIColor(hex: 0xCCFF90) - - /// SwifterSwift: hex #B2FF59 - public static let lightGreenA200 = UIColor(hex: 0xB2FF59) - - /// SwifterSwift: hex #76FF03 - public static let lightGreenA400 = UIColor(hex: 0x76FF03) - - /// SwifterSwift: hex #64DD17 - public static let lightGreenA700 = UIColor(hex: 0x64DD17) - - /// SwifterSwift: color lime500 - public static let lime = lime500 - - /// SwifterSwift: hex #F9FBE7 - public static let lime50 = UIColor(hex: 0xF9FBE7) - - /// SwifterSwift: hex #F0F4C3 - public static let lime100 = UIColor(hex: 0xF0F4C3) - - /// SwifterSwift: hex #E6EE9C - public static let lime200 = UIColor(hex: 0xE6EE9C) - - /// SwifterSwift: hex #DCE775 - public static let lime300 = UIColor(hex: 0xDCE775) - - /// SwifterSwift: hex #D4E157 - public static let lime400 = UIColor(hex: 0xD4E157) - - /// SwifterSwift: hex #CDDC39 - public static let lime500 = UIColor(hex: 0xCDDC39) - - /// SwifterSwift: hex #C0CA33 - public static let lime600 = UIColor(hex: 0xC0CA33) - - /// SwifterSwift: hex #AFB42B - public static let lime700 = UIColor(hex: 0xAFB42B) - - /// SwifterSwift: hex #9E9D24 - public static let lime800 = UIColor(hex: 0x9E9D24) - - /// SwifterSwift: hex #827717 - public static let lime900 = UIColor(hex: 0x827717) - - /// SwifterSwift: hex #F4FF81 - public static let limeA100 = UIColor(hex: 0xF4FF81) - - /// SwifterSwift: hex #EEFF41 - public static let limeA200 = UIColor(hex: 0xEEFF41) - - /// SwifterSwift: hex #C6FF00 - public static let limeA400 = UIColor(hex: 0xC6FF00) - - /// SwifterSwift: hex #AEEA00 - public static let limeA700 = UIColor(hex: 0xAEEA00) - - /// SwifterSwift: color yellow500 - public static let yellow = yellow500 - - /// SwifterSwift: hex #FFFDE7 - public static let yellow50 = UIColor(hex: 0xFFFDE7) - - /// SwifterSwift: hex #FFF9C4 - public static let yellow100 = UIColor(hex: 0xFFF9C4) - - /// SwifterSwift: hex #FFF59D - public static let yellow200 = UIColor(hex: 0xFFF59D) - - /// SwifterSwift: hex #FFF176 - public static let yellow300 = UIColor(hex: 0xFFF176) - - /// SwifterSwift: hex #FFEE58 - public static let yellow400 = UIColor(hex: 0xFFEE58) - - /// SwifterSwift: hex #FFEB3B - public static let yellow500 = UIColor(hex: 0xFFEB3B) - - /// SwifterSwift: hex #FDD835 - public static let yellow600 = UIColor(hex: 0xFDD835) - - /// SwifterSwift: hex #FBC02D - public static let yellow700 = UIColor(hex: 0xFBC02D) - - /// SwifterSwift: hex #F9A825 - public static let yellow800 = UIColor(hex: 0xF9A825) - - /// SwifterSwift: hex #F57F17 - public static let yellow900 = UIColor(hex: 0xF57F17) - - /// SwifterSwift: hex #FFFF8D - public static let yellowA100 = UIColor(hex: 0xFFFF8D) - - /// SwifterSwift: hex #FFFF00 - public static let yellowA200 = UIColor(hex: 0xFFFF00) - - /// SwifterSwift: hex #FFEA00 - public static let yellowA400 = UIColor(hex: 0xFFEA00) - - /// SwifterSwift: hex #FFD600 - public static let yellowA700 = UIColor(hex: 0xFFD600) - - /// SwifterSwift: color amber500 - public static let amber = amber500 - - /// SwifterSwift: hex #FFF8E1 - public static let amber50 = UIColor(hex: 0xFFF8E1) - - /// SwifterSwift: hex #FFECB3 - public static let amber100 = UIColor(hex: 0xFFECB3) - - /// SwifterSwift: hex #FFE082 - public static let amber200 = UIColor(hex: 0xFFE082) - - /// SwifterSwift: hex #FFD54F - public static let amber300 = UIColor(hex: 0xFFD54F) - - /// SwifterSwift: hex #FFCA28 - public static let amber400 = UIColor(hex: 0xFFCA28) - - /// SwifterSwift: hex #FFC107 - public static let amber500 = UIColor(hex: 0xFFC107) - - /// SwifterSwift: hex #FFB300 - public static let amber600 = UIColor(hex: 0xFFB300) - - /// SwifterSwift: hex #FFA000 - public static let amber700 = UIColor(hex: 0xFFA000) - - /// SwifterSwift: hex #FF8F00 - public static let amber800 = UIColor(hex: 0xFF8F00) - - /// SwifterSwift: hex #FF6F00 - public static let amber900 = UIColor(hex: 0xFF6F00) - - /// SwifterSwift: hex #FFE57F - public static let amberA100 = UIColor(hex: 0xFFE57F) - - /// SwifterSwift: hex #FFD740 - public static let amberA200 = UIColor(hex: 0xFFD740) - - /// SwifterSwift: hex #FFC400 - public static let amberA400 = UIColor(hex: 0xFFC400) - - /// SwifterSwift: hex #FFAB00 - public static let amberA700 = UIColor(hex: 0xFFAB00) - - /// SwifterSwift: color orange500 - public static let orange = orange500 - - /// SwifterSwift: hex #FFF3E0 - public static let orange50 = UIColor(hex: 0xFFF3E0) - - /// SwifterSwift: hex #FFE0B2 - public static let orange100 = UIColor(hex: 0xFFE0B2) - - /// SwifterSwift: hex #FFCC80 - public static let orange200 = UIColor(hex: 0xFFCC80) - - /// SwifterSwift: hex #FFB74D - public static let orange300 = UIColor(hex: 0xFFB74D) - - /// SwifterSwift: hex #FFA726 - public static let orange400 = UIColor(hex: 0xFFA726) - - /// SwifterSwift: hex #FF9800 - public static let orange500 = UIColor(hex: 0xFF9800) - - /// SwifterSwift: hex #FB8C00 - public static let orange600 = UIColor(hex: 0xFB8C00) - - /// SwifterSwift: hex #F57C00 - public static let orange700 = UIColor(hex: 0xF57C00) - - /// SwifterSwift: hex #EF6C00 - public static let orange800 = UIColor(hex: 0xEF6C00) - - /// SwifterSwift: hex #E65100 - public static let orange900 = UIColor(hex: 0xE65100) - - /// SwifterSwift: hex #FFD180 - public static let orangeA100 = UIColor(hex: 0xFFD180) - - /// SwifterSwift: hex #FFAB40 - public static let orangeA200 = UIColor(hex: 0xFFAB40) - - /// SwifterSwift: hex #FF9100 - public static let orangeA400 = UIColor(hex: 0xFF9100) - - /// SwifterSwift: hex #FF6D00 - public static let orangeA700 = UIColor(hex: 0xFF6D00) - - /// SwifterSwift: color deepOrange500 - public static let deepOrange = deepOrange500 - - /// SwifterSwift: hex #FBE9E7 - public static let deepOrange50 = UIColor(hex: 0xFBE9E7) - - /// SwifterSwift: hex #FFCCBC - public static let deepOrange100 = UIColor(hex: 0xFFCCBC) - - /// SwifterSwift: hex #FFAB91 - public static let deepOrange200 = UIColor(hex: 0xFFAB91) - - /// SwifterSwift: hex #FF8A65 - public static let deepOrange300 = UIColor(hex: 0xFF8A65) - - /// SwifterSwift: hex #FF7043 - public static let deepOrange400 = UIColor(hex: 0xFF7043) - - /// SwifterSwift: hex #FF5722 - public static let deepOrange500 = UIColor(hex: 0xFF5722) - - /// SwifterSwift: hex #F4511E - public static let deepOrange600 = UIColor(hex: 0xF4511E) - - /// SwifterSwift: hex #E64A19 - public static let deepOrange700 = UIColor(hex: 0xE64A19) - - /// SwifterSwift: hex #D84315 - public static let deepOrange800 = UIColor(hex: 0xD84315) - - /// SwifterSwift: hex #BF360C - public static let deepOrange900 = UIColor(hex: 0xBF360C) - - /// SwifterSwift: hex #FF9E80 - public static let deepOrangeA100 = UIColor(hex: 0xFF9E80) - - /// SwifterSwift: hex #FF6E40 - public static let deepOrangeA200 = UIColor(hex: 0xFF6E40) - - /// SwifterSwift: hex #FF3D00 - public static let deepOrangeA400 = UIColor(hex: 0xFF3D00) - - /// SwifterSwift: hex #DD2C00 - public static let deepOrangeA700 = UIColor(hex: 0xDD2C00) - - /// SwifterSwift: color brown500 - public static let brown = brown500 - - /// SwifterSwift: hex #EFEBE9 - public static let brown50 = UIColor(hex: 0xEFEBE9) - - /// SwifterSwift: hex #D7CCC8 - public static let brown100 = UIColor(hex: 0xD7CCC8) - - /// SwifterSwift: hex #BCAAA4 - public static let brown200 = UIColor(hex: 0xBCAAA4) - - /// SwifterSwift: hex #A1887F - public static let brown300 = UIColor(hex: 0xA1887F) - - /// SwifterSwift: hex #8D6E63 - public static let brown400 = UIColor(hex: 0x8D6E63) - - /// SwifterSwift: hex #795548 - public static let brown500 = UIColor(hex: 0x795548) - - /// SwifterSwift: hex #6D4C41 - public static let brown600 = UIColor(hex: 0x6D4C41) - - /// SwifterSwift: hex #5D4037 - public static let brown700 = UIColor(hex: 0x5D4037) - - /// SwifterSwift: hex #4E342E - public static let brown800 = UIColor(hex: 0x4E342E) - - /// SwifterSwift: hex #3E2723 - public static let brown900 = UIColor(hex: 0x3E2723) - - /// SwifterSwift: color grey500 - public static let grey = grey500 - - /// SwifterSwift: hex #FAFAFA - public static let grey50 = UIColor(hex: 0xFAFAFA) - - /// SwifterSwift: hex #F5F5F5 - public static let grey100 = UIColor(hex: 0xF5F5F5) - - /// SwifterSwift: hex #EEEEEE - public static let grey200 = UIColor(hex: 0xEEEEEE) - - /// SwifterSwift: hex #E0E0E0 - public static let grey300 = UIColor(hex: 0xE0E0E0) - - /// SwifterSwift: hex #BDBDBD - public static let grey400 = UIColor(hex: 0xBDBDBD) - - /// SwifterSwift: hex #9E9E9E - public static let grey500 = UIColor(hex: 0x9E9E9E) - - /// SwifterSwift: hex #757575 - public static let grey600 = UIColor(hex: 0x757575) - - /// SwifterSwift: hex #616161 - public static let grey700 = UIColor(hex: 0x616161) - - /// SwifterSwift: hex #424242 - public static let grey800 = UIColor(hex: 0x424242) - - /// SwifterSwift: hex #212121 - public static let grey900 = UIColor(hex: 0x212121) - - /// SwifterSwift: color blueGrey500 - public static let blueGrey = blueGrey500 - - /// SwifterSwift: hex #ECEFF1 - public static let blueGrey50 = UIColor(hex: 0xECEFF1) - - /// SwifterSwift: hex #CFD8DC - public static let blueGrey100 = UIColor(hex: 0xCFD8DC) - - /// SwifterSwift: hex #B0BEC5 - public static let blueGrey200 = UIColor(hex: 0xB0BEC5) - - /// SwifterSwift: hex #90A4AE - public static let blueGrey300 = UIColor(hex: 0x90A4AE) - - /// SwifterSwift: hex #78909C - public static let blueGrey400 = UIColor(hex: 0x78909C) - - /// SwifterSwift: hex #607D8B - public static let blueGrey500 = UIColor(hex: 0x607D8B) - - /// SwifterSwift: hex #546E7A - public static let blueGrey600 = UIColor(hex: 0x546E7A) - - /// SwifterSwift: hex #455A64 - public static let blueGrey700 = UIColor(hex: 0x455A64) - - /// SwifterSwift: hex #37474F - public static let blueGrey800 = UIColor(hex: 0x37474F) - - /// SwifterSwift: hex #263238 - public static let blueGrey900 = UIColor(hex: 0x263238) - - /// SwifterSwift: hex #000000 - public static let black = UIColor(hex: 0x000000) - - /// SwifterSwift: hex #FFFFFF - public static let white = UIColor(hex: 0xFFFFFF) - } - -} - -// MARK: - CSS colors -public extension UIColor { - - /// SwifterSwift: CSS colors. - public struct CSS { - // http://www.w3schools.com/colors/colors_names.asp - - /// SwifterSwift: hex #F0F8FF - public static let aliceBlue = UIColor(hex: 0xF0F8FF) - - /// SwifterSwift: hex #FAEBD7 - public static let antiqueWhite = UIColor(hex: 0xFAEBD7) - - /// SwifterSwift: hex #00FFFF - public static let aqua = UIColor(hex: 0x00FFFF) - - /// SwifterSwift: hex #7FFFD4 - public static let aquamarine = UIColor(hex: 0x7FFFD4) - - /// SwifterSwift: hex #F0FFFF - public static let azure = UIColor(hex: 0xF0FFFF) - - /// SwifterSwift: hex #F5F5DC - public static let beige = UIColor(hex: 0xF5F5DC) - - /// SwifterSwift: hex #FFE4C4 - public static let bisque = UIColor(hex: 0xFFE4C4) - - /// SwifterSwift: hex #000000 - public static let black = UIColor(hex: 0x000000) - - /// SwifterSwift: hex #FFEBCD - public static let blanchedAlmond = UIColor(hex: 0xFFEBCD) - - /// SwifterSwift: hex #0000FF - public static let blue = UIColor(hex: 0x0000FF) - - /// SwifterSwift: hex #8A2BE2 - public static let blueViolet = UIColor(hex: 0x8A2BE2) - - /// SwifterSwift: hex #A52A2A - public static let brown = UIColor(hex: 0xA52A2A) - - /// SwifterSwift: hex #DEB887 - public static let burlyWood = UIColor(hex: 0xDEB887) - - /// SwifterSwift: hex #5F9EA0 - public static let cadetBlue = UIColor(hex: 0x5F9EA0) - - /// SwifterSwift: hex #7FFF00 - public static let chartreuse = UIColor(hex: 0x7FFF00) - - /// SwifterSwift: hex #D2691E - public static let chocolate = UIColor(hex: 0xD2691E) - - /// SwifterSwift: hex #FF7F50 - public static let coral = UIColor(hex: 0xFF7F50) - - /// SwifterSwift: hex #6495ED - public static let cornflowerBlue = UIColor(hex: 0x6495ED) - - /// SwifterSwift: hex #FFF8DC - public static let cornsilk = UIColor(hex: 0xFFF8DC) - - /// SwifterSwift: hex #DC143C - public static let crimson = UIColor(hex: 0xDC143C) - - /// SwifterSwift: hex #00FFFF - public static let cyan = UIColor(hex: 0x00FFFF) - - /// SwifterSwift: hex #00008B - public static let darkBlue = UIColor(hex: 0x00008B) - - /// SwifterSwift: hex #008B8B - public static let darkCyan = UIColor(hex: 0x008B8B) - - /// SwifterSwift: hex #B8860B - public static let darkGoldenRod = UIColor(hex: 0xB8860B) - - /// SwifterSwift: hex #A9A9A9 - public static let darkGray = UIColor(hex: 0xA9A9A9) - - /// SwifterSwift: hex #A9A9A9 - public static let darkGrey = UIColor(hex: 0xA9A9A9) - - /// SwifterSwift: hex #006400 - public static let darkGreen = UIColor(hex: 0x006400) - - /// SwifterSwift: hex #BDB76B - public static let darkKhaki = UIColor(hex: 0xBDB76B) - - /// SwifterSwift: hex #8B008B - public static let darkMagenta = UIColor(hex: 0x8B008B) - - /// SwifterSwift: hex #556B2F - public static let darkOliveGreen = UIColor(hex: 0x556B2F) - - /// SwifterSwift: hex #FF8C00 - public static let darkOrange = UIColor(hex: 0xFF8C00) - - /// SwifterSwift: hex #9932CC - public static let darkOrchid = UIColor(hex: 0x9932CC) - - /// SwifterSwift: hex #8B0000 - public static let darkRed = UIColor(hex: 0x8B0000) - - /// SwifterSwift: hex #E9967A - public static let darkSalmon = UIColor(hex: 0xE9967A) - - /// SwifterSwift: hex #8FBC8F - public static let darkSeaGreen = UIColor(hex: 0x8FBC8F) - - /// SwifterSwift: hex #483D8B - public static let darkSlateBlue = UIColor(hex: 0x483D8B) - - /// SwifterSwift: hex #2F4F4F - public static let darkSlateGray = UIColor(hex: 0x2F4F4F) - - /// SwifterSwift: hex #2F4F4F - public static let darkSlateGrey = UIColor(hex: 0x2F4F4F) - - /// SwifterSwift: hex #00CED1 - public static let darkTurquoise = UIColor(hex: 0x00CED1) - - /// SwifterSwift: hex #9400D3 - public static let darkViolet = UIColor(hex: 0x9400D3) - - /// SwifterSwift: hex #FF1493 - public static let deepPink = UIColor(hex: 0xFF1493) - - /// SwifterSwift: hex #00BFFF - public static let deepSkyBlue = UIColor(hex: 0x00BFFF) - - /// SwifterSwift: hex #696969 - public static let dimGray = UIColor(hex: 0x696969) - - /// SwifterSwift: hex #696969 - public static let dimGrey = UIColor(hex: 0x696969) - - /// SwifterSwift: hex #1E90FF - public static let dodgerBlue = UIColor(hex: 0x1E90FF) - - /// SwifterSwift: hex #B22222 - public static let fireBrick = UIColor(hex: 0xB22222) - - /// SwifterSwift: hex #FFFAF0 - public static let floralWhite = UIColor(hex: 0xFFFAF0) - - /// SwifterSwift: hex #228B22 - public static let forestGreen = UIColor(hex: 0x228B22) - - /// SwifterSwift: hex #FF00FF - public static let fuchsia = UIColor(hex: 0xFF00FF) - - /// SwifterSwift: hex #DCDCDC - public static let gainsboro = UIColor(hex: 0xDCDCDC) - - /// SwifterSwift: hex #F8F8FF - public static let ghostWhite = UIColor(hex: 0xF8F8FF) - - /// SwifterSwift: hex #FFD700 - public static let gold = UIColor(hex: 0xFFD700) - - /// SwifterSwift: hex #DAA520 - public static let goldenRod = UIColor(hex: 0xDAA520) - - /// SwifterSwift: hex #808080 - public static let gray = UIColor(hex: 0x808080) - - /// SwifterSwift: hex #808080 - public static let grey = UIColor(hex: 0x808080) - - /// SwifterSwift: hex #008000 - public static let green = UIColor(hex: 0x008000) - - /// SwifterSwift: hex #ADFF2F - public static let greenYellow = UIColor(hex: 0xADFF2F) - - /// SwifterSwift: hex #F0FFF0 - public static let honeyDew = UIColor(hex: 0xF0FFF0) - - /// SwifterSwift: hex #FF69B4 - public static let hotPink = UIColor(hex: 0xFF69B4) - - /// SwifterSwift: hex #CD5C5C - public static let indianRed = UIColor(hex: 0xCD5C5C) - - /// SwifterSwift: hex #4B0082 - public static let indigo = UIColor(hex: 0x4B0082) - - /// SwifterSwift: hex #FFFFF0 - public static let ivory = UIColor(hex: 0xFFFFF0) - - /// SwifterSwift: hex #F0E68C - public static let khaki = UIColor(hex: 0xF0E68C) - - /// SwifterSwift: hex #E6E6FA - public static let lavender = UIColor(hex: 0xE6E6FA) - - /// SwifterSwift: hex #FFF0F5 - public static let lavenderBlush = UIColor(hex: 0xFFF0F5) - - /// SwifterSwift: hex #7CFC00 - public static let lawnGreen = UIColor(hex: 0x7CFC00) - - /// SwifterSwift: hex #FFFACD - public static let lemonChiffon = UIColor(hex: 0xFFFACD) - - /// SwifterSwift: hex #ADD8E6 - public static let lightBlue = UIColor(hex: 0xADD8E6) - - /// SwifterSwift: hex #F08080 - public static let lightCoral = UIColor(hex: 0xF08080) - - /// SwifterSwift: hex #E0FFFF - public static let lightCyan = UIColor(hex: 0xE0FFFF) - - /// SwifterSwift: hex #FAFAD2 - public static let lightGoldenRodYellow = UIColor(hex: 0xFAFAD2) - - /// SwifterSwift: hex #D3D3D3 - public static let lightGray = UIColor(hex: 0xD3D3D3) - - /// SwifterSwift: hex #D3D3D3 - public static let lightGrey = UIColor(hex: 0xD3D3D3) - - /// SwifterSwift: hex #90EE90 - public static let lightGreen = UIColor(hex: 0x90EE90) - - /// SwifterSwift: hex #FFB6C1 - public static let lightPink = UIColor(hex: 0xFFB6C1) - - /// SwifterSwift: hex #FFA07A - public static let lightSalmon = UIColor(hex: 0xFFA07A) - - /// SwifterSwift: hex #20B2AA - public static let lightSeaGreen = UIColor(hex: 0x20B2AA) - - /// SwifterSwift: hex #87CEFA - public static let lightSkyBlue = UIColor(hex: 0x87CEFA) - - /// SwifterSwift: hex #778899 - public static let lightSlateGray = UIColor(hex: 0x778899) - - /// SwifterSwift: hex #778899 - public static let lightSlateGrey = UIColor(hex: 0x778899) - - /// SwifterSwift: hex #B0C4DE - public static let lightSteelBlue = UIColor(hex: 0xB0C4DE) - - /// SwifterSwift: hex #FFFFE0 - public static let lightYellow = UIColor(hex: 0xFFFFE0) - - /// SwifterSwift: hex #00FF00 - public static let lime = UIColor(hex: 0x00FF00) - - /// SwifterSwift: hex #32CD32 - public static let limeGreen = UIColor(hex: 0x32CD32) - - /// SwifterSwift: hex #FAF0E6 - public static let linen = UIColor(hex: 0xFAF0E6) - - /// SwifterSwift: hex #FF00FF - public static let magenta = UIColor(hex: 0xFF00FF) - - /// SwifterSwift: hex #800000 - public static let maroon = UIColor(hex: 0x800000) - - /// SwifterSwift: hex #66CDAA - public static let mediumAquaMarine = UIColor(hex: 0x66CDAA) - - /// SwifterSwift: hex #0000CD - public static let mediumBlue = UIColor(hex: 0x0000CD) - - /// SwifterSwift: hex #BA55D3 - public static let mediumOrchid = UIColor(hex: 0xBA55D3) - - /// SwifterSwift: hex #9370DB - public static let mediumPurple = UIColor(hex: 0x9370DB) - - /// SwifterSwift: hex #3CB371 - public static let mediumSeaGreen = UIColor(hex: 0x3CB371) - - /// SwifterSwift: hex #7B68EE - public static let mediumSlateBlue = UIColor(hex: 0x7B68EE) - - /// SwifterSwift: hex #00FA9A - public static let mediumSpringGreen = UIColor(hex: 0x00FA9A) - - /// SwifterSwift: hex #48D1CC - public static let mediumTurquoise = UIColor(hex: 0x48D1CC) - - /// SwifterSwift: hex #C71585 - public static let mediumVioletRed = UIColor(hex: 0xC71585) - - /// SwifterSwift: hex #191970 - public static let midnightBlue = UIColor(hex: 0x191970) - - /// SwifterSwift: hex #F5FFFA - public static let mintCream = UIColor(hex: 0xF5FFFA) - - /// SwifterSwift: hex #FFE4E1 - public static let mistyRose = UIColor(hex: 0xFFE4E1) - - /// SwifterSwift: hex #FFE4B5 - public static let moccasin = UIColor(hex: 0xFFE4B5) - - /// SwifterSwift: hex #FFDEAD - public static let navajoWhite = UIColor(hex: 0xFFDEAD) - - /// SwifterSwift: hex #000080 - public static let navy = UIColor(hex: 0x000080) - - /// SwifterSwift: hex #FDF5E6 - public static let oldLace = UIColor(hex: 0xFDF5E6) - - /// SwifterSwift: hex #808000 - public static let olive = UIColor(hex: 0x808000) - - /// SwifterSwift: hex #6B8E23 - public static let oliveDrab = UIColor(hex: 0x6B8E23) - - /// SwifterSwift: hex #FFA500 - public static let orange = UIColor(hex: 0xFFA500) - - /// SwifterSwift: hex #FF4500 - public static let orangeRed = UIColor(hex: 0xFF4500) - - /// SwifterSwift: hex #DA70D6 - public static let orchid = UIColor(hex: 0xDA70D6) - - /// SwifterSwift: hex #EEE8AA - public static let paleGoldenRod = UIColor(hex: 0xEEE8AA) - - /// SwifterSwift: hex #98FB98 - public static let paleGreen = UIColor(hex: 0x98FB98) - - /// SwifterSwift: hex #AFEEEE - public static let paleTurquoise = UIColor(hex: 0xAFEEEE) - - /// SwifterSwift: hex #DB7093 - public static let paleVioletRed = UIColor(hex: 0xDB7093) - - /// SwifterSwift: hex #FFEFD5 - public static let papayaWhip = UIColor(hex: 0xFFEFD5) - - /// SwifterSwift: hex #FFDAB9 - public static let peachPuff = UIColor(hex: 0xFFDAB9) - - /// SwifterSwift: hex #CD853F - public static let peru = UIColor(hex: 0xCD853F) - - /// SwifterSwift: hex #FFC0CB - public static let pink = UIColor(hex: 0xFFC0CB) - - /// SwifterSwift: hex #DDA0DD - public static let plum = UIColor(hex: 0xDDA0DD) - - /// SwifterSwift: hex #B0E0E6 - public static let powderBlue = UIColor(hex: 0xB0E0E6) - - /// SwifterSwift: hex #800080 - public static let purple = UIColor(hex: 0x800080) - - /// SwifterSwift: hex #663399 - public static let rebeccaPurple = UIColor(hex: 0x663399) - - /// SwifterSwift: hex #FF0000 - public static let red = UIColor(hex: 0xFF0000) - - /// SwifterSwift: hex #BC8F8F - public static let rosyBrown = UIColor(hex: 0xBC8F8F) - - /// SwifterSwift: hex #4169E1 - public static let royalBlue = UIColor(hex: 0x4169E1) - - /// SwifterSwift: hex #8B4513 - public static let saddleBrown = UIColor(hex: 0x8B4513) - - /// SwifterSwift: hex #FA8072 - public static let salmon = UIColor(hex: 0xFA8072) - - /// SwifterSwift: hex #F4A460 - public static let sandyBrown = UIColor(hex: 0xF4A460) - - /// SwifterSwift: hex #2E8B57 - public static let seaGreen = UIColor(hex: 0x2E8B57) - - /// SwifterSwift: hex #FFF5EE - public static let seaShell = UIColor(hex: 0xFFF5EE) - - /// SwifterSwift: hex #A0522D - public static let sienna = UIColor(hex: 0xA0522D) - - /// SwifterSwift: hex #C0C0C0 - public static let silver = UIColor(hex: 0xC0C0C0) - - /// SwifterSwift: hex #87CEEB - public static let skyBlue = UIColor(hex: 0x87CEEB) - - /// SwifterSwift: hex #6A5ACD - public static let slateBlue = UIColor(hex: 0x6A5ACD) - - /// SwifterSwift: hex #708090 - public static let slateGray = UIColor(hex: 0x708090) - - /// SwifterSwift: hex #708090 - public static let slateGrey = UIColor(hex: 0x708090) - - /// SwifterSwift: hex #FFFAFA - public static let snow = UIColor(hex: 0xFFFAFA) - - /// SwifterSwift: hex #00FF7F - public static let springGreen = UIColor(hex: 0x00FF7F) - - /// SwifterSwift: hex #4682B4 - public static let steelBlue = UIColor(hex: 0x4682B4) - - /// SwifterSwift: hex #D2B48C - public static let tan = UIColor(hex: 0xD2B48C) - - /// SwifterSwift: hex #008080 - public static let teal = UIColor(hex: 0x008080) - - /// SwifterSwift: hex #D8BFD8 - public static let thistle = UIColor(hex: 0xD8BFD8) - - /// SwifterSwift: hex #FF6347 - public static let tomato = UIColor(hex: 0xFF6347) - - /// SwifterSwift: hex #40E0D0 - public static let turquoise = UIColor(hex: 0x40E0D0) - - /// SwifterSwift: hex #EE82EE - public static let violet = UIColor(hex: 0xEE82EE) - - /// SwifterSwift: hex #F5DEB3 - public static let wheat = UIColor(hex: 0xF5DEB3) - - /// SwifterSwift: hex #FFFFFF - public static let white = UIColor(hex: 0xFFFFFF) - - /// SwifterSwift: hex #F5F5F5 - public static let whiteSmoke = UIColor(hex: 0xF5F5F5) - - /// SwifterSwift: hex #FFFF00 - public static let yellow = UIColor(hex: 0xFFFF00) - - /// SwifterSwift: hex #9ACD32 - public static let yellowGreen = UIColor(hex: 0x9ACD32) - - } - -} - -// MARK: - Flat UI colors -public extension UIColor { - - /// SwifterSwift: Flat UI colors - public struct FlatUI { - // http://flatuicolors.com. - - /// SwifterSwift: hex #1ABC9C - public static let turquoise = UIColor(hex: 0x1abc9c) - - /// SwifterSwift: hex #16A085 - public static let greenSea = UIColor(hex: 0x16a085) - - /// SwifterSwift: hex #2ECC71 - public static let emerald = UIColor(hex: 0x2ecc71) - - /// SwifterSwift: hex #27AE60 - public static let nephritis = UIColor(hex: 0x27ae60) - - /// SwifterSwift: hex #3498DB - public static let peterRiver = UIColor(hex: 0x3498db) - - /// SwifterSwift: hex #2980B9 - public static let belizeHole = UIColor(hex: 0x2980b9) - - /// SwifterSwift: hex #9B59B6 - public static let amethyst = UIColor(hex: 0x9b59b6) - - /// SwifterSwift: hex #8E44AD - public static let wisteria = UIColor(hex: 0x8e44ad) - - /// SwifterSwift: hex #34495E - public static let wetAsphalt = UIColor(hex: 0x34495e) - - /// SwifterSwift: hex #2C3E50 - public static let midnightBlue = UIColor(hex: 0x2c3e50) - - /// SwifterSwift: hex #F1C40F - public static let sunFlower = UIColor(hex: 0xf1c40f) - - /// SwifterSwift: hex #F39C12 - public static let flatOrange = UIColor(hex: 0xf39c12) - - /// SwifterSwift: hex #E67E22 - public static let carrot = UIColor(hex: 0xe67e22) - - /// SwifterSwift: hex #D35400 - public static let pumkin = UIColor(hex: 0xd35400) - - /// SwifterSwift: hex #E74C3C - public static let alizarin = UIColor(hex: 0xe74c3c) - - /// SwifterSwift: hex #C0392B - public static let pomegranate = UIColor(hex: 0xc0392b) - - /// SwifterSwift: hex #ECF0F1 - public static let clouds = UIColor(hex: 0xecf0f1) - - /// SwifterSwift: hex #BDC3C7 - public static let silver = UIColor(hex: 0xbdc3c7) - - /// SwifterSwift: hex #7F8C8D - public static let asbestos = UIColor(hex: 0x7f8c8d) - - /// SwifterSwift: hex #95A5A6 - public static let concerte = UIColor(hex: 0x95a5a6) - } -} #endif diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index a9021651c..5226f48e0 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwifterSwift' - s.version = '4.0.0' + s.version = '4.0.1' s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. @@ -37,12 +37,12 @@ Pod::Spec.new do |s| # UIKit Extensions s.subspec 'UIKit' do |sp| - sp.source_files = 'Sources/Extensions/UIKit/*.swift' + sp.source_files = 'Sources/Extensions/UIKit/*.swift', 'Sources/Extensions/Shared/ColorExtensions.swift' end # AppKit Extensions s.subspec 'AppKit' do |sp| - sp.source_files = 'Sources/Extensions/AppKit/*.swift' + sp.source_files = 'Sources/Extensions/AppKit/*.swift', 'Sources/Extensionss/Shared/ColorExtensions.swift' end # CoreGraphics Extensions diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 201541e0a..88b974139 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; + 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; + 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; + 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; 074EAF1B1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; 074EAF1C1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; 074EAF1D1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; @@ -174,7 +178,6 @@ 07B7F2231F5EB44600E6F910 /* CGSizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */; }; 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */; }; 07B7F2251F5EB44600E6F910 /* NSAttributedStringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */; }; - 07B7F2261F5EB44600E6F910 /* NSColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */; }; 07B7F2271F5EB44600E6F910 /* NSViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */; }; 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */; }; 07B7F2291F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */; }; @@ -335,6 +338,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensions.swift; sourceTree = ""; }; 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; @@ -504,6 +508,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0726D7751F7C19880028CAB5 /* Shared */ = { + isa = PBXGroup; + children = ( + 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */, + ); + path = Shared; + sourceTree = ""; + }; 077BA0871F6BE73000D9C4AC /* SwiftStdlib */ = { isa = PBXGroup; children = ( @@ -577,6 +589,7 @@ 07898B941F27904200558C97 /* Extensions */ = { isa = PBXGroup; children = ( + 0726D7751F7C19880028CAB5 /* Shared */, 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, 07B7F1651F5EB41600E6F910 /* Foundation */, 07B7F1791F5EB41600E6F910 /* UIKit */, @@ -1124,6 +1137,7 @@ buildActionMask = 2147483647; files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, 07B7F1991F5EB42000E6F910 /* UILabelExtensions.swift in Sources */, @@ -1180,6 +1194,7 @@ buildActionMask = 2147483647; files = ( 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1BD1F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, 07B7F1AF1F5EB42000E6F910 /* UILabelExtensions.swift in Sources */, @@ -1236,6 +1251,7 @@ buildActionMask = 2147483647; files = ( 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, + 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1D31F5EB42200E6F910 /* UIViewExtensions.swift in Sources */, 07B7F1C51F5EB42200E6F910 /* UILabelExtensions.swift in Sources */, @@ -1312,7 +1328,7 @@ 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */, 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, - 07B7F2261F5EB44600E6F910 /* NSColorExtensions.swift in Sources */, + 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */, From b0053b17c755b2b830ec379485e9a3749b7ec59e Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 28 Sep 2017 09:41:24 +0300 Subject: [PATCH 028/201] Move blend from UIColor to Color - Add cgFloatComponenets - Correct a typo in rgbComponenets --- CHANGELOG.md | 7 +- .../Extensions/Shared/ColorExtensions.swift | 84 ++++++++++-- .../Extensions/UIKit/UIColorExtensions.swift | 27 ---- SwifterSwift.xcodeproj/project.pbxproj | 2 - Tests/UIKitTests/UIColorExtensionsTests.swift | 128 +++++++++++------- 5 files changed, 155 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 852738f4b..2d61bd950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,11 +25,12 @@ N/A ### Enhancements - **Color** - Refactored duplicated code from `UIColorExtensions` and `NSColorExtensions` into `ColorExtensions`. thanks to [SD10](https://github.com/SD10). - + - Add `cgFloatComponents` to get RGB components for a Color represented as CGFloat numbers (between 0 and 1) + - `blend` now support NSColor as well. ### Bugfixes - **Color** - - Fixed a bug in `rgbComponenets`, `shortHexString`, and `shortHexOrHexString` where an exception was raised when color is white or black. - + - Fixed a bug in `rgbComponents`, `shortHexString`, and `shortHexOrHexString` where an exception was raised when color is white or black. + - Corrected a typo in `rgbComponenets` -> `rgbComponents` # v4.0.0 diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index 75fed3868..eb9598299 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -32,13 +32,13 @@ public extension Color { #endif } - /// SwifterSwift: RGB components for a UIColor + /// SwifterSwift: RGB components for a Color (between 0 and 255). /// - /// UIColor.red.rgbComponenets.red -> 255 - /// UIColor.green.rgbComponenets.green -> 255 - /// UIColor.blue.rgbComponenets.blue -> 255 + /// UIColor.red.rgbComponents.red -> 255 + /// NSColor.green.rgbComponents.green -> 255 + /// UIColor.blue.rgbComponents.blue -> 255 /// - public var rgbComponenets: (red: Int, green: Int, blue: Int) { + public var rgbComponents: (red: Int, green: Int, blue: Int) { var components: [CGFloat] { let c = cgColor.components! if c.count == 4 { @@ -52,6 +52,26 @@ public extension Color { return (red: Int(r * 255.0), green: Int(g * 255.0), blue: Int(b * 255.0)) } + /// SwifterSwift: RGB components for a Color represented as CGFloat numbers (between 0 and 1) + /// + /// UIColor.red.rgbComponents.red -> 1.0 + /// NSColor.green.rgbComponents.green -> 1.0 + /// UIColor.blue.rgbComponents.blue -> 1.0 + /// + public var cgFloatComponents: (red: CGFloat, green: CGFloat, blue: CGFloat) { + var components: [CGFloat] { + let c = cgColor.components! + if c.count == 4 { + return c + } + return [c[0], c[0], c[0], c[1]] + } + let r = components[0] + let g = components[1] + let b = components[2] + return (red: r, green: g, blue: b) + } + /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { var hue: CGFloat = 0.0 @@ -65,9 +85,9 @@ public extension Color { /// SwifterSwift: Hexadecimal value string (read-only). public var hexString: String { - let r = rgbComponenets.red - let g = rgbComponenets.green - let b = rgbComponenets.blue + let r = rgbComponents.red + let g = rgbComponents.green + let b = rgbComponents.blue return String(format: "#%02X%02X%02X", r, g, b) } @@ -84,7 +104,7 @@ public extension Color { return shortHexString ?? hexString } - /// SwifterSwift: Alpha of UIColor (read-only). + /// SwifterSwift: Alpha of Color (read-only). public var alpha: CGFloat { return cgColor.alpha } @@ -98,6 +118,52 @@ public extension Color { } +// MARK: - Methods +public extension Color { + + /// SwifterSwift: Blend two Colors + /// + /// - Parameters: + /// - color1: first color to blend + /// - intensity1: intensity of first color (default is 0.5) + /// - color2: second color to blend + /// - intensity2: intensity of second color (default is 0.5) + /// - Returns: Color created by blending first and seond colors. + public static func blend(_ color1: Color, intensity1: CGFloat = 0.5, with color2: Color, intensity2: CGFloat = 0.5) -> Color { + // http://stackoverflow.com/questions/27342715/blend-uicolors-in-swift + + let total = intensity1 + intensity2 + let level1 = intensity1/total + let level2 = intensity2/total + + guard level1 > 0 else { return color2 } + guard level2 > 0 else { return color1 } + + let components1 = color1.cgFloatComponents + let components2 = color2.cgFloatComponents + + let r1 = components1.red + let r2 = components2.red + + let g1 = components1.green + let g2 = components2.green + + let b1 = components1.blue + let b2 = components2.blue + + let a1 = color1.alpha + let a2 = color2.alpha + + let r = level1*r1 + level2*r2 + let g = level1*g1 + level2*g2 + let b = level1*b1 + level2*b2 + let a = level1*a1 + level2*a2 + + return Color(red: r, green: g, blue: b, alpha: a) + } + +} + // MARK: - Initializers public extension Color { diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift index 4f466ddf5..17698e7ac 100755 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ b/Sources/Extensions/UIKit/UIColorExtensions.swift @@ -36,33 +36,6 @@ public extension UIColor { } -// MARK: - Methods -public extension UIColor { - - /// SwifterSwift: Blend two UIColors - /// - /// - Parameters: - /// - color1: first color to blend - /// - intensity1: intensity of first color (default is 0.5) - /// - color2: second color to blend - /// - intensity2: intensity of second color (default is 0.5) - /// - Returns: UIColor created by blending first and seond colors. - public static func blend(_ color1: UIColor, intensity1: CGFloat = 0.5, with color2: UIColor, intensity2: CGFloat = 0.5) -> UIColor { - // http://stackoverflow.com/questions/27342715/blend-uicolors-in-swift - let total = intensity1 + intensity2 - let l1 = intensity1/total - let l2 = intensity2/total - guard l1 > 0 else { return color2} - guard l2 > 0 else { return color1} - var (r1, g1, b1, a1): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) - var (r2, g2, b2, a2): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) - color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2) - return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2) - } - -} - // MARK: - Initializers public extension UIColor { diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 88b974139..c7b402e51 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -358,7 +358,6 @@ 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGSizeExtensions.swift; sourceTree = ""; }; 07B7F1611F5EB41600E6F910 /* CLLocationExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationExtensions.swift; sourceTree = ""; }; 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensions.swift; sourceTree = ""; }; - 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSColorExtensions.swift; sourceTree = ""; }; 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensions.swift; sourceTree = ""; }; 07B7F1661F5EB41600E6F910 /* ArrayExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; }; @@ -604,7 +603,6 @@ 07B7F15C1F5EB41600E6F910 /* AppKit */ = { isa = PBXGroup; children = ( - 07B7F1631F5EB41600E6F910 /* NSColorExtensions.swift */, 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */, ); path = AppKit; diff --git a/Tests/UIKitTests/UIColorExtensionsTests.swift b/Tests/UIKitTests/UIColorExtensionsTests.swift index ed63a0ff7..59adf4866 100644 --- a/Tests/UIKitTests/UIColorExtensionsTests.swift +++ b/Tests/UIKitTests/UIColorExtensionsTests.swift @@ -12,29 +12,53 @@ import XCTest class UIColorExtensionsTests: XCTestCase { // MARK: - Test properties - func testRgbComponenets() { - XCTAssertEqual(UIColor.red.rgbComponenets.red, 255) - XCTAssertEqual(UIColor.red.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.red.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.green.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.green.rgbComponenets.green, 255) - XCTAssertEqual(UIColor.green.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.blue.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.blue.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.blue.rgbComponenets.blue, 255) - - XCTAssertEqual(UIColor.black.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.black.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.black.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.white.rgbComponenets.red, 255) - XCTAssertEqual(UIColor.white.rgbComponenets.green, 255) - XCTAssertEqual(UIColor.white.rgbComponenets.blue, 255) + func testRgbComponents() { + XCTAssertEqual(UIColor.red.rgbComponents.red, 255) + XCTAssertEqual(UIColor.red.rgbComponents.green, 0) + XCTAssertEqual(UIColor.red.rgbComponents.blue, 0) + + XCTAssertEqual(UIColor.green.rgbComponents.red, 0) + XCTAssertEqual(UIColor.green.rgbComponents.green, 255) + XCTAssertEqual(UIColor.green.rgbComponents.blue, 0) + + XCTAssertEqual(UIColor.blue.rgbComponents.red, 0) + XCTAssertEqual(UIColor.blue.rgbComponents.green, 0) + XCTAssertEqual(UIColor.blue.rgbComponents.blue, 255) + + XCTAssertEqual(UIColor.black.rgbComponents.red, 0) + XCTAssertEqual(UIColor.black.rgbComponents.green, 0) + XCTAssertEqual(UIColor.black.rgbComponents.blue, 0) + + XCTAssertEqual(UIColor.white.rgbComponents.red, 255) + XCTAssertEqual(UIColor.white.rgbComponents.green, 255) + XCTAssertEqual(UIColor.white.rgbComponents.blue, 255) - XCTAssertEqual(UIColor(hex: 0x12FFFF)?.rgbComponenets.red, 0x12) + XCTAssertEqual(UIColor(hex: 0x12FFFF)?.rgbComponents.red, 0x12) + } + + func testCGFloatComponents() { + XCTAssertEqual(UIColor.red.cgFloatComponents.red, 1) + XCTAssertEqual(UIColor.red.cgFloatComponents.green, 0) + XCTAssertEqual(UIColor.red.cgFloatComponents.blue, 0) + + XCTAssertEqual(UIColor.green.cgFloatComponents.red, 0) + XCTAssertEqual(UIColor.green.cgFloatComponents.green, 1) + XCTAssertEqual(UIColor.green.cgFloatComponents.blue, 0) + + XCTAssertEqual(UIColor.blue.cgFloatComponents.red, 0) + XCTAssertEqual(UIColor.blue.cgFloatComponents.green, 0) + XCTAssertEqual(UIColor.blue.cgFloatComponents.blue, 1) + + XCTAssertEqual(UIColor.black.cgFloatComponents.red, 0) + XCTAssertEqual(UIColor.black.cgFloatComponents.green, 0) + XCTAssertEqual(UIColor.black.cgFloatComponents.blue, 0) + + XCTAssertEqual(UIColor.white.cgFloatComponents.red, 1) + XCTAssertEqual(UIColor.white.cgFloatComponents.green, 1) + XCTAssertEqual(UIColor.white.cgFloatComponents.blue, 1) + let color = UIColor(hex: 0x12FFFF)! + XCTAssertEqual(color.cgFloatComponents.red, 0.070, accuracy: 0.001) } func testAlpha() { @@ -52,7 +76,7 @@ class UIColorExtensionsTests: XCTestCase { } // MARK: - Test properties - func testHsbaComponenets() { + func testHsbaComponents() { var color = UIColor(hex: 0xFF0000, transparency: 1.0) XCTAssertEqual(color?.hsbaComponents.hue, 0.0) XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) @@ -205,36 +229,36 @@ class UIColorExtensionsTests: XCTestCase { var color2 = UIColor.black var blendColor = UIColor.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.red, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.green, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, 0xFF / 2) color1 = UIColor(hex: 0x123456, transparency: 0.5)! color2 = UIColor(hex: 0x665544, transparency: 0.7)! blendColor = UIColor.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, (0x12 + 0x66) / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, (0x34 + 0x55) / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, (0x56 + 0x44) / 2) + XCTAssertEqual(blendColor.rgbComponents.red, (0x12 + 0x66) / 2) + XCTAssertEqual(blendColor.rgbComponents.green, (0x34 + 0x55) / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, (0x56 + 0x44) / 2) XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) blendColor = UIColor.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) var output: Double = 0x12 * 0.7 + 0x66 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) output = 0x34 * 0.7 + 0x55 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) output = 0x56 * 0.7 + 0x44 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = 0.5 * 0.7 + 0.7 * 0.3 XCTAssertEqual(blendColor.alpha, CGFloat(output)) blendColor = UIColor.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) XCTAssertEqual(blendColor.alpha, CGFloat(output)) @@ -245,39 +269,39 @@ class UIColorExtensionsTests: XCTestCase { // MARK: - Test initializers func testInit() { var color = UIColor(hex: 0xFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0xf) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0xf) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) color = UIColor(hex: 0xFFFFFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0xff) - XCTAssertEqual(color?.rgbComponenets.green, 0xff) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.rgbComponents.red, 0xff) + XCTAssertEqual(color?.rgbComponents.green, 0xff) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) color = UIColor(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.rgbComponenets.red, 0x12) - XCTAssertEqual(color?.rgbComponenets.green, 0x34) - XCTAssertEqual(color?.rgbComponenets.blue, 0x56) + XCTAssertEqual(color?.rgbComponents.red, 0x12) + XCTAssertEqual(color?.rgbComponents.green, 0x34) + XCTAssertEqual(color?.rgbComponents.blue, 0x56) XCTAssertEqual(color?.alpha, 1.0) color = UIColor(hex: 0x999, transparency: 21.0) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0x09) - XCTAssertEqual(color?.rgbComponenets.blue, 0x99) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0x09) + XCTAssertEqual(color?.rgbComponents.blue, 0x99) XCTAssertEqual(color?.alpha, 1.0) color = UIColor(hex: 0xaabbcc, transparency: 0.0) - XCTAssertEqual(color?.rgbComponenets.red, 0xaa) - XCTAssertEqual(color?.rgbComponenets.green, 0xbb) - XCTAssertEqual(color?.rgbComponenets.blue, 0xcc) + XCTAssertEqual(color?.rgbComponents.red, 0xaa) + XCTAssertEqual(color?.rgbComponents.green, 0xbb) + XCTAssertEqual(color?.rgbComponents.blue, 0xcc) XCTAssertEqual(color?.alpha, 0.0) color = UIColor(hex: 0x1, transparency: 0.5) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0) - XCTAssertEqual(color?.rgbComponenets.blue, 1) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0) + XCTAssertEqual(color?.rgbComponents.blue, 1) XCTAssertEqual(color?.alpha, 0.5) let color1 = UIColor(hex: 0xFFF, transparency: -0.4) From 70d5ce7939653e05f1394d6427d5347a398deed4 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Thu, 28 Sep 2017 16:17:44 +0300 Subject: [PATCH 029/201] Add unit tests for NSColor extensions #257 fix Added tests for NSColor, renamed to ColorExtensionsTests --- SwifterSwift.xcodeproj/project.pbxproj | 14 +- Tests/UIKitTests/ColorExtensionsTests.swift | 401 ++++++++++++++++++ Tests/UIKitTests/UIColorExtensionsTests.swift | 388 ----------------- 3 files changed, 409 insertions(+), 394 deletions(-) create mode 100644 Tests/UIKitTests/ColorExtensionsTests.swift delete mode 100644 Tests/UIKitTests/UIColorExtensionsTests.swift diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 88b974139..ae67b0d3d 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -204,7 +204,7 @@ 07C50D2C1F5EB04600F46E5A /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */; }; 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */; }; 07C50D2E1F5EB04600F46E5A /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */; }; - 07C50D2F1F5EB04600F46E5A /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */; }; + 07C50D2F1F5EB04600F46E5A /* ColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */; }; 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */; }; 07C50D311F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */; }; 07C50D321F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */; }; @@ -226,7 +226,7 @@ 07C50D421F5EB04700F46E5A /* UIBarButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */; }; 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */; }; 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */; }; - 07C50D451F5EB04700F46E5A /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */; }; + 07C50D451F5EB04700F46E5A /* ColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */; }; 07C50D461F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */; }; 07C50D471F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */; }; 07C50D481F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */; }; @@ -311,6 +311,7 @@ 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; + D85EA0131F7D2DA700B8539B /* ColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -426,7 +427,7 @@ 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonExtensionsTests.swift; sourceTree = ""; }; 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonExtensionsTests.swift; sourceTree = ""; }; 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensionsTests.swift; sourceTree = ""; }; - 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; }; + 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensionsTests.swift; sourceTree = ""; }; 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtensionsTests.swift; sourceTree = ""; }; 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensionsTests.swift; sourceTree = ""; }; 07C50D151F5EB03200F46E5A /* UILabelExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelExtensionsTests.swift; sourceTree = ""; }; @@ -702,7 +703,7 @@ 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */, 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */, 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */, - 07C50D121F5EB03200F46E5A /* UIColorExtensionsTests.swift */, + 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */, 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */, 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */, 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */, @@ -1351,7 +1352,7 @@ 07C50D2E1F5EB04600F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, 07C50D3C1F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, 07C50D381F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, - 07C50D2F1F5EB04600F46E5A /* UIColorExtensionsTests.swift in Sources */, + 07C50D2F1F5EB04600F46E5A /* ColorExtensionsTests.swift in Sources */, 07C50D331F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, 07C50D401F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, 07C50D311F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, @@ -1403,7 +1404,7 @@ 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, 07C50D521F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, 07C50D4E1F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, - 07C50D451F5EB04700F46E5A /* UIColorExtensionsTests.swift in Sources */, + 07C50D451F5EB04700F46E5A /* ColorExtensionsTests.swift in Sources */, 07C50D491F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, 07C50D561F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, 07C50D471F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, @@ -1469,6 +1470,7 @@ 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */, 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, + D85EA0131F7D2DA700B8539B /* ColorExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/UIKitTests/ColorExtensionsTests.swift b/Tests/UIKitTests/ColorExtensionsTests.swift new file mode 100644 index 000000000..546c348bf --- /dev/null +++ b/Tests/UIKitTests/ColorExtensionsTests.swift @@ -0,0 +1,401 @@ +// +// ColorExtensionsTests.swift +// SwifterSwift +// +// Created by Ewelina on 25/01/2017. +// Copyright © 2017 omaralbeik. All rights reserved. +// +import XCTest +@testable import SwifterSwift + +#if os(macOS) + import Cocoa + public typealias Color = NSColor +#else + import UIKit + public typealias Color = UIColor +#endif + +#if !os(watchOS) + import CoreImage +#endif + +class ColorExtensionsTests: XCTestCase { + + // MARK: - Test properties + func testRgbComponenets() { + XCTAssertEqual(Color.red.rgbComponenets.red, 255) + XCTAssertEqual(Color.red.rgbComponenets.green, 0) + XCTAssertEqual(Color.red.rgbComponenets.blue, 0) + + XCTAssertEqual(Color.green.rgbComponenets.red, 0) + XCTAssertEqual(Color.green.rgbComponenets.green, 255) + XCTAssertEqual(Color.green.rgbComponenets.blue, 0) + + XCTAssertEqual(Color.blue.rgbComponenets.red, 0) + XCTAssertEqual(Color.blue.rgbComponenets.green, 0) + XCTAssertEqual(Color.blue.rgbComponenets.blue, 255) + + XCTAssertEqual(Color.black.rgbComponenets.red, 0) + XCTAssertEqual(Color.black.rgbComponenets.green, 0) + XCTAssertEqual(Color.black.rgbComponenets.blue, 0) + + XCTAssertEqual(Color.white.rgbComponenets.red, 255) + XCTAssertEqual(Color.white.rgbComponenets.green, 255) + XCTAssertEqual(Color.white.rgbComponenets.blue, 255) + + XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponenets.red, 0x12) + + } + + func testAlpha() { + var color: Color = Color.red + XCTAssertEqual(color.alpha, 1.0) + + color = Color.white.withAlphaComponent(0.5) + XCTAssertEqual(color.alpha, 0.5) + + color = Color(red: 0, green: 0, blue: 0, transparency: 0.7)! + XCTAssertEqual(color.alpha, 0.7) + + color = Color(red: 0, green: 0, blue: 0, transparency: 1.1)! + XCTAssertEqual(color.alpha, 1.0) + } + + // MARK: - Test properties + func testHsbaComponenets() { + var color = Color(hex: 0xFF0000, transparency: 1.0) + XCTAssertEqual(color?.hsbaComponents.hue, 0.0) + XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) + XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x00FF00, transparency: 1.0) + XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (120/360)) / 1000)) + XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) + XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x0000FF, transparency: 1.0) + XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (240/360)) / 1000)) + XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) + XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x000000, transparency: 1.0) + XCTAssertEqual(color?.hsbaComponents.hue, 0.0) + XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) + XCTAssertEqual(color?.hsbaComponents.brightness, 0.0) + + color = Color(hex: 0xFFFFFF, transparency: 1.0) + XCTAssertEqual(color?.hsbaComponents.hue, 0.0) + XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) + XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x123456, transparency: 1.0) + XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (210/360)) / 1000)) + XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 79) + XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 34) + + color = Color(hex: 0xFCA864, transparency: 1.0) + XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (27/360)) / 1000)) + XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 60) + XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 99) + + color = Color(hex: 0x1F2D3C, transparency: 1.0) + XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (211/360)) / 1000)) + XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 48) + XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 24) + } + + func testUInt() { + var color = Color(hex: 0xFF0000, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFF0000) + + color = Color(hex: 0x00FF00, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x00FF00) + + color = Color(hex: 0x0000FF, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x0000FF) + + color = Color(hex: 0x000000, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x000000) + + color = Color(hex: 0xFFFFFF, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFFFFFF) + + color = Color(hex: 0x123456, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x123456) + + color = Color(hex: 0xFCA864, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFCA864) + + color = Color(hex: 0xFCA864, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFCA864) + + color = Color(hex: 0x1F2D3C, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x1F2D3C) + + } + + func testHexString() { + var color = Color.red + XCTAssertEqual(color.hexString, "#FF0000") + + color = Color.blue + XCTAssertEqual(color.hexString, "#0000FF") + + color = Color(hex: 0xABCDEF)! + XCTAssertEqual(color.hexString, "#ABCDEF") + + color = Color(hex: 0xABC)! + XCTAssertEqual(color.hexString, "#000ABC") + + color = Color.black + XCTAssertEqual(color.hexString, "#000000") + } + + func testShortHexString() { + var color: Color? = Color.red + XCTAssertEqual(color?.shortHexString, "#F00") + + color = Color.blue + XCTAssertEqual(color?.shortHexString, "#00F") + + color = Color(hexString: "#0F120F") + XCTAssertNil(color?.shortHexString) + + color = Color(hexString: "#8FFFF") + XCTAssertNil(color?.shortHexString) + } + + func testShortHexOrHexString() { + var color: Color? = Color.red + XCTAssertEqual(color?.shortHexOrHexString, "#F00") + + color = Color(hexString: "#8FFFFF") + XCTAssertEqual(color?.shortHexOrHexString, "#8FFFFF") + + color = Color(hexString: "#F") + XCTAssertEqual(color?.shortHexOrHexString, "#00000F") + + color = Color(hexString: "#11") + XCTAssertEqual(color?.shortHexOrHexString, "#001") + } + + func testComplementary() { + var color = Color.black + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 1) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + + color = Color.white + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 0) + XCTAssertEqual(b, 0) + + color = Color.red + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + } + + func testRandom() { + let color1 = Color.random + let color2 = Color.random + + XCTAssertNotEqual(color1, color2) + } + + // MARK: - Test methods + func testBlend() { + var color1 = Color.white + var color2 = Color.black + + var blendColor = Color.blend(color1, with: color2) + XCTAssertEqual(blendColor.rgbComponenets.red, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponenets.green, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponenets.blue, 0xFF / 2) + + color1 = Color(hex: 0x123456, transparency: 0.5)! + color2 = Color(hex: 0x665544, transparency: 0.7)! + + blendColor = Color.blend(color1, with: color2) + XCTAssertEqual(blendColor.rgbComponenets.red, (0x12 + 0x66) / 2) + XCTAssertEqual(blendColor.rgbComponenets.green, (0x34 + 0x55) / 2) + XCTAssertEqual(blendColor.rgbComponenets.blue, (0x56 + 0x44) / 2) + XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) + + blendColor = Color.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) + var output: Double = 0x12 * 0.7 + 0x66 * 0.3 + XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + output = 0x34 * 0.7 + 0x55 * 0.3 + XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + output = 0x56 * 0.7 + 0x44 * 0.3 + XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + output = 0.5 * 0.7 + 0.7 * 0.3 + XCTAssertEqual(blendColor.alpha, CGFloat(output)) + + blendColor = Color.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) + output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) + XCTAssertEqual(blendColor.alpha, CGFloat(output)) + + blendColor = Color.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) + XCTAssertEqual(blendColor, color1) + } + + // MARK: - Test initializers + func testInit() { + var color = Color(hex: 0xFFF) + XCTAssertEqual(color?.rgbComponenets.red, 0) + XCTAssertEqual(color?.rgbComponenets.green, 0xf) + XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0xFFFFFFF) + XCTAssertEqual(color?.rgbComponenets.red, 0xff) + XCTAssertEqual(color?.rgbComponenets.green, 0xff) + XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0x123456, transparency: 1.0) + XCTAssertEqual(color?.rgbComponenets.red, 0x12) + XCTAssertEqual(color?.rgbComponenets.green, 0x34) + XCTAssertEqual(color?.rgbComponenets.blue, 0x56) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0x999, transparency: 21.0) + XCTAssertEqual(color?.rgbComponenets.red, 0) + XCTAssertEqual(color?.rgbComponenets.green, 0x09) + XCTAssertEqual(color?.rgbComponenets.blue, 0x99) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0xaabbcc, transparency: 0.0) + XCTAssertEqual(color?.rgbComponenets.red, 0xaa) + XCTAssertEqual(color?.rgbComponenets.green, 0xbb) + XCTAssertEqual(color?.rgbComponenets.blue, 0xcc) + XCTAssertEqual(color?.alpha, 0.0) + + color = Color(hex: 0x1, transparency: 0.5) + XCTAssertEqual(color?.rgbComponenets.red, 0) + XCTAssertEqual(color?.rgbComponenets.green, 0) + XCTAssertEqual(color?.rgbComponenets.blue, 1) + XCTAssertEqual(color?.alpha, 0.5) + + let color1 = Color(hex: 0xFFF, transparency: -0.4) + let color2 = Color(hex: 0xFFF, transparency: 0) + XCTAssertEqual(color1, color2) + + let color3 = Color(hex: 0xFFF, transparency: 1.5) + let color4 = Color(hex: 0xFFF, transparency: 1) + XCTAssertEqual(color3, color4) + + } + + func testFailableInit() { + var color = Color(hexString: "0xFFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "#FFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "FFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "#ABC") + XCTAssertNotNil(color) + + color = Color(hexString: "#GGG") + XCTAssertNil(color) + + color = Color(hexString: "4#fff") + XCTAssertNil(color) + + color = Color(hexString: "FFFFFFF") + XCTAssertNotNil(color) + } + + func testInitWithComponents() { + var r1: CGFloat = 0 + var r2: CGFloat = 0 + var g1: CGFloat = 0 + var g2: CGFloat = 0 + var b1: CGFloat = 0 + var b2: CGFloat = 0 + var alpha1: CGFloat = 0 + var alpha2: CGFloat = 0 + + var color1 = Color(red: 255, green: 244, blue: 255, transparency: 2.0) + var color2 = Color(red: 1.0, green: 244.0 / 255.0, blue: 1.0, alpha: 2.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + + color1 = Color(red: 25, green: 244, blue: 55, transparency: -1.0) + color2 = Color(red: 25.0 / 255.0, green: 244.0 / 255.0, blue: 55.0 / 255.0, alpha: -1.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + + color1 = Color(red: 2, green: 4, blue: 5) + color2 = Color(red: 2.0 / 255.0, green: 4.0 / 255.0, blue: 5.0 / 255.0, alpha: 1.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + } + + func testFailableInitWithComponents() { + let color1 = Color(red: 258, green: 0, blue: 0) + XCTAssertNil(color1) + + let color2 = Color(red: 0, green: 258, blue: 0) + XCTAssertNil(color2) + + let color3 = Color(red: 0, green: 0, blue: 258) + XCTAssertNil(color3) + + let color4 = Color(red: 258, green: 258, blue: 258) + XCTAssertNil(color4) + + } + + func testFailableInitWithComplementaryColor() { + var color = Color(complementaryFor: Color.black) + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + + color?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 1) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + + color = Color(complementaryFor: Color.red) + color?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + } +} + + + + diff --git a/Tests/UIKitTests/UIColorExtensionsTests.swift b/Tests/UIKitTests/UIColorExtensionsTests.swift deleted file mode 100644 index ed63a0ff7..000000000 --- a/Tests/UIKitTests/UIColorExtensionsTests.swift +++ /dev/null @@ -1,388 +0,0 @@ -// -// UIColorExtensionsTests.swift -// SwifterSwift -// -// Created by Ewelina on 25/01/2017. -// Copyright © 2017 omaralbeik. All rights reserved. -// -import XCTest -@testable import SwifterSwift - -#if !os(macOS) -class UIColorExtensionsTests: XCTestCase { - - // MARK: - Test properties - func testRgbComponenets() { - XCTAssertEqual(UIColor.red.rgbComponenets.red, 255) - XCTAssertEqual(UIColor.red.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.red.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.green.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.green.rgbComponenets.green, 255) - XCTAssertEqual(UIColor.green.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.blue.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.blue.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.blue.rgbComponenets.blue, 255) - - XCTAssertEqual(UIColor.black.rgbComponenets.red, 0) - XCTAssertEqual(UIColor.black.rgbComponenets.green, 0) - XCTAssertEqual(UIColor.black.rgbComponenets.blue, 0) - - XCTAssertEqual(UIColor.white.rgbComponenets.red, 255) - XCTAssertEqual(UIColor.white.rgbComponenets.green, 255) - XCTAssertEqual(UIColor.white.rgbComponenets.blue, 255) - - XCTAssertEqual(UIColor(hex: 0x12FFFF)?.rgbComponenets.red, 0x12) - - } - - func testAlpha() { - var color: UIColor = UIColor.red - XCTAssertEqual(color.alpha, 1.0) - - color = UIColor.white.withAlphaComponent(0.5) - XCTAssertEqual(color.alpha, 0.5) - - color = UIColor(red: 0, green: 0, blue: 0, transparency: 0.7)! - XCTAssertEqual(color.alpha, 0.7) - - color = UIColor(red: 0, green: 0, blue: 0, transparency: 1.1)! - XCTAssertEqual(color.alpha, 1.0) - } - - // MARK: - Test properties - func testHsbaComponenets() { - var color = UIColor(hex: 0xFF0000, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = UIColor(hex: 0x00FF00, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (120/360)) / 1000)) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = UIColor(hex: 0x0000FF, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (240/360)) / 1000)) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = UIColor(hex: 0x000000, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 0.0) - - color = UIColor(hex: 0xFFFFFF, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = UIColor(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (210/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 79) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 34) - - color = UIColor(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (27/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 60) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 99) - - color = UIColor(hex: 0x1F2D3C, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (211/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 48) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 24) - } - - func testUInt() { - var color = UIColor(hex: 0xFF0000, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFF0000) - - color = UIColor(hex: 0x00FF00, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x00FF00) - - color = UIColor(hex: 0x0000FF, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x0000FF) - - color = UIColor(hex: 0x000000, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x000000) - - color = UIColor(hex: 0xFFFFFF, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFFFFFF) - - color = UIColor(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x123456) - - color = UIColor(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFCA864) - - color = UIColor(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFCA864) - - color = UIColor(hex: 0x1F2D3C, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x1F2D3C) - - } - - func testHexString() { - var color = UIColor.red - XCTAssertEqual(color.hexString, "#FF0000") - - color = UIColor.blue - XCTAssertEqual(color.hexString, "#0000FF") - - color = UIColor(hex: 0xABCDEF)! - XCTAssertEqual(color.hexString, "#ABCDEF") - - color = UIColor(hex: 0xABC)! - XCTAssertEqual(color.hexString, "#000ABC") - - color = UIColor.black - XCTAssertEqual(color.hexString, "#000000") - } - - func testShortHexString() { - var color: UIColor? = UIColor.red - XCTAssertEqual(color?.shortHexString, "#F00") - - color = UIColor.blue - XCTAssertEqual(color?.shortHexString, "#00F") - - color = UIColor(hexString: "#0F120F") - XCTAssertNil(color?.shortHexString) - - color = UIColor(hexString: "#8FFFF") - XCTAssertNil(color?.shortHexString) - } - - func testShortHexOrHexString() { - var color: UIColor? = UIColor.red - XCTAssertEqual(color?.shortHexOrHexString, "#F00") - - color = UIColor(hexString: "#8FFFFF") - XCTAssertEqual(color?.shortHexOrHexString, "#8FFFFF") - - color = UIColor(hexString: "#F") - XCTAssertEqual(color?.shortHexOrHexString, "#00000F") - - color = UIColor(hexString: "#11") - XCTAssertEqual(color?.shortHexOrHexString, "#001") - } - - func testComplementary() { - var color = UIColor.black - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - - color = UIColor.white - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 0) - XCTAssertEqual(b, 0) - - color = UIColor.red - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - } - - func testRandom() { - let color1 = UIColor.random - let color2 = UIColor.random - - XCTAssertNotEqual(color1, color2) - } - - // MARK: - Test methods - func testBlend() { - var color1 = UIColor.white - var color2 = UIColor.black - - var blendColor = UIColor.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, 0xFF / 2) - - color1 = UIColor(hex: 0x123456, transparency: 0.5)! - color2 = UIColor(hex: 0x665544, transparency: 0.7)! - - blendColor = UIColor.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, (0x12 + 0x66) / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, (0x34 + 0x55) / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, (0x56 + 0x44) / 2) - XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) - - blendColor = UIColor.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) - var output: Double = 0x12 * 0.7 + 0x66 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) - output = 0x34 * 0.7 + 0x55 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) - output = 0x56 * 0.7 + 0x44 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) - output = 0.5 * 0.7 + 0.7 * 0.3 - XCTAssertEqual(blendColor.alpha, CGFloat(output)) - - blendColor = UIColor.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) - output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) - output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) - output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) - output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) - XCTAssertEqual(blendColor.alpha, CGFloat(output)) - - blendColor = UIColor.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) - XCTAssertEqual(blendColor, color1) - } - - // MARK: - Test initializers - func testInit() { - var color = UIColor(hex: 0xFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0xf) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) - XCTAssertEqual(color?.alpha, 1.0) - - color = UIColor(hex: 0xFFFFFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0xff) - XCTAssertEqual(color?.rgbComponenets.green, 0xff) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) - XCTAssertEqual(color?.alpha, 1.0) - - color = UIColor(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.rgbComponenets.red, 0x12) - XCTAssertEqual(color?.rgbComponenets.green, 0x34) - XCTAssertEqual(color?.rgbComponenets.blue, 0x56) - XCTAssertEqual(color?.alpha, 1.0) - - color = UIColor(hex: 0x999, transparency: 21.0) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0x09) - XCTAssertEqual(color?.rgbComponenets.blue, 0x99) - XCTAssertEqual(color?.alpha, 1.0) - - color = UIColor(hex: 0xaabbcc, transparency: 0.0) - XCTAssertEqual(color?.rgbComponenets.red, 0xaa) - XCTAssertEqual(color?.rgbComponenets.green, 0xbb) - XCTAssertEqual(color?.rgbComponenets.blue, 0xcc) - XCTAssertEqual(color?.alpha, 0.0) - - color = UIColor(hex: 0x1, transparency: 0.5) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0) - XCTAssertEqual(color?.rgbComponenets.blue, 1) - XCTAssertEqual(color?.alpha, 0.5) - - let color1 = UIColor(hex: 0xFFF, transparency: -0.4) - let color2 = UIColor(hex: 0xFFF, transparency: 0) - XCTAssertEqual(color1, color2) - - let color3 = UIColor(hex: 0xFFF, transparency: 1.5) - let color4 = UIColor(hex: 0xFFF, transparency: 1) - XCTAssertEqual(color3, color4) - - } - - func testFailableInit() { - var color = UIColor(hexString: "0xFFFFFF") - XCTAssertNotNil(color) - - color = UIColor(hexString: "#FFFFFF") - XCTAssertNotNil(color) - - color = UIColor(hexString: "FFFFFF") - XCTAssertNotNil(color) - - color = UIColor(hexString: "#ABC") - XCTAssertNotNil(color) - - color = UIColor(hexString: "#GGG") - XCTAssertNil(color) - - color = UIColor(hexString: "4#fff") - XCTAssertNil(color) - - color = UIColor(hexString: "FFFFFFF") - XCTAssertNotNil(color) - } - - func testInitWithComponents() { - var r1: CGFloat = 0 - var r2: CGFloat = 0 - var g1: CGFloat = 0 - var g2: CGFloat = 0 - var b1: CGFloat = 0 - var b2: CGFloat = 0 - var alpha1: CGFloat = 0 - var alpha2: CGFloat = 0 - - var color1 = UIColor(red: 255, green: 244, blue: 255, transparency: 2.0) - var color2 = UIColor(red: 1.0, green: 244.0 / 255.0, blue: 1.0, alpha: 2.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - - color1 = UIColor(red: 25, green: 244, blue: 55, transparency: -1.0) - color2 = UIColor(red: 25.0 / 255.0, green: 244.0 / 255.0, blue: 55.0 / 255.0, alpha: -1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - - color1 = UIColor(red: 2, green: 4, blue: 5) - color2 = UIColor(red: 2.0 / 255.0, green: 4.0 / 255.0, blue: 5.0 / 255.0, alpha: 1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - } - - func testFailableInitWithComponents() { - let color1 = UIColor(red: 258, green: 0, blue: 0) - XCTAssertNil(color1) - - let color2 = UIColor(red: 0, green: 258, blue: 0) - XCTAssertNil(color2) - - let color3 = UIColor(red: 0, green: 0, blue: 258) - XCTAssertNil(color3) - - let color4 = UIColor(red: 258, green: 258, blue: 258) - XCTAssertNil(color4) - - } - - func testFailableInitWithComplementaryColor() { - var color = UIColor(complementaryFor: UIColor.black) - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - - color = UIColor(complementaryFor: UIColor.red) - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - } -} - -#endif From 6f7130c07b9a828ee6d3b1d14f344a8c167d0f71 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 28 Sep 2017 16:25:02 +0300 Subject: [PATCH 030/201] Fixes #255 --- .travis.yml | 3 +- SwifterSwift.xcodeproj/project.pbxproj | 42 ++++++++++++++------------ 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index e11b4422e..4156659b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,9 +26,8 @@ script: - set -o pipefail - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty + - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty - - xcodebuild clean build -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty after_success: - bash <(curl -s https://codecov.io/bash) - diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 88b974139..4d22a46ab 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -1540,8 +1540,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1616,8 +1616,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1686,7 +1686,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1762,7 +1762,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1832,7 +1832,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1909,7 +1909,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -1977,7 +1977,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; @@ -2053,7 +2053,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; @@ -2122,8 +2122,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; @@ -2190,8 +2190,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -2251,7 +2251,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; @@ -2318,7 +2319,8 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -2378,12 +2380,12 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = C3VKVFB3SA; + DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -2445,12 +2447,12 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = C3VKVFB3SA; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; From 3764736bf8fc6945185743c44142e8945bf4ae41 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 29 Sep 2017 13:01:28 +0300 Subject: [PATCH 031/201] fix conflicts Fixed conflicts and relocated tests to SharedTests folder --- SwifterSwift.xcodeproj/project.pbxproj | 10 +++++++++- .../ColorExtensionsTests.swift | 0 2 files changed, 9 insertions(+), 1 deletion(-) rename Tests/{UIKitTests => SharedTests}/ColorExtensionsTests.swift (100%) diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index ae67b0d3d..bcc7932cb 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -664,6 +664,7 @@ 07D8960F1F5ED8AB00FC894D /* CoreLocationTests */, 07D8960E1F5ED89A00FC894D /* CoreGraphicsTests */, 07C50D241F5EB03200F46E5A /* AppKitTests */, + D86A98EE1F7E50C90084EDCD /* SharedTests */, 07C50CCD1F5EAF2700F46E5A /* Info.plist */, 07C50D081F5EB03200F46E5A /* Resources */, 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */, @@ -703,7 +704,6 @@ 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */, 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */, 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */, - 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */, 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */, 07C50D131F5EB03200F46E5A /* UIImageExtensionsTests.swift */, 07C50D141F5EB03200F46E5A /* UIImageViewExtensionsTests.swift */, @@ -771,6 +771,14 @@ path = CoreLocationTests; sourceTree = ""; }; + D86A98EE1F7E50C90084EDCD /* SharedTests */ = { + isa = PBXGroup; + children = ( + 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */, + ); + path = SharedTests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ diff --git a/Tests/UIKitTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift similarity index 100% rename from Tests/UIKitTests/ColorExtensionsTests.swift rename to Tests/SharedTests/ColorExtensionsTests.swift From a874871df8c4734caa41d468062be9c685eb6553 Mon Sep 17 00:00:00 2001 From: Nick C Date: Sun, 1 Oct 2017 20:06:41 -0400 Subject: [PATCH 032/201] edited wording in readme edited wording in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 86fa501a4..edd6e98f9 100755 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ Check [Examples.md](https://github.com/SwifterSwift/SwifterSwift/tree/master/Exa ## Documentation -A complete documentation for all extensions with examples is available at [swifterswift.com/docs](http://swifterswift.com/docs) +Complete documentation for all extensions with examples is available at [swifterswift.com/docs](http://swifterswift.com/docs) @@ -239,7 +239,7 @@ It is always nice to talk with other people using SwifterSwift and exchange expe Special thanks to: - [Steven Deutsch](https://github.com/SD10) and [Luciano Almeida](https://github.com/LucianoPAlmeida) for their latest contributions to extensions, docs and tests. -- [Paweł Urbanek](https://github.com/pawurb) for adding tvOS, watchOS and macOS initial support and helping with extensions. +- [Paweł Urbanek](https://github.com/pawurb) for adding tvOS, watchOS, and macOS initial support and helping with extensions. - [Mert Akengin](https://github.com/PvtMert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swiftierswift.com) and logo. - [Abdul Rahman Dabbour](https://github.com/thedabbour) for helping document the project. - Many thanks to all other [contributors](https://github.com/SwifterSwift/SwifterSwift/graphs/contributors) of this project. From babadb490ee317b4c10630f3d452daaa3d79ac12 Mon Sep 17 00:00:00 2001 From: Nick C Date: Sun, 1 Oct 2017 20:10:21 -0400 Subject: [PATCH 033/201] fixed wording in changelog fixed wording in changelog --- CHANGELOG.md | 66 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d61bd950..382290ede 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,7 +79,7 @@ N/A ### API Breaking - **Swift 3.2** - - Code has been updated to Swift 3.2, please use [`v3.1.1`](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1) if you are still using Swift 3 or Xcode 8 + - Code has been updated to Swift 3.2; please use [`v3.1.1`](https://github.com/SwifterSwift/SwifterSwift/releases/tag/3.1.1) if you are still using Swift 3 or Xcode 8 - **SwifterSwift** - `userDefaults` is deprecated, use Apple's `UserDefaults.standard` instead. - `object(forKey: String)` is deprecated, use Apple's `UserDefaults.standard.object(forKey: _)` instead. @@ -111,13 +111,13 @@ N/A ### Enhancements - New **Date** extensions - - added `secondsSince(_ date: Date)` method to get number of seconds between two date. - - added `minutesSince(_ date: Date)` method to get number of minutes between two date. - - added `hoursSince(_ date: Date)` method to get number of hours between two date. - - added `daysSince(_ date: Date)` method to get number of days between two date. - - added `isInThisYear` property to check if date is in the current year. - - added `isInThisMonth` property to check if date is in the current month. - - added `isInThisWeek` property to check if date is in the current week. + - added `secondsSince(_ date: Date)` method to get a number of seconds between two dates. + - added `minutesSince(_ date: Date)` method to get a number of minutes between two date. + - added `hoursSince(_ date: Date)` method to get a number of hours between two dates. + - added `daysSince(_ date: Date)` method to get a number of days between two date. + - added `isInThisYear` property to check if the date is in the current year. + - added `isInThisMonth` property to check if the date is in the current month. + - added `isInThisWeek` property to check if the date is in the current week. - New **URLRequest** extensions - added `init?(urlString: String)` fallible initializer create a URLRequest from URL string. - New **UIWebView** extensions @@ -272,31 +272,31 @@ N/A - New **Array** extensions - added `removeAll` passing an array of items. - added `swap` and `safeSwap` extensions to swap to elements in an array. - - new `firstIndex` and `lastIndex` that return the (first or last) index where condition is true . - - new `indexes` extention that return indexes where condition is true . - - new `all` and `none` that checks if (all or none) of array elements matches condition. + - new `firstIndex` and `lastIndex` that returns the (first or last) index where the condition is true. + - new `indexes` extension that return indexes where the condition is true. + - new `all` and `none` that checks if (all or none) of array elements match condition. - new `last` extension to find the last element that matches condition. - new `reject` extension to filter elements that **not** matches condition. - - new `count` extension to count elements that matches condition. - - new `forEachReversed` extension to iterate over array in reverse order. + - new `count` extension to count elements that match condition. + - new `forEachReversed` extension to iterate over an array in reverse order. - new `accumulate` extension to reduces an array while returning each interim combination. - - new `forEach` with condition to a filtered interation over the array. - - new `keep` extention to keep all elements that in order are until the condition is false. + - new `forEach` with condition to a filtered interaction over the array. + - new `keep` extension to keep all elements that in order are until the condition is false. - new `take` extension that returns all elements that in order are until the condition is false. - new `skip` extension that returns all elements that in order are after the condition is false. - - new `filtered:map` extension to perform a map and filter operation in just one iteration. + - new `filtered: map` extension to perform a map and filter operation in just one iteration. - New **Character** extensions - added isLetter & isWhiteSpace extensions - new lowercased extension to lower case the character - new uppercased extension to upper case the character - New **Date** extensions - - new `isInWeekday` extension to check if date is within a weekday period + - new `isInWeekday` extension to check if the date is within a weekday period - New **Dictionary** extensions - - new `removeAll` extension to remove the values for all keys in a array. + - new `removeAll` extension to remove the values for all keys in an array. - new + operator to merge to dictionaries in a new one and += to merge one dictionary into another. - - new - operator to get a new dictionary with the values for all keys in a array removed and -= to remove the values for all keys in a array. + - new - operator to get a new dictionary with the values for all keys in an array removed and -= to remove the values for all keys in an array. - New **String** extensions - - new `matches` extension to check if string matches a regex pattern. + - new `matches` extension to check if the string matches a regex pattern. - New **Locale** extensions - new posix property extension to convenience create the "en_US_POSIX" locale. - New **CLLocation** extensions @@ -314,7 +314,7 @@ N/A ### Testing -This release has drastically increased test coverage: currently 92% . +This release has drastically increased test coverage: currently 92%. Areas affected are: **Foundation** @@ -362,7 +362,7 @@ Areas affected are: - added quick getter and setter for frame’s X and Y values - New **Array** extensions - - added `safeSwap` method as a fail safe way to swap to elements in an array + - added `safeSwap` method as a fail-safe way to swap to elements in an array - New **NSView** extensions - `borderColor` (IBInspectable) @@ -394,7 +394,7 @@ Areas affected are: - Improve Array extensions - properties with O(n) or higher complexity have been changed to methods - reduced shuffle method complexity by using Fisher-Yates algorithm and is now completely random - - `removeDuplicates` renamed to `duplicatesRemoved` + - `removeDuplicates` renamed to `duplicatesRemoved.` - remove generic constraint on `firstIndex(of:)` and `lastIndex(of:)` - Improve String extensions @@ -461,7 +461,7 @@ Fixed Cocoapods. # v1.6 This is the biggest update since v1.3! -With over 100 new extensions, improved Cocoa support, new tests and many minor bug fixes. +With over 100 new extensions, improved Cocoa support, new tests, and many minor bug fixes. ## New Extensions - CGColorExtensions @@ -618,7 +618,7 @@ Thanks to [matt](https://github.com/ythecombinator) # v1.3.9 -- Extension moved to Source directory, tests moved to Tests directory for a cleaner structure +- Extension moved to Source directory; tests moved to Tests directory for a cleaner structure --- @@ -672,7 +672,7 @@ Thanks to [matt](https://github.com/ythecombinator) ### DateExtensions: -Fixed a bug in DateExtensinos where year was not set correctly. Thanks to [songhailiang](https://github.com/songhailiang) you for reporting this bug. +Fixed a bug in DateExtensinos where the year was not set correctly. Thanks to [songhailiang](https://github.com/songhailiang) you for reporting this bug. --- @@ -705,22 +705,22 @@ Added [CollectionViewExtensions](https://github.com/omaralbeik/SwifterSwift/wiki ### ArrayExtensions: -- removed duplicated contains method -- use of reduce to remove duplicates (Thanks to [sairamkotha](https://github.com/sairamkotha)) +- removed duplicated contains a method +- use of reducing to remove duplicates (Thanks to [sairamkotha](https://github.com/sairamkotha)) --- # v1.3 This version adds **more than 90 new extensions** making it the widest extensions library available online for Swift 3 with **more than 360 properties and methods for more than 35 type**. -This is the biggest update since library launch! we're so excited 🤓 +This is the biggest update since library launch! We're so excited 🤓 Here are some changes: - Updated some properties and methods names to follow [Swift API Design Guidelines](https://developer.apple.com/videos/play/wwdc2016/403/). - Added default values to methods parameters (where possible). -- All units documentation has been re-written in xcode, +- All units documentation has been re-written in Xcode, - Now you see "**SwifterSwift:** " at the beginning of description to know the source of the extension while writing your code. - - All method parameters and return types has been documented in xcode as well. + - All method parameters and return types have been documented in Xcode as well. - All extensions documentation has been re-written in [Wiki](https://github.com/omaralbeik/SwifterSwift/wiki), separating properties from methods in different tables. - All extensions files re-organized in separate extensions based on type (properties, methods, initializers, ..) - Fixed some bugs where some extensions were not public. @@ -871,11 +871,11 @@ DoubleExtensions: - **asLocaleCurrency**: Return string with number and current locale currency StringExtensions: -- Fixed a bug in toDouble, toFloat, toFloat32, toFloat64 where number is not calculated if not in english +- Fixed a bug in toDouble, toFloat, toFloat32, toFloat64 where number is not calculated if not in English DateExtensions: - **adding(component, value)**: Return date by adding a component -- **nearestHourQuarter**: Return nearest quarter to date +- **nearestHourQuarter**: Return the nearest quarter to date - **nearestHalfHour**: Return nearest half hour to date - **changing(component, value)**: Return date by changing a component - Fixed a bug in nearestFiveMinutes, nearestTenMinutes where date was always rounded always to next 5, 10 mins From 423bd6e6179fa4a0fcd5c646df27b766bedde4d4 Mon Sep 17 00:00:00 2001 From: Caleb Kleveter Date: Mon, 2 Oct 2017 06:44:30 -0500 Subject: [PATCH 034/201] Setup swiftlint and pod lint for travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4156659b4..cddbadf93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ before_install: before_script: - bundle exec danger + - brew install swiftlint script: - set -o pipefail @@ -28,6 +29,8 @@ script: - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty + - swiftlint lint + - pod lib lint after_success: - bash <(curl -s https://codecov.io/bash) From 6dd06dd5e56199254eec399f8a3cccd7f8e9a6d2 Mon Sep 17 00:00:00 2001 From: Caleb Kleveter Date: Mon, 2 Oct 2017 07:06:19 -0500 Subject: [PATCH 035/201] Removed unnecessary swiftlint install --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cddbadf93..aa23db507 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,6 @@ before_install: before_script: - bundle exec danger - - brew install swiftlint script: - set -o pipefail From 2c94dcf64086028e0202b6417ac172042a153a83 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Mon, 2 Oct 2017 19:28:38 +0300 Subject: [PATCH 036/201] Fix typo in website name Thanks to @plbrooks for reporting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index edd6e98f9..27f209cd0 100755 --- a/README.md +++ b/README.md @@ -240,6 +240,6 @@ Special thanks to: - [Steven Deutsch](https://github.com/SD10) and [Luciano Almeida](https://github.com/LucianoPAlmeida) for their latest contributions to extensions, docs and tests. - [Paweł Urbanek](https://github.com/pawurb) for adding tvOS, watchOS, and macOS initial support and helping with extensions. -- [Mert Akengin](https://github.com/PvtMert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swiftierswift.com) and logo. +- [Mert Akengin](https://github.com/PvtMert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swifterswift.com) and logo. - [Abdul Rahman Dabbour](https://github.com/thedabbour) for helping document the project. - Many thanks to all other [contributors](https://github.com/SwifterSwift/SwifterSwift/graphs/contributors) of this project. From aa5a819452ab71c6ec21a49b018a85b2c15b252e Mon Sep 17 00:00:00 2001 From: Caleb Kleveter Date: Mon, 2 Oct 2017 14:17:54 -0500 Subject: [PATCH 037/201] Added swiftlint to Danger CI --- Dangerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dangerfile b/Dangerfile index 46be46921..d0859bd40 100644 --- a/Dangerfile +++ b/Dangerfile @@ -17,6 +17,8 @@ if source_changes_exist && no_changelog_entry warn(“The source files have been modified. Please consider adding a CHANGELOG entry if necessary.“) end +swiftlint.lint_files + # Checks if pull request is labeled as [WIP] warn(“This pull request is marked as Work in Progress. DO NOT MERGE!“) if github.pr_title.include? “[WIP]” From f8caf3f41533dd2efe54db7afc4bf443f64888b0 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 3 Oct 2017 13:42:06 +0300 Subject: [PATCH 038/201] changed rgbComponents method name --- Tests/SharedTests/ColorExtensionsTests.swift | 97 ++++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index 546c348bf..e7e870edc 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -23,29 +23,28 @@ import XCTest class ColorExtensionsTests: XCTestCase { // MARK: - Test properties - func testRgbComponenets() { - XCTAssertEqual(Color.red.rgbComponenets.red, 255) - XCTAssertEqual(Color.red.rgbComponenets.green, 0) - XCTAssertEqual(Color.red.rgbComponenets.blue, 0) + func testrgbComponents() { + XCTAssertEqual(Color.red.rgbComponents.red, 255) + XCTAssertEqual(Color.red.rgbComponents.green, 0) + XCTAssertEqual(Color.red.rgbComponents.blue, 0) - XCTAssertEqual(Color.green.rgbComponenets.red, 0) - XCTAssertEqual(Color.green.rgbComponenets.green, 255) - XCTAssertEqual(Color.green.rgbComponenets.blue, 0) + XCTAssertEqual(Color.green.rgbComponents.red, 0) + XCTAssertEqual(Color.green.rgbComponents.green, 255) + XCTAssertEqual(Color.green.rgbComponents.blue, 0) - XCTAssertEqual(Color.blue.rgbComponenets.red, 0) - XCTAssertEqual(Color.blue.rgbComponenets.green, 0) - XCTAssertEqual(Color.blue.rgbComponenets.blue, 255) + XCTAssertEqual(Color.blue.rgbComponents.red, 0) + XCTAssertEqual(Color.blue.rgbComponents.green, 0) + XCTAssertEqual(Color.blue.rgbComponents.blue, 255) - XCTAssertEqual(Color.black.rgbComponenets.red, 0) - XCTAssertEqual(Color.black.rgbComponenets.green, 0) - XCTAssertEqual(Color.black.rgbComponenets.blue, 0) + XCTAssertEqual(Color.black.rgbComponents.red, 0) + XCTAssertEqual(Color.black.rgbComponents.green, 0) + XCTAssertEqual(Color.black.rgbComponents.blue, 0) - XCTAssertEqual(Color.white.rgbComponenets.red, 255) - XCTAssertEqual(Color.white.rgbComponenets.green, 255) - XCTAssertEqual(Color.white.rgbComponenets.blue, 255) - - XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponenets.red, 0x12) + XCTAssertEqual(Color.white.rgbComponents.red, 255) + XCTAssertEqual(Color.white.rgbComponents.green, 255) + XCTAssertEqual(Color.white.rgbComponents.blue, 255) + XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponents.red, 0x12) } func testAlpha() { @@ -63,7 +62,7 @@ class ColorExtensionsTests: XCTestCase { } // MARK: - Test properties - func testHsbaComponenets() { + func testHsbaComponents() { var color = Color(hex: 0xFF0000, transparency: 1.0) XCTAssertEqual(color?.hsbaComponents.hue, 0.0) XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) @@ -216,36 +215,36 @@ class ColorExtensionsTests: XCTestCase { var color2 = Color.black var blendColor = Color.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.red, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.green, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, 0xFF / 2) color1 = Color(hex: 0x123456, transparency: 0.5)! color2 = Color(hex: 0x665544, transparency: 0.7)! blendColor = Color.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponenets.red, (0x12 + 0x66) / 2) - XCTAssertEqual(blendColor.rgbComponenets.green, (0x34 + 0x55) / 2) - XCTAssertEqual(blendColor.rgbComponenets.blue, (0x56 + 0x44) / 2) + XCTAssertEqual(blendColor.rgbComponents.red, (0x12 + 0x66) / 2) + XCTAssertEqual(blendColor.rgbComponents.green, (0x34 + 0x55) / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, (0x56 + 0x44) / 2) XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) blendColor = Color.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) var output: Double = 0x12 * 0.7 + 0x66 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) output = 0x34 * 0.7 + 0x55 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) output = 0x56 * 0.7 + 0x44 * 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = 0.5 * 0.7 + 0.7 * 0.3 XCTAssertEqual(blendColor.alpha, CGFloat(output)) blendColor = Color.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.red, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.green, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponenets.blue, Int(output)) + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) XCTAssertEqual(blendColor.alpha, CGFloat(output)) @@ -256,39 +255,39 @@ class ColorExtensionsTests: XCTestCase { // MARK: - Test initializers func testInit() { var color = Color(hex: 0xFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0xf) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0xf) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) color = Color(hex: 0xFFFFFFF) - XCTAssertEqual(color?.rgbComponenets.red, 0xff) - XCTAssertEqual(color?.rgbComponenets.green, 0xff) - XCTAssertEqual(color?.rgbComponenets.blue, 0xff) + XCTAssertEqual(color?.rgbComponents.red, 0xff) + XCTAssertEqual(color?.rgbComponents.green, 0xff) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) color = Color(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.rgbComponenets.red, 0x12) - XCTAssertEqual(color?.rgbComponenets.green, 0x34) - XCTAssertEqual(color?.rgbComponenets.blue, 0x56) + XCTAssertEqual(color?.rgbComponents.red, 0x12) + XCTAssertEqual(color?.rgbComponents.green, 0x34) + XCTAssertEqual(color?.rgbComponents.blue, 0x56) XCTAssertEqual(color?.alpha, 1.0) color = Color(hex: 0x999, transparency: 21.0) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0x09) - XCTAssertEqual(color?.rgbComponenets.blue, 0x99) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0x09) + XCTAssertEqual(color?.rgbComponents.blue, 0x99) XCTAssertEqual(color?.alpha, 1.0) color = Color(hex: 0xaabbcc, transparency: 0.0) - XCTAssertEqual(color?.rgbComponenets.red, 0xaa) - XCTAssertEqual(color?.rgbComponenets.green, 0xbb) - XCTAssertEqual(color?.rgbComponenets.blue, 0xcc) + XCTAssertEqual(color?.rgbComponents.red, 0xaa) + XCTAssertEqual(color?.rgbComponents.green, 0xbb) + XCTAssertEqual(color?.rgbComponents.blue, 0xcc) XCTAssertEqual(color?.alpha, 0.0) color = Color(hex: 0x1, transparency: 0.5) - XCTAssertEqual(color?.rgbComponenets.red, 0) - XCTAssertEqual(color?.rgbComponenets.green, 0) - XCTAssertEqual(color?.rgbComponenets.blue, 1) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0) + XCTAssertEqual(color?.rgbComponents.blue, 1) XCTAssertEqual(color?.alpha, 0.5) let color1 = Color(hex: 0xFFF, transparency: -0.4) From f00c8c14608a8afa20afee0168b4a42bbca853df Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 3 Oct 2017 15:14:29 +0300 Subject: [PATCH 039/201] Merged UIColorExtensions into ColorExtensions --- .../Extensions/Shared/ColorExtensions.swift | 54 +++++++++++++- .../Extensions/UIKit/UIColorExtensions.swift | 71 ------------------- SwifterSwift.xcodeproj/project.pbxproj | 8 --- 3 files changed, 52 insertions(+), 81 deletions(-) delete mode 100755 Sources/Extensions/UIKit/UIColorExtensions.swift diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index eb9598299..014f8202a 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -19,7 +19,29 @@ // MARK: - Properties public extension Color { - + + /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). + public var uInt: UInt { + var colorAsUInt32: UInt32 = 0 + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + var a: CGFloat = 0 + + self.getRed(&r, green: &g, blue: &b, alpha: &a) + + colorAsUInt32 += UInt32(r * 255.0) << 16 + colorAsUInt32 += UInt32(g * 255.0) << 8 + colorAsUInt32 += UInt32(b * 255.0) + + return UInt(colorAsUInt32) + } + + /// SwifterSwift: Get color complementary (read-only, if applicable). + public var complementary: Color? { + return Color.init(complementaryFor: self) + } + /// SwifterSwift: Random color. public static var random: Color { let r = Int(arc4random_uniform(255)) @@ -166,7 +188,35 @@ public extension Color { // MARK: - Initializers public extension Color { - + + /// SwifterSwift: Create Color from a complementary of a Color (if applicable). + /// + /// - Parameter color: color of which opposite color is desired. + public convenience init?(complementaryFor color: Color) { + let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() + let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in + if color.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { + let oldComponents = color.cgColor.components + let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] + let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) + let colorOut = Color(cgColor: colorRef!) + return colorOut + } else { + return color + } + } + + let c = convertColorToRGBSpace(color) + guard let componentColors = c?.cgColor.components else { + return nil + } + + let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 + let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 + let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 + self.init(red: r, green: g, blue: b, alpha: 1.0) + } + /// SwifterSwift: Create NSColor from RGB values with optional transparency. /// /// - Parameters: diff --git a/Sources/Extensions/UIKit/UIColorExtensions.swift b/Sources/Extensions/UIKit/UIColorExtensions.swift deleted file mode 100755 index 17698e7ac..000000000 --- a/Sources/Extensions/UIKit/UIColorExtensions.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// UIColorExtensions.swift -// SwifterSwift -// -// Created by Omar Albeik on 8/6/16. -// Copyright © 2016 Omar Albeik. All rights reserved. -// - -#if os(iOS) || os(tvOS) || os(watchOS) -import UIKit - -// MARK: - Properties -public extension UIColor { - - /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). - public var uInt: UInt { - var colorAsUInt32: UInt32 = 0 - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - var a: CGFloat = 0 - - self.getRed(&r, green: &g, blue: &b, alpha: &a) - - colorAsUInt32 += UInt32(r * 255.0) << 16 - colorAsUInt32 += UInt32(g * 255.0) << 8 - colorAsUInt32 += UInt32(b * 255.0) - - return UInt(colorAsUInt32) - } - - /// SwifterSwift: Get color complementary (read-only, if applicable). - public var complementary: UIColor? { - return UIColor.init(complementaryFor: self) - } - -} - -// MARK: - Initializers -public extension UIColor { - - /// SwifterSwift: Create UIColor from a complementary of a UIColor (if applicable). - /// - /// - Parameter color: color of which opposite color is desired. - public convenience init?(complementaryFor color: UIColor) { - let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() - let convertColorToRGBSpace: ((_ color: UIColor) -> UIColor?) = { color -> UIColor? in - if color.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { - let oldComponents = color.cgColor.components - let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] - let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) - let colorOut = UIColor(cgColor: colorRef!) - return colorOut - } else { - return color - } - } - - let c = convertColorToRGBSpace(color) - guard let componentColors = c?.cgColor.components else { - return nil - } - - let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 - let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 - let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 - self.init(red: r, green: g, blue: b, alpha: 1.0) - } - -} -#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 651e6d49d..1718b5d08 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -38,7 +38,6 @@ 07B7F1931F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; 07B7F1941F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; 07B7F1951F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; - 07B7F1961F5EB42000E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; 07B7F1981F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; 07B7F1991F5EB42000E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; @@ -60,7 +59,6 @@ 07B7F1A91F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; 07B7F1AA1F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; - 07B7F1AC1F5EB42000E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; 07B7F1AE1F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; 07B7F1AF1F5EB42000E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; @@ -82,7 +80,6 @@ 07B7F1BF1F5EB42200E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; 07B7F1C01F5EB42200E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; 07B7F1C11F5EB42200E6F910 /* UICollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */; }; - 07B7F1C21F5EB42200E6F910 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */; }; 07B7F1C31F5EB42200E6F910 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */; }; 07B7F1C41F5EB42200E6F910 /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */; }; 07B7F1C51F5EB42200E6F910 /* UILabelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */; }; @@ -381,7 +378,6 @@ 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItemExtensions.swift; sourceTree = ""; }; 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewExtensions.swift; sourceTree = ""; }; - 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; }; 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelExtensions.swift; sourceTree = ""; }; @@ -630,7 +626,6 @@ 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */, 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */, 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */, - 07B7F1801F5EB41600E6F910 /* UIColorExtensions.swift */, 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */, 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */, 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */, @@ -1189,7 +1184,6 @@ 07B7F2101F5EB43C00E6F910 /* DateExtensions.swift in Sources */, 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F19E1F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, - 07B7F1961F5EB42000E6F910 /* UIColorExtensions.swift in Sources */, 07B7F20F1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, 07B7F19C1F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */, 07B7F1A51F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */, @@ -1246,7 +1240,6 @@ 07B7F1FE1F5EB43C00E6F910 /* DateExtensions.swift in Sources */, 07B7F2021F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F1B41F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, - 07B7F1AC1F5EB42000E6F910 /* UIColorExtensions.swift in Sources */, 07B7F1FD1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, 07B7F1B21F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */, 07B7F1BB1F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */, @@ -1303,7 +1296,6 @@ 07B7F1EC1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, 07B7F1F01F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F1CA1F5EB42200E6F910 /* UISegmentedControlExtensions.swift in Sources */, - 07B7F1C21F5EB42200E6F910 /* UIColorExtensions.swift in Sources */, 07B7F1EB1F5EB43B00E6F910 /* DataExtensions.swift in Sources */, 07B7F1C81F5EB42200E6F910 /* UINavigationItemExtensions.swift in Sources */, 07B7F1D11F5EB42200E6F910 /* UITextViewExtensions.swift in Sources */, From 33237964def1c2e8e8acfaa56b3aac37b833ccc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Tue, 3 Oct 2017 20:19:55 +0200 Subject: [PATCH 040/201] Add convenience initializer init(text:) to UILabel, including a test --- Sources/Extensions/UIKit/UILabelExtensions.swift | 6 ++++++ Tests/UIKitTests/UILabelExtensionsTests.swift | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/Sources/Extensions/UIKit/UILabelExtensions.swift b/Sources/Extensions/UIKit/UILabelExtensions.swift index 7b11e7a2b..c78479424 100644 --- a/Sources/Extensions/UIKit/UILabelExtensions.swift +++ b/Sources/Extensions/UIKit/UILabelExtensions.swift @@ -12,6 +12,12 @@ import UIKit // MARK: - Methods public extension UILabel { + /// SwifterSwift: Initialize a UILabel with text + public convenience init(text: String?) { + self.init() + self.text = text + } + /// SwifterSwift: Required height for a label public var requiredHeight: CGFloat { let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: CGFloat.greatestFiniteMagnitude)) diff --git a/Tests/UIKitTests/UILabelExtensionsTests.swift b/Tests/UIKitTests/UILabelExtensionsTests.swift index 52df4e918..8afb88897 100644 --- a/Tests/UIKitTests/UILabelExtensionsTests.swift +++ b/Tests/UIKitTests/UILabelExtensionsTests.swift @@ -12,6 +12,11 @@ import XCTest #if os(iOS) || os(tvOS) class UILabelExtensionsTests: XCTestCase { + func testInitWithText() { + let label = UILabel(text: "Hello world") + XCTAssertEqual(label.text, "Hello world") + } + func testrequiredHeight() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let label = UILabel(frame: frame) From 8b1c183276d6c6602d9c008599520082f9b81f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Wed, 4 Oct 2017 14:57:39 +0200 Subject: [PATCH 041/201] Add random to Bool, including a test --- Sources/Extensions/SwiftStdlib/BoolExtensions.swift | 9 +++++++++ Tests/SwiftStdlibTests/BoolExtensionsTests.swift | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift index f1c747efd..b15be0ab0 100644 --- a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift @@ -37,6 +37,15 @@ public extension Bool { public var toggled: Bool { return !self } + + /// SwifterSwift: Returns a random boolean value. + /// + /// Bool.random -> true + /// Bool.random -> false + /// + public static var random: Bool { + return arc4random_uniform(2) == 1 + } } diff --git a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift index 96b616324..36bf0121a 100644 --- a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift @@ -25,6 +25,18 @@ class BoolExtensionsTests: XCTestCase { XCTAssertFalse(true.toggled) XCTAssert(false.toggled) } + + func testRandom() { + var yes = 0, no = 0 + for _ in 1...10000 { + if Bool.random { + yes += 1 + } else { + no += 1 + } + } + XCTAssert(yes >= 10 && no >= 10) + } func testToggle() { var t = true From 0ba137c8f487acac17cfe073e6f30b3cae8ce6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Wed, 4 Oct 2017 15:20:27 +0200 Subject: [PATCH 042/201] Add and(_:) and or(_:) to NSPredicate, including appropriate tests --- .../CoreData/NSPredicateExtensions.swift | 24 +++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 34 +++++++++++++++++++ .../NSPredicateExtensionsTests.swift | 32 +++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 Sources/Extensions/CoreData/NSPredicateExtensions.swift create mode 100644 Tests/CoreDataTests/NSPredicateExtensionsTests.swift diff --git a/Sources/Extensions/CoreData/NSPredicateExtensions.swift b/Sources/Extensions/CoreData/NSPredicateExtensions.swift new file mode 100644 index 000000000..f9b41981d --- /dev/null +++ b/Sources/Extensions/CoreData/NSPredicateExtensions.swift @@ -0,0 +1,24 @@ +// +// NSPredicateExtensions.swift +// SwifterSwift +// +// Created by Max Härtwig on 04.10.17. +// + +import CoreData +import Foundation + +// MARK: - Methods +public extension NSPredicate { + + /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. + public func and(_ predicate: NSPredicate) -> NSCompoundPredicate { + return NSCompoundPredicate(andPredicateWithSubpredicates: [self, predicate]) + } + + /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. + public func or(_ predicate: NSPredicate) -> NSCompoundPredicate { + return NSCompoundPredicate(orPredicateWithSubpredicates: [self, predicate]) + } + +} diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 01ec19229..76b9b4131 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -311,6 +311,13 @@ 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; + 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; + 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; + 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; + 9D4914861F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; + 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; + 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; + 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -449,6 +456,8 @@ 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; + 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; + 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -592,6 +601,7 @@ 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, 07B7F1651F5EB41600E6F910 /* Foundation */, 07B7F1791F5EB41600E6F910 /* UIKit */, + 9D4914811F85135600F3868F /* CoreData */, 07D8960D1F5ED85400FC894D /* CoreGraphics */, 07D8960C1F5ED84400FC894D /* CoreLocation */, 07B7F15C1F5EB41600E6F910 /* AppKit */, @@ -658,6 +668,7 @@ 077BA0931F6BE93000D9C4AC /* SwiftStdlibTests */, 07C50CF91F5EB03200F46E5A /* FoundationTests */, 07C50D0D1F5EB03200F46E5A /* UIKitTests */, + 9D4914871F8515A100F3868F /* CoreDataTests */, 07D8960F1F5ED8AB00FC894D /* CoreLocationTests */, 07D8960E1F5ED89A00FC894D /* CoreGraphicsTests */, 07C50D241F5EB03200F46E5A /* AppKitTests */, @@ -768,6 +779,22 @@ path = CoreLocationTests; sourceTree = ""; }; + 9D4914811F85135600F3868F /* CoreData */ = { + isa = PBXGroup; + children = ( + 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */, + ); + path = CoreData; + sourceTree = ""; + }; + 9D4914871F8515A100F3868F /* CoreDataTests */ = { + isa = PBXGroup; + children = ( + 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */, + ); + path = CoreDataTests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1169,6 +1196,7 @@ 07B7F2331F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F2131F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, @@ -1226,6 +1254,7 @@ 07B7F2391F5EB45200E6F910 /* NSAttributedStringExtensions.swift in Sources */, 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F2011F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, 07B7F2001F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2051F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, @@ -1283,6 +1312,7 @@ 07B7F22D1F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, 07B7F1C31F5EB42200E6F910 /* UIImageExtensions.swift in Sources */, 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F1EF1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */, 07B7F1EE1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F1F31F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */, @@ -1331,6 +1361,7 @@ 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */, 07B7F1E41F5EB43B00E6F910 /* StringExtensions.swift in Sources */, + 9D4914861F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F2271F5EB44600E6F910 /* NSViewExtensions.swift in Sources */, 07B7F2211F5EB44600E6F910 /* CGFloatExtensions.swift in Sources */, ); @@ -1356,6 +1387,7 @@ 07C50D2C1F5EB04600F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, 077BA0B91F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, 07C50D591F5EB05000F46E5A /* CharacterExtensionsTests.swift in Sources */, + 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */, 07C50D571F5EB05000F46E5A /* ArrayExtensionsTests.swift in Sources */, 07C50D5F1F5EB05000F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D371F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, @@ -1408,6 +1440,7 @@ 07C50D421F5EB04700F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, 077BA0BA1F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, 07C50D671F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, + 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */, 07C50D651F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */, 07C50D6D1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D4D1F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, @@ -1444,6 +1477,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */, 07C50D731F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */, 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */, 07C50D7E1F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */, diff --git a/Tests/CoreDataTests/NSPredicateExtensionsTests.swift b/Tests/CoreDataTests/NSPredicateExtensionsTests.swift new file mode 100644 index 000000000..965104b21 --- /dev/null +++ b/Tests/CoreDataTests/NSPredicateExtensionsTests.swift @@ -0,0 +1,32 @@ +// +// NSPredicateExtensionsTests.swift +// SwifterSwift +// +// Created by Max Härtwig on 04.10.17. +// + +import XCTest +import CoreData + +class NSPredicateExtensionsTests: XCTestCase { + + func testAndPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let andPredicate = predicate1.and(predicate2) + XCTAssert(andPredicate.compoundPredicateType == .and) + if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOrPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let orPredicate = predicate1.or(predicate2) + XCTAssert(orPredicate.compoundPredicateType == .or) + if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } +} From ada8a113eaabcaee958826acfaefc92ca5ea52d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Wed, 4 Oct 2017 20:35:55 +0200 Subject: [PATCH 043/201] Add not property to NSPredicate, including a test --- .../Extensions/CoreData/NSPredicateExtensions.swift | 10 ++++++++++ Tests/CoreDataTests/NSPredicateExtensionsTests.swift | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/Sources/Extensions/CoreData/NSPredicateExtensions.swift b/Sources/Extensions/CoreData/NSPredicateExtensions.swift index f9b41981d..c032c7bef 100644 --- a/Sources/Extensions/CoreData/NSPredicateExtensions.swift +++ b/Sources/Extensions/CoreData/NSPredicateExtensions.swift @@ -8,6 +8,16 @@ import CoreData import Foundation +// MARK: - Methods +public extension NSPredicate { + + /// SwifterSwift: Returns a new predicate formed by NOT-ing the predicate. + public var not: NSCompoundPredicate { + return NSCompoundPredicate(notPredicateWithSubpredicate: self) + } + +} + // MARK: - Methods public extension NSPredicate { diff --git a/Tests/CoreDataTests/NSPredicateExtensionsTests.swift b/Tests/CoreDataTests/NSPredicateExtensionsTests.swift index 965104b21..af329d795 100644 --- a/Tests/CoreDataTests/NSPredicateExtensionsTests.swift +++ b/Tests/CoreDataTests/NSPredicateExtensionsTests.swift @@ -10,6 +10,15 @@ import CoreData class NSPredicateExtensionsTests: XCTestCase { + func testNot() { + let predicate = NSPredicate(format: "a < 7") + let notPredicate = predicate.not + XCTAssert(notPredicate.compoundPredicateType == .not) + if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate]) + } + } + func testAndPredicate() { let predicate1 = NSPredicate(format: "a < 7") let predicate2 = NSPredicate(format: "a > 3") From bd6bddb861b9602bb773d688ab2a5c0b6be869ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Wed, 4 Oct 2017 20:44:24 +0200 Subject: [PATCH 044/201] Add withPredicate(_:) function to NSFetchRequest, including a test --- .../CoreData/NSFetchRequestExtensions.swift | 19 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 ++++++++++++++++++ .../NSFetchRequestExtensionsTests.swift | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 Sources/Extensions/CoreData/NSFetchRequestExtensions.swift create mode 100644 Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift diff --git a/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift b/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift new file mode 100644 index 000000000..1581483fb --- /dev/null +++ b/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift @@ -0,0 +1,19 @@ +// +// NSFetchRequestExtensions.swift +// SwifterSwift +// +// Created by Max Härtwig on 04.10.17. +// + +import CoreData +import Foundation + +// MARK: - Methods +public extension NSFetchRequest { + + /// SwifterSwift: Returns the fetch request with the given predicate. + @objc public func withPredicate(_ predicate: NSPredicate) -> NSFetchRequest { + self.predicate = predicate + return self + } +} diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 76b9b4131..15fc7b51f 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -318,6 +318,13 @@ 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; + 9D49148D1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; + 9D49148E1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; + 9D49148F1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; + 9D4914901F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; + 9D4914921F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; + 9D4914931F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; + 9D4914941F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -458,6 +465,8 @@ 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; + 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchRequestExtensions.swift; sourceTree = ""; }; + 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchRequestExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -782,6 +791,7 @@ 9D4914811F85135600F3868F /* CoreData */ = { isa = PBXGroup; children = ( + 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */, 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */, ); path = CoreData; @@ -790,6 +800,7 @@ 9D4914871F8515A100F3868F /* CoreDataTests */ = { isa = PBXGroup; children = ( + 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */, 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */, ); path = CoreDataTests; @@ -1162,6 +1173,7 @@ buildActionMask = 2147483647; files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 9D49148D1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, @@ -1220,6 +1232,7 @@ buildActionMask = 2147483647; files = ( 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 9D49148E1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1BD1F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, @@ -1278,6 +1291,7 @@ buildActionMask = 2147483647; files = ( 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, + 9D49148F1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1D31F5EB42200E6F910 /* UIViewExtensions.swift in Sources */, @@ -1356,6 +1370,7 @@ 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */, 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, + 9D4914901F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, @@ -1412,6 +1427,7 @@ 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, + 9D4914921F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D611F5EB05000F46E5A /* LocaleExtensionsTests.swift in Sources */, @@ -1465,6 +1481,7 @@ 07C50D721F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D411F5EB04700F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D6C1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 9D4914931F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D6B1F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D691F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D6F1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, @@ -1490,6 +1507,7 @@ 07C50D791F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, + 9D4914941F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, diff --git a/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift b/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift new file mode 100644 index 000000000..7a23f2688 --- /dev/null +++ b/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift @@ -0,0 +1,18 @@ +// +// NSFetchRequestExtensionsTests.swift +// SwifterSwift +// +// Created by Max Härtwig on 04.10.17. +// + +import XCTest +import CoreData + +class NSFetchRequestExtensionsTests: XCTestCase { + + func testWithPredicate() { + let predicate = NSPredicate(format: "age < 23") + let fetchRequest = NSFetchRequest(entityName: "entity").withPredicate(predicate) + XCTAssertEqual(fetchRequest.predicate, predicate) + } +} From 5efd48f2e623254062b80e763b314263d812e735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Wed, 4 Oct 2017 13:30:37 +0200 Subject: [PATCH 045/201] Add localized(comment:) function to String --- Sources/Extensions/SwiftStdlib/StringExtensions.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 7b42e6d2e..37e8a89e6 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -371,6 +371,14 @@ public extension String { } return result } + + /// SwifterSwift: Returns a localized string, with an optional comment for translators. + /// + /// "Hello world".localized -> Hallo Welt + /// + public func localized(comment: String = "") -> String { + return NSLocalizedString(self, comment: comment) + } /// SwifterSwift: The most common character in string. /// From 5634f7af0bb8c18a2af09c8a6b476f0238bfde88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Ha=CC=88rtwig?= Date: Thu, 5 Oct 2017 10:12:40 +0200 Subject: [PATCH 046/201] Remove NSFetchRequest extensions and move NSPredicate extensions to Foundation --- .../CoreData/NSFetchRequestExtensions.swift | 19 ---------- .../NSPredicateExtensions.swift | 1 - SwifterSwift.xcodeproj/project.pbxproj | 38 +------------------ .../NSFetchRequestExtensionsTests.swift | 18 --------- .../NSPredicateExtensionsTests.swift | 2 +- 5 files changed, 3 insertions(+), 75 deletions(-) delete mode 100644 Sources/Extensions/CoreData/NSFetchRequestExtensions.swift rename Sources/Extensions/{CoreData => Foundation}/NSPredicateExtensions.swift (98%) delete mode 100644 Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift rename Tests/{CoreDataTests => FoundationTests}/NSPredicateExtensionsTests.swift (97%) diff --git a/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift b/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift deleted file mode 100644 index 1581483fb..000000000 --- a/Sources/Extensions/CoreData/NSFetchRequestExtensions.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// NSFetchRequestExtensions.swift -// SwifterSwift -// -// Created by Max Härtwig on 04.10.17. -// - -import CoreData -import Foundation - -// MARK: - Methods -public extension NSFetchRequest { - - /// SwifterSwift: Returns the fetch request with the given predicate. - @objc public func withPredicate(_ predicate: NSPredicate) -> NSFetchRequest { - self.predicate = predicate - return self - } -} diff --git a/Sources/Extensions/CoreData/NSPredicateExtensions.swift b/Sources/Extensions/Foundation/NSPredicateExtensions.swift similarity index 98% rename from Sources/Extensions/CoreData/NSPredicateExtensions.swift rename to Sources/Extensions/Foundation/NSPredicateExtensions.swift index c032c7bef..4043f5dbb 100644 --- a/Sources/Extensions/CoreData/NSPredicateExtensions.swift +++ b/Sources/Extensions/Foundation/NSPredicateExtensions.swift @@ -5,7 +5,6 @@ // Created by Max Härtwig on 04.10.17. // -import CoreData import Foundation // MARK: - Methods diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 15fc7b51f..6f8c88288 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -318,13 +318,6 @@ 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; - 9D49148D1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; - 9D49148E1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; - 9D49148F1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; - 9D4914901F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */; }; - 9D4914921F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; - 9D4914931F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; - 9D4914941F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -465,8 +458,6 @@ 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; - 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchRequestExtensions.swift; sourceTree = ""; }; - 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFetchRequestExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -610,7 +601,6 @@ 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, 07B7F1651F5EB41600E6F910 /* Foundation */, 07B7F1791F5EB41600E6F910 /* UIKit */, - 9D4914811F85135600F3868F /* CoreData */, 07D8960D1F5ED85400FC894D /* CoreGraphics */, 07D8960C1F5ED84400FC894D /* CoreLocation */, 07B7F15C1F5EB41600E6F910 /* AppKit */, @@ -634,6 +624,7 @@ 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */, 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */, 07B7F1621F5EB41600E6F910 /* NSAttributedStringExtensions.swift */, + 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */, 07B7F1781F5EB41600E6F910 /* URLExtensions.swift */, 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */, 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */, @@ -677,7 +668,6 @@ 077BA0931F6BE93000D9C4AC /* SwiftStdlibTests */, 07C50CF91F5EB03200F46E5A /* FoundationTests */, 07C50D0D1F5EB03200F46E5A /* UIKitTests */, - 9D4914871F8515A100F3868F /* CoreDataTests */, 07D8960F1F5ED8AB00FC894D /* CoreLocationTests */, 07D8960E1F5ED89A00FC894D /* CoreGraphicsTests */, 07C50D241F5EB03200F46E5A /* AppKitTests */, @@ -695,6 +685,7 @@ 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */, 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */, 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */, + 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */, 07C50D071F5EB03200F46E5A /* URLExtensionsTests.swift */, 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */, 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */, @@ -788,24 +779,6 @@ path = CoreLocationTests; sourceTree = ""; }; - 9D4914811F85135600F3868F /* CoreData */ = { - isa = PBXGroup; - children = ( - 9D49148C1F8561BF00F3868F /* NSFetchRequestExtensions.swift */, - 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */, - ); - path = CoreData; - sourceTree = ""; - }; - 9D4914871F8515A100F3868F /* CoreDataTests */ = { - isa = PBXGroup; - children = ( - 9D4914911F85623000F3868F /* NSFetchRequestExtensionsTests.swift */, - 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */, - ); - path = CoreDataTests; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1173,7 +1146,6 @@ buildActionMask = 2147483647; files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, - 9D49148D1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, @@ -1232,7 +1204,6 @@ buildActionMask = 2147483647; files = ( 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, - 9D49148E1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1BD1F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, @@ -1291,7 +1262,6 @@ buildActionMask = 2147483647; files = ( 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, - 9D49148F1F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1D31F5EB42200E6F910 /* UIViewExtensions.swift in Sources */, @@ -1370,7 +1340,6 @@ 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */, 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, - 9D4914901F8561BF00F3868F /* NSFetchRequestExtensions.swift in Sources */, 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, @@ -1427,7 +1396,6 @@ 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, - 9D4914921F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D611F5EB05000F46E5A /* LocaleExtensionsTests.swift in Sources */, @@ -1481,7 +1449,6 @@ 07C50D721F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D411F5EB04700F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D6C1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, - 9D4914931F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D6B1F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D691F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D6F1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, @@ -1507,7 +1474,6 @@ 07C50D791F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, - 9D4914941F85623000F3868F /* NSFetchRequestExtensionsTests.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, diff --git a/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift b/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift deleted file mode 100644 index 7a23f2688..000000000 --- a/Tests/CoreDataTests/NSFetchRequestExtensionsTests.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// NSFetchRequestExtensionsTests.swift -// SwifterSwift -// -// Created by Max Härtwig on 04.10.17. -// - -import XCTest -import CoreData - -class NSFetchRequestExtensionsTests: XCTestCase { - - func testWithPredicate() { - let predicate = NSPredicate(format: "age < 23") - let fetchRequest = NSFetchRequest(entityName: "entity").withPredicate(predicate) - XCTAssertEqual(fetchRequest.predicate, predicate) - } -} diff --git a/Tests/CoreDataTests/NSPredicateExtensionsTests.swift b/Tests/FoundationTests/NSPredicateExtensionsTests.swift similarity index 97% rename from Tests/CoreDataTests/NSPredicateExtensionsTests.swift rename to Tests/FoundationTests/NSPredicateExtensionsTests.swift index af329d795..867d49375 100644 --- a/Tests/CoreDataTests/NSPredicateExtensionsTests.swift +++ b/Tests/FoundationTests/NSPredicateExtensionsTests.swift @@ -6,7 +6,7 @@ // import XCTest -import CoreData +@testable import SwifterSwift class NSPredicateExtensionsTests: XCTestCase { From fb7225aa61e0022fd98421333948a0d6526aff1d Mon Sep 17 00:00:00 2001 From: Luciano Date: Fri, 6 Oct 2017 22:30:18 -0300 Subject: [PATCH 047/201] Bug fixes and performance improvements on the string and array exentesions. --- .../Extensions/SwiftStdlib/ArrayExtensions.swift | 15 +++++++++++++-- .../Extensions/SwiftStdlib/StringExtensions.swift | 11 +++++------ Tests/SwiftStdlibTests/ArrayExtensionsTests.swift | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index a5832ba0a..1cfa68d30 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -494,7 +494,11 @@ public extension Array where Element: Equatable { /// public mutating func removeDuplicates() { // Thanks to https://github.com/sairamkotha for improving the method - self = reduce([]) { $0.contains($1) ? $0 : $0 + [$1] } + self = reduce(into: [Element]()) { + if !$0.contains($1) { + $0.append($1) + } + } } /// SwifterSwift: Return array with all duplicate elements removed. @@ -505,7 +509,14 @@ public extension Array where Element: Equatable { /// - Returns: an array of unique elements. public func duplicatesRemoved() -> [Element] { // Thanks to https://github.com/sairamkotha for improving the property - return reduce([]) { ($0 as [Element]).contains($1) ? $0 : $0 + [$1] } + var noDuplicates: [Element] = [] + return reduce(into: [Element]()) { + if !noDuplicates.contains($1) { + noDuplicates.append($1) + } else { + $0.append($1) + } + } } /// SwifterSwift: First index of a given item in an array. diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 7b42e6d2e..0ce191deb 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -378,12 +378,11 @@ public extension String { /// /// - Returns: The most common character. public func mostCommonCharacter() -> String { - let mostCommon = withoutSpacesAndNewLines.characters.reduce([Character: Int]()) { - var counts = $0 - counts[$1] = ($0[$1] ?? 0) + 1 - return counts - }.max { $0.1 < $1.1 }?.0 - return mostCommon?.string ?? "" + let mostCommon = withoutSpacesAndNewLines.characters.reduce(into: [Character: Int]()) { + let count = $0[$1] ?? 0 + $0[$1] = count + 1 + }.max { $0.1 < $1.1 }?.0 + return mostCommon?.string ?? "" } /// SwifterSwift: Reversed string. diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index cdd213c8e..9d20e5bfb 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -145,7 +145,8 @@ class ArrayExtensionsTests: XCTestCase { } func testDuplicatesRemoved() { - XCTAssertEqual([1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved(), [1, 2, 3, 4, 5]) + XCTAssertEqual([1, 2, 2, 3, 4, 5, 5].duplicatesRemoved(), [2, 5]) + XCTAssertEqual(["h", "e", "l", "l", "o"].duplicatesRemoved(), ["l"]) } func testItemAtIndex() { From 706dbcc914b160262b59694c3d469913dadcf6bf Mon Sep 17 00:00:00 2001 From: Luciano Date: Fri, 6 Oct 2017 22:42:45 -0300 Subject: [PATCH 048/201] Correcting a mistake, the inconsistence was in the docs not implementation. --- Sources/Extensions/SwiftStdlib/ArrayExtensions.swift | 12 +++++------- Tests/SwiftStdlibTests/ArrayExtensionsTests.swift | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 1cfa68d30..cb2b52b12 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -503,17 +503,15 @@ public extension Array where Element: Equatable { /// SwifterSwift: Return array with all duplicate elements removed. /// - /// [1, 2, 2, 3, 4, 5, 5].duplicatesRemoved() -> [ 2, 5] - /// ["h", "e", "l", "l", "o"]. duplicatesRemoved() -> ["l"] - /// + /// [1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved() -> [1, 2, 3, 4, 5]) + /// ["h", "e", "l", "l", "o"].duplicatesRemoved() -> ["h", "e", "l", "o"]) + /// /// - Returns: an array of unique elements. + /// public func duplicatesRemoved() -> [Element] { // Thanks to https://github.com/sairamkotha for improving the property - var noDuplicates: [Element] = [] return reduce(into: [Element]()) { - if !noDuplicates.contains($1) { - noDuplicates.append($1) - } else { + if !$0.contains($1) { $0.append($1) } } diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index 9d20e5bfb..23440322f 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -145,8 +145,8 @@ class ArrayExtensionsTests: XCTestCase { } func testDuplicatesRemoved() { - XCTAssertEqual([1, 2, 2, 3, 4, 5, 5].duplicatesRemoved(), [2, 5]) - XCTAssertEqual(["h", "e", "l", "l", "o"].duplicatesRemoved(), ["l"]) + XCTAssertEqual([1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved(), [1, 2, 3, 4, 5]) + XCTAssertEqual(["h", "e", "l", "l", "o"].duplicatesRemoved(), ["h", "e", "l", "o"]) } func testItemAtIndex() { From 0e409405bd4c4db04ffa76e6b9722096dce97583 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sat, 7 Oct 2017 11:02:27 +0300 Subject: [PATCH 049/201] Update ColorExtensions.swift --- .../Extensions/Shared/ColorExtensions.swift | 119 ++++++++---------- 1 file changed, 55 insertions(+), 64 deletions(-) diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index 014f8202a..ed4926e17 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -19,29 +19,7 @@ // MARK: - Properties public extension Color { - - /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). - public var uInt: UInt { - var colorAsUInt32: UInt32 = 0 - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - var a: CGFloat = 0 - - self.getRed(&r, green: &g, blue: &b, alpha: &a) - - colorAsUInt32 += UInt32(r * 255.0) << 16 - colorAsUInt32 += UInt32(g * 255.0) << 8 - colorAsUInt32 += UInt32(b * 255.0) - - return UInt(colorAsUInt32) - } - - /// SwifterSwift: Get color complementary (read-only, if applicable). - public var complementary: Color? { - return Color.init(complementaryFor: self) - } - + /// SwifterSwift: Random color. public static var random: Color { let r = Int(arc4random_uniform(255)) @@ -96,13 +74,13 @@ public extension Color { /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { - var hue: CGFloat = 0.0 - var sat: CGFloat = 0.0 - var bri: CGFloat = 0.0 - var alpha: CGFloat = 0.0 - self.getHue(&hue, saturation: &sat, brightness: &bri, alpha: &alpha) - - return (hue:hue, saturation:sat, brightness:bri, alpha:alpha) + var h: CGFloat = 0.0 + var s: CGFloat = 0.0 + var b: CGFloat = 0.0 + var a: CGFloat = 0.0 + + self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) + return (hue: h, saturation: s, brightness: b, alpha: a) } /// SwifterSwift: Hexadecimal value string (read-only). @@ -138,6 +116,23 @@ public extension Color { } #endif + /// SwifterSwift: Get UInt representation of a Color (read-only). + public var uInt: UInt { + let c = self.cgFloatComponents + + var colorAsUInt32: UInt32 = 0 + colorAsUInt32 += UInt32(c.red * 255.0) << 16 + colorAsUInt32 += UInt32(c.green * 255.0) << 8 + colorAsUInt32 += UInt32(c.blue * 255.0) + + return UInt(colorAsUInt32) + } + + /// SwifterSwift: Get color complementary (read-only, if applicable). + public var complementary: Color? { + return Color.init(complementaryFor: self) + } + } // MARK: - Methods @@ -188,35 +183,7 @@ public extension Color { // MARK: - Initializers public extension Color { - - /// SwifterSwift: Create Color from a complementary of a Color (if applicable). - /// - /// - Parameter color: color of which opposite color is desired. - public convenience init?(complementaryFor color: Color) { - let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() - let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in - if color.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { - let oldComponents = color.cgColor.components - let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] - let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) - let colorOut = Color(cgColor: colorRef!) - return colorOut - } else { - return color - } - } - - let c = convertColorToRGBSpace(color) - guard let componentColors = c?.cgColor.components else { - return nil - } - - let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 - let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 - let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 - self.init(red: r, green: g, blue: b, alpha: 1.0) - } - + /// SwifterSwift: Create NSColor from RGB values with optional transparency. /// /// - Parameters: @@ -233,11 +200,7 @@ public extension Color { if trans < 0 { trans = 0 } if trans > 1 { trans = 1 } - #if os(macOS) - self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) - #else - self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) - #endif + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) } /// SwifterSwift: Create NSColor from hexadecimal value with optional transparency. @@ -286,6 +249,34 @@ public extension Color { self.init(hex: Int(hexValue), transparency: trans) } + /// SwifterSwift: Create UIColor from a complementary of a UIColor (if applicable). + /// + /// - Parameter color: color of which opposite color is desired. + public convenience init?(complementaryFor color: Color) { + let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() + let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in + if color.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { + let oldComponents = color.cgColor.components + let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] + let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) + let colorOut = Color(cgColor: colorRef!) + return colorOut + } else { + return color + } + } + + let c = convertColorToRGBSpace(color) + guard let componentColors = c?.cgColor.components else { + return nil + } + + let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 + let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 + let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 + self.init(red: r, green: g, blue: b, alpha: 1.0) + } + } // MARK: - Social From 7fcb8730a2f8db4524ce5270c08bde3e36e36b67 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sat, 7 Oct 2017 11:03:07 +0300 Subject: [PATCH 050/201] Update ColorExtensionsTests.swift --- Tests/SharedTests/ColorExtensionsTests.swift | 753 +++++++++---------- 1 file changed, 372 insertions(+), 381 deletions(-) diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index e7e870edc..b2899424c 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -9,392 +9,383 @@ import XCTest @testable import SwifterSwift #if os(macOS) - import Cocoa - public typealias Color = NSColor + import Cocoa + public typealias Color = NSColor #else - import UIKit - public typealias Color = UIColor + import UIKit + public typealias Color = UIColor #endif #if !os(watchOS) - import CoreImage + import CoreImage #endif class ColorExtensionsTests: XCTestCase { - - // MARK: - Test properties - func testrgbComponents() { - XCTAssertEqual(Color.red.rgbComponents.red, 255) - XCTAssertEqual(Color.red.rgbComponents.green, 0) - XCTAssertEqual(Color.red.rgbComponents.blue, 0) - - XCTAssertEqual(Color.green.rgbComponents.red, 0) - XCTAssertEqual(Color.green.rgbComponents.green, 255) - XCTAssertEqual(Color.green.rgbComponents.blue, 0) - - XCTAssertEqual(Color.blue.rgbComponents.red, 0) - XCTAssertEqual(Color.blue.rgbComponents.green, 0) - XCTAssertEqual(Color.blue.rgbComponents.blue, 255) - - XCTAssertEqual(Color.black.rgbComponents.red, 0) - XCTAssertEqual(Color.black.rgbComponents.green, 0) - XCTAssertEqual(Color.black.rgbComponents.blue, 0) - - XCTAssertEqual(Color.white.rgbComponents.red, 255) - XCTAssertEqual(Color.white.rgbComponents.green, 255) - XCTAssertEqual(Color.white.rgbComponents.blue, 255) - - XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponents.red, 0x12) - } - - func testAlpha() { - var color: Color = Color.red - XCTAssertEqual(color.alpha, 1.0) - - color = Color.white.withAlphaComponent(0.5) - XCTAssertEqual(color.alpha, 0.5) - - color = Color(red: 0, green: 0, blue: 0, transparency: 0.7)! - XCTAssertEqual(color.alpha, 0.7) - - color = Color(red: 0, green: 0, blue: 0, transparency: 1.1)! - XCTAssertEqual(color.alpha, 1.0) - } - - // MARK: - Test properties - func testHsbaComponents() { - var color = Color(hex: 0xFF0000, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = Color(hex: 0x00FF00, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (120/360)) / 1000)) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = Color(hex: 0x0000FF, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (240/360)) / 1000)) - XCTAssertEqual(color?.hsbaComponents.saturation, 1.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = Color(hex: 0x000000, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 0.0) - - color = Color(hex: 0xFFFFFF, transparency: 1.0) - XCTAssertEqual(color?.hsbaComponents.hue, 0.0) - XCTAssertEqual(color?.hsbaComponents.saturation, 0.0) - XCTAssertEqual(color?.hsbaComponents.brightness, 1.0) - - color = Color(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (210/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 79) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 34) - - color = Color(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (27/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 60) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 99) - - color = Color(hex: 0x1F2D3C, transparency: 1.0) - XCTAssertEqual(CGFloat(round(1000 * (color?.hsbaComponents.hue)!) / 1000), CGFloat(round(1000 * (211/360)) / 1000)) - XCTAssertEqual(((color?.hsbaComponents.saturation)! * 100).rounded(), 48) - XCTAssertEqual(((color?.hsbaComponents.brightness)! * 100).rounded(), 24) - } - - func testUInt() { - var color = Color(hex: 0xFF0000, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFF0000) - - color = Color(hex: 0x00FF00, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x00FF00) - - color = Color(hex: 0x0000FF, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x0000FF) - - color = Color(hex: 0x000000, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x000000) - - color = Color(hex: 0xFFFFFF, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFFFFFF) - - color = Color(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x123456) - - color = Color(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFCA864) - - color = Color(hex: 0xFCA864, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0xFCA864) - - color = Color(hex: 0x1F2D3C, transparency: 1.0) - XCTAssertEqual(color?.uInt, 0x1F2D3C) - - } - - func testHexString() { - var color = Color.red - XCTAssertEqual(color.hexString, "#FF0000") - - color = Color.blue - XCTAssertEqual(color.hexString, "#0000FF") - - color = Color(hex: 0xABCDEF)! - XCTAssertEqual(color.hexString, "#ABCDEF") - - color = Color(hex: 0xABC)! - XCTAssertEqual(color.hexString, "#000ABC") - - color = Color.black - XCTAssertEqual(color.hexString, "#000000") - } - - func testShortHexString() { - var color: Color? = Color.red - XCTAssertEqual(color?.shortHexString, "#F00") - - color = Color.blue - XCTAssertEqual(color?.shortHexString, "#00F") - - color = Color(hexString: "#0F120F") - XCTAssertNil(color?.shortHexString) - - color = Color(hexString: "#8FFFF") - XCTAssertNil(color?.shortHexString) - } - - func testShortHexOrHexString() { - var color: Color? = Color.red - XCTAssertEqual(color?.shortHexOrHexString, "#F00") - - color = Color(hexString: "#8FFFFF") - XCTAssertEqual(color?.shortHexOrHexString, "#8FFFFF") - - color = Color(hexString: "#F") - XCTAssertEqual(color?.shortHexOrHexString, "#00000F") - - color = Color(hexString: "#11") - XCTAssertEqual(color?.shortHexOrHexString, "#001") - } - - func testComplementary() { - var color = Color.black - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - - color = Color.white - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 0) - XCTAssertEqual(b, 0) - - color = Color.red - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - } - - func testRandom() { - let color1 = Color.random - let color2 = Color.random - - XCTAssertNotEqual(color1, color2) - } - - // MARK: - Test methods - func testBlend() { - var color1 = Color.white - var color2 = Color.black - - var blendColor = Color.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponents.red, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponents.green, 0xFF / 2) - XCTAssertEqual(blendColor.rgbComponents.blue, 0xFF / 2) - - color1 = Color(hex: 0x123456, transparency: 0.5)! - color2 = Color(hex: 0x665544, transparency: 0.7)! - - blendColor = Color.blend(color1, with: color2) - XCTAssertEqual(blendColor.rgbComponents.red, (0x12 + 0x66) / 2) - XCTAssertEqual(blendColor.rgbComponents.green, (0x34 + 0x55) / 2) - XCTAssertEqual(blendColor.rgbComponents.blue, (0x56 + 0x44) / 2) - XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) - - blendColor = Color.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) - var output: Double = 0x12 * 0.7 + 0x66 * 0.3 - XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) - output = 0x34 * 0.7 + 0x55 * 0.3 - XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) - output = 0x56 * 0.7 + 0x44 * 0.3 - XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) - output = 0.5 * 0.7 + 0.7 * 0.3 - XCTAssertEqual(blendColor.alpha, CGFloat(output)) - - blendColor = Color.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) - output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) - output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) - output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 - XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) - output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) - XCTAssertEqual(blendColor.alpha, CGFloat(output)) - - blendColor = Color.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) - XCTAssertEqual(blendColor, color1) - } - - // MARK: - Test initializers - func testInit() { - var color = Color(hex: 0xFFF) - XCTAssertEqual(color?.rgbComponents.red, 0) - XCTAssertEqual(color?.rgbComponents.green, 0xf) - XCTAssertEqual(color?.rgbComponents.blue, 0xff) - XCTAssertEqual(color?.alpha, 1.0) - - color = Color(hex: 0xFFFFFFF) - XCTAssertEqual(color?.rgbComponents.red, 0xff) - XCTAssertEqual(color?.rgbComponents.green, 0xff) - XCTAssertEqual(color?.rgbComponents.blue, 0xff) - XCTAssertEqual(color?.alpha, 1.0) - - color = Color(hex: 0x123456, transparency: 1.0) - XCTAssertEqual(color?.rgbComponents.red, 0x12) - XCTAssertEqual(color?.rgbComponents.green, 0x34) - XCTAssertEqual(color?.rgbComponents.blue, 0x56) - XCTAssertEqual(color?.alpha, 1.0) - - color = Color(hex: 0x999, transparency: 21.0) - XCTAssertEqual(color?.rgbComponents.red, 0) - XCTAssertEqual(color?.rgbComponents.green, 0x09) - XCTAssertEqual(color?.rgbComponents.blue, 0x99) - XCTAssertEqual(color?.alpha, 1.0) - - color = Color(hex: 0xaabbcc, transparency: 0.0) - XCTAssertEqual(color?.rgbComponents.red, 0xaa) - XCTAssertEqual(color?.rgbComponents.green, 0xbb) - XCTAssertEqual(color?.rgbComponents.blue, 0xcc) - XCTAssertEqual(color?.alpha, 0.0) - - color = Color(hex: 0x1, transparency: 0.5) - XCTAssertEqual(color?.rgbComponents.red, 0) - XCTAssertEqual(color?.rgbComponents.green, 0) - XCTAssertEqual(color?.rgbComponents.blue, 1) - XCTAssertEqual(color?.alpha, 0.5) - - let color1 = Color(hex: 0xFFF, transparency: -0.4) - let color2 = Color(hex: 0xFFF, transparency: 0) - XCTAssertEqual(color1, color2) - - let color3 = Color(hex: 0xFFF, transparency: 1.5) - let color4 = Color(hex: 0xFFF, transparency: 1) - XCTAssertEqual(color3, color4) - - } - - func testFailableInit() { - var color = Color(hexString: "0xFFFFFF") - XCTAssertNotNil(color) - - color = Color(hexString: "#FFFFFF") - XCTAssertNotNil(color) - - color = Color(hexString: "FFFFFF") - XCTAssertNotNil(color) - - color = Color(hexString: "#ABC") - XCTAssertNotNil(color) - - color = Color(hexString: "#GGG") - XCTAssertNil(color) - - color = Color(hexString: "4#fff") - XCTAssertNil(color) - - color = Color(hexString: "FFFFFFF") - XCTAssertNotNil(color) - } - - func testInitWithComponents() { - var r1: CGFloat = 0 - var r2: CGFloat = 0 - var g1: CGFloat = 0 - var g2: CGFloat = 0 - var b1: CGFloat = 0 - var b2: CGFloat = 0 - var alpha1: CGFloat = 0 - var alpha2: CGFloat = 0 - - var color1 = Color(red: 255, green: 244, blue: 255, transparency: 2.0) - var color2 = Color(red: 1.0, green: 244.0 / 255.0, blue: 1.0, alpha: 2.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - - color1 = Color(red: 25, green: 244, blue: 55, transparency: -1.0) - color2 = Color(red: 25.0 / 255.0, green: 244.0 / 255.0, blue: 55.0 / 255.0, alpha: -1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - - color1 = Color(red: 2, green: 4, blue: 5) - color2 = Color(red: 2.0 / 255.0, green: 4.0 / 255.0, blue: 5.0 / 255.0, alpha: 1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) - XCTAssertEqual(alpha1, alpha2) - } - - func testFailableInitWithComponents() { - let color1 = Color(red: 258, green: 0, blue: 0) - XCTAssertNil(color1) - - let color2 = Color(red: 0, green: 258, blue: 0) - XCTAssertNil(color2) - - let color3 = Color(red: 0, green: 0, blue: 258) - XCTAssertNil(color3) - - let color4 = Color(red: 258, green: 258, blue: 258) - XCTAssertNil(color4) - - } - - func testFailableInitWithComplementaryColor() { - var color = Color(complementaryFor: Color.black) - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - - color = Color(complementaryFor: Color.red) - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - } + + // MARK: - Test properties + func testRgbComponents() { + XCTAssertEqual(Color.red.rgbComponents.red, 255) + XCTAssertEqual(Color.red.rgbComponents.green, 0) + XCTAssertEqual(Color.red.rgbComponents.blue, 0) + + XCTAssertEqual(Color.green.rgbComponents.red, 0) + XCTAssertEqual(Color.green.rgbComponents.green, 255) + XCTAssertEqual(Color.green.rgbComponents.blue, 0) + + XCTAssertEqual(Color.blue.rgbComponents.red, 0) + XCTAssertEqual(Color.blue.rgbComponents.green, 0) + XCTAssertEqual(Color.blue.rgbComponents.blue, 255) + + XCTAssertEqual(Color.black.rgbComponents.red, 0) + XCTAssertEqual(Color.black.rgbComponents.green, 0) + XCTAssertEqual(Color.black.rgbComponents.blue, 0) + + XCTAssertEqual(Color.white.rgbComponents.red, 255) + XCTAssertEqual(Color.white.rgbComponents.green, 255) + XCTAssertEqual(Color.white.rgbComponents.blue, 255) + + XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponents.red, 0x12) + } + + func testAlpha() { + var color: Color = Color.red + XCTAssertEqual(color.alpha, 1.0) + + color = Color.white.withAlphaComponent(0.5) + XCTAssertEqual(color.alpha, 0.5) + + color = Color(red: 0, green: 0, blue: 0, transparency: 0.7)! + XCTAssertEqual(color.alpha, 0.7) + + color = Color(red: 0, green: 0, blue: 0, transparency: 1.1)! + XCTAssertEqual(color.alpha, 1.0) + } + + // MARK: - Test properties + func testHsbaComponents() { + var color = Color(hex: 0x00FF00, transparency: 1.0)! + XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (120/360)) / 1000)) + XCTAssertEqual(color.hsbaComponents.saturation, 1.0) + XCTAssertEqual(color.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x0000FF, transparency: 1.0)! + XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (240/360)) / 1000)) + XCTAssertEqual(color.hsbaComponents.saturation, 1.0) + XCTAssertEqual(color.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x000000, transparency: 1.0)! + XCTAssertEqual(color.hsbaComponents.hue, 0.0) + XCTAssertEqual(color.hsbaComponents.saturation, 0.0) + XCTAssertEqual(color.hsbaComponents.brightness, 0.0) + + color = Color(hex: 0xFFFFFF, transparency: 1.0)! + XCTAssertEqual(color.hsbaComponents.hue, 0.0) + XCTAssertEqual(color.hsbaComponents.saturation, 0.0) + XCTAssertEqual(color.hsbaComponents.brightness, 1.0) + + color = Color(hex: 0x123456, transparency: 1.0)! + XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (210/360)) / 1000)) + XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 79) + XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 34) + + color = Color(hex: 0xFCA864, transparency: 1.0)! + XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (27/360)) / 1000)) + XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 60) + XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 99) + + color = Color(hex: 0x1F2D3C, transparency: 1.0)! + XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (211/360)) / 1000)) + XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 48) + XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 24) + } + + func testUInt() { + var color = Color(hex: 0xFF0000, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFF0000) + + color = Color(hex: 0x00FF00, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x00FF00) + + color = Color(hex: 0x0000FF, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x0000FF) + + color = Color(hex: 0x000000, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x000000) + + color = Color(hex: 0xFFFFFF, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFFFFFF) + + color = Color(hex: 0x123456, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x123456) + + color = Color(hex: 0xFCA864, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFCA864) + + color = Color(hex: 0xFCA864, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0xFCA864) + + color = Color(hex: 0x1F2D3C, transparency: 1.0) + XCTAssertEqual(color?.uInt, 0x1F2D3C) + + } + + func testHexString() { + var color = Color.red + XCTAssertEqual(color.hexString, "#FF0000") + + color = Color.blue + XCTAssertEqual(color.hexString, "#0000FF") + + color = Color(hex: 0xABCDEF)! + XCTAssertEqual(color.hexString, "#ABCDEF") + + color = Color(hex: 0xABC)! + XCTAssertEqual(color.hexString, "#000ABC") + + color = Color.black + XCTAssertEqual(color.hexString, "#000000") + } + + func testShortHexString() { + var color: Color? = Color.red + XCTAssertEqual(color?.shortHexString, "#F00") + + color = Color.blue + XCTAssertEqual(color?.shortHexString, "#00F") + + color = Color(hexString: "#0F120F") + XCTAssertNil(color?.shortHexString) + + color = Color(hexString: "#8FFFF") + XCTAssertNil(color?.shortHexString) + } + + func testShortHexOrHexString() { + var color: Color? = Color.red + XCTAssertEqual(color?.shortHexOrHexString, "#F00") + + color = Color(hexString: "#8FFFFF") + XCTAssertEqual(color?.shortHexOrHexString, "#8FFFFF") + + color = Color(hexString: "#F") + XCTAssertEqual(color?.shortHexOrHexString, "#00000F") + + color = Color(hexString: "#11") + XCTAssertEqual(color?.shortHexOrHexString, "#001") + } + + func testComplementary() { + var color = Color.black + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 1) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + + color = Color.white + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 0) + XCTAssertEqual(b, 0) + + color = Color.red + color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + } + + func testRandom() { + let color1 = Color.random + let color2 = Color.random + + XCTAssertNotEqual(color1, color2) + } + + // MARK: - Test methods + func testBlend() { + var color1 = Color.white + var color2 = Color.black + + var blendColor = Color.blend(color1, with: color2) + XCTAssertEqual(blendColor.rgbComponents.red, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.green, 0xFF / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, 0xFF / 2) + + color1 = Color(hex: 0x123456, transparency: 0.5)! + color2 = Color(hex: 0x665544, transparency: 0.7)! + + blendColor = Color.blend(color1, with: color2) + XCTAssertEqual(blendColor.rgbComponents.red, (0x12 + 0x66) / 2) + XCTAssertEqual(blendColor.rgbComponents.green, (0x34 + 0x55) / 2) + XCTAssertEqual(blendColor.rgbComponents.blue, (0x56 + 0x44) / 2) + XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) + + blendColor = Color.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) + var output: Double = 0x12 * 0.7 + 0x66 * 0.3 + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) + output = 0x34 * 0.7 + 0x55 * 0.3 + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) + output = 0x56 * 0.7 + 0x44 * 0.3 + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) + output = 0.5 * 0.7 + 0.7 * 0.3 + XCTAssertEqual(blendColor.alpha, CGFloat(output)) + + blendColor = Color.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) + output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) + output = (0x34 * 0.0 + 0x55 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponents.green, Int(output)) + output = (0x56 * 0.0 + 0x44 * 0.3) / 0.3 + XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) + output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) + XCTAssertEqual(blendColor.alpha, CGFloat(output)) + + blendColor = Color.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) + XCTAssertEqual(blendColor, color1) + } + + // MARK: - Test initializers + func testInit() { + var color = Color(hex: 0xFFF) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0xf) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0xFFFFFFF) + XCTAssertEqual(color?.rgbComponents.red, 0xff) + XCTAssertEqual(color?.rgbComponents.green, 0xff) + XCTAssertEqual(color?.rgbComponents.blue, 0xff) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0x123456, transparency: 1.0) + XCTAssertEqual(color?.rgbComponents.red, 0x12) + XCTAssertEqual(color?.rgbComponents.green, 0x34) + XCTAssertEqual(color?.rgbComponents.blue, 0x56) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0x999, transparency: 21.0) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0x09) + XCTAssertEqual(color?.rgbComponents.blue, 0x99) + XCTAssertEqual(color?.alpha, 1.0) + + color = Color(hex: 0xaabbcc, transparency: 0.0) + XCTAssertEqual(color?.rgbComponents.red, 0xaa) + XCTAssertEqual(color?.rgbComponents.green, 0xbb) + XCTAssertEqual(color?.rgbComponents.blue, 0xcc) + XCTAssertEqual(color?.alpha, 0.0) + + color = Color(hex: 0x1, transparency: 0.5) + XCTAssertEqual(color?.rgbComponents.red, 0) + XCTAssertEqual(color?.rgbComponents.green, 0) + XCTAssertEqual(color?.rgbComponents.blue, 1) + XCTAssertEqual(color?.alpha, 0.5) + + let color1 = Color(hex: 0xFFF, transparency: -0.4) + let color2 = Color(hex: 0xFFF, transparency: 0) + XCTAssertEqual(color1, color2) + + let color3 = Color(hex: 0xFFF, transparency: 1.5) + let color4 = Color(hex: 0xFFF, transparency: 1) + XCTAssertEqual(color3, color4) + + } + + func testFailableInit() { + var color = Color(hexString: "0xFFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "#FFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "FFFFFF") + XCTAssertNotNil(color) + + color = Color(hexString: "#ABC") + XCTAssertNotNil(color) + + color = Color(hexString: "#GGG") + XCTAssertNil(color) + + color = Color(hexString: "4#fff") + XCTAssertNil(color) + + color = Color(hexString: "FFFFFFF") + XCTAssertNotNil(color) + } + + func testInitWithComponents() { + var r1: CGFloat = 0 + var r2: CGFloat = 0 + var g1: CGFloat = 0 + var g2: CGFloat = 0 + var b1: CGFloat = 0 + var b2: CGFloat = 0 + var alpha1: CGFloat = 0 + var alpha2: CGFloat = 0 + + var color1 = Color(red: 255, green: 244, blue: 255, transparency: 2.0) + var color2 = Color(red: 1.0, green: 244.0 / 255.0, blue: 1.0, alpha: 1.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + + color1 = Color(red: 25, green: 244, blue: 55, transparency: -1.0) + color2 = Color(red: 25.0 / 255.0, green: 244.0 / 255.0, blue: 55.0 / 255.0, alpha: 0.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + + color1 = Color(red: 2, green: 4, blue: 5) + color2 = Color(red: 2.0 / 255.0, green: 4.0 / 255.0, blue: 5.0 / 255.0, alpha: 1.0) + color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) + color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) + XCTAssertEqual(r1, r2) + XCTAssertEqual(g1, g2) + XCTAssertEqual(b1, b2) + XCTAssertEqual(alpha1, alpha2) + } + + func testFailableInitWithComponents() { + let color1 = Color(red: 258, green: 0, blue: 0) + XCTAssertNil(color1) + + let color2 = Color(red: 0, green: 258, blue: 0) + XCTAssertNil(color2) + + let color3 = Color(red: 0, green: 0, blue: 258) + XCTAssertNil(color3) + + let color4 = Color(red: 258, green: 258, blue: 258) + XCTAssertNil(color4) + + } + + func testFailableInitWithComplementaryColor() { + var color = Color(complementaryFor: Color.black) + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + + color?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 1) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + + color = Color(complementaryFor: Color.red) + color?.getRed(&r, green: &g, blue: &b, alpha: nil) + XCTAssertEqual(r, 0) + XCTAssertEqual(g, 1) + XCTAssertEqual(b, 1) + } } - - - - From b8ee998f36aa25ad952a2fc3be956834e6fa4782 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sat, 7 Oct 2017 18:12:19 +0300 Subject: [PATCH 051/201] 4.0.1 --- CHANGELOG.md | 18 ++++++++++++++ README.md | 7 +++--- .../Foundation/NSPredicateExtensions.swift | 10 ++++++-- .../Extensions/Shared/ColorExtensions.swift | 8 +++---- Sources/Info.plist | 2 +- SwifterSwift.xcodeproj/project.pbxproj | 11 ++++++++- .../SignedNumericExtensionsTests.swift | 24 +++++++++++++++++++ 7 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 382290ede..590f517d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,13 +25,31 @@ N/A ### Enhancements - **Color** - Refactored duplicated code from `UIColorExtensions` and `NSColorExtensions` into `ColorExtensions`. thanks to [SD10](https://github.com/SD10). + - Refactored duplicated tests from `UIColorExtensionsTests` and `NSColorExtensionsTests` into `ColorExtensionsTests`. [#260](https://github.com/SwifterSwift/SwifterSwift/pull/260) by [LeLuckyVint](https://github.com/LeLuckyVint). - Add `cgFloatComponents` to get RGB components for a Color represented as CGFloat numbers (between 0 and 1) - `blend` now support NSColor as well. + - Corrected some typos in README. [#263](https://github.com/SwifterSwift/SwifterSwift/pull/263) by [nick3399](https://github.com/nick3399). +- New **String** extensions + - Add `localized(comment:)` to returns a localized string, with an optional comment for translators. [#269](https://github.com/SwifterSwift/SwifterSwift/pull/269) by [Vyax](https://github.com/Vyax). +- New **NSPredicate** extensions: [#273](https://github.com/SwifterSwift/SwifterSwift/pull/273) by [Vyax](https://github.com/Vyax). + - Add `not` to returns a new predicate formed by NOT-ing the predicate. + - Add `and(_ predicate: NSPredicate)` to returns a new predicate formed by AND-ing the argument to the predicate. + - Add `or(_ predicate: NSPredicate)` to returns a new predicate formed by OR-ing the argument to the predicate. +- New **UILabel** extensions + - Add `convenience init(text: String?)` to initialize a UILabel with text. [#271](https://github.com/SwifterSwift/SwifterSwift/pull/271) by [Vyax](https://github.com/Vyax). +- New **Bool** extensions + - Add `random` to returns a random boolean value. [#272](https://github.com/SwifterSwift/SwifterSwift/pull/272) by [Vyax](https://github.com/Vyax). +- **Continuous Integration** + - Add macOS tests to travis-ci. + - Add calls to `swiftlint` and `pod lib lint` in Travis [#264](https://github.com/SwifterSwift/SwifterSwift/pull/264) by [calebkleveter](https://github.com/calebkleveter). +- New **SignedNumeric** extensions tests ### Bugfixes - **Color** - Fixed a bug in `rgbComponents`, `shortHexString`, and `shortHexOrHexString` where an exception was raised when color is white or black. - Corrected a typo in `rgbComponenets` -> `rgbComponents` + + # v4.0.0 ### API Breaking diff --git a/README.md b/README.md index 27f209cd0..fcd61bfb8 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### [Whats New in v4.0.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v400) +### [Whats New in v4.0.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v401) ## Requirements: - **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ @@ -130,6 +130,7 @@ let package = Package(
  • Date extensions
  • Locale extensions
  • NSAttributedString extensions
  • +
  • NSPredicate extensions
  • URL extensions
  • URLRequest extensions
  • UserDefaults extensions
  • @@ -145,7 +146,7 @@ let package = Package(
  • UIBarButtonItem extensions
  • UIButton extensions
  • UICollectionView extensions
  • -
  • UIColor extensions
  • +
  • UIColor extensions
  • UIImage extensions
  • UIImageView extensions
  • UILabel extensions
  • @@ -171,7 +172,7 @@ let package = Package( AppKit Extensions
    diff --git a/Sources/Extensions/Foundation/NSPredicateExtensions.swift b/Sources/Extensions/Foundation/NSPredicateExtensions.swift index 4043f5dbb..6a4fe340d 100644 --- a/Sources/Extensions/Foundation/NSPredicateExtensions.swift +++ b/Sources/Extensions/Foundation/NSPredicateExtensions.swift @@ -20,12 +20,18 @@ public extension NSPredicate { // MARK: - Methods public extension NSPredicate { - /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. + /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. + /// + /// - Parameter predicate: NSPredicate + /// - Returns: NSCompoundPredicate public func and(_ predicate: NSPredicate) -> NSCompoundPredicate { return NSCompoundPredicate(andPredicateWithSubpredicates: [self, predicate]) } - /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. + /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. + /// + /// - Parameter predicate: NSPredicate + /// - Returns: NSCompoundPredicate public func or(_ predicate: NSPredicate) -> NSCompoundPredicate { return NSCompoundPredicate(orPredicateWithSubpredicates: [self, predicate]) } diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index ed4926e17..c1bad571b 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -219,7 +219,7 @@ public extension Color { self.init(red: red, green: green, blue: blue, transparency: trans) } - /// SwifterSwift: Create UIColor from hexadecimal string with optional transparency (if applicable). + /// SwifterSwift: Create Color from hexadecimal string with optional transparency (if applicable). /// /// - Parameters: /// - hexString: hexadecimal string (examples: EDE7F6, 0xEDE7F6, #EDE7F6, #0ff, 0xF0F, ..). @@ -249,7 +249,7 @@ public extension Color { self.init(hex: Int(hexValue), transparency: trans) } - /// SwifterSwift: Create UIColor from a complementary of a UIColor (if applicable). + /// SwifterSwift: Create Color from a complementary of a Color (if applicable). /// /// - Parameter color: color of which opposite color is desired. public convenience init?(complementaryFor color: Color) { @@ -267,9 +267,7 @@ public extension Color { } let c = convertColorToRGBSpace(color) - guard let componentColors = c?.cgColor.components else { - return nil - } + guard let componentColors = c?.cgColor.components else { return nil } let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 diff --git a/Sources/Info.plist b/Sources/Info.plist index 1b41cf5ab..5cd2f72f8 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.0.0 + 4.0.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index eb8ea5b51..4724337c3 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -308,6 +308,10 @@ 07D896091F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960A1F5EC80700FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50CF81F5EB03200F46E5A /* SwifterSwiftTests.swift */; }; + 07FE50431F891B40000766AA /* ColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C50D121F5EB03200F46E5A /* ColorExtensionsTests.swift */; }; + 07FE50451F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; + 07FE50461F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; + 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -452,6 +456,7 @@ 07C50D281F5EB03200F46E5A /* CLLocationExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationExtensionsTests.swift; sourceTree = ""; }; 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; + 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -553,6 +558,7 @@ 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */, 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */, 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */, + 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */, ); path = SwiftStdlibTests; sourceTree = ""; @@ -1377,6 +1383,7 @@ 07C50D371F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, 07C50D8E1F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */, 07C50D581F5EB05000F46E5A /* BoolExtensionsTests.swift in Sources */, + 07FE50451F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, 07C50D391F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, 07C50D361F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, 07C50D8C1F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, @@ -1430,6 +1437,7 @@ 07C50D4D1F5EB04700F46E5A /* UISegmentedControlExtensionsTests.swift in Sources */, 07C50D891F5EB06000F46E5A /* CGSizeExtensionsTests.swift in Sources */, 07C50D661F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */, + 07FE50461F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, 07C50D4F1F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, 07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, 07C50D871F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, @@ -1481,11 +1489,12 @@ 07C50D831F5EB05800F46E5A /* CGSizeExtensionsTests.swift in Sources */, 077BA0BB1F6BEA6B00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, 07C50D751F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, + 07FE50431F891B40000766AA /* ColorExtensionsTests.swift in Sources */, 07C50D7D1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */, 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, - D85EA0131F7D2DA700B8539B /* ColorExtensionsTests.swift in Sources */, + 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift new file mode 100644 index 000000000..2b3a87ca8 --- /dev/null +++ b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift @@ -0,0 +1,24 @@ +// +// SignedNumericExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 10/7/17. +// + +import XCTest +@testable import SwifterSwift + +class SignedNumericExtensionsTests: XCTestCase { + + func testString() { + let number: Double = -1.2 + XCTAssertEqual(number.string, "-1.2") + } + + func testAsLocaleCurrency() { + let number: Double = 3.2 + print(number.asLocaleCurrency) + XCTAssertEqual(number.asLocaleCurrency, "$3.20") + } + +} From 25705f23bcd00a19b2872c6b2233853ef23d5b35 Mon Sep 17 00:00:00 2001 From: Zac Kwan Date: Sun, 8 Oct 2017 10:57:36 +0800 Subject: [PATCH 052/201] Updated all class that subclass XCTestCase as final class --- Tests/AppKitTests/NSViewExtensionsTests.swift | 2 +- Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift | 2 +- Tests/CoreGraphicsTests/CGPointExtensionsTests.swift | 2 +- Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift | 2 +- Tests/CoreLocationTests/CLLocationExtensionsTests.swift | 2 +- Tests/FoundationTests/DataExtensionsTests.swift | 2 +- Tests/FoundationTests/DateExtensionsTests.swift | 2 +- Tests/FoundationTests/LocaleExtensionsTests.swift | 2 +- Tests/FoundationTests/NSAttributedStringExtensionsTests.swift | 2 +- Tests/FoundationTests/NSPredicateExtensionsTests.swift | 2 +- Tests/FoundationTests/URLExtensionsTests.swift | 2 +- Tests/FoundationTests/URLRequestExtensionsTests.swift | 2 +- Tests/FoundationTests/UserDefaultsExtensionsTests.swift | 2 +- Tests/SharedTests/ColorExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/ArrayExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/BoolExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/CharacterExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/CollectionExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/DoubleExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/FloatExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/IntExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/OptionalExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/StringExtensionsTests.swift | 2 +- Tests/SwifterSwiftTests.swift | 2 +- Tests/UIKitTests/UIAlertControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UIBarButtonExtensionsTests.swift | 2 +- Tests/UIKitTests/UIButtonExtensionsTests.swift | 2 +- Tests/UIKitTests/UICollectionViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UIFontExtensionsTest.swift | 2 +- Tests/UIKitTests/UIImageExtensionsTests.swift | 2 +- Tests/UIKitTests/UIImageViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UILabelExtensionsTests.swift | 2 +- Tests/UIKitTests/UINavigationBarExtensionTests.swift | 2 +- Tests/UIKitTests/UINavigationControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UINavigationItemExtensionsTests.swift | 2 +- Tests/UIKitTests/UISearchBarExtensionsTests.swift | 2 +- Tests/UIKitTests/UISegmentedControlExtensionsTests.swift | 2 +- Tests/UIKitTests/UISliderExtensionsTests.swift | 2 +- Tests/UIKitTests/UIStoryboardExtensionsTests.swift | 2 +- Tests/UIKitTests/UISwitchExtensionsTests.swift | 2 +- Tests/UIKitTests/UITabBarExtensionsTests.swift | 2 +- Tests/UIKitTests/UITableViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UITextFieldExtensionsTests.swift | 2 +- Tests/UIKitTests/UITextViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UIViewControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UIViewExtensionsTests.swift | 2 +- 47 files changed, 47 insertions(+), 47 deletions(-) diff --git a/Tests/AppKitTests/NSViewExtensionsTests.swift b/Tests/AppKitTests/NSViewExtensionsTests.swift index 211e6c6a2..a6f0f7745 100644 --- a/Tests/AppKitTests/NSViewExtensionsTests.swift +++ b/Tests/AppKitTests/NSViewExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class NSViewExtensionsTests: XCTestCase { +final class NSViewExtensionsTests: XCTestCase { func testBorderColor() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) diff --git a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift index e50ec8f76..b9deb364f 100644 --- a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class CGFloatExtensionsTests: XCTestCase { +final class CGFloatExtensionsTests: XCTestCase { #if !os(macOS) func testAbs() { diff --git a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift index 03ea9e53b..b7040513b 100644 --- a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class CGPointExtensionsTests: XCTestCase { +final class CGPointExtensionsTests: XCTestCase { let point1 = CGPoint(x: 10, y: 10) let point2 = CGPoint(x: 30, y: 30) diff --git a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift index affac36e5..d8f05aeed 100644 --- a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class CGSizeExtensionsTests: XCTestCase { +final class CGSizeExtensionsTests: XCTestCase { func testAspectFit() { let rect = CGSize(width: 120, height: 80) diff --git a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift index 46e3834bf..208f22cd6 100644 --- a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift +++ b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest import CoreLocation -class CLLocationExtensionsTests: XCTestCase { +final class CLLocationExtensionsTests: XCTestCase { func testMidLocation() { let a = CLLocation(latitude: -15.822877, longitude: -47.941839) diff --git a/Tests/FoundationTests/DataExtensionsTests.swift b/Tests/FoundationTests/DataExtensionsTests.swift index c3d6234e0..337af40c7 100644 --- a/Tests/FoundationTests/DataExtensionsTests.swift +++ b/Tests/FoundationTests/DataExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class DataExtensionsTests: XCTestCase { +final class DataExtensionsTests: XCTestCase { func testString() { let dataFromString = "hello".data(using: .utf8) diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 7c16c7905..44b2326e9 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class DateExtensionsTests: XCTestCase { +final class DateExtensionsTests: XCTestCase { override func setUp() { super.setUp() diff --git a/Tests/FoundationTests/LocaleExtensionsTests.swift b/Tests/FoundationTests/LocaleExtensionsTests.swift index 1ceffed34..de27e7422 100644 --- a/Tests/FoundationTests/LocaleExtensionsTests.swift +++ b/Tests/FoundationTests/LocaleExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class LocaleExtensionsTests: XCTestCase { +final class LocaleExtensionsTests: XCTestCase { func testPosix() { let test: Locale = .posix diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index 37e7c5a59..a84f954c9 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class NSAttributedStringExtensionsTests: XCTestCase { +final class NSAttributedStringExtensionsTests: XCTestCase { #if !os(macOS) && !os(tvOS) func testBolded() { diff --git a/Tests/FoundationTests/NSPredicateExtensionsTests.swift b/Tests/FoundationTests/NSPredicateExtensionsTests.swift index 867d49375..a859f565d 100644 --- a/Tests/FoundationTests/NSPredicateExtensionsTests.swift +++ b/Tests/FoundationTests/NSPredicateExtensionsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class NSPredicateExtensionsTests: XCTestCase { +final class NSPredicateExtensionsTests: XCTestCase { func testNot() { let predicate = NSPredicate(format: "a < 7") diff --git a/Tests/FoundationTests/URLExtensionsTests.swift b/Tests/FoundationTests/URLExtensionsTests.swift index bd1e414ef..6359246e0 100644 --- a/Tests/FoundationTests/URLExtensionsTests.swift +++ b/Tests/FoundationTests/URLExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class URLExtensionsTests: XCTestCase { +final class URLExtensionsTests: XCTestCase { var url = URL(string: "https://www.google.com")! let params = ["q": "swifter swift"] diff --git a/Tests/FoundationTests/URLRequestExtensionsTests.swift b/Tests/FoundationTests/URLRequestExtensionsTests.swift index 4999c7c8e..d66f1070b 100644 --- a/Tests/FoundationTests/URLRequestExtensionsTests.swift +++ b/Tests/FoundationTests/URLRequestExtensionsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class URLRequestExtensionsTests: XCTestCase { +final class URLRequestExtensionsTests: XCTestCase { func testInitFromURLString() { let urlString = "https://www.w3schools.com/" diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift index 226005b5f..cb73ed9d6 100644 --- a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class UserDefaultsExtensionsTests: XCTestCase { +final class UserDefaultsExtensionsTests: XCTestCase { func testSubscript() { let key = "testKey" diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index b2899424c..bc016c5a5 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -20,7 +20,7 @@ import XCTest import CoreImage #endif -class ColorExtensionsTests: XCTestCase { +final class ColorExtensionsTests: XCTestCase { // MARK: - Test properties func testRgbComponents() { diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index cdd213c8e..127cfb52b 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class ArrayExtensionsTests: XCTestCase { +final class ArrayExtensionsTests: XCTestCase { func testRandomItem() { XCTAssert([1, 2, 3].contains([1, 2, 3].randomItem)) diff --git a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift index 36bf0121a..615f49086 100644 --- a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class BoolExtensionsTests: XCTestCase { +final class BoolExtensionsTests: XCTestCase { func testInt() { XCTAssertEqual(true.int, 1) diff --git a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift index 99aedbbd6..942a0bf9f 100644 --- a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift @@ -17,7 +17,7 @@ import XCTest @testable import SwifterSwift -class CharacterExtensionsTests: XCTestCase { +final class CharacterExtensionsTests: XCTestCase { func testOperators() { let s = Character("s") diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index c6ba009de..86c1e39a7 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class CollectionExtensionsTests: XCTestCase { +final class CollectionExtensionsTests: XCTestCase { func testForEachInParallel() { let collection = [1, 2, 3, 4, 5] diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index c448d1643..4408d4618 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class DictionaryExtensionsTests: XCTestCase { +final class DictionaryExtensionsTests: XCTestCase { var testDict: [String : Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] diff --git a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift index c4f611232..1aa7d4caa 100644 --- a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class DoubleExtensionsTests: XCTestCase { +final class DoubleExtensionsTests: XCTestCase { func testAbs() { XCTAssertEqual(Double(-9.3).abs, Double(9.3)) diff --git a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift index bb2dca10d..5fe6a7db0 100644 --- a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class FloatExtensionsTests: XCTestCase { +final class FloatExtensionsTests: XCTestCase { func testAbs() { XCTAssertEqual(Float(-9.3).abs, Float(9.3)) diff --git a/Tests/SwiftStdlibTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift index bc3cff984..38588a846 100644 --- a/Tests/SwiftStdlibTests/IntExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/IntExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class IntExtensionsTests: XCTestCase { +final class IntExtensionsTests: XCTestCase { func testAbs() { XCTAssertEqual((-9).abs, 9) diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index 0bec47d01..1089a2e6b 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class OptionalExtensionsTests: XCTestCase { +final class OptionalExtensionsTests: XCTestCase { func testUnwrappedOrDefault() { var str: String? = nil diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 450c62383..f0aa13bfa 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class StringExtensionsTests: XCTestCase { +final class StringExtensionsTests: XCTestCase { override func setUp() { super.setUp() diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 691471935..338f779f6 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import SwifterSwift -class SwifterSwiftTests: XCTestCase { +final class SwifterSwiftTests: XCTestCase { func testTypeName() { let number = 8 diff --git a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift index 7b3ef8128..5396ac9fe 100644 --- a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift -class UIAlertControllerExtensionsTests: XCTestCase { +final class UIAlertControllerExtensionsTests: XCTestCase { func testAddAction() { diff --git a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift index afe9a227e..accb00a34 100644 --- a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIBarButtonExtensionsTests: XCTestCase { +final class UIBarButtonExtensionsTests: XCTestCase { func testSelector() {} diff --git a/Tests/UIKitTests/UIButtonExtensionsTests.swift b/Tests/UIKitTests/UIButtonExtensionsTests.swift index 7a3e4a4a0..41c3c184a 100644 --- a/Tests/UIKitTests/UIButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIButtonExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIButtonExtensionsTests: XCTestCase { +final class UIButtonExtensionsTests: XCTestCase { func testImageForDisabled() { diff --git a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift index a3c25de93..223322568 100644 --- a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift +++ b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UICollectionViewExtensionsTests: XCTestCase { +final class UICollectionViewExtensionsTests: XCTestCase { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) let emptyCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index 9e5c861d7..ed1e30420 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift -class UIFontExtension: XCTestCase { +final class UIFontExtension: XCTestCase { func testMonospacedDigitFont() { let font = UIFont.preferredFont(forTextStyle: .body) diff --git a/Tests/UIKitTests/UIImageExtensionsTests.swift b/Tests/UIKitTests/UIImageExtensionsTests.swift index f5bf71561..3154dc774 100644 --- a/Tests/UIKitTests/UIImageExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIImageExtensionsTests: XCTestCase { +final class UIImageExtensionsTests: XCTestCase { func testBytesSize() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index e0cebe08d..5332ae1ca 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIImageViewExtensionsTests: XCTestCase { +final class UIImageViewExtensionsTests: XCTestCase { func testDownload() { // Success diff --git a/Tests/UIKitTests/UILabelExtensionsTests.swift b/Tests/UIKitTests/UILabelExtensionsTests.swift index 8afb88897..f9ef9dcf8 100644 --- a/Tests/UIKitTests/UILabelExtensionsTests.swift +++ b/Tests/UIKitTests/UILabelExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) || os(tvOS) - class UILabelExtensionsTests: XCTestCase { + final class UILabelExtensionsTests: XCTestCase { func testInitWithText() { let label = UILabel(text: "Hello world") diff --git a/Tests/UIKitTests/UINavigationBarExtensionTests.swift b/Tests/UIKitTests/UINavigationBarExtensionTests.swift index 733a1bd68..2f6a2658e 100644 --- a/Tests/UIKitTests/UINavigationBarExtensionTests.swift +++ b/Tests/UIKitTests/UINavigationBarExtensionTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UINavigationBarExtensionsTests: XCTestCase { +final class UINavigationBarExtensionsTests: XCTestCase { func testSetTitleFont() { let navigationBar = UINavigationBar() diff --git a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift index abfab3298..639c9c570 100644 --- a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UINavigationControllerExtensionsTests: XCTestCase { +final class UINavigationControllerExtensionsTests: XCTestCase { // This test is commented because we not sure if after the animation it already removed the viewcontroller from the array, it's something internal of UIKit that require a deeper looking. // func testPopViewController() { // let navigationController = UINavigationController() diff --git a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift index 5a9868a51..d516b523a 100644 --- a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UINavigationItemExtensionsTests: XCTestCase { +final class UINavigationItemExtensionsTests: XCTestCase { func testReplaceTitle() { let navigationItem = UINavigationItem() diff --git a/Tests/UIKitTests/UISearchBarExtensionsTests.swift b/Tests/UIKitTests/UISearchBarExtensionsTests.swift index c898e8e6f..1fac5baf8 100644 --- a/Tests/UIKitTests/UISearchBarExtensionsTests.swift +++ b/Tests/UIKitTests/UISearchBarExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) -class UISearchBarExtensionsTests: XCTestCase { +final class UISearchBarExtensionsTests: XCTestCase { func testSearchBar() { let searchBar = UISearchBar() diff --git a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift index ebcf23278..98ced5b4c 100644 --- a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift +++ b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UISegmentedControlExtensionsTests: XCTestCase { +final class UISegmentedControlExtensionsTests: XCTestCase { func testSegmentTitles() { let segmentControl = UISegmentedControl() diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index ecd9d5a0e..e61e1417a 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UISliderExtensionsTests: XCTestCase { +final class UISliderExtensionsTests: XCTestCase { func testCompletionCalledAnimated() { let slider = UISlider() diff --git a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift index ea6b4fa12..cc739ca58 100644 --- a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift +++ b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIStoryboardExtensionsTests: XCTestCase { +final class UIStoryboardExtensionsTests: XCTestCase { func testInstantiateViewController() { let storyboard = UIStoryboard(name: "TestStoryboard", bundle: Bundle(for: UIStoryboardExtensionsTests.self)) diff --git a/Tests/UIKitTests/UISwitchExtensionsTests.swift b/Tests/UIKitTests/UISwitchExtensionsTests.swift index 02a3eafb0..f3c95a0d3 100644 --- a/Tests/UIKitTests/UISwitchExtensionsTests.swift +++ b/Tests/UIKitTests/UISwitchExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) -class UISwitchExtensionsTests: XCTestCase { +final class UISwitchExtensionsTests: XCTestCase { func testToggle() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) diff --git a/Tests/UIKitTests/UITabBarExtensionsTests.swift b/Tests/UIKitTests/UITabBarExtensionsTests.swift index f8d3c560c..35a322420 100644 --- a/Tests/UIKitTests/UITabBarExtensionsTests.swift +++ b/Tests/UIKitTests/UITabBarExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UITabBarExtensionsTests: XCTestCase { +final class UITabBarExtensionsTests: XCTestCase { func testSetColors() { let frame = CGRect(x: 0, y: 0, width: 300, height: 44) diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 08152d1e3..456f7db04 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift -class UITableViewExtensionsTests: XCTestCase { +final class UITableViewExtensionsTests: XCTestCase { let tableView = UITableView() let emptyTableView = UITableView() diff --git a/Tests/UIKitTests/UITextFieldExtensionsTests.swift b/Tests/UIKitTests/UITextFieldExtensionsTests.swift index a0b247daf..4888a5675 100644 --- a/Tests/UIKitTests/UITextFieldExtensionsTests.swift +++ b/Tests/UIKitTests/UITextFieldExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) || os(tvOS) -class UITextFieldExtensionsTests: XCTestCase { +final class UITextFieldExtensionsTests: XCTestCase { func testIsEmpty() { let textField = UITextField() diff --git a/Tests/UIKitTests/UITextViewExtensionsTests.swift b/Tests/UIKitTests/UITextViewExtensionsTests.swift index d402d1819..de6c5376d 100644 --- a/Tests/UIKitTests/UITextViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITextViewExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) || os(tvOS) -class UITextViewExtensionsTests: XCTestCase { +final class UITextViewExtensionsTests: XCTestCase { var textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index 14fdd80a9..bd7a8828c 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIViewControllerExtensionsTests: XCTestCase { +final class UIViewControllerExtensionsTests: XCTestCase { class MockNotificationViewController: UIViewController { var notificationFired = false diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index c42ad121b..03c845e80 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift #if os(iOS) || os(tvOS) -class UIViewExtensionsTests: XCTestCase { +final class UIViewExtensionsTests: XCTestCase { func testBorderColor() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) From 5087b48a01008f91e4272ca33ae4b11ac3002631 Mon Sep 17 00:00:00 2001 From: Ryan Batchelder Date: Sun, 8 Oct 2017 15:46:07 -0400 Subject: [PATCH 053/201] Added CGColorExtensionsTests for iOS and macOS --- .../CGColorExtensionsTests.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Tests/CoreGraphicsTests/CGColorExtensionsTests.swift diff --git a/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift new file mode 100644 index 000000000..b158df22e --- /dev/null +++ b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift @@ -0,0 +1,32 @@ +// +// CGColorExtensionsTests.swift +// SwifterSwift-iOS +// +// Created by Ryan Batchelder on 10/8/17. +// + +import XCTest +#if os(macOS) + import Cocoa +#else + import UIKit +#endif +@testable import SwifterSwift + +final class CGColorExtensionsTests: XCTestCase { + #if !os(macOS) + func testUiColor() { + let red = UIColor.red + let cgRed = red.cgColor + XCTAssertEqual(cgRed.uiColor, red) + } + #endif + + #if os(macOS) + func testNsColor() { + let red = NSColor.red + let cgRed = red.cgColor + XCTAssertEqual(cgRed.nsColor, red) + } + #endif +} From 85759d3e6e6862c97aa3fc7811a1414487e468dd Mon Sep 17 00:00:00 2001 From: Ryan Batchelder Date: Sun, 8 Oct 2017 15:50:34 -0400 Subject: [PATCH 054/201] mend --- SwifterSwift.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 4724337c3..1f2e42c7a 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -312,6 +312,9 @@ 07FE50451F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; 07FE50461F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */; }; + 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; + 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; + 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -457,6 +460,7 @@ 07C50D291F5EB03200F46E5A /* NSAttributedStringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringExtensionsTests.swift; sourceTree = ""; }; 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensionsTests.swift; sourceTree = ""; }; + 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -768,6 +772,7 @@ 07C50D251F5EB03200F46E5A /* CGFloatExtensionsTests.swift */, 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */, 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */, + 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */, ); path = CoreGraphicsTests; sourceTree = ""; @@ -1396,6 +1401,7 @@ 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, 07C50D3F1F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, @@ -1450,6 +1456,7 @@ 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8A1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D881F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, 07C50D551F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, @@ -1483,6 +1490,7 @@ 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D771F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, From 7efd618aec1690a46ae0a9c0c3c9b9f4e75d17fb Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Tue, 10 Oct 2017 18:49:04 +0300 Subject: [PATCH 055/201] Fixes #282 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa23db507..5be416bcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,11 +25,11 @@ before_script: script: - set -o pipefail - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty + - bash <(curl -s https://codecov.io/bash) -cF ios -J 'SwifterSwift' - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty + - bash <(curl -s https://codecov.io/bash) -cF tvos -J 'SwifterSwift' - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty + - bash <(curl -s https://codecov.io/bash) -cF osx -J 'SwifterSwift' - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty - swiftlint lint - pod lib lint - -after_success: - - bash <(curl -s https://codecov.io/bash) From 406305ee87c1bdc195f7576c9caa6e244feda639 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Tue, 10 Oct 2017 18:53:04 +0300 Subject: [PATCH 056/201] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5be416bcc..27eec928c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,9 +27,9 @@ script: - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty - bash <(curl -s https://codecov.io/bash) -cF ios -J 'SwifterSwift' - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty - - bash <(curl -s https://codecov.io/bash) -cF tvos -J 'SwifterSwift' + - bash <(curl -s https://codecov.io/bash) -cF tvos -J 'SwifterSwift' - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty - - bash <(curl -s https://codecov.io/bash) -cF osx -J 'SwifterSwift' + - bash <(curl -s https://codecov.io/bash) -cF osx -J 'SwifterSwift' - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty - swiftlint lint - pod lib lint From 7bfe4073e4b8777c8e4e520bfd30728459d14df3 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Mon, 16 Oct 2017 15:24:23 +0200 Subject: [PATCH 057/201] Update README.md A few minor suggestions for improved readability. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fcd61bfb8..00118fdf5 100755 --- a/README.md +++ b/README.md @@ -210,7 +210,7 @@ let package = Package( ## How cool is this? -SwifterSwift is a library of **over 500 properties and methods**, designed to extend Swift's functionality and productivity, staying faithful to the original API design guidelines of Swift. +SwifterSwift is a library of **over 500 properties and methods**, designed to extend Swift's functionality and productivity, staying faithful to the original Swift API design guidelines. Check [Examples.md](https://github.com/SwifterSwift/SwifterSwift/tree/master/Examples/Examples.md) for some cool examples! @@ -218,20 +218,20 @@ Check [Examples.md](https://github.com/SwifterSwift/SwifterSwift/tree/master/Exa ## Documentation -Complete documentation for all extensions with examples is available at [swifterswift.com/docs](http://swifterswift.com/docs) +Documentation for all extensions, with examples, is available at [swifterswift.com/docs](http://swifterswift.com/docs) ## Get involved: -Your feedback is always appreciated and welcomed. +We want your feedback. Please refer to [contributing guidelines](https://github.com/SwifterSwift/SwifterSwift/tree/master/CONTRIBUTING.md) before participating. ## Slack Channel: [![Slack](http://slack.swifterswift.com/badge.svg)](http://slack.swifterswift.com/) -It is always nice to talk with other people using SwifterSwift and exchange experiences, [Join Channel](http://slack.swifterswift.com/) +It is always nice to talk with other people using SwifterSwift and exchange experiences, so come [join our Slack channel](http://slack.swifterswift.com/). From 9c67b5d3b670e7ca31742671c9bb2a6c3078bcad Mon Sep 17 00:00:00 2001 From: Bas van Kuijck Date: Tue, 17 Oct 2017 01:22:00 +0200 Subject: [PATCH 058/201] Improve Array.sum() and Array.average() (#285) * Improve Array.sum() and Array.average() 300% speed improvement * Data.chunks(of:) * Fixed unit tests (scheme set locale) * Replaced reduce with for loop in sum() and average() Also added some comments in the chunks DataExtensionsTests tests and removed the fatalError in chunks() * DataExtensions shouldn't have been in this PR * Reset CHANGELOG.md --- CHANGELOG.md | 3 +-- Sources/Extensions/Foundation/DataExtensions.swift | 1 - Sources/Extensions/SwiftStdlib/ArrayExtensions.swift | 12 ++++++++---- .../xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme | 3 ++- .../xcschemes/SwifterSwift-macOS.xcscheme | 5 +++-- .../xcschemes/SwifterSwift-tvOS.xcscheme | 3 ++- .../xcschemes/SwifterSwift-watchOS.xcscheme | 3 ++- .../SignedNumericExtensionsTests.swift | 1 - 8 files changed, 18 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 590f517d9..2bbed39ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,10 @@ All notable changes to this project will be documented in this file. > > ### Enhancements > N/A -> +> > ### Bugfixes > N/A - # v4.0.1 ### API Breaking diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index b77acbb1a..c2e2e23b2 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -32,5 +32,4 @@ public extension Data { public func string(encoding: String.Encoding) -> String? { return String(data: self, encoding: encoding) } - } diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index cb2b52b12..edb0279d6 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -13,12 +13,14 @@ public extension Array where Element: Numeric { /// SwifterSwift: Sum of all elements in array. /// - /// [1, 2, 3, 4, 5].sum -> 15 + /// [1, 2, 3, 4, 5].sum() -> 15 /// /// - Returns: sum of the array's elements. public func sum() -> Element { var total: Element = 0 - forEach { total += $0 } + for i in 0.. Element { guard !isEmpty else { return 0 } var total: Element = 0 - forEach { total += $0 } + for i in 0.. diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme index cbb282437..65feb5f37 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme @@ -26,7 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + language = "en" + region = "US" shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"> @@ -57,7 +58,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + language = "en" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme index 7c0f45c67..01910925f 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme @@ -26,7 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + language = "en" + region = "US" shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"> diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme index fcb306f8d..304fc1b5e 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme @@ -26,7 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + language = "en" + region = "US" shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift index 2b3a87ca8..aceac661d 100644 --- a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift @@ -17,7 +17,6 @@ class SignedNumericExtensionsTests: XCTestCase { func testAsLocaleCurrency() { let number: Double = 3.2 - print(number.asLocaleCurrency) XCTAssertEqual(number.asLocaleCurrency, "$3.20") } From 3e06eed60b98c34cc9d4fa726432db51581ebbe1 Mon Sep 17 00:00:00 2001 From: Zhuo Huang Date: Fri, 20 Oct 2017 12:56:16 -0700 Subject: [PATCH 059/201] add semicolons to lastIndex(of:) and firstIndex(of:) doc --- Sources/Extensions/SwiftStdlib/ArrayExtensions.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index edb0279d6..f8bf13852 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -523,9 +523,9 @@ public extension Array where Element: Equatable { /// SwifterSwift: First index of a given item in an array. /// - /// [1, 2, 2, 3, 4, 2, 5].firstIndex(of 2) -> 1 - /// [1.2, 2.3, 4.5, 3.4, 4.5].firstIndex(of 6.5) -> nil - /// ["h", "e", "l", "l", "o"].firstIndex(of "l") -> 2 + /// [1, 2, 2, 3, 4, 2, 5].firstIndex(of: 2) -> 1 + /// [1.2, 2.3, 4.5, 3.4, 4.5].firstIndex(of: 6.5) -> nil + /// ["h", "e", "l", "l", "o"].firstIndex(of: "l") -> 2 /// /// - Parameter item: item to check. /// - Returns: first index of item in array (if exists). @@ -538,9 +538,9 @@ public extension Array where Element: Equatable { /// SwifterSwift: Last index of element in array. /// - /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of 2) -> 5 - /// [1.2, 2.3, 4.5, 3.4, 4.5].lastIndex(of 6.5) -> nil - /// ["h", "e", "l", "l", "o"].lastIndex(of "l") -> 3 + /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of: 2) -> 5 + /// [1.2, 2.3, 4.5, 3.4, 4.5].lastIndex(of: 6.5) -> nil + /// ["h", "e", "l", "l", "o"].lastIndex(of: "l") -> 3 /// /// - Parameter item: item to check. /// - Returns: last index of item in array (if exists). From 55a4603aaaedae074d011eacbdb131913e535f7c Mon Sep 17 00:00:00 2001 From: Yurii Date: Sun, 22 Oct 2017 12:35:26 +0200 Subject: [PATCH 060/201] Add test for Date.isBetween (#289) --- Tests/FoundationTests/DateExtensionsTests.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 44b2326e9..f2e06b4e5 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -655,6 +655,17 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date2.daysSince(date1), 1) XCTAssertEqual(date1.daysSince(date2), -1) } + + func testIsBetween() { + let date1 = Date(timeIntervalSince1970: 0) + let date2 = date1.addingTimeInterval(60) + let date3 = date2.addingTimeInterval(60) + + XCTAssert(date2.isBetween(date1, date3)) + XCTAssertFalse(date1.isBetween(date2, date3)) + XCTAssert(date1.isBetween(date1, date2, includeBounds: true)) + XCTAssertFalse(date1.isBetween(date1, date2)) + } func testNewDateFromComponenets() { let date = Date(calendar: Date().calendar, timeZone: Date().timeZone, era: Date().era, year: Date().year, month: Date().month, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) From a338f27f7a1497cac88261a3a393dc2b302665c2 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 22 Oct 2017 14:35:50 +0300 Subject: [PATCH 061/201] Update slack badge (#293) Fixes #292 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 00118fdf5..e7cb202cb 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [![Swift](https://img.shields.io/badge/Swift-4.0-orange.svg)](https://swift.org) [![Xcode](https://img.shields.io/badge/Xcode-9.0-blue.svg)](https://developer.apple.com/xcode) [![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) -[![Slack Channel](http://slack.swifterswift.com/badge.svg)](http://slack.swifterswift.com/) +[![Slack Channel](https://slackin-ppvrggbpgn.now.sh/badge.svg)](https://slackin-ppvrggbpgn.now.sh/) SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. @@ -229,9 +229,9 @@ Please refer to [contributing guidelines](https://github.com/SwifterSwift/Swifte -## Slack Channel: [![Slack](http://slack.swifterswift.com/badge.svg)](http://slack.swifterswift.com/) +## Slack Channel: [![Slack](https://slackin-ppvrggbpgn.now.sh/badge.svg)](https://slackin-ppvrggbpgn.now.sh/) -It is always nice to talk with other people using SwifterSwift and exchange experiences, so come [join our Slack channel](http://slack.swifterswift.com/). +It is always nice to talk with other people using SwifterSwift and exchange experiences, so come [join our Slack channel](https://slackin-ppvrggbpgn.now.sh/). From e0067e227995acf742bb80681810f72c2f575f36 Mon Sep 17 00:00:00 2001 From: Yurii Date: Sun, 22 Oct 2017 17:05:50 +0200 Subject: [PATCH 062/201] Fixes #258 (#295) --- .../Foundation/DateExtensions.swift | 15 ++++++++++++ .../FoundationTests/DateExtensionsTests.swift | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 25d7eb15b..4a2a55888 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -714,6 +714,21 @@ public extension Date { return startDate.compare(self).rawValue * self.compare(endDate).rawValue > 0 } } + + /// SwifterSwift: check if a date is a number of date components of another date + /// + /// - Parameters: + /// - value: number of times component is used in creating range + /// - component: Calendar.Component to use. + /// - date: Date to compare self to. + /// - Returns: true if the date is within a number of components of another date + + public func isWithin(_ value: UInt, _ component: Calendar.Component, of date: Date) -> Bool { + return calendar + .dateComponents([component], from: self, to: date) + .value(for: component) + .map { abs($0) <= value } ?? false + } } // MARK: - Initializers diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index f2e06b4e5..06fa85b38 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -667,6 +667,29 @@ final class DateExtensionsTests: XCTestCase { XCTAssertFalse(date1.isBetween(date1, date2)) } + func testIsWithin() { + let date1 = Date(timeIntervalSince1970: 60 * 60 * 24) // 1970-01-01T00:00:00.000Z + let date2 = date1.addingTimeInterval(60 * 60) // 1970-01-01T00:01:00.000Z, one hour later than date1 + + //The regular + XCTAssertFalse(date1.isWithin(1, .second, of: date2)) + XCTAssertFalse(date1.isWithin(1, .minute, of: date2)) + XCTAssert(date1.isWithin(1, .hour, of: date2)) + XCTAssert(date1.isWithin(1, .day, of: date2)) + + //The other way around + XCTAssertFalse(date2.isWithin(1, .second, of: date1)) + XCTAssertFalse(date2.isWithin(1, .minute, of: date1)) + XCTAssert(date2.isWithin(1, .hour, of: date1)) + XCTAssert(date2.isWithin(1, .day, of: date1)) + + //With itself + XCTAssert(date1.isWithin(1, .second, of: date1)) + XCTAssert(date1.isWithin(1, .minute, of: date1)) + XCTAssert(date1.isWithin(1, .hour, of: date1)) + XCTAssert(date1.isWithin(1, .day, of: date1)) + } + func testNewDateFromComponenets() { let date = Date(calendar: Date().calendar, timeZone: Date().timeZone, era: Date().era, year: Date().year, month: Date().month, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNotNil(date) From 8d460f79787853a3c84b0f7c4ffb6913f9359662 Mon Sep 17 00:00:00 2001 From: buddax2 Date: Wed, 25 Oct 2017 14:42:59 +0300 Subject: [PATCH 063/201] add optional assignment operator (#296) * add optional assignment operator * fixing the warnings * change description * put the func into the extension --- .../SwiftStdlib/OptionalExtensions.swift | 16 ++++++++++++++++ .../OptionalExtensionsTests.swift | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index c0fb2f9c2..8db9c0f31 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -8,6 +8,9 @@ import Foundation +// MARK: - Operators +infix operator ??= : AssignmentPrecedence + public extension Optional { /// SwifterSwift: Get self of default value (if self is nil). @@ -45,4 +48,17 @@ public extension Optional { _ = self.map(block) } + /// SwifterSwift: Assign an optional value to a variable only if the value is not nil. + /// + /// let someParameter: String? = nil + /// let parameters = [String:Any]() //Some parameters to be attached to a GET request + /// parameters[someKey] ??= someParameter //It won't be added to the parameters dict + /// + /// - Parameters: + /// - lhs: Any? + /// - rhs: Any? + public static func ??= (lhs: inout Optional, rhs: Optional) { + guard let rhs = rhs else { return } + lhs = rhs + } } diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index 1089a2e6b..61b6793ea 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -35,4 +35,20 @@ final class OptionalExtensionsTests: XCTestCase { } } + func testOptionalAssignment() { + let parameter1: String? = nil + let parameter2: String? = "foo" + + let key1: String = "key1" + let key2: String = "key2" + + var parameters = [String: String]() + + parameters[key1] ??= parameter1 + parameters[key2] ??= parameter2 + + XCTAssert(parameters[key1] == nil) + XCTAssertFalse(parameters[key1] != parameter1) + XCTAssert(parameters[key2] == parameter2) + } } From 67e5bbd003edc72fd46942724dbffe3ae423be52 Mon Sep 17 00:00:00 2001 From: Ben Snider Date: Thu, 26 Oct 2017 10:57:51 -0600 Subject: [PATCH 064/201] Remove cross references #294 (#297) * Removing cross references per #286. * Cleaning up some imports. * Removing unit dependencies for color extensions. * Fixing compiler error on macos. * Adding more Color extension tests. --- .../Foundation/DataExtensions.swift | 6 +- .../Foundation/DateExtensions.swift | 2 +- .../Extensions/Shared/ColorExtensions.swift | 99 +++++++++++++------ .../SwiftStdlib/IntExtensions.swift | 2 +- .../SwiftStdlib/StringExtensions.swift | 4 +- .../Extensions/UIKit/UITabBarExtensions.swift | 39 +++++++- .../Extensions/UIKit/UIViewExtensions.swift | 2 +- Tests/SharedTests/ColorExtensionsTests.swift | 25 +++++ 8 files changed, 138 insertions(+), 41 deletions(-) diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index c2e2e23b2..75998df24 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -6,11 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import Foundation // MARK: - Properties public extension Data { diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 4a2a55888..ede046bd3 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -788,7 +788,7 @@ public extension Date { public init?(iso8601String: String) { // https://github.com/justinmakaila/NSDate-ISO-8601/blob/master/NSDateISO8601.swift let dateFormatter = DateFormatter() - dateFormatter.locale = .posix + dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.timeZone = TimeZone.current dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" if let date = dateFormatter.date(from: iso8601String) { diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index c1bad571b..c41c7f0e2 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -25,11 +25,7 @@ public extension Color { let r = Int(arc4random_uniform(255)) let g = Int(arc4random_uniform(255)) let b = Int(arc4random_uniform(255)) - #if os(macOS) - return NSColor(red: r, green: g, blue: b)! - #else - return UIColor(red: r, green: g, blue: b)! - #endif + return Color(red: r, green: g, blue: b)! } /// SwifterSwift: RGB components for a Color (between 0 and 255). @@ -85,10 +81,12 @@ public extension Color { /// SwifterSwift: Hexadecimal value string (read-only). public var hexString: String { - let r = rgbComponents.red - let g = rgbComponents.green - let b = rgbComponents.blue - return String(format: "#%02X%02X%02X", r, g, b) + let components: [Int] = { + let c = cgColor.components! + let components = c.count == 4 ? c : [c[0], c[0], c[0], c[1]] + return components.map { Int($0 * 255.0) } + }() + return String(format: "#%02X%02X%02X", components[0], components[1], components[2]) } /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). @@ -101,7 +99,16 @@ public extension Color { /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). public var shortHexOrHexString: String { - return shortHexString ?? hexString + let components: [Int] = { + let c = cgColor.components! + let components = c.count == 4 ? c : [c[0], c[0], c[0], c[1]] + return components.map { Int($0 * 255.0) } + }() + let hexString = String(format: "#%02X%02X%02X", components[0], components[1], components[2]) + let string = hexString.replacingOccurrences(of: "#", with: "") + let chrs = Array(string.characters) + guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return hexString } + return "#\(chrs[0])\(chrs[2])\(chrs[4])" } /// SwifterSwift: Alpha of Color (read-only). @@ -118,19 +125,42 @@ public extension Color { /// SwifterSwift: Get UInt representation of a Color (read-only). public var uInt: UInt { - let c = self.cgFloatComponents + let c: [CGFloat] = { + let c = cgColor.components! + return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] + }() var colorAsUInt32: UInt32 = 0 - colorAsUInt32 += UInt32(c.red * 255.0) << 16 - colorAsUInt32 += UInt32(c.green * 255.0) << 8 - colorAsUInt32 += UInt32(c.blue * 255.0) + colorAsUInt32 += UInt32(c[0] * 255.0) << 16 + colorAsUInt32 += UInt32(c[1] * 255.0) << 8 + colorAsUInt32 += UInt32(c[2] * 255.0) return UInt(colorAsUInt32) } /// SwifterSwift: Get color complementary (read-only, if applicable). public var complementary: Color? { - return Color.init(complementaryFor: self) + let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() + let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in + if self.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { + let oldComponents = self.cgColor.components + let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] + let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) + let colorOut = Color(cgColor: colorRef!) + return colorOut + } else { + return self + } + } + + let c = convertColorToRGBSpace(self) + guard let componentColors = c?.cgColor.components else { return nil } + + let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 + let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 + let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 + + return Color(red: r, green: g, blue: b, alpha: 1.0) } } @@ -156,20 +186,26 @@ public extension Color { guard level1 > 0 else { return color2 } guard level2 > 0 else { return color1 } - let components1 = color1.cgFloatComponents - let components2 = color2.cgFloatComponents + let components1: [CGFloat] = { + let c = color1.cgColor.components! + return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] + }() + let components2: [CGFloat] = { + let c = color2.cgColor.components! + return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] + }() - let r1 = components1.red - let r2 = components2.red + let r1 = components1[0] + let r2 = components2[0] - let g1 = components1.green - let g2 = components2.green + let g1 = components1[1] + let g2 = components2[1] - let b1 = components1.blue - let b2 = components2.blue + let b1 = components1[2] + let b2 = components2[2] - let a1 = color1.alpha - let a2 = color2.alpha + let a1 = color1.cgColor.alpha + let a2 = color2.cgColor.alpha let r = level1*r1 + level2*r2 let g = level1*g1 + level2*g2 @@ -242,11 +278,14 @@ public extension Color { guard let hexValue = Int(string, radix: 16) else { return nil } - var trans = transparency - if trans < 0 { trans = 0 } - if trans > 1 { trans = 1 } - - self.init(hex: Int(hexValue), transparency: trans) + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + let red = (hexValue >> 16) & 0xff + let green = (hexValue >> 8) & 0xff + let blue = hexValue & 0xff + self.init(red: red, green: green, blue: blue, transparency: trans) } /// SwifterSwift: Create Color from a complementary of a Color (if applicable). diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 1d0c27c7a..3b474105f 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -56,7 +56,7 @@ public extension Int { var sign: String { return self >= 0 ? "" : "-" } - let abs = self.abs + let abs = Swift.abs(self) if abs == 0 { return "0k" } else if abs >= 0 && abs < 1000 { diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index e770001ae..e9e87a2dc 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -390,7 +390,9 @@ public extension String { let count = $0[$1] ?? 0 $0[$1] = count + 1 }.max { $0.1 < $1.1 }?.0 - return mostCommon?.string ?? "" + + guard let character = mostCommon else { return "" } + return String(character) } /// SwifterSwift: Reversed string. diff --git a/Sources/Extensions/UIKit/UITabBarExtensions.swift b/Sources/Extensions/UIKit/UITabBarExtensions.swift index 7dbcbf5ed..0ac73e285 100644 --- a/Sources/Extensions/UIKit/UITabBarExtensions.swift +++ b/Sources/Extensions/UIKit/UITabBarExtensions.swift @@ -40,7 +40,19 @@ public extension UITabBar { if let selectedbg = selectedBackground { let rect = CGSize(width: frame.width/CGFloat(barItems.count), height: frame.height) - selectionIndicatorImage = UIImage(color: selectedbg, size: rect) + selectionIndicatorImage = { (color: UIColor, size: CGSize) -> UIImage in + UIGraphicsBeginImageContextWithOptions(size, false, 1) + color.setFill() + UIRectFill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) + guard let image = UIGraphicsGetImageFromCurrentImageContext() else { + return UIImage() + } + UIGraphicsEndImageContext() + guard let aCgImage = image.cgImage else { + return UIImage() + } + return UIImage(cgImage: aCgImage) + }(selectedbg, rect) } if let itemColor = item { @@ -49,7 +61,30 @@ public extension UITabBar { guard let image = barItem.image else { continue } - barItem.image = image.filled(withColor: itemColor).withRenderingMode(.alwaysOriginal) + + barItem.image = { (image: UIImage, color: UIColor) -> UIImage in + UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) + color.setFill() + guard let context = UIGraphicsGetCurrentContext() else { + return image + } + + context.translateBy(x: 0, y: image.size.height) + context.scaleBy(x: 1.0, y: -1.0) + context.setBlendMode(CGBlendMode.normal) + + let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) + guard let mask = image.cgImage else { + return image + } + context.clip(to: rect, mask: mask) + context.fill(rect) + + let newImage = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext() + return newImage + }(image, itemColor).withRenderingMode(.alwaysOriginal) + barItem.setTitleTextAttributes([.foregroundColor: itemColor], for: .normal) if let selected = selectedItem { barItem.setTitleTextAttributes([.foregroundColor: selected], for: .selected) diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 42bf40077..2919074d2 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -248,7 +248,7 @@ public extension UIView { /// - radius: shadow radius (default is 3). /// - offset: shadow offset (default is .zero). /// - opacity: shadow opacity (default is 0.5). - public func addShadow(ofColor color: UIColor = UIColor(hex: 0x137992)!, radius: CGFloat = 3, offset: CGSize = .zero, opacity: Float = 0.5) { + public func addShadow(ofColor color: UIColor = UIColor(red:0.07, green:0.47, blue:0.57, alpha:1.0), radius: CGFloat = 3, offset: CGSize = .zero, opacity: Float = 0.5) { layer.shadowColor = color.cgColor layer.shadowOffset = offset layer.shadowRadius = radius diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index bc016c5a5..fa505e186 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -21,6 +21,31 @@ import XCTest #endif final class ColorExtensionsTests: XCTestCase { + + // MARK: - Test properties + func testCGFloatComponents() { + XCTAssertEqual(Color.red.cgFloatComponents.red, 1.0) + XCTAssertEqual(Color.red.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.red.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.green.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.green.cgFloatComponents.green, 1.0) + XCTAssertEqual(Color.green.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.blue.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.blue.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.blue.cgFloatComponents.blue, 1.0) + + XCTAssertEqual(Color.black.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.black.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.black.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.white.cgFloatComponents.red, 1.0) + XCTAssertEqual(Color.white.cgFloatComponents.green, 1.0) + XCTAssertEqual(Color.white.cgFloatComponents.blue, 1.0) + + XCTAssertEqual(Int(Color(hex: 0x12FFFF)!.cgFloatComponents.red * 255.0), 0x12) + } // MARK: - Test properties func testRgbComponents() { From f86752833106e8b41531238b950c0f84fa188809 Mon Sep 17 00:00:00 2001 From: buddax2 Date: Wed, 1 Nov 2017 02:00:16 +0200 Subject: [PATCH 065/201] Add scaled(toMaxSize:NSSize) to NSImage, including a test (#291) * Add scaled(toMaxSize:NSSize) to NSImage, including a test * fixed several issues mentioned by linter * changed the test name * make code coverage tool happy * update CHANGELOG * add missing entry about #296 --- CHANGELOG.md | 7 ++- .../Extensions/AppKit/NSImageExtensions.swift | 53 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 8 +++ .../AppKitTests/NSImageExtensionsTests.swift | 27 ++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 Sources/Extensions/AppKit/NSImageExtensions.swift create mode 100644 Tests/AppKitTests/NSImageExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bbed39ad..622327dd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,11 @@ All notable changes to this project will be documented in this file. > N/A > > ### Enhancements -> N/A -> +> - New **NSImage** extensions +> - Add `scaled(toMaxSize:)` to scale image to maximum size with respect to aspect ratio [#291](https://github.com/SwifterSwift/SwifterSwift/pull/291) by [buddax2](https://github.com/buddax2). +> - **Optional** +> - Add optional assignment operator `??=` [#296](https://github.com/SwifterSwift/SwifterSwift/pull/296) by [buddax2](https://github.com/buddax2). +> > ### Bugfixes > N/A diff --git a/Sources/Extensions/AppKit/NSImageExtensions.swift b/Sources/Extensions/AppKit/NSImageExtensions.swift new file mode 100644 index 000000000..1bd21591d --- /dev/null +++ b/Sources/Extensions/AppKit/NSImageExtensions.swift @@ -0,0 +1,53 @@ +// +// NSImageExtensions.swift +// SwifterSwift-macOS +// +// Created by BUDDAx2 on 20.10.2017. +// + +#if os(macOS) +import AppKit + +// MARK: - Methods +extension NSImage { + + /// SwifterSwift: NSImage scaled to maximum size with respect to aspect ratio + /// + /// - Parameter toMaxSize: maximum size + /// - Returns: scaled NSImage + public func scaled(toMaxSize: NSSize) -> NSImage { + var ratio: Float = 0.0 + let imageWidth = Float(self.size.width) + let imageHeight = Float(self.size.height) + let maxWidth = Float(toMaxSize.width) + let maxHeight = Float(toMaxSize.height) + + // Get ratio (landscape or portrait) + if imageWidth > imageHeight { + // Landscape + ratio = maxWidth / imageWidth + } else { + // Portrait + ratio = maxHeight / imageHeight + } + + // Calculate new size based on the ratio + let newWidth = imageWidth * ratio + let newHeight = imageHeight * ratio + + // Create a new NSSize object with the newly calculated size + let newSize: NSSize = NSSize(width: Int(newWidth), height: Int(newHeight)) + + // Cast the NSImage to a CGImage + var imageRect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) + let imageRef = self.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) + + // Create NSImage from the CGImage using the new size + let imageWithNewSize = NSImage(cgImage: imageRef!, size: newSize) + + // Return the new image + return imageWithNewSize + } +} + +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 1f2e42c7a..12f663263 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -315,6 +315,8 @@ 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; + 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */; }; + 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -461,6 +463,8 @@ 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensionsTests.swift; sourceTree = ""; }; 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensionsTests.swift; sourceTree = ""; }; + 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensions.swift; sourceTree = ""; }; + 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -619,6 +623,7 @@ isa = PBXGroup; children = ( 07B7F1641F5EB41600E6F910 /* NSViewExtensions.swift */, + 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */, ); path = AppKit; sourceTree = ""; @@ -743,6 +748,7 @@ isa = PBXGroup; children = ( 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */, + 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */, ); path = AppKitTests; sourceTree = ""; @@ -1346,6 +1352,7 @@ 077BA08D1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, + 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */, 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */, 077BA0921F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, @@ -1490,6 +1497,7 @@ 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */, 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D801F5EB05100F46E5A /* URLExtensionsTests.swift in Sources */, diff --git a/Tests/AppKitTests/NSImageExtensionsTests.swift b/Tests/AppKitTests/NSImageExtensionsTests.swift new file mode 100644 index 000000000..aecc60c9e --- /dev/null +++ b/Tests/AppKitTests/NSImageExtensionsTests.swift @@ -0,0 +1,27 @@ +// +// NSImageExtensionsTests.swift +// SwifterSwift-macOSTests +// +// Created by BUDDAx2 on 20.10.2017. +// + +#if os(macOS) + +import XCTest +@testable import SwifterSwift + +final class NSImageExtensionsTests: XCTestCase { + + func testScaledToMaxSize() { + let bundle = Bundle.init(for: NSImageExtensionsTests.self) + let image = bundle.image(forResource: NSImage.Name(rawValue: "TestImage")) + XCTAssertNotNil(image) + + let scaledImage = image!.scaled(toMaxSize: NSSize(width: 150, height: 150)) + XCTAssertNotNil(scaledImage) + XCTAssertEqual(scaledImage.size.width, 150) + } + +} + +#endif From e7e24f1a863b291b571b3b4400984d38b162a271 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 1 Nov 2017 00:15:41 -0200 Subject: [PATCH 066/201] Adding padStart/padEnd and paddingStart/paddingEnd String extensions (#300) * Adding padStart/padEnd and paddingStart and paddingEnd string extensions. --- CHANGELOG.md | 20 ++++-- .../SwiftStdlib/StringExtensions.swift | 71 ++++++++++++++++++- .../StringExtensionsTests.swift | 70 ++++++++++++++++++ 3 files changed, 153 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622327dd9..176942ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,17 @@ All notable changes to this project will be documented in this file. > ### API Breaking > N/A > -> ### Enhancements -> - New **NSImage** extensions -> - Add `scaled(toMaxSize:)` to scale image to maximum size with respect to aspect ratio [#291](https://github.com/SwifterSwift/SwifterSwift/pull/291) by [buddax2](https://github.com/buddax2). -> - **Optional** -> - Add optional assignment operator `??=` [#296](https://github.com/SwifterSwift/SwifterSwift/pull/296) by [buddax2](https://github.com/buddax2). -> + +### Enhancements + - New **String** extensions + - Add `padStart(lenght:with:)` and `padEnd(lenght:with:)` to pad the string to a lenght on the start or end. + - Add `paddingStart(lenght:with:)` and `paddingEnd(lenght:with:)` to return a padding string to a lenght on the start or end. + [#300](https://github.com/SwifterSwift/SwifterSwift/pull/300) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida) + - New **NSImage** extensions + - Add `scaled(toMaxSize:)` to scale image to maximum size with respect to aspect ratio [#291](https://github.com/SwifterSwift/SwifterSwift/pull/291) by [buddax2](https://github.com/buddax2). + - **Optional** + - Add optional assignment operator `??=` [#296](https://github.com/SwifterSwift/SwifterSwift/pull/296) by [buddax2](https://github.com/buddax2). + > ### Bugfixes > N/A @@ -33,10 +38,11 @@ N/A - Corrected some typos in README. [#263](https://github.com/SwifterSwift/SwifterSwift/pull/263) by [nick3399](https://github.com/nick3399). - New **String** extensions - Add `localized(comment:)` to returns a localized string, with an optional comment for translators. [#269](https://github.com/SwifterSwift/SwifterSwift/pull/269) by [Vyax](https://github.com/Vyax). -- New **NSPredicate** extensions: [#273](https://github.com/SwifterSwift/SwifterSwift/pull/273) by [Vyax](https://github.com/Vyax). +- New **NSPredicate** extensions - Add `not` to returns a new predicate formed by NOT-ing the predicate. - Add `and(_ predicate: NSPredicate)` to returns a new predicate formed by AND-ing the argument to the predicate. - Add `or(_ predicate: NSPredicate)` to returns a new predicate formed by OR-ing the argument to the predicate. + [#273](https://github.com/SwifterSwift/SwifterSwift/pull/273) by [Vyax](https://github.com/Vyax). - New **UILabel** extensions - Add `convenience init(text: String?)` to initialize a UILabel with text. [#271](https://github.com/SwifterSwift/SwifterSwift/pull/271) by [Vyax](https://github.com/Vyax). - New **Bool** extensions diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index e9e87a2dc..5c4d00a17 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -812,12 +812,81 @@ public extension String { /// /// - Parameter pattern: Pattern to verify. /// - Returns: true if string matches the pattern. - func matches(pattern: String) -> Bool { + public func matches(pattern: String) -> Bool { return range(of: pattern, options: String.CompareOptions.regularExpression, range: nil, locale: nil) != nil } + /// SwifterSwift: Pad string to fit the length parameter size with another string in the start. + /// + /// "hue".padStart(10) -> " hue" + /// "hue".padStart(10, with: "br") -> "brbrbrbhue" + /// + /// - Parameter length: The target length to pad. + /// - Parameter string: Pad string. Default is " ". + public mutating func padStart(_ length: Int, with string: String = " ") { + self = paddingStart(length, with: string) + } + + /// SwifterSwift: Returns a string by padding to fit the length parameter size with another string in the start. + /// + /// "hue".paddingStart(10) -> " hue" + /// "hue".paddingStart(10, with: "br") -> "brbrbrbhue" + /// + /// - Parameter length: The target length to pad. + /// - Parameter string: Pad string. Default is " ". + /// - Returns: The string with the padding on the start. + public func paddingStart(_ length: Int, with string: String = " ") -> String { + + guard count < length else { return self } + + let padLength = length - count + if padLength < string.count { + return string[string.startIndex.. "hue " + /// "hue".padEnd(10, with: "br") -> "huebrbrbrb" + /// + /// - Parameter length: The target length to pad. + /// - Parameter string: Pad string. Default is " ". + public mutating func padEnd(_ length: Int, with string: String = " ") { + self = paddingEnd(length, with: string) + } + + /// SwifterSwift: Returns a string by padding to fit the length parameter size with another string in the end. + /// + /// "hue".paddingEnd(10) -> "hue " + /// "hue".paddingEnd(10, with: "br") -> "huebrbrbrb" + /// + /// - Parameter length: The target length to pad. + /// - Parameter string: Pad string. Default is " ". + /// - Returns: The string with the padding on the end. + public func paddingEnd(_ length: Int, with string: String = " ") -> String { + guard count < length else { return self } + + let padLength = length - count + if padLength < string.count { + return self + string[string.startIndex.. Date: Sat, 4 Nov 2017 17:51:48 -0400 Subject: [PATCH 067/201] Closes #298 Date.year not working properly (#299) * Closes #298 Date.year not working properly * #298 Check certain date extensions when going back in time --- .../Foundation/DateExtensions.swift | 9 ++- .../FoundationTests/DateExtensionsTests.swift | 64 +++++++++++++++---- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index ede046bd3..97cef20ec 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -83,7 +83,9 @@ public extension Date { return Calendar.current.component(.year, from: self) } set { - if let date = Calendar.current.date(bySetting: .year, value: newValue, of: self) { + let currentYear = Calendar.current.component(.year, from: self) + let yearsToAdd = newValue - currentYear + if let date = Calendar.current.date(byAdding: .year, value: yearsToAdd, to: self) { self = date } } @@ -170,7 +172,10 @@ public extension Date { return Calendar.current.component(.minute, from: self) } set { - if let date = Calendar.current.date(bySetting: .minute, value: newValue, of: self) { + guard newValue >= 0 && newValue < 60 else { return } + let currentMinutes = Calendar.current.component(.minute, from: self) + let minutesToAdd = newValue - currentMinutes + if let date = Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) { self = date } } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 06fa85b38..5e1a2de04 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -63,6 +63,12 @@ final class DateExtensionsTests: XCTestCase { date.year = 2000 XCTAssertEqual(date.year, 2000) + + date.year = 2017 + XCTAssertEqual(date.year, 2017) + + date.year = 1988 + XCTAssertEqual(date.year, 1988) } func testQuarter() { @@ -79,14 +85,20 @@ final class DateExtensionsTests: XCTestCase { date.month = 14 XCTAssertEqual(date.month, 2) + + date.month = 1 + XCTAssertEqual(date.month, 1) } func testWeekOfYear() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.weekOfYear, 1) - let dateAfter10Days = Calendar.current.date(byAdding: .day, value: 7, to: date) - XCTAssertEqual(dateAfter10Days?.weekOfYear, 2) + let dateAfter7Days = Calendar.current.date(byAdding: .day, value: 7, to: date) + XCTAssertEqual(dateAfter7Days?.weekOfYear, 2) + + let originalDate = Calendar.current.date(byAdding: .day, value: -7, to: dateAfter7Days!) + XCTAssertEqual(originalDate?.weekOfYear, 1) } func testWeekOfMonth() { @@ -95,6 +107,9 @@ final class DateExtensionsTests: XCTestCase { let dateAfter7Days = Calendar.current.date(byAdding: .day, value: 7, to: date) XCTAssertEqual(dateAfter7Days?.weekOfMonth, 2) + + let originalDate = Calendar.current.date(byAdding: .day, value: -7, to: dateAfter7Days!) + XCTAssertEqual(originalDate?.weekOfMonth, 1) } func testWeekday() { @@ -110,6 +125,9 @@ final class DateExtensionsTests: XCTestCase { date.weekday = 7 XCTAssertEqual(date.weekday, 7) + + date.weekday = 5 + XCTAssertEqual(date.weekday, 5) } func testDay() { @@ -124,6 +142,9 @@ final class DateExtensionsTests: XCTestCase { date.day = 4 XCTAssertEqual(date.day, 4) + + date.day = 1 + XCTAssertEqual(date.day, 1) } func testHour() { @@ -138,6 +159,9 @@ final class DateExtensionsTests: XCTestCase { date.hour = 4 XCTAssertEqual(date.hour, 4) + + date.hour = 1 + XCTAssertEqual(date.hour, 1) } func testMinute() { @@ -152,6 +176,9 @@ final class DateExtensionsTests: XCTestCase { date.minute = 4 XCTAssertEqual(date.minute, 4) + + date.minute = 1 + XCTAssertEqual(date.minute, 1) } func testSecond() { @@ -166,6 +193,9 @@ final class DateExtensionsTests: XCTestCase { date.second = 12 XCTAssertEqual(date.second, 12) + + date.second = 1 + XCTAssertEqual(date.second, 1) } func testNanosecond() { @@ -178,6 +208,10 @@ final class DateExtensionsTests: XCTestCase { date.nanosecond = 10000 XCTAssert(date.nanosecond >= 1000) XCTAssert(date.nanosecond <= 100000) + + date.nanosecond = 100 + XCTAssert(date.nanosecond >= 10) + XCTAssert(date.nanosecond <= 1000) } func testMillisecond() { @@ -190,6 +224,10 @@ final class DateExtensionsTests: XCTestCase { date.millisecond = 10 XCTAssert(date.millisecond >= 9) XCTAssert(date.millisecond <= 11) + + date.millisecond = 3 + XCTAssert(date.millisecond >= 2) + XCTAssert(date.millisecond <= 4) } func testIsInFuture() { @@ -655,17 +693,17 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date2.daysSince(date1), 1) XCTAssertEqual(date1.daysSince(date2), -1) } - - func testIsBetween() { - let date1 = Date(timeIntervalSince1970: 0) - let date2 = date1.addingTimeInterval(60) - let date3 = date2.addingTimeInterval(60) - - XCTAssert(date2.isBetween(date1, date3)) - XCTAssertFalse(date1.isBetween(date2, date3)) - XCTAssert(date1.isBetween(date1, date2, includeBounds: true)) - XCTAssertFalse(date1.isBetween(date1, date2)) - } + + func testIsBetween() { + let date1 = Date(timeIntervalSince1970: 0) + let date2 = date1.addingTimeInterval(60) + let date3 = date2.addingTimeInterval(60) + + XCTAssert(date2.isBetween(date1, date3)) + XCTAssertFalse(date1.isBetween(date2, date3)) + XCTAssert(date1.isBetween(date1, date2, includeBounds: true)) + XCTAssertFalse(date1.isBetween(date1, date2)) + } func testIsWithin() { let date1 = Date(timeIntervalSince1970: 60 * 60 * 24) // 1970-01-01T00:00:00.000Z From c3c0925942e16673464042b9ecd30249c615378f Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 5 Nov 2017 19:53:08 +0300 Subject: [PATCH 068/201] Closes #286 (#307) --- Sources/Extensions/Foundation/URLExtensions.swift | 1 + Sources/Extensions/Foundation/URLRequestExtensions.swift | 1 + Sources/Extensions/SwiftStdlib/ArrayExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/BoolExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/CharacterExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/CollectionExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/DoubleExtensions.swift | 7 +------ Sources/Extensions/SwiftStdlib/FloatExtensions.swift | 7 +------ .../Extensions/SwiftStdlib/FloatingPointExtensions.swift | 2 -- Sources/Extensions/SwiftStdlib/IntExtensions.swift | 7 +------ Sources/Extensions/SwiftStdlib/OptionalExtensions.swift | 2 -- .../Extensions/SwiftStdlib/SignedIntegerExtensions.swift | 2 -- .../Extensions/SwiftStdlib/SignedNumericExtensions.swift | 3 +-- 14 files changed, 6 insertions(+), 36 deletions(-) diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 678cd5beb..1f5deca18 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -8,6 +8,7 @@ import Foundation +// MARK: - Methods public extension URL { /// SwifterSwift: URL with appending query parameters. diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift index be4c7cd90..f9d324455 100644 --- a/Sources/Extensions/Foundation/URLRequestExtensions.swift +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -5,6 +5,7 @@ // Created by Omar Albeik on 9/5/17. // // + import Foundation // MARK: - Initializers diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index f8bf13852..fe1c7c2c4 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation - // MARK: - Methods (Integer) public extension Array where Element: Numeric { diff --git a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift index b15be0ab0..c6d1d29da 100644 --- a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation - // MARK: - Properties public extension Bool { diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index 050b87991..d14223a6a 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation - // MARK: - Properties public extension Character { diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index b4fcd877e..f7593d721 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation - // MARK: - Methods public extension Collection { diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 0d1429c83..3cf7a5b2d 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation - // MARK: - Methods public extension Dictionary { diff --git a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift index b6bfde58c..c70f8aaa9 100755 --- a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift @@ -6,12 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import CoreGraphics // MARK: - Properties public extension Double { diff --git a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift index f46afca6e..a4755e9e9 100755 --- a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift @@ -6,12 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import CoreGraphics // MARK: - Properties public extension Float { diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index 37db0af69..e148da471 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -6,8 +6,6 @@ // // -import Foundation - // MARK: - Properties public extension FloatingPoint { diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 3b474105f..fa243cdee 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -6,12 +6,7 @@ // Copyright © 2016 Omar Albeik. All rights reserved. // -import Foundation -#if os(macOS) - import Cocoa -#else - import UIKit -#endif +import CoreGraphics // MARK: - Properties public extension Int { diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index 8db9c0f31..ce2b53e4e 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -6,8 +6,6 @@ // Copyright © 2017 omaralbeik. All rights reserved. // -import Foundation - // MARK: - Operators infix operator ??= : AssignmentPrecedence diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index c4a52eb7d..26d15028f 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -6,8 +6,6 @@ // // -import Foundation - // MARK: - Properties public extension SignedInteger { diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index ebfbfe943..d06fe3663 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -6,8 +6,7 @@ // // -import Foundation - +// MARK: - Properties public extension SignedNumeric { /// SwifterSwift: String. From 46a5d8e6666601fee243528127344b43793c4ac7 Mon Sep 17 00:00:00 2001 From: Cameron Deardorff Date: Tue, 7 Nov 2017 12:43:55 -0500 Subject: [PATCH 069/201] Update copyright headers with community inclusive text (#308) * added template macros for consistent SwifterSwift file headers moving forward * updated copyright headers * Fixes #308 --- Sources/Extensions/AppKit/NSImageExtensions.swift | 1 + Sources/Extensions/AppKit/NSViewExtensions.swift | 2 +- .../CoreGraphics/CGColorExtensions.swift | 2 +- .../CoreGraphics/CGFloatExtensions.swift | 2 +- .../CoreGraphics/CGPointExtensions.swift | 2 +- .../Extensions/CoreGraphics/CGSizeExtensions.swift | 2 +- .../CoreLocation/CLLocationExtensions.swift | 2 +- Sources/Extensions/Foundation/DataExtensions.swift | 2 +- Sources/Extensions/Foundation/DateExtensions.swift | 2 +- .../Extensions/Foundation/LocaleExtensions.swift | 2 +- .../Foundation/NSAttributedStringExtensions.swift | 2 +- .../Foundation/NSPredicateExtensions.swift | 1 + Sources/Extensions/Foundation/URLExtensions.swift | 2 +- .../Foundation/URLRequestExtensions.swift | 2 +- .../Foundation/UserDefaultsExtensions.swift | 2 +- Sources/Extensions/Shared/ColorExtensions.swift | 1 + .../Extensions/SwiftStdlib/ArrayExtensions.swift | 2 +- .../Extensions/SwiftStdlib/BoolExtensions.swift | 2 +- .../SwiftStdlib/CharacterExtensions.swift | 2 +- .../SwiftStdlib/CollectionExtensions.swift | 2 +- .../SwiftStdlib/DictionaryExtensions.swift | 2 +- .../Extensions/SwiftStdlib/DoubleExtensions.swift | 2 +- .../Extensions/SwiftStdlib/FloatExtensions.swift | 2 +- .../SwiftStdlib/FloatingPointExtensions.swift | 2 +- Sources/Extensions/SwiftStdlib/IntExtensions.swift | 2 +- .../SwiftStdlib/OptionalExtensions.swift | 2 +- .../SwiftStdlib/SignedIntegerExtensions.swift | 2 +- .../SwiftStdlib/SignedNumericExtensions.swift | 2 +- .../Extensions/SwiftStdlib/StringExtensions.swift | 2 +- Sources/Extensions/SwifterSwift.swift | 2 +- .../UIKit/UIAlertControllerExtensions.swift | 2 +- .../UIKit/UIBarButtonItemExtensions.swift | 2 +- Sources/Extensions/UIKit/UIButtonExtensions.swift | 2 +- .../UIKit/UICollectionViewExtensions.swift | 2 +- Sources/Extensions/UIKit/UIFontExtensions.swift | 1 + Sources/Extensions/UIKit/UIImageExtensions.swift | 2 +- .../Extensions/UIKit/UIImageViewExtensions.swift | 2 +- Sources/Extensions/UIKit/UILabelExtensions.swift | 2 +- .../UIKit/UINavigationBarExtensions.swift | 2 +- .../UIKit/UINavigationControllerExtensions.swift | 2 +- .../UIKit/UINavigationItemExtensions.swift | 2 +- .../Extensions/UIKit/UISearchBarExtensions.swift | 2 +- .../UIKit/UISegmentedControlExtensions.swift | 2 +- Sources/Extensions/UIKit/UISliderExtensions.swift | 2 +- .../Extensions/UIKit/UIStoryboardExtensions.swift | 2 +- Sources/Extensions/UIKit/UISwitchExtensions.swift | 2 +- Sources/Extensions/UIKit/UITabBarExtensions.swift | 2 +- .../Extensions/UIKit/UITableViewExtensions.swift | 2 +- .../Extensions/UIKit/UITextFieldExtensions.swift | 2 +- .../Extensions/UIKit/UITextViewExtensions.swift | 2 +- .../UIKit/UIViewControllerExtensions.swift | 2 +- Sources/Extensions/UIKit/UIViewExtensions.swift | 2 +- Sources/SwifterSwift.h | 1 + SwifterSwift.xcodeproj/project.pbxproj | 1 + .../xcshareddata/IDETemplateMacros.plist | 14 ++++++++++++++ Tests/AppKitTests/NSImageExtensionsTests.swift | 1 + Tests/AppKitTests/NSViewExtensionsTests.swift | 2 +- .../CoreGraphicsTests/CGColorExtensionsTests.swift | 1 + .../CoreGraphicsTests/CGFloatExtensionsTests.swift | 2 +- .../CoreGraphicsTests/CGPointExtensionsTests.swift | 2 +- .../CoreGraphicsTests/CGSizeExtensionsTests.swift | 2 +- .../CLLocationExtensionsTests.swift | 2 +- Tests/FoundationTests/DataExtensionsTests.swift | 2 +- Tests/FoundationTests/DateExtensionsTests.swift | 2 +- Tests/FoundationTests/LocaleExtensionsTests.swift | 2 +- .../NSAttributedStringExtensionsTests.swift | 2 +- .../NSPredicateExtensionsTests.swift | 1 + Tests/FoundationTests/URLExtensionsTests.swift | 2 +- .../URLRequestExtensionsTests.swift | 2 +- .../UserDefaultsExtensionsTests.swift | 2 +- Tests/SharedTests/ColorExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/ArrayExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/BoolExtensionsTests.swift | 2 +- .../CharacterExtensionsTests.swift | 4 ++-- .../CollectionExtensionsTests.swift | 2 +- .../DictionaryExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/DoubleExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/FloatExtensionsTests.swift | 2 +- Tests/SwiftStdlibTests/IntExtensionsTests.swift | 2 +- .../SwiftStdlibTests/OptionalExtensionsTests.swift | 2 +- .../SignedNumericExtensionsTests.swift | 1 + Tests/SwiftStdlibTests/StringExtensionsTests.swift | 2 +- Tests/SwifterSwiftTests.swift | 2 +- .../UIAlertControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UIBarButtonExtensionsTests.swift | 2 +- Tests/UIKitTests/UIButtonExtensionsTests.swift | 2 +- .../UICollectionViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UIFontExtensionsTest.swift | 1 + Tests/UIKitTests/UIImageExtensionsTests.swift | 2 +- Tests/UIKitTests/UIImageViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UILabelExtensionsTests.swift | 2 +- .../UIKitTests/UINavigationBarExtensionTests.swift | 2 +- .../UINavigationControllerExtensionsTests.swift | 2 +- .../UINavigationItemExtensionsTests.swift | 2 +- Tests/UIKitTests/UISearchBarExtensionsTests.swift | 2 +- .../UISegmentedControlExtensionsTests.swift | 2 +- Tests/UIKitTests/UISliderExtensionsTests.swift | 2 +- Tests/UIKitTests/UIStoryboardExtensionsTests.swift | 2 +- Tests/UIKitTests/UISwitchExtensionsTests.swift | 2 +- Tests/UIKitTests/UITabBarExtensionsTests.swift | 2 +- Tests/UIKitTests/UITableViewExtensionsTests.swift | 2 +- Tests/UIKitTests/UITextFieldExtensionsTests.swift | 2 +- Tests/UIKitTests/UITextViewExtensionsTests.swift | 2 +- .../UIViewControllerExtensionsTests.swift | 2 +- Tests/UIKitTests/UIViewExtensionsTests.swift | 2 +- 105 files changed, 119 insertions(+), 94 deletions(-) create mode 100644 SwifterSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist diff --git a/Sources/Extensions/AppKit/NSImageExtensions.swift b/Sources/Extensions/AppKit/NSImageExtensions.swift index 1bd21591d..142132350 100644 --- a/Sources/Extensions/AppKit/NSImageExtensions.swift +++ b/Sources/Extensions/AppKit/NSImageExtensions.swift @@ -3,6 +3,7 @@ // SwifterSwift-macOS // // Created by BUDDAx2 on 20.10.2017. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/AppKit/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift index 1cc4ed44d..816be4dac 100644 --- a/Sources/Extensions/AppKit/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/3/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift index 8c11d5c22..15112ff2d 100644 --- a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 03/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift index d1e4833b8..11cd24c70 100644 --- a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/23/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift index de812cdb7..2e159958d 100644 --- a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 07/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift index db19d69a8..10ff069aa 100644 --- a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/22/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift index ba8ef1f00..ea599e701 100644 --- a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift +++ b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Luciano Almeida on 21/04/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import CoreLocation diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index 75998df24..f7bc2e0e1 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 07/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 97cef20ec..771ab76c2 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/5/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/LocaleExtensions.swift b/Sources/Extensions/Foundation/LocaleExtensions.swift index 7c17aa928..7b0b220aa 100644 --- a/Sources/Extensions/Foundation/LocaleExtensions.swift +++ b/Sources/Extensions/Foundation/LocaleExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Basem Emara on 4/19/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift index 251ade26a..f43eb5b5f 100644 --- a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 26/11/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/Foundation/NSPredicateExtensions.swift b/Sources/Extensions/Foundation/NSPredicateExtensions.swift index 6a4fe340d..81a07cc93 100644 --- a/Sources/Extensions/Foundation/NSPredicateExtensions.swift +++ b/Sources/Extensions/Foundation/NSPredicateExtensions.swift @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Max Härtwig on 04.10.17. +// Copyright © 2017 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 1f5deca18..1a474b18c 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 03/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift index f9d324455..7296fc699 100644 --- a/Sources/Extensions/Foundation/URLRequestExtensions.swift +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/5/17. -// +// Copyright © 2017 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift index 7e050f7af..401afbab2 100644 --- a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift +++ b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/5/17. -// +// Copyright © 2017 SwifterSwift // import Foundation diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index c41c7f0e2..a56870c2b 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -3,6 +3,7 @@ // SwifterSwift-iOS // // Created by Omar Albeik on 9/27/17. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index fe1c7c2c4..28526c8da 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/5/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // MARK: - Methods (Integer) diff --git a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift index c6d1d29da..0c2589788 100644 --- a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 07/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // MARK: - Properties diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index d14223a6a..e56f170e0 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/8/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // MARK: - Properties diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index f7593d721..6ff0733c8 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Sergey Fedortsov on 19.12.16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // MARK: - Methods diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 3cf7a5b2d..abd46001a 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/24/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // MARK: - Methods diff --git a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift index c70f8aaa9..ac4ebd3b9 100755 --- a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/6/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import CoreGraphics diff --git a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift index a4755e9e9..206c08f19 100755 --- a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/8/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import CoreGraphics diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index e148da471..830f2b32e 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 7/23/17. -// +// Copyright © 2017 SwifterSwift // // MARK: - Properties diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index fa243cdee..929b922ec 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/6/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import CoreGraphics diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index ce2b53e4e..40cb54b8b 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/3/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // // MARK: - Operators diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index 26d15028f..f9894e41b 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/15/17. -// +// Copyright © 2017 SwifterSwift // // MARK: - Properties diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index d06fe3663..ba7be8827 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/15/17. -// +// Copyright © 2017 SwifterSwift // // MARK: - Properties diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 5c4d00a17..94822942b 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/5/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) import Cocoa diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 2cb4c5417..ca9a38b3d 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/8/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(macOS) import Cocoa diff --git a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift index c785675e3..fc5c6cab6 100644 --- a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/23/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) diff --git a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift index 881d891fe..e7bceb1a9 100644 --- a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift +++ b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 08/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UIButtonExtensions.swift b/Sources/Extensions/UIKit/UIButtonExtensions.swift index 0095b25a8..296fefd6c 100644 --- a/Sources/Extensions/UIKit/UIButtonExtensions.swift +++ b/Sources/Extensions/UIKit/UIButtonExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/22/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index 0dc9fd468..55af7d7ad 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 11/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UIFontExtensions.swift b/Sources/Extensions/UIKit/UIFontExtensions.swift index 5c20202ff..ac24c4a4f 100644 --- a/Sources/Extensions/UIKit/UIFontExtensions.swift +++ b/Sources/Extensions/UIKit/UIFontExtensions.swift @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Benjamin Meyer on 9/16/17. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) || os(watchOS) diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index 936375380..fc5e5aeec 100755 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/6/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) || os(watchOS) diff --git a/Sources/Extensions/UIKit/UIImageViewExtensions.swift b/Sources/Extensions/UIKit/UIImageViewExtensions.swift index 8dda49cc9..2d66ba290 100644 --- a/Sources/Extensions/UIKit/UIImageViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/25/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UILabelExtensions.swift b/Sources/Extensions/UIKit/UILabelExtensions.swift index c78479424..0bc6489e9 100644 --- a/Sources/Extensions/UIKit/UILabelExtensions.swift +++ b/Sources/Extensions/UIKit/UILabelExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/23/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift index 9b64d027d..231a7e9af 100644 --- a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/22/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift index 4459064fe..f1d3098c1 100755 --- a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/6/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift index 799df8d71..3989bc6c9 100644 --- a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/28/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index 673d56816..0895fc5a2 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/23/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift index fef598625..8dcb23cfd 100644 --- a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift +++ b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/28/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UISliderExtensions.swift b/Sources/Extensions/UIKit/UISliderExtensions.swift index d3c224e65..16c54e5d2 100644 --- a/Sources/Extensions/UIKit/UISliderExtensions.swift +++ b/Sources/Extensions/UIKit/UISliderExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/28/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) diff --git a/Sources/Extensions/UIKit/UIStoryboardExtensions.swift b/Sources/Extensions/UIKit/UIStoryboardExtensions.swift index d3820714d..1105844b8 100644 --- a/Sources/Extensions/UIKit/UIStoryboardExtensions.swift +++ b/Sources/Extensions/UIKit/UIStoryboardExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/6/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UISwitchExtensions.swift b/Sources/Extensions/UIKit/UISwitchExtensions.swift index 78c65cf05..41e27a013 100644 --- a/Sources/Extensions/UIKit/UISwitchExtensions.swift +++ b/Sources/Extensions/UIKit/UISwitchExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 08/12/2016. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) diff --git a/Sources/Extensions/UIKit/UITabBarExtensions.swift b/Sources/Extensions/UIKit/UITabBarExtensions.swift index 0ac73e285..e29b82750 100644 --- a/Sources/Extensions/UIKit/UITabBarExtensions.swift +++ b/Sources/Extensions/UIKit/UITabBarExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/28/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index 52ce2e0bc..383e5349d 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/22/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index faabf9642..7c9818b6c 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/5/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UITextViewExtensions.swift b/Sources/Extensions/UIKit/UITextViewExtensions.swift index 41a385e91..24437eb09 100644 --- a/Sources/Extensions/UIKit/UITextViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITextViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/28/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift index 469904f14..403e862cf 100755 --- a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Emirhan Erdogan on 07/08/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 2919074d2..f8215d19d 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/5/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Sources/SwifterSwift.h b/Sources/SwifterSwift.h index 482bc29de..9af45b4fe 100644 --- a/Sources/SwifterSwift.h +++ b/Sources/SwifterSwift.h @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 6/12/17. +// Copyright © 2017 SwifterSwift // #import diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 12f663263..aff17b93d 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -976,6 +976,7 @@ attributes = { LastSwiftUpdateCheck = 0900; LastUpgradeCheck = 0900; + ORGANIZATIONNAME = SwifterSwift; TargetAttributes = { 07898B5C1F278D7600558C97 = { CreatedOnToolsVersion = 9.0; diff --git a/SwifterSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist b/SwifterSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist new file mode 100644 index 000000000..18da7dfa2 --- /dev/null +++ b/SwifterSwift.xcworkspace/xcshareddata/IDETemplateMacros.plist @@ -0,0 +1,14 @@ + + + + + FILEHEADER + +// ___FILENAME___ +// ___PROJECTNAME___ +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright © ___YEAR___ ___ORGANIZATIONNAME___ +// + + diff --git a/Tests/AppKitTests/NSImageExtensionsTests.swift b/Tests/AppKitTests/NSImageExtensionsTests.swift index aecc60c9e..ac1eab51f 100644 --- a/Tests/AppKitTests/NSImageExtensionsTests.swift +++ b/Tests/AppKitTests/NSImageExtensionsTests.swift @@ -3,6 +3,7 @@ // SwifterSwift-macOSTests // // Created by BUDDAx2 on 20.10.2017. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Tests/AppKitTests/NSViewExtensionsTests.swift b/Tests/AppKitTests/NSViewExtensionsTests.swift index a6f0f7745..6f46f38b6 100644 --- a/Tests/AppKitTests/NSViewExtensionsTests.swift +++ b/Tests/AppKitTests/NSViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/3/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(macOS) diff --git a/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift index b158df22e..e613177c8 100644 --- a/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift @@ -3,6 +3,7 @@ // SwifterSwift-iOS // // Created by Ryan Batchelder on 10/8/17. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift index b9deb364f..7cb20a879 100644 --- a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift index b7040513b..fbdea8e43 100644 --- a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/26/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift index d8f05aeed..87d514c72 100644 --- a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift index 208f22cd6..502cf916c 100644 --- a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift +++ b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Luciano Almeida on 21/04/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/DataExtensionsTests.swift b/Tests/FoundationTests/DataExtensionsTests.swift index 337af40c7..dae2e5458 100644 --- a/Tests/FoundationTests/DataExtensionsTests.swift +++ b/Tests/FoundationTests/DataExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 09/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 5e1a2de04..ef397273f 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/FoundationTests/LocaleExtensionsTests.swift b/Tests/FoundationTests/LocaleExtensionsTests.swift index de27e7422..6b0787984 100644 --- a/Tests/FoundationTests/LocaleExtensionsTests.swift +++ b/Tests/FoundationTests/LocaleExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Basem Emara on 4/19/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index a84f954c9..b3911862e 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Ewelina on 26/01/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/NSPredicateExtensionsTests.swift b/Tests/FoundationTests/NSPredicateExtensionsTests.swift index a859f565d..2ee901dc3 100644 --- a/Tests/FoundationTests/NSPredicateExtensionsTests.swift +++ b/Tests/FoundationTests/NSPredicateExtensionsTests.swift @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Max Härtwig on 04.10.17. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/URLExtensionsTests.swift b/Tests/FoundationTests/URLExtensionsTests.swift index 6359246e0..cdc48ad55 100644 --- a/Tests/FoundationTests/URLExtensionsTests.swift +++ b/Tests/FoundationTests/URLExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 03/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/FoundationTests/URLRequestExtensionsTests.swift b/Tests/FoundationTests/URLRequestExtensionsTests.swift index d66f1070b..bde6daefa 100644 --- a/Tests/FoundationTests/URLRequestExtensionsTests.swift +++ b/Tests/FoundationTests/URLRequestExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/6/17. -// +// Copyright © 2016 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift index cb73ed9d6..bb7c1968b 100644 --- a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 9/6/17. -// +// Copyright © 2016 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index fa505e186..1583ac5d8 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Ewelina on 25/01/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index 794cdd494..dad10d71c 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/26/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift index 615f49086..b2cf901b7 100644 --- a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 20/01/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift index 942a0bf9f..dec9ae85d 100644 --- a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // // @@ -11,7 +11,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index 86c1e39a7..2da901511 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 09/02/2017. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 4408d4618..0e17441ed 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift index 1aa7d4caa..c7de716d9 100644 --- a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift index 5fe6a7db0..cafce5b2b 100644 --- a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift index 38588a846..5e603c805 100644 --- a/Tests/SwiftStdlibTests/IntExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/IntExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index 61b6793ea..67844070d 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/3/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift index aceac661d..5df5426c6 100644 --- a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 10/7/17. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 6cea4d2fd..1961ee70c 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 338f779f6..3fe99fa57 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 8/27/16. -// Copyright © 2016 Omar Albeik. All rights reserved. +// Copyright © 2016 SwifterSwift // import XCTest @testable import SwifterSwift diff --git a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift index 5396ac9fe..70ba8ffc3 100644 --- a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/13/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) diff --git a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift index accb00a34..b1f9491f4 100644 --- a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/14/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UIButtonExtensionsTests.swift b/Tests/UIKitTests/UIButtonExtensionsTests.swift index 41c3c184a..7b8e2c010 100644 --- a/Tests/UIKitTests/UIButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIButtonExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/14/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift index 223322568..995011e69 100644 --- a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift +++ b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/24/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index ed1e30420..ac0f9d94d 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -3,6 +3,7 @@ // SwifterSwift // // Created by Benjamin Meyer on 9/16/17. +// Copyright © 2016 SwifterSwift // #if os(iOS) || os(tvOS) || os(watchOS) diff --git a/Tests/UIKitTests/UIImageExtensionsTests.swift b/Tests/UIKitTests/UIImageExtensionsTests.swift index 3154dc774..49f58404d 100644 --- a/Tests/UIKitTests/UIImageExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/22/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index 5332ae1ca..87128a952 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/19/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UILabelExtensionsTests.swift b/Tests/UIKitTests/UILabelExtensionsTests.swift index f9ef9dcf8..a74ecb667 100644 --- a/Tests/UIKitTests/UILabelExtensionsTests.swift +++ b/Tests/UIKitTests/UILabelExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/26/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/UIKitTests/UINavigationBarExtensionTests.swift b/Tests/UIKitTests/UINavigationBarExtensionTests.swift index 2f6a2658e..8aec86a1c 100644 --- a/Tests/UIKitTests/UINavigationBarExtensionTests.swift +++ b/Tests/UIKitTests/UINavigationBarExtensionTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/16/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift index 639c9c570..b25df7af7 100644 --- a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/16/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift index d516b523a..76fc20760 100644 --- a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/16/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UISearchBarExtensionsTests.swift b/Tests/UIKitTests/UISearchBarExtensionsTests.swift index 1fac5baf8..42ef97764 100644 --- a/Tests/UIKitTests/UISearchBarExtensionsTests.swift +++ b/Tests/UIKitTests/UISearchBarExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift index 98ced5b4c..e076066f5 100644 --- a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift +++ b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index e61e1417a..d0f581948 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/16/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) diff --git a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift index cc739ca58..dc007b669 100644 --- a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift +++ b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/25/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) diff --git a/Tests/UIKitTests/UISwitchExtensionsTests.swift b/Tests/UIKitTests/UISwitchExtensionsTests.swift index f3c95a0d3..47d75cc47 100644 --- a/Tests/UIKitTests/UISwitchExtensionsTests.swift +++ b/Tests/UIKitTests/UISwitchExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/UIKitTests/UITabBarExtensionsTests.swift b/Tests/UIKitTests/UITabBarExtensionsTests.swift index 35a322420..65ab6c65c 100644 --- a/Tests/UIKitTests/UITabBarExtensionsTests.swift +++ b/Tests/UIKitTests/UITabBarExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 3/26/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 456f7db04..ec8a483a5 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/24/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UITextFieldExtensionsTests.swift b/Tests/UIKitTests/UITextFieldExtensionsTests.swift index 4888a5675..8f6caef67 100644 --- a/Tests/UIKitTests/UITextFieldExtensionsTests.swift +++ b/Tests/UIKitTests/UITextFieldExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/UIKitTests/UITextViewExtensionsTests.swift b/Tests/UIKitTests/UITextViewExtensionsTests.swift index de6c5376d..25ede2f68 100644 --- a/Tests/UIKitTests/UITextViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITextViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index bd7a8828c..a65053687 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Steven on 2/25/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // #if os(iOS) || os(tvOS) diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 03c845e80..11a578c33 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 2/15/17. -// Copyright © 2017 omaralbeik. All rights reserved. +// Copyright © 2017 SwifterSwift // import XCTest @testable import SwifterSwift From ff2bf31cd416678ad844176365fe02afebead67e Mon Sep 17 00:00:00 2001 From: chaithanyaprathyush Date: Fri, 10 Nov 2017 13:15:19 +0530 Subject: [PATCH 070/201] Add numberOfDaysInMonth (#311) Closes #310 --- .../Foundation/CalendarExtensions.swift | 23 ++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 ++++++++++ .../CalendarExtensionTest.swift | 35 +++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 Sources/Extensions/Foundation/CalendarExtensions.swift create mode 100644 Tests/FoundationTests/CalendarExtensionTest.swift diff --git a/Sources/Extensions/Foundation/CalendarExtensions.swift b/Sources/Extensions/Foundation/CalendarExtensions.swift new file mode 100644 index 000000000..6618023aa --- /dev/null +++ b/Sources/Extensions/Foundation/CalendarExtensions.swift @@ -0,0 +1,23 @@ +// +// CalendarExtensions.swift +// SwifterSwift +// +// Created by Chaithanya Prathyush on 09/11/17. +// Copyright © 2017 SwifterSwift +// + +import Foundation + +// MARK: - Methods +public extension Calendar { + /// SwifterSwift: Return the number of days in the month for a specified 'Date'. + /// + /// let date = Date() // "Jan 12, 2017, 7:07 PM" + /// Calendar.current.numberOfDaysInMonth(for: date) -> 31 + /// + /// - Parameter date: the date form which the number of days in month is calculated. + /// - Returns: The number of days in the month of 'Date'. + public func numberOfDaysInMonth(for date: Date) -> Int { + return range(of: .day, in: .month, for: date)?.count ?? 0 + } +} diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index aff17b93d..c49e334e1 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -317,6 +317,13 @@ 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */; }; 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */; }; + 70269A2B1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */; }; + 70269A2C1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */; }; + 70269A2D1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */; }; + 70269A2E1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */; }; + 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; + 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; + 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -465,6 +472,8 @@ 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensionsTests.swift; sourceTree = ""; }; 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensions.swift; sourceTree = ""; }; 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensionsTests.swift; sourceTree = ""; }; + 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensions.swift; sourceTree = ""; }; + 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -631,6 +640,7 @@ 07B7F1651F5EB41600E6F910 /* Foundation */ = { isa = PBXGroup; children = ( + 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */, 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */, 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */, 07B7F1731F5EB41600E6F910 /* LocaleExtensions.swift */, @@ -692,6 +702,7 @@ 07C50CF91F5EB03200F46E5A /* FoundationTests */ = { isa = PBXGroup; children = ( + 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */, 07C50CFE1F5EB03200F46E5A /* DataExtensionsTests.swift */, 07C50CFF1F5EB03200F46E5A /* DateExtensionsTests.swift */, 07C50D041F5EB03200F46E5A /* LocaleExtensionsTests.swift */, @@ -1209,6 +1220,7 @@ 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F22E1F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21F1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 70269A2B1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F2161F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, 07B7F2101F5EB43C00E6F910 /* DateExtensions.swift in Sources */, 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, @@ -1266,6 +1278,7 @@ 07B7F1A81F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2341F5EB45200E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21E1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 70269A2C1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F2041F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, 07B7F1FE1F5EB43C00E6F910 /* DateExtensions.swift in Sources */, 07B7F2021F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, @@ -1323,6 +1336,7 @@ 07B7F1BE1F5EB42200E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21D1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, + 70269A2E1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F1F21F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */, 07B7F1EC1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, 07B7F1F01F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */, @@ -1341,6 +1355,7 @@ 07B7F1DA1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, 07B7F1D81F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */, 07B7F1DD1F5EB43B00E6F910 /* FloatExtensions.swift in Sources */, + 70269A2D1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F1D61F5EB43B00E6F910 /* BoolExtensions.swift in Sources */, 07B7F1DE1F5EB43B00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F1DB1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */, @@ -1409,6 +1424,7 @@ 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, @@ -1464,6 +1480,7 @@ 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */, + 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8A1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D881F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, @@ -1497,6 +1514,7 @@ 07C50D791F5EB05100F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D7B1F5EB05100F46E5A /* FloatExtensionsTests.swift in Sources */, 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, + 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */, 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, diff --git a/Tests/FoundationTests/CalendarExtensionTest.swift b/Tests/FoundationTests/CalendarExtensionTest.swift new file mode 100644 index 000000000..82fecb558 --- /dev/null +++ b/Tests/FoundationTests/CalendarExtensionTest.swift @@ -0,0 +1,35 @@ +// +// CalendarExtension.swift +// SwifterSwift +// +// Created by Chaithanya Prathyush on 09/11/17. +// Copyright © 2017 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +class CalendarExtensionTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + func testNumberOfDaysInAMonth() { + let calendar = Calendar(identifier: .gregorian) + let longMonths = [1, 3, 5, 7, 8, 10, 12] + let shortMonths = [4, 6, 9, 11] + let febDateComponent = DateComponents(year: 2015, month: 2) + let febDate = calendar.date(from: febDateComponent)! + let leapYearDateComponent = DateComponents(year: 2020, month: 2) + let leapYearDate = calendar.date(from: leapYearDateComponent)! + let longMonthsDateComponents = longMonths.map { DateComponents(year: 2015, month: $0) } + let shortMonthsDateComponents = shortMonths.map { DateComponents(year: 2015, month: $0) } + let longMonthDates = longMonthsDateComponents.flatMap { calendar.date(from: $0) } + let shortMonthDates = shortMonthsDateComponents.flatMap { calendar.date(from: $0) } + longMonthDates.forEach { XCTAssert(calendar.numberOfDaysInMonth(for: $0) == 31) } + shortMonthDates.forEach { XCTAssert(calendar.numberOfDaysInMonth(for: $0) == 30) } + XCTAssert(calendar.numberOfDaysInMonth(for: febDate) == 28) + XCTAssert(calendar.numberOfDaysInMonth(for: leapYearDate) == 29) + } +} From 621e37ec25912a3ef91eb068b46236ed49144481 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 12 Nov 2017 00:53:14 +0300 Subject: [PATCH 071/201] Rewrite DateExtensions.swift (#309) Fixes #302, Fixes #301 --- .../Foundation/DateExtensions.swift | 297 +++++++++++------ .../Deprecated/FoundationDeprecated.swift | 31 ++ SwifterSwift.xcodeproj/project.pbxproj | 78 ++++- .../CalendarExtensionTest.swift | 5 +- .../FoundationTests/DateExtensionsTests.swift | 298 ++++++++++++------ 5 files changed, 510 insertions(+), 199 deletions(-) create mode 100644 Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 771ab76c2..3463c4fd5 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -51,13 +51,19 @@ public extension Date { } /// SwifterSwift: Quarter. + /// + /// Date().quarter -> 3 // date in third quarter of the year. + /// public var quarter: Int { - return Calendar.current.component(.quarter, from: self) + let month = Double(Calendar.current.component(.month, from: self)) + let numberOfMonths = Double(Calendar.current.monthSymbols.count) + let numberOfMonthsInQuarter = numberOfMonths / 4 + return Int(ceil(month/numberOfMonthsInQuarter)) } /// SwifterSwift: Week of year. /// - /// Date().weekOfYear -> 2 // second week in the current year. + /// Date().weekOfYear -> 2 // second week in the year. /// public var weekOfYear: Int { return Calendar.current.component(.weekOfYear, from: self) @@ -65,7 +71,7 @@ public extension Date { /// SwifterSwift: Week of month. /// - /// Date().weekOfMonth -> 2 // second week in the current month. + /// Date().weekOfMonth -> 3 // date is in third week of the month. /// public var weekOfMonth: Int { return Calendar.current.component(.weekOfMonth, from: self) @@ -83,6 +89,7 @@ public extension Date { return Calendar.current.component(.year, from: self) } set { + guard newValue > 0 else { return } let currentYear = Calendar.current.component(.year, from: self) let yearsToAdd = newValue - currentYear if let date = Calendar.current.date(byAdding: .year, value: yearsToAdd, to: self) { @@ -96,14 +103,19 @@ public extension Date { /// Date().month -> 1 /// /// var someDate = Date() - /// someDate.year = 10 // sets someDate's month to 10. + /// someDate.month = 10 // sets someDate's month to 10. /// public var month: Int { get { return Calendar.current.component(.month, from: self) } set { - if let date = Calendar.current.date(bySetting: .month, value: newValue, of: self) { + let allowedRange = Calendar.current.range(of: .month, in: .year, for: self)! + guard allowedRange.contains(newValue) else { return } + + let currentMonth = Calendar.current.component(.month, from: self) + let monthsToAdd = newValue - currentMonth + if let date = Calendar.current.date(byAdding: .month, value: monthsToAdd, to: self) { self = date } } @@ -121,7 +133,12 @@ public extension Date { return Calendar.current.component(.day, from: self) } set { - if let date = Calendar.current.date(bySetting: .day, value: newValue, of: self) { + let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)! + guard allowedRange.contains(newValue) else { return } + + let currentDay = Calendar.current.component(.day, from: self) + let daysToAdd = newValue - currentDay + if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) { self = date } } @@ -132,14 +149,7 @@ public extension Date { /// Date().weekOfMonth -> 5 // fifth day in the current week. /// public var weekday: Int { - get { - return Calendar.current.component(.weekday, from: self) - } - set { - if let date = Calendar.current.date(bySetting: .weekday, value: newValue, of: self) { - self = date - } - } + return Calendar.current.component(.weekday, from: self) } /// SwifterSwift: Hour. @@ -147,14 +157,19 @@ public extension Date { /// Date().hour -> 17 // 5 pm /// /// var someDate = Date() - /// someDate.day = 13 // sets someDate's hour to 1 pm. + /// someDate.hour = 13 // sets someDate's hour to 1 pm. /// public var hour: Int { get { return Calendar.current.component(.hour, from: self) } set { - if let date = Calendar.current.date(bySetting: .hour, value: newValue, of: self) { + let allowedRange = Calendar.current.range(of: .hour, in: .day, for: self)! + guard allowedRange.contains(newValue) else { return } + + let currentHour = Calendar.current.component(.hour, from: self) + let hoursToAdd = newValue - currentHour + if let date = Calendar.current.date(byAdding: .hour, value: hoursToAdd, to: self) { self = date } } @@ -172,7 +187,9 @@ public extension Date { return Calendar.current.component(.minute, from: self) } set { - guard newValue >= 0 && newValue < 60 else { return } + let allowedRange = Calendar.current.range(of: .minute, in: .hour, for: self)! + guard allowedRange.contains(newValue) else { return } + let currentMinutes = Calendar.current.component(.minute, from: self) let minutesToAdd = newValue - currentMinutes if let date = Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) { @@ -186,14 +203,19 @@ public extension Date { /// Date().second -> 55 /// /// var someDate = Date() - /// someDate. second = 15 // sets someDate's seconds to 15. + /// someDate.second = 15 // sets someDate's seconds to 15. /// public var second: Int { get { return Calendar.current.component(.second, from: self) } set { - if let date = Calendar.current.date(bySetting: .second, value: newValue, of: self) { + let allowedRange = Calendar.current.range(of: .second, in: .minute, for: self)! + guard allowedRange.contains(newValue) else { return } + + let currentSeconds = Calendar.current.component(.second, from: self) + let secondsToAdd = newValue - currentSeconds + if let date = Calendar.current.date(byAdding: .second, value: secondsToAdd, to: self) { self = date } } @@ -203,24 +225,42 @@ public extension Date { /// /// Date().nanosecond -> 981379985 /// + /// var someDate = Date() + /// someDate.nanosecond = 981379985 // sets someDate's seconds to 981379985. + /// public var nanosecond: Int { get { return Calendar.current.component(.nanosecond, from: self) } set { - if let date = Calendar.current.date(bySetting: .nanosecond, value: newValue, of: self) { + let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! + guard allowedRange.contains(newValue) else { return } + + let currentNanoseconds = Calendar.current.component(.nanosecond, from: self) + let nanosecondsToAdd = newValue - currentNanoseconds + + if let date = Calendar.current.date(byAdding: .nanosecond, value: nanosecondsToAdd, to: self) { self = date } } } /// SwifterSwift: Milliseconds. + /// + /// Date().millisecond -> 68 + /// + /// var someDate = Date() + /// someDate.millisecond = 68 // sets someDate's nanosecond to 68000000. + /// public var millisecond: Int { get { return Calendar.current.component(.nanosecond, from: self) / 1000000 } set { let ns = newValue * 1000000 + let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! + guard allowedRange.contains(ns) else { return } + if let date = Calendar.current.date(bySetting: .nanosecond, value: ns, of: self) { self = date } @@ -243,7 +283,7 @@ public extension Date { return self < Date() } - /// SwifterSwift: Check if date is in today. + /// SwifterSwift: Check if date is within today. /// /// Date().isInToday -> true /// @@ -278,17 +318,17 @@ public extension Date { } /// SwifterSwift: Check if date is within the current week. - public var isInThisWeek: Bool { + public var isInCurrentWeek: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) } /// SwifterSwift: Check if date is within the current month. - public var isInThisMonth: Bool { + public var isInCurrentMonth: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) } /// SwifterSwift: Check if date is within the current year. - public var isInThisYear: Bool { + public var isInCurrentYear: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) } @@ -316,10 +356,11 @@ public extension Date { /// date.nearestFiveMinutes // "5:45 PM" /// public var nearestFiveMinutes: Date { - var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: self) let min = components.minute! components.minute! = min % 5 < 3 ? min - min % 5 : min + 5 - (min % 5) components.second = 0 + components.nanosecond = 0 return Calendar.current.date(from: components)! } @@ -333,10 +374,11 @@ public extension Date { /// date.nearestTenMinutes // "5:50 PM" /// public var nearestTenMinutes: Date { - var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: self) let min = components.minute! components.minute? = min % 10 < 6 ? min - min % 10 : min + 10 - (min % 10) components.second = 0 + components.nanosecond = 0 return Calendar.current.date(from: components)! } @@ -350,10 +392,11 @@ public extension Date { /// date.nearestQuarterHour // "5:45 PM" /// public var nearestQuarterHour: Date { - var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: self) let min = components.minute! components.minute! = min % 15 < 8 ? min - min % 15 : min + 15 - (min % 15) components.second = 0 + components.nanosecond = 0 return Calendar.current.date(from: components)! } @@ -367,10 +410,11 @@ public extension Date { /// date.nearestHalfHour // "7:00 PM" /// public var nearestHalfHour: Date { - var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self) + var components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: self) let min = components.minute! components.minute! = min % 30 < 15 ? min - min % 30 : min + 30 - (min % 30) components.second = 0 + components.nanosecond = 0 return Calendar.current.date(from: components)! } @@ -383,13 +427,17 @@ public extension Date { /// date.nearestHour // "7:00 PM" /// public var nearestHour: Date { - if minute >= 30 { - return beginning(of: .hour)!.adding(.hour, value: 1) + let min = Calendar.current.component(.minute, from: self) + let components: Set = [.year, .month, .day, .hour] + let date = Calendar.current.date(from: Calendar.current.dateComponents(components, from: self))! + + if min < 30 { + return date } - return beginning(of: .hour)! + return Calendar.current.date(byAdding: .hour, value: 1, to: date)! } - /// SwifterSwift: Time zone used by system. + /// SwifterSwift: Time zone used currently by system. /// /// Date().timeZone -> Europe/Istanbul (current) /// @@ -438,7 +486,9 @@ public extension Date { /// - component: component type. /// - value: multiples of compnenet to add. public mutating func add(_ component: Calendar.Component, value: Int) { - self = adding(component, value: value) + if let date = Calendar.current.date(byAdding: component, value: value, to: self) { + self = date + } } /// SwifterSwift: Date by changing value of calendar component. @@ -453,53 +503,105 @@ public extension Date { /// - component: component type. /// - value: new value of compnenet to change. /// - Returns: original date after changing given component to given value. - public func changing(_ component: Calendar.Component, value: Int) -> Date? { - return Calendar.current.date(bySetting: component, value: value, of: self) - } - - /// SwifterSwift: Data at the beginning of calendar component. - /// - /// let date = Date() // "Jan 12, 2017, 7:14 PM" - /// let date2 = date.beginning(of: .hour) // "Jan 12, 2017, 7:00 PM" - /// let date3 = date.beginning(of: .month) // "Jan 1, 2017, 12:00 AM" - /// let date4 = date.beginning(of: .year) // "Jan 1, 2017, 12:00 AM" - /// - /// - Parameter component: calendar component to get date at the beginning of. - /// - Returns: date at the beginning of calendar component (if applicable). - public func beginning(of component: Calendar.Component) -> Date? { + public func changing(_ component: Calendar.Component, value: Int) -> Date? { switch component { + case .nanosecond: + let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentNanoseconds = Calendar.current.component(.nanosecond, from: self) + let nanosecondsToAdd = value - currentNanoseconds + return Calendar.current.date(byAdding: .nanosecond, value: nanosecondsToAdd, to: self) + case .second: - return Calendar.current.date(from: - Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)) + let allowedRange = Calendar.current.range(of: .second, in: .minute, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentSeconds = Calendar.current.component(.second, from: self) + let secondsToAdd = value - currentSeconds + return Calendar.current.date(byAdding: .second, value: secondsToAdd, to: self) case .minute: - return Calendar.current.date(from: - Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self)) + let allowedRange = Calendar.current.range(of: .minute, in: .hour, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentMinutes = Calendar.current.component(.minute, from: self) + let minutesToAdd = value - currentMinutes + return Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) case .hour: - return Calendar.current.date(from: - Calendar.current.dateComponents([.year, .month, .day, .hour], from: self)) + let allowedRange = Calendar.current.range(of: .hour, in: .day, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentHour = Calendar.current.component(.hour, from: self) + let hoursToAdd = value - currentHour + return Calendar.current.date(byAdding: .hour, value: hoursToAdd, to: self) case .day: - return Calendar.current.startOfDay(for: self) - - case .weekOfYear, .weekOfMonth: - return Calendar.current.date(from: - Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) + let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentDay = Calendar.current.component(.day, from: self) + let daysToAdd = value - currentDay + return Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) case .month: - return Calendar.current.date(from: - Calendar.current.dateComponents([.year, .month], from: self)) + let allowedRange = Calendar.current.range(of: .month, in: .year, for: self)! + guard allowedRange.contains(value) else { return nil } + let currentMonth = Calendar.current.component(.month, from: self) + let monthsToAdd = value - currentMonth + return Calendar.current.date(byAdding: .month, value: monthsToAdd, to: self) case .year: - return Calendar.current.date(from: - Calendar.current.dateComponents([.year], from: self)) + guard value > 0 else { return nil } + let currentYear = Calendar.current.component(.year, from: self) + let yearsToAdd = value - currentYear + return Calendar.current.date(byAdding: .year, value: yearsToAdd, to: self) default: - return nil + return Calendar.current.date(bySetting: component, value: value, of: self) } } + /// SwifterSwift: Data at the beginning of calendar component. + /// + /// let date = Date() // "Jan 12, 2017, 7:14 PM" + /// let date2 = date.beginning(of: .hour) // "Jan 12, 2017, 7:00 PM" + /// let date3 = date.beginning(of: .month) // "Jan 1, 2017, 12:00 AM" + /// let date4 = date.beginning(of: .year) // "Jan 1, 2017, 12:00 AM" + /// + /// - Parameter component: calendar component to get date at the beginning of. + /// - Returns: date at the beginning of calendar component (if applicable). + public func beginning(of component: Calendar.Component) -> Date? { + + if component == .day { + return Calendar.current.startOfDay(for: self) + } + + var components: Set { + switch component { + case .second: + return [.year, .month, .day, .hour, .minute, .second] + + case .minute: + return [.year, .month, .day, .hour, .minute] + + case .hour: + return [.year, .month, .day, .hour] + + case .weekOfYear, .weekOfMonth: + return [.yearForWeekOfYear, .weekOfYear] + + case .month: + return [.year, .month] + + case .year: + return [.year] + + default: + return [] + } + } + + guard !components.isEmpty else { return nil } + return Calendar.current.date(from: Calendar.current.dateComponents(components, from: self)) + } + /// SwifterSwift: Date at the end of calendar component. /// /// let date = Date() // "Jan 12, 2017, 7:27 PM" @@ -564,6 +666,17 @@ public extension Date { } } + /// SwifterSwift: Check if date is in current given calendar component. + /// + /// Date().isInCurrent(.day) -> true + /// Date().isInCurrent(.year) -> true + /// + /// - Parameter component: calendar component to check. + /// - Returns: true if date is in current given calendar component. + public func isInCurrent(_ component: Calendar.Component) -> Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: component) + } + /// SwifterSwift: Date string from date. /// /// Date().dateString(ofStyle: .short) -> "1/12/17" @@ -596,17 +709,6 @@ public extension Date { return dateFormatter.string(from: self) } - /// SwifterSwift: Check if date is in current given calendar component. - /// - /// Date().isInCurrent(.day) -> true - /// Date().isInCurrent(.year) -> true - /// - /// - Parameter component: calendar component to check. - /// - Returns: true if date is in current given calendar component. - public func isInCurrent(_ component: Calendar.Component) -> Bool { - return calendar.isDate(self, equalTo: Date(), toGranularity: component) - } - /// SwifterSwift: Time string from date /// /// Date().timeString(ofStyle: .short) -> "7:37 PM" @@ -678,7 +780,7 @@ public extension Date { /// - Parameter date: date to compate self to. /// - Returns: number of seconds between self and given date. public func secondsSince(_ date: Date) -> Double { - return self.timeIntervalSince(date) + return timeIntervalSince(date) } /// SwifterSwift: get number of minutes between two date @@ -686,7 +788,7 @@ public extension Date { /// - Parameter date: date to compate self to. /// - Returns: number of minutes between self and given date. public func minutesSince(_ date: Date) -> Double { - return self.timeIntervalSince(date)/60 + return timeIntervalSince(date)/60 } /// SwifterSwift: get number of hours between two date @@ -694,7 +796,7 @@ public extension Date { /// - Parameter date: date to compate self to. /// - Returns: number of hours between self and given date. public func hoursSince(_ date: Date) -> Double { - return self.timeIntervalSince(date)/3600 + return timeIntervalSince(date)/3600 } /// SwifterSwift: get number of days between two date @@ -702,23 +804,22 @@ public extension Date { /// - Parameter date: date to compate self to. /// - Returns: number of days between self and given date. public func daysSince(_ date: Date) -> Double { - return self.timeIntervalSince(date)/(3600*24) - } - - /// SwifterSwift: check if a date is between two other dates - /// - /// - Parameters: - /// - startDate: start date to compare self to. - /// - endDate: endDate date to compare self to. - /// - includeBounds: true if the start and end date should be included (default is false) - /// - Returns: true if the date is between the two given dates. - public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool { - if includeBounds { - return startDate.compare(self).rawValue * self.compare(endDate).rawValue >= 0 - } else { - return startDate.compare(self).rawValue * self.compare(endDate).rawValue > 0 - } - } + return timeIntervalSince(date)/(3600*24) + } + + /// SwifterSwift: check if a date is between two other dates + /// + /// - Parameters: + /// - startDate: start date to compare self to. + /// - endDate: endDate date to compare self to. + /// - includeBounds: true if the start and end date should be included (default is false) + /// - Returns: true if the date is between the two given dates. + public func isBetween(_ startDate: Date, _ endDate: Date, includeBounds: Bool = false) -> Bool { + if includeBounds { + return startDate.compare(self).rawValue * compare(endDate).rawValue >= 0 + } + return startDate.compare(self).rawValue * compare(endDate).rawValue > 0 + } /// SwifterSwift: check if a date is a number of date components of another date /// @@ -727,12 +828,10 @@ public extension Date { /// - component: Calendar.Component to use. /// - date: Date to compare self to. /// - Returns: true if the date is within a number of components of another date - public func isWithin(_ value: UInt, _ component: Calendar.Component, of date: Date) -> Bool { - return calendar - .dateComponents([component], from: self, to: date) - .value(for: component) - .map { abs($0) <= value } ?? false + let components = Calendar.current.dateComponents([component], from: self, to: date) + let componentValue = components.value(for: component)! + return abs(componentValue) <= value } } diff --git a/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift b/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift new file mode 100644 index 000000000..80bf53429 --- /dev/null +++ b/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift @@ -0,0 +1,31 @@ +// +// FoundationDeprecated.swift +// SwifterSwift +// +// Created by Omar Albeik on 11/8/17. +// Copyright © 2017 SwifterSwift +// + +import Foundation + +public extension Date { + + @available(*, deprecated: 4.1.0, message: "Use isInCurrentWeek instead", renamed: "isInCurrentWeek") + /// SwifterSwift: Check if date is within the current week. + public var isInThisWeek: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) + } + + @available(*, deprecated: 4.1.0, message: "Use isInCurrentMonth instead", renamed: "isInCurrentMonth") + /// SwifterSwift: Check if date is within the current month. + public var isInThisMonth: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) + } + + @available(*, deprecated: 4.1.0, message: "Use isInCurrentYear instead", renamed: "isInCurrentYear") + /// SwifterSwift: Check if date is within the current year. + public var isInThisYear: Bool { + return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) + } + +} diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index c49e334e1..6e3fb6d6a 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 0713066F1FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; + 071306701FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; + 071306711FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; + 071306721FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; @@ -358,6 +362,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; + 07263D5C1FB3175F003CE515 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensions.swift; sourceTree = ""; }; 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; @@ -534,6 +540,22 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 071306651FB596600023A9D8 /* Recovered References */ = { + isa = PBXGroup; + children = ( + 07263D5C1FB3175F003CE515 /* FoundationDeprecated.swift */, + ); + name = "Recovered References"; + sourceTree = ""; + }; + 0713066D1FB5977F0023A9D8 /* Deprecated */ = { + isa = PBXGroup; + children = ( + 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */, + ); + path = Deprecated; + sourceTree = ""; + }; 0726D7751F7C19880028CAB5 /* Shared */ = { isa = PBXGroup; children = ( @@ -586,6 +608,7 @@ 07898B8D1F278E6300558C97 /* Sources */, 07C50CF21F5EAF7B00F46E5A /* Tests */, 07898B5E1F278D7600558C97 /* Products */, + 071306651FB596600023A9D8 /* Recovered References */, ); sourceTree = ""; }; @@ -640,6 +663,7 @@ 07B7F1651F5EB41600E6F910 /* Foundation */ = { isa = PBXGroup; children = ( + 0713066D1FB5977F0023A9D8 /* Deprecated */, 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */, 07B7F16A1F5EB41600E6F910 /* DataExtensions.swift */, 07B7F16B1F5EB41600E6F910 /* DateExtensions.swift */, @@ -986,7 +1010,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0900; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0910; ORGANIZATIONNAME = SwifterSwift; TargetAttributes = { 07898B5C1F278D7600558C97 = { @@ -1210,6 +1234,7 @@ 07B7F19D1F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F21A1F5EB43C00E6F910 /* StringExtensions.swift in Sources */, 07B7F2331F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 0713066F1FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, @@ -1268,6 +1293,7 @@ 07B7F1B31F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F2081F5EB43C00E6F910 /* StringExtensions.swift in Sources */, 07B7F2391F5EB45200E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 071306701FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, @@ -1326,6 +1352,7 @@ 07B7F1C91F5EB42200E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F1F61F5EB43B00E6F910 /* StringExtensions.swift in Sources */, 07B7F22D1F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, + 071306711FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1C31F5EB42200E6F910 /* UIImageExtensions.swift in Sources */, 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, @@ -1380,6 +1407,7 @@ 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */, 07B7F1E41F5EB43B00E6F910 /* StringExtensions.swift in Sources */, 9D4914861F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, + 071306721FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F2271F5EB44600E6F910 /* NSViewExtensions.swift in Sources */, 07B7F2211F5EB44600E6F910 /* CGFloatExtensions.swift in Sources */, ); @@ -1557,8 +1585,33 @@ 07898B561F278CF900558C97 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; + ONLY_ACTIVE_ARCH = YES; SWIFT_VERSION = 4.0; }; name = Debug; @@ -1566,6 +1619,29 @@ 07898B571F278CF900558C97 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; SWIFT_VERSION = 4.0; diff --git a/Tests/FoundationTests/CalendarExtensionTest.swift b/Tests/FoundationTests/CalendarExtensionTest.swift index 82fecb558..667640c8d 100644 --- a/Tests/FoundationTests/CalendarExtensionTest.swift +++ b/Tests/FoundationTests/CalendarExtensionTest.swift @@ -11,10 +11,6 @@ import XCTest class CalendarExtensionTests: XCTestCase { - override func setUp() { - super.setUp() - } - func testNumberOfDaysInAMonth() { let calendar = Calendar(identifier: .gregorian) let longMonths = [1, 3, 5, 7, 8, 10, 12] @@ -32,4 +28,5 @@ class CalendarExtensionTests: XCTestCase { XCTAssert(calendar.numberOfDaysInMonth(for: febDate) == 28) XCTAssert(calendar.numberOfDaysInMonth(for: leapYearDate) == 29) } + } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index ef397273f..01266b5f7 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -57,37 +57,18 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.era, 1) } - func testYear() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.year, 1970) - - date.year = 2000 - XCTAssertEqual(date.year, 2000) - - date.year = 2017 - XCTAssertEqual(date.year, 2017) - - date.year = 1988 - XCTAssertEqual(date.year, 1988) - } - func testQuarter() { - let date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.quarter, 0) - } - - func testMonth() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.month, 1) - - date.month = 2 - XCTAssertEqual(date.month, 2) - - date.month = 14 - XCTAssertEqual(date.month, 2) - - date.month = 1 - XCTAssertEqual(date.month, 1) + let date1 = Date(timeIntervalSince1970: 0) + XCTAssertEqual(date1.quarter, 1) + + let date2 = Calendar.current.date(byAdding: .month, value: 4, to: date1) + XCTAssertEqual(date2?.quarter, 2) + + let date3 = Calendar.current.date(byAdding: .month, value: 8, to: date1) + XCTAssertEqual(date3?.quarter, 3) + + let date4 = Calendar.current.date(byAdding: .month, value: 11, to: date1) + XCTAssertEqual(date4?.quarter, 4) } func testWeekOfYear() { @@ -112,106 +93,203 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(originalDate?.weekOfMonth, 1) } - func testWeekday() { - var date = Date(timeIntervalSince1970: 0) - date.weekday = 1 - XCTAssertEqual(date.weekday, 1) + func testYear() { + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.year, 1970) + + var isLowerComponentsValid: Bool { + guard date.month == 1 else { return false } + guard date.day == 2 else { return false } + guard date.hour == 3 else { return false } + guard date.minute == 46 else { return false } + guard date.second == 40 else { return false } + guard date.nanosecond == 123450040 else { return false } + return true + } - date.weekday = -1 - XCTAssertEqual(date.weekday, 1) + date.year = 2000 + XCTAssertEqual(date.year, 2000) + XCTAssert(isLowerComponentsValid) + + date.year = 2017 + XCTAssertEqual(date.year, 2017) + XCTAssert(isLowerComponentsValid) - date.weekday = 10 - XCTAssertEqual(date.weekday, 1) + date.year = 1988 + XCTAssertEqual(date.year, 1988) + XCTAssert(isLowerComponentsValid) - date.weekday = 7 - XCTAssertEqual(date.weekday, 7) + date.year = -100 + XCTAssertEqual(date.year, 1988) + XCTAssert(isLowerComponentsValid) - date.weekday = 5 - XCTAssertEqual(date.weekday, 5) + date.year = 0 + XCTAssertEqual(date.year, 1988) + XCTAssert(isLowerComponentsValid) } - func testDay() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.day, 1) + func testMonth() { + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.month, 1) - date.day = -3 - XCTAssertEqual(date.day, 1) + var isLowerComponentsValid: Bool { + guard date.day == 2 else { return false } + guard date.hour == 3 else { return false } + guard date.minute == 46 else { return false } + guard date.second == 40 else { return false } + guard date.nanosecond == 123450040 else { return false } + return true + } - date.day = 45 - XCTAssertEqual(date.day, 1) + date.month = 2 + XCTAssert(isLowerComponentsValid) + + date.month = 14 + XCTAssertEqual(date.month, 2) + XCTAssert(isLowerComponentsValid) + + date.month = 1 + XCTAssertEqual(date.month, 1) + XCTAssert(isLowerComponentsValid) + + date.month = 0 + XCTAssertEqual(date.month, 1) + XCTAssert(isLowerComponentsValid) + + date.month = -3 + XCTAssertEqual(date.month, 1) + XCTAssert(isLowerComponentsValid) + } + + func testDay() { + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.day, 2) + + var isLowerComponentsValid: Bool { + guard date.hour == 3 else { return false } + guard date.minute == 46 else { return false } + guard date.second == 40 else { return false } + guard date.nanosecond == 123450040 else { return false } + return true + } date.day = 4 XCTAssertEqual(date.day, 4) - + XCTAssert(isLowerComponentsValid) + date.day = 1 XCTAssertEqual(date.day, 1) + XCTAssert(isLowerComponentsValid) + + date.day = 0 + XCTAssertEqual(date.day, 1) + XCTAssert(isLowerComponentsValid) + + date.day = -3 + XCTAssertEqual(date.day, 1) + XCTAssert(isLowerComponentsValid) + + date.day = 45 + XCTAssertEqual(date.day, 1) + XCTAssert(isLowerComponentsValid) + } + + func testWeekday() { + let date = Date(timeIntervalSince1970: 100000) + XCTAssertEqual(date.weekday, 6) } func testHour() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.hour, 0) + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.hour, 3) + + var isLowerComponentsValid: Bool { + guard date.minute == 46 else { return false } + guard date.second == 40 else { return false } + guard date.nanosecond == 123450040 else { return false } + return true + } date.hour = -3 - XCTAssertEqual(date.hour, 0) + XCTAssertEqual(date.hour, 3) + XCTAssert(isLowerComponentsValid) date.hour = 25 - XCTAssertEqual(date.hour, 0) - + XCTAssertEqual(date.hour, 3) + XCTAssert(isLowerComponentsValid) + date.hour = 4 XCTAssertEqual(date.hour, 4) - + XCTAssert(isLowerComponentsValid) + date.hour = 1 XCTAssertEqual(date.hour, 1) + XCTAssert(isLowerComponentsValid) } func testMinute() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.minute, 0) + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.minute, 46) - date.minute = -3 - XCTAssertEqual(date.minute, 0) + var isLowerComponentsValid: Bool { + guard date.second == 40 else { return false } + guard date.nanosecond == 123450040 else { return false } + return true + } + date.minute = -3 + XCTAssertEqual(date.minute, 46) + XCTAssert(isLowerComponentsValid) + date.minute = 71 - XCTAssertEqual(date.minute, 0) - + XCTAssertEqual(date.minute, 46) + XCTAssert(isLowerComponentsValid) + date.minute = 4 XCTAssertEqual(date.minute, 4) - + XCTAssert(isLowerComponentsValid) + date.minute = 1 XCTAssertEqual(date.minute, 1) + XCTAssert(isLowerComponentsValid) } func testSecond() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.second, 0) + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.second, 40) - date.second = -3 - XCTAssertEqual(date.second, 0) + var isLowerComponentsValid: Bool { + guard date.nanosecond == 123450040 else { return false } + return true + } + date.second = -3 + XCTAssertEqual(date.second, 40) + XCTAssert(isLowerComponentsValid) + date.second = 71 - XCTAssertEqual(date.second, 0) - + XCTAssertEqual(date.second, 40) + XCTAssert(isLowerComponentsValid) + date.second = 12 XCTAssertEqual(date.second, 12) - + XCTAssert(isLowerComponentsValid) + date.second = 1 XCTAssertEqual(date.second, 1) + XCTAssert(isLowerComponentsValid) } func testNanosecond() { - var date = Date(timeIntervalSince1970: 0) - XCTAssertEqual(date.nanosecond, 0) + var date = Date(timeIntervalSince1970: 100000.123450040) + XCTAssertEqual(date.nanosecond, 123450040) date.nanosecond = -3 - XCTAssertEqual(date.nanosecond, 0) + XCTAssertEqual(date.nanosecond, 123450040) date.nanosecond = 10000 XCTAssert(date.nanosecond >= 1000) XCTAssert(date.nanosecond <= 100000) - - date.nanosecond = 100 - XCTAssert(date.nanosecond >= 10) - XCTAssert(date.nanosecond <= 1000) } func testMillisecond() { @@ -280,25 +358,25 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.isInWeekday, !Calendar.current.isDateInWeekend(date)) } - func testIsInThisWeek() { + func testIsInCurrentWeek() { let date = Date() - XCTAssert(date.isInThisWeek) + XCTAssert(date.isInCurrentWeek) let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisWeek) + XCTAssertFalse(dateOneYearFromNow.isInCurrentWeek) } - func testIsInThisMonth() { + func testIsInCurrentMonth() { let date = Date() - XCTAssert(date.isInThisMonth) + XCTAssert(date.isInCurrentMonth) let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisMonth) + XCTAssertFalse(dateOneYearFromNow.isInCurrentMonth) } - func testIsInThisYear() { + func testIsInCurrentYear() { let date = Date() - XCTAssert(date.isInThisYear) + XCTAssert(date.isInCurrentYear) let dateOneYearFromNow = date.adding(.year, value: 1) - XCTAssertFalse(dateOneYearFromNow.isInThisYear) + XCTAssertFalse(dateOneYearFromNow.isInCurrentYear) } func testIso8601String() { @@ -311,11 +389,11 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.nearestFiveMinutes, date) let date2 = date.adding(.minute, value: 4) // adding 4 minutes - XCTAssertNotEqual(date2.nearestFiveMinutes, date) - XCTAssertEqual(date2.nearestFiveMinutes, date.adding(.minute, value: 5)) + XCTAssertNotEqual(date2.nearestFiveMinutes, date2) + XCTAssertEqual(date2.nearestFiveMinutes, date2.adding(.minute, value: 1)) let date3 = date.adding(.minute, value: 7) // adding 7 minutes - XCTAssertEqual(date3.nearestFiveMinutes, date.adding(.minute, value: 5)) + XCTAssertEqual(date3.nearestFiveMinutes, date3.adding(.minute, value: -2)) let date4 = date.adding(.hour, value: 1).adding(.minute, value: 2) // adding 1 hour and 2 minutes XCTAssertEqual(date4.nearestFiveMinutes, date.adding(.hour, value: 1)) @@ -389,40 +467,45 @@ final class DateExtensionsTests: XCTestCase { func testAdding() { let date = Date(timeIntervalSince1970: 3610) // Jan 1, 1970, 3:00:10 AM + XCTAssertEqual(date.adding(.second, value: 0), date) let date1 = date.adding(.second, value: 10) XCTAssertEqual(date1.second, date.second + 10) XCTAssertEqual(date1.adding(.second, value: -10), date) + XCTAssertEqual(date.adding(.minute, value: 0), date) let date2 = date.adding(.minute, value: 10) XCTAssertEqual(date2.minute, date.minute + 10) XCTAssertEqual(date2.adding(.minute, value: -10), date) + XCTAssertEqual(date.adding(.hour, value: 0), date) let date3 = date.adding(.hour, value: 2) XCTAssertEqual(date3.hour, date.hour + 2) XCTAssertEqual(date3.adding(.hour, value: -2), date) + XCTAssertEqual(date.adding(.day, value: 0), date) let date4 = date.adding(.day, value: 2) XCTAssertEqual(date4.day, date.day + 2) XCTAssertEqual(date4.adding(.day, value: -2), date) + XCTAssertEqual(date.adding(.weekOfYear, value: 0), date) let date5 = date.adding(.weekOfYear, value: 1) XCTAssertEqual(date5.day, date.day + 7) XCTAssertEqual(date5.adding(.weekOfYear, value: -1), date) + XCTAssertEqual(date.adding(.weekOfMonth, value: 0), date) let date6 = date.adding(.weekOfMonth, value: 1) XCTAssertEqual(date6.day, date.day + 7) XCTAssertEqual(date6.adding(.weekOfMonth, value: -1), date) + XCTAssertEqual(date.adding(.month, value: 0), date) let date7 = date.adding(.month, value: 2) XCTAssertEqual(date7.month, date.month + 2) XCTAssertEqual(date7.adding(.month, value: -2), date) + XCTAssertEqual(date.adding(.year, value: 0), date) let date8 = date.adding(.year, value: 4) XCTAssertEqual(date8.year, date.year + 4) XCTAssertEqual(date8.adding(.year, value: -4), date) - - XCTAssertEqual(date.adding(.calendar, value: 10), date) - } func testAdd() { @@ -431,6 +514,8 @@ final class DateExtensionsTests: XCTestCase { date.second = 10 date.add(.second, value: -1) XCTAssertEqual(date.second, 9) + date.add(.second, value: 0) + XCTAssertEqual(date.second, 9) date.add(.second, value: 1) XCTAssertEqual(date.second, 10) @@ -438,6 +523,8 @@ final class DateExtensionsTests: XCTestCase { date.minute = 10 date.add(.minute, value: -1) XCTAssertEqual(date.minute, 9) + date.add(.minute, value: 0) + XCTAssertEqual(date.minute, 9) date.add(.minute, value: 1) XCTAssertEqual(date.minute, 10) @@ -445,6 +532,8 @@ final class DateExtensionsTests: XCTestCase { date.hour = 10 date.add(.hour, value: -1) XCTAssertEqual(date.hour, 9) + date.add(.hour, value: 0) + XCTAssertEqual(date.hour, 9) date.add(.hour, value: 1) XCTAssertEqual(date.hour, 10) @@ -452,6 +541,8 @@ final class DateExtensionsTests: XCTestCase { date.day = 10 date.add(.day, value: -1) XCTAssertEqual(date.day, 9) + date.add(.day, value: 0) + XCTAssertEqual(date.day, 9) date.add(.day, value: 1) XCTAssertEqual(date.day, 10) @@ -459,6 +550,8 @@ final class DateExtensionsTests: XCTestCase { date.month = 10 date.add(.month, value: -1) XCTAssertEqual(date.month, 9) + date.add(.month, value: 0) + XCTAssertEqual(date.month, 9) date.add(.month, value: 1) XCTAssertEqual(date.month, 10) @@ -466,6 +559,8 @@ final class DateExtensionsTests: XCTestCase { date = Date() date.add(.year, value: -1) XCTAssertEqual(date.year, 2016) + date.add(.year, value: 0) + XCTAssertEqual(date.year, 2016) date.add(.year, value: 1) XCTAssertEqual(date.year, 2017) @@ -474,6 +569,10 @@ final class DateExtensionsTests: XCTestCase { func testChanging() { let date = Date(timeIntervalSince1970: 0) + XCTAssertNil(date.changing(.nanosecond, value: -10)) + XCTAssertNotNil(date.changing(.nanosecond, value: 123450040)) + XCTAssertEqual(date.changing(.nanosecond, value: 123450040)?.nanosecond, 123450040) + XCTAssertNil(date.changing(.second, value: -10)) XCTAssertNil(date.changing(.second, value: 70)) XCTAssertNotNil(date.changing(.second, value: 20)) @@ -499,8 +598,14 @@ final class DateExtensionsTests: XCTestCase { XCTAssertNotNil(date.changing(.month, value: 6)) XCTAssertEqual(date.changing(.month, value: 6)?.month, 6) + XCTAssertNil(date.changing(.year, value: -2)) + XCTAssertNil(date.changing(.year, value: 0)) XCTAssertNotNil(date.changing(.year, value: 2015)) XCTAssertEqual(date.changing(.year, value: 2015)?.year, 2015) + + let date1 = Date() + let date2 = date1.changing(.weekOfYear, value: 10) + XCTAssertEqual(date2, Calendar.current.date(bySetting: .weekOfYear, value: 10, of: date1)) } func testBeginning() { @@ -709,23 +814,26 @@ final class DateExtensionsTests: XCTestCase { let date1 = Date(timeIntervalSince1970: 60 * 60 * 24) // 1970-01-01T00:00:00.000Z let date2 = date1.addingTimeInterval(60 * 60) // 1970-01-01T00:01:00.000Z, one hour later than date1 - //The regular + // The regular XCTAssertFalse(date1.isWithin(1, .second, of: date2)) XCTAssertFalse(date1.isWithin(1, .minute, of: date2)) XCTAssert(date1.isWithin(1, .hour, of: date2)) XCTAssert(date1.isWithin(1, .day, of: date2)) - //The other way around + // The other way around XCTAssertFalse(date2.isWithin(1, .second, of: date1)) XCTAssertFalse(date2.isWithin(1, .minute, of: date1)) XCTAssert(date2.isWithin(1, .hour, of: date1)) XCTAssert(date2.isWithin(1, .day, of: date1)) - //With itself + // With itself XCTAssert(date1.isWithin(1, .second, of: date1)) XCTAssert(date1.isWithin(1, .minute, of: date1)) XCTAssert(date1.isWithin(1, .hour, of: date1)) XCTAssert(date1.isWithin(1, .day, of: date1)) + + // Invalid + XCTAssertFalse(Date().isWithin(1, .calendar, of: Date())) } func testNewDateFromComponenets() { From e92a82ef4ddddd2ffa3943d4ec0dc166340c39c5 Mon Sep 17 00:00:00 2001 From: Yurii Date: Sat, 11 Nov 2017 22:54:31 +0100 Subject: [PATCH 072/201] Rename weekday to workweek (#313) --- Sources/Extensions/Foundation/DateExtensions.swift | 2 +- Tests/FoundationTests/DateExtensionsTests.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 3463c4fd5..ffd244e8b 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -313,7 +313,7 @@ public extension Date { } /// SwifterSwift: Check if date is within a weekday period. - public var isInWeekday: Bool { + public var isWorkday: Bool { return !Calendar.current.isDateInWeekend(self) } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 01266b5f7..b061ff411 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -353,9 +353,9 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.isInWeekend, Calendar.current.isDateInWeekend(date)) } - func testIsInWeekday() { + func testIsWorkday() { let date = Date() - XCTAssertEqual(date.isInWeekday, !Calendar.current.isDateInWeekend(date)) + XCTAssertEqual(date.isWorkday, !Calendar.current.isDateInWeekend(date)) } func testIsInCurrentWeek() { From 50303ce2cbf88ccc3a01a0f38694492ef557c2b1 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 12 Nov 2017 15:21:31 -0200 Subject: [PATCH 073/201] Removing deprecated string.characters calls and xcode 9.1 recommend settings. (#305) --- CHANGELOG.md | 18 +- .../Extensions/Shared/ColorExtensions.swift | 8 +- .../SwiftStdlib/CharacterExtensions.swift | 4 +- .../Deprecated/SwiftStdlibDeprecated.swift | 84 +++++++++ .../SwiftStdlib/StringExtensions.swift | 163 ++++++------------ SwifterSwift.xcodeproj/project.pbxproj | 19 +- .../xcschemes/SwifterSwift-iOS.xcscheme | 2 +- .../xcschemes/SwifterSwift-macOS.xcscheme | 2 +- .../xcschemes/SwifterSwift-tvOS.xcscheme | 2 +- .../xcschemes/SwifterSwift-watchOS.xcscheme | 2 +- .../ArrayExtensionsTests.swift | 2 +- .../StringExtensionsTests.swift | 32 +--- 12 files changed, 185 insertions(+), 153 deletions(-) create mode 100644 Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 176942ba0..b9e92e2d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,21 @@ All notable changes to this project will be documented in this file. > # Next Release > -> ### API Breaking -> N/A -> +### API Breaking + - **String** + - `length` is deprecated, use native `count` instead. + + - `slicing(i:)` is deprecated, use `string[safe: i]` instead. + + - `slicing(from: to:)` is deprecated, use `string[safe: start.. String` is deprecated, use the Swift 4 new `reversed() -> ReversedCollection` + + [#305](https://github.com/SwifterSwift/SwifterSwift/pull/305) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida) ### Enhancements - New **String** extensions diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index a56870c2b..714cdb433 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -93,7 +93,7 @@ public extension Color { /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). public var shortHexString: String? { let string = hexString.replacingOccurrences(of: "#", with: "") - let chrs = Array(string.characters) + let chrs = Array(string) guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return nil } return "#\(chrs[0])\(chrs[2])\(chrs[4])" } @@ -107,7 +107,7 @@ public extension Color { }() let hexString = String(format: "#%02X%02X%02X", components[0], components[1], components[2]) let string = hexString.replacingOccurrences(of: "#", with: "") - let chrs = Array(string.characters) + let chrs = Array(string) guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return hexString } return "#\(chrs[0])\(chrs[2])\(chrs[4])" } @@ -271,9 +271,9 @@ public extension Color { string = hexString } - if string.characters.count == 3 { // convert hex to 6 digit format if in short format + if string.count == 3 { // convert hex to 6 digit format if in short format var str = "" - string.characters.forEach { str.append(String(repeating: String($0), count: 2)) } + string.forEach { str.append(String(repeating: String($0), count: 2)) } string = str } diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index e56f170e0..4e58e1cfa 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -95,7 +95,7 @@ public extension Character { /// Character("A").lowercased -> Character("a") /// public var lowercased: Character { - return String(self).lowercased().characters.first! + return String(self).lowercased().first! } /// SwifterSwift: Return the character uppercased. @@ -103,7 +103,7 @@ public extension Character { /// Character("a").uppercased -> Character("A") /// public var uppercased: Character { - return String(self).uppercased().characters.first! + return String(self).uppercased().first! } } diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift new file mode 100644 index 000000000..db30ed1c3 --- /dev/null +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -0,0 +1,84 @@ +// +// SwiftStdlibDeprecated.swift +// SwifterSwift +// +// Copyright © 2016 SwifterSwift +// + +extension String { + /// SwifterSwift: Number of characters in string. + /// + /// "Hello world!".length -> 12 + /// + @available(*, deprecated: 4.1.0, message: "This extension is deprecated, please use .count instead.") + public var length: Int { + return count + } + + /// SwifterSwift: Sliced string from a start index. + /// + /// "Hello World".slicing(at: 6) -> "World" + /// + /// - Parameter i: string index the slicing should start from. + /// - Returns: sliced substring starting from start index (if applicable) (example: "Hello world".slicing(at: 6) -> "world") + @available(*, deprecated: 4.1.0, message: "Please use string[safe: i] instead.") + public func slicing(at i: Int) -> String? { + guard i < count else { + return nil + } + return self[safe: i.. "World" + /// + /// - Parameters: + /// - start: string index the slicing should start from. + /// - end: string index the slicing should end at. + /// - Returns: sliced substring starting from start index, and ends at end index (if applicable) (example: "Hello World".slicing(from: 6, to: 11) -> "World") + @available(*, deprecated: 4.1.0, message: "Please use string[safe: start.. String? { + guard end >= start else { + return nil + } + return self[safe: start.. 2 + /// "Hello World!".firstIndex(of: "s") -> nil + /// + /// - Parameter string: substring to search for. + /// - Returns: first index of substring in string (if applicable). + @available(*, deprecated: 4.1.0, message: "Please use string.index(of: Character) or string.range(of: StringProtocol) instead.") + public func firstIndex(of string: String) -> Int? { + return map({ String($0) }).index(of: string) + } + + // + + /// SwifterSwift: Array of strings separated by given string. + /// + /// "hello World".splited(by: " ") -> ["hello", "World"] + /// + /// - Parameter separator: separator to split string by. + /// - Returns: array of strings separated by given string. + @available(*, deprecated: 4.1.0, message: "Please use string.split(separator: Character) instead.") + public func splitted(by separator: Character) -> [String] { + return split { $0 == separator }.map(String.init) + } + + /// SwifterSwift: Reversed string. + /// + /// "foo".reversed() -> "oof" + /// + /// - Returns: The reversed string. + @available(*, deprecated: 4.1.0, message: "Please use String(str.reversed()) or reversed() -> ReversedCollection instead.") + public func reversed() -> String { + let chars: [Character] = reversed() + return String(chars) + } + +} diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 94822942b..1d5cecfcc 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -39,7 +39,7 @@ public extension String { /// SwifterSwift: Array of characters of a string. /// public var charactersArray: [Character] { - return Array(characters) + return Array(self) } /// SwifterSwift: CamelCase of string. @@ -49,13 +49,13 @@ public extension String { public var camelCased: String { let source = lowercased() let first = source[.. nil /// public var firstCharacterAsString: String? { - guard let first = characters.first else { + guard let first = self.first else { return nil } return String(first) @@ -131,7 +131,7 @@ public extension String { let hasLetters = rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil let hasNumbers = rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil let comps = components(separatedBy: .alphanumerics) - return comps.joined(separator: "").characters.count == 0 && hasLetters && hasNumbers + return comps.joined(separator: "").count == 0 && hasLetters && hasNumbers } /// SwifterSwift: Check if string is valid email format. @@ -210,7 +210,7 @@ public extension String { /// "".lastCharacterAsString -> nil /// public var lastCharacterAsString: String? { - guard let last = characters.last else { + guard let last = self.last else { return nil } return String(last) @@ -224,14 +224,6 @@ public extension String { return folding(options: .diacriticInsensitive, locale: Locale.current) } - /// SwifterSwift: Number of characters in string. - /// - /// "Hello world!".length -> 12 - /// - public var length: Int { - return characters.count - } - /// SwifterSwift: Bool value from string (if applicable). /// /// "1".bool -> true @@ -385,23 +377,13 @@ public extension String { /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter() -> "e" /// /// - Returns: The most common character. - public func mostCommonCharacter() -> String { - let mostCommon = withoutSpacesAndNewLines.characters.reduce(into: [Character: Int]()) { + public func mostCommonCharacter() -> Character? { + let mostCommon = withoutSpacesAndNewLines.reduce(into: [Character: Int]()) { let count = $0[$1] ?? 0 $0[$1] = count + 1 }.max { $0.1 < $1.1 }?.0 - guard let character = mostCommon else { return "" } - return String(character) - } - - /// SwifterSwift: Reversed string. - /// - /// "foo".reversed() -> "oof" - /// - /// - Returns: The reversed string. - public func reversed() -> String { - return String(characters.reversed()) + return mostCommon } /// SwifterSwift: Array with unicodes for all characters in a string. @@ -441,11 +423,11 @@ public extension String { /// "Hello World!"[20] -> nil /// /// - Parameter i: index. - public subscript(safe i: Int) -> String? { - guard i >= 0 && i < characters.count else { + public subscript(safe i: Int) -> Character? { + guard i >= 0 && i < count else { return nil } - return String(self[index(startIndex, offsetBy: i)]) + return self[index(startIndex, offsetBy: i)] } /// SwifterSwift: Safely subscript string within a half-open range. @@ -508,9 +490,9 @@ public extension String { /// SwifterSwift: Check if string contains only unique characters. /// public func hasUniqueCharacters() -> Bool { - guard self.characters.count > 0 else { return false } + guard count > 0 else { return false } var uniqueChars = Set() - for char in self.characters { + for char in self { if uniqueChars.contains(String(char)) { return false } @@ -567,17 +549,6 @@ public extension String { return hasSuffix(suffix) } - /// SwifterSwift: First index of substring in string. - /// - /// "Hello World!".firstIndex(of: "l") -> 2 - /// "Hello World!".firstIndex(of: "s") -> nil - /// - /// - Parameter string: substring to search for. - /// - Returns: first index of substring in string (if applicable). - public func firstIndex(of string: String) -> Int? { - return Array(characters).map({String($0)}).index(of: string) - } - /// SwifterSwift: Latinize string. /// /// var str = "Hèllö Wórld!" @@ -599,7 +570,7 @@ public extension String { let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" var randomString = "" for _ in 1...length { - let randomIndex = arc4random_uniform(UInt32(base.characters.count)) + let randomIndex = arc4random_uniform(UInt32(base.count)) let randomCharacter = base.charactersArray[Int(randomIndex)] randomString.append(randomCharacter) } @@ -608,30 +579,31 @@ public extension String { /// SwifterSwift: Reverse string. public mutating func reverse() { - self = String(characters.reversed()) + let chars: [Character] = reversed() + self = String(chars) } - - /// SwifterSwift: Sliced string from a start index with length. - /// - /// "Hello World".slicing(from: 6, length: 5) -> "World" - /// - /// - Parameters: - /// - i: string index the slicing should start from. - /// - length: amount of characters to be sliced after given index. - /// - Returns: sliced substring of length number of characters (if applicable) (example: "Hello World".slicing(from: 6, length: 5) -> "World") - public func slicing(from i: Int, length: Int) -> String? { - guard length >= 0, i >= 0, i < characters.count else { - return nil - } - guard i.advanced(by: length) <= characters.count else { - return slicing(at: i) - } - guard length > 0 else { - return "" - } - return self[safe: i.. "World" + /// + /// - Parameters: + /// - i: string index the slicing should start from. + /// - length: amount of characters to be sliced after given index. + /// - Returns: sliced substring of length number of characters (if applicable) (example: "Hello World".slicing(from: 6, length: 5) -> "World") + public func slicing(from i: Int, length: Int) -> String? { + guard length >= 0, i >= 0, i < count else { + return nil + } + guard i.advanced(by: length) <= count else { + return self[safe: i.. 0 else { + return "" + } + return self[safe: i.. "World" - /// - /// - Parameters: - /// - start: string index the slicing should start from. - /// - end: string index the slicing should end at. - /// - Returns: sliced substring starting from start index, and ends at end index (if applicable) (example: "Hello World".slicing(from: 6, to: 11) -> "World") - public func slicing(from start: Int, to end: Int) -> String? { - guard end >= start else { - return nil + + if let str = self.slicing(from: i, length: length) { + self = String(str) } - return self[safe: start..= start else { return } + + if let str = self[safe: start.. "World" - /// - /// - Parameter i: string index the slicing should start from. - /// - Returns: sliced substring starting from start index (if applicable) (example: "Hello world".slicing(at: 6) -> "world") - public func slicing(at i: Int) -> String? { - guard i < characters.count else { - return nil - } - return self[safe: i.. ["hello", "World"] - /// - /// - Parameter separator: separator to split string by. - /// - Returns: array of strings separated by given string. - public func splitted(by separator: Character) -> [String] { - return characters.split { $0 == separator }.map(String.init) - } - /// SwifterSwift: Check if string starts with substring. /// /// "hello World".starts(with: "h") -> true @@ -765,7 +704,7 @@ public extension String { guard length > 0 else { return } - if characters.count > length { + if count > length { self = self[startIndex.. String { - guard 1.. String in - return String(element.characters.first ?? Character("")) + return String(element.first!) } XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) XCTAssertEqual(grouped["i"] ?? [], [ "irving", "iverson" ]) diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 1961ee70c..ef167864e 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -70,11 +70,7 @@ final class StringExtensionsTests: XCTestCase { XCTAssertNotNil("Hello".firstCharacterAsString) XCTAssertEqual("Hello".firstCharacterAsString, "H") } - - func testFirstIndex() { - XCTAssertEqual("Hello Test".firstIndex(of: "e"), 1) - } - + func testHasLetters() { XCTAssert("hsj 1 wq3".hasLetters) XCTAssertFalse("123".hasLetters) @@ -165,10 +161,6 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual("Hëllô Teśt".latinized, "Hello Test") } - func testLength() { - XCTAssertEqual("Hello world!".length, 12) - } - func testLines() { XCTAssertEqual("Hello\ntest".lines(), ["Hello", "test"]) } @@ -176,15 +168,15 @@ final class StringExtensionsTests: XCTestCase { func testMostCommonCharacter() { let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter XCTAssertEqual(mostCommonCharacter(), "e") - XCTAssertEqual("".mostCommonCharacter(), "") + XCTAssertNil("".mostCommonCharacter()) } func testRandom() { let str1 = String.random(ofLength: 10) - XCTAssertEqual(str1.length, 10) + XCTAssertEqual(str1.count, 10) let str2 = String.random(ofLength: 10) - XCTAssertEqual(str2.length, 10) + XCTAssertEqual(str2.count, 10) XCTAssertNotEqual(str1, str2) @@ -197,19 +189,11 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(str, "olleH") } - func testReversed() { - XCTAssertEqual("Hello".reversed(), "olleH") - } - func testSlice() { XCTAssertEqual("12345678".slicing(from: 2, length: 3), "345") - XCTAssertNil("12345678".slicing(at: 50)) XCTAssertEqual("12345678".slicing(from: 2, length: 0), "") XCTAssertNil("12345678".slicing(from: 12, length: 0)) XCTAssertEqual("12345678".slicing(from: 2, length: 100), "345678") - XCTAssertEqual("12345678".slicing(from: 2, to: 5), "345") - XCTAssertNil("12345678".slicing(from: 2, to: 1)) - XCTAssertEqual("12345678".slicing(at: 2), "345678") var str = "12345678" str.slice(from: 2, length: 3) @@ -241,10 +225,6 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(str, "345678") } - func testSplit() { - XCTAssertEqual("Hello Tests".splitted(by: " "), ["Hello", "Tests"]) - } - func testStart() { XCTAssert("Hello Test".starts(with: "hello", caseSensitive: false)) XCTAssert("Hello Tests".starts(with: "He")) @@ -442,10 +422,10 @@ final class StringExtensionsTests: XCTestCase { func testInitRandomOfLength() { let str1 = String(randomOfLength: 10) - XCTAssertEqual(str1.length, 10) + XCTAssertEqual(str1.count, 10) let str2 = String(randomOfLength: 10) - XCTAssertEqual(str2.length, 10) + XCTAssertEqual(str2.count, 10) XCTAssertNotEqual(str1, str2) From 6bdda8fa8f0cdb76e6830f6eba4ab9f92f537d24 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 13 Nov 2017 07:58:01 +0100 Subject: [PATCH 074/201] #312 Update travis to use xcode 9.1 (#314) Fixes #314 * Update travis to use xcode 9.1 * Change tv os destination simulator on travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27eec928c..95bec5217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9 +osx_image: xcode9.1 env: global: @@ -9,7 +9,7 @@ env: - WATCHOS_SCHEME='SwifterSwift-watchOS' - MACOS_SCHEME='SwifterSwift-macOS' - IOS_DESTINATION='platform=iOS Simulator,name=iPhone 6S' - - TVOS_DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p' + - TVOS_DESTINATION='platform=tvOS Simulator,name=Apple TV 4K (at 1080p)' - WATCHOS_DESTINATION='name=Apple Watch - 42mm' - MACOS_DESTINATION='platform=OS X' From 2348013fe8efb96dbc6dc79447db4bd6a3d759f8 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 16 Nov 2017 11:36:25 +0300 Subject: [PATCH 075/201] Update Copyright in LICENSE --- LICENSE | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index ef6614598..4caea1348 100755 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2015-2016 Omar Albeik (https://github.com/omaralbeik) +MIT License + +Copyright (c) 2015-2017 SwifterSwift (https://github.com/swifterswift) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From b612fb9faa46d876c72ba156864b3bbccba2af20 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 16 Nov 2017 12:47:23 +0300 Subject: [PATCH 076/201] Update CHANGELOG --- CHANGELOG.md | 79 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e92e2d0..591faadb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,34 +7,69 @@ All notable changes to this project will be documented in this file. > # Next Release > -### API Breaking - - **String** - - `length` is deprecated, use native `count` instead. - - - `slicing(i:)` is deprecated, use `string[safe: i]` instead. - - - `slicing(from: to:)` is deprecated, use `string[safe: start.. ### API Breaking +> N/A +> +> ### Enhancements +> N/A +> +> ### Bugfixes +> N/A - - `splitted(by:)` is deprecated, use the native `split(separator: )` instead. - - `reversed() -> String` is deprecated, use the Swift 4 new `reversed() -> ReversedCollection` +# 4.1.0 - [#305](https://github.com/SwifterSwift/SwifterSwift/pull/305) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida) +### API Breaking +- **String** + - `length` is deprecated, use native `count` instead. + - `slicing(i:)` is deprecated, use `string[safe: i]` instead. + - `slicing(from: to:)` is deprecated, use `string[safe: start.. String` is deprecated, use the Swift 4 new `reversed() -> ReversedCollection`. [#305](https://github.com/SwifterSwift/SwifterSwift/pull/305) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **Date** + - `weekday` is now a _get-only_ property. + - `isInThisWeek` has been renamed to `isInCurrentWeek`. + - `isInThisMonth` has been renamed to `isInCurrentMonth`. + - `isInThisYear` has been renamed to `isInCurrentYear`. + - `isInWeekday` has been renamed to `isWorkday`. [#313](https://github.com/SwifterSwift/SwifterSwift/pull/313) by [kaphacius](https://github.com/kaphacius). ### Enhancements - - New **String** extensions - - Add `padStart(lenght:with:)` and `padEnd(lenght:with:)` to pad the string to a lenght on the start or end. - - Add `paddingStart(lenght:with:)` and `paddingEnd(lenght:with:)` to return a padding string to a lenght on the start or end. - [#300](https://github.com/SwifterSwift/SwifterSwift/pull/300) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida) - - New **NSImage** extensions - - Add `scaled(toMaxSize:)` to scale image to maximum size with respect to aspect ratio [#291](https://github.com/SwifterSwift/SwifterSwift/pull/291) by [buddax2](https://github.com/buddax2). - - **Optional** - - Add optional assignment operator `??=` [#296](https://github.com/SwifterSwift/SwifterSwift/pull/296) by [buddax2](https://github.com/buddax2). +- New **String** extensions + - added `padStart(length: with:)` and `padEnd(length: with:)` to pad the string to a length on the start or end. + - added `paddingStart(length: with:)` and `paddingEnd(length: with:)` to return a padding string to a length on the start or end. [#300](https://github.com/SwifterSwift/SwifterSwift/pull/300) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida) +- New **NSImage** extensions + - added `scaled(toMaxSize:)` to scale image to maximum size with respect to aspect ratio [#291](https://github.com/SwifterSwift/SwifterSwift/pull/291) by [buddax2](https://github.com/buddax2). +- New **Date** extensions + - added `isWithin(_ value: , _ component: , of date:)` method to check if date is within a number of date components of another date. [295](https://github.com/SwifterSwift/SwifterSwift/pull/295) by [kaphacius](https://github.com/kaphacius). +- New **Optional** extensions + - added optional assignment operator `??=` [#296](https://github.com/SwifterSwift/SwifterSwift/pull/296) by [buddax2](https://github.com/buddax2). +- New **Calendar** extensions + - added `numberOfDaysInMonth` to get number of days in the month for a specified date. [#311](https://github.com/SwifterSwift/SwifterSwift/pull/311) by [chaithanyaprathyush](https://github.com/chaithanyaprathyush). +- New **Color** tests + - added tests for `cgFloatComponents`. [#297](https://github.com/SwifterSwift/SwifterSwift/pull/297) by [stupergenius](https://github.com/stupergenius). +- New **CGColor** tests + - added tests for `uiColor` and `nsColor`. [#281](https://github.com/SwifterSwift/SwifterSwift/pull/281) by [c1phr](https://github.com/c1phr) +- New **Date** tests + - added new tests for `isBetween` method. [#289](https://github.com/SwifterSwift/SwifterSwift/pull/289) by [kaphacius](https://github.com/kaphacius). +- Updated Travis image to Xcode 9.1. [#314](https://github.com/SwifterSwift/SwifterSwift/pull/314) by [kaphacius](https://github.com/kaphacius) +- Removed cross references from extensions. [#297](https://github.com/SwifterSwift/SwifterSwift/pull/297) by [stupergenius](https://github.com/stupergenius). +- Updated copyright headers to _Copyright © 2017 SwifterSwift_ everywhere. [#308](https://github.com/SwifterSwift/SwifterSwift/pull/308) by [camdeardorff](https://github.com/camdeardorff). + +### Bugfixes +- **Date** + - complete rewrite for most extensions. [#309](https://github.com/SwifterSwift/SwifterSwift/pull/309) by [omaralbeik](https:github.com/omaralbeik) + - fixed a bug in `year` where setting year was resetting all smaller components to zero. + - fixed a bug in `month` where setting month was resetting all smaller components to zero. + - fixed a bug in `day` where setting day was resetting all smaller components to zero. + - fixed a bug in `hour` where setting hour was resetting all smaller components to zero. + - fixed a bug in `minute` where setting minute was resetting all smaller components to zero. + - fixed a bug in `second` where setting second was resetting all smaller components to zero. + - added validation to setters for properties above. + - fixed the above bugs in `changing` method as well. + - fixed a bug where `quarter` was returning 1 always. + - Added more tests to edge cases. -> ### Bugfixes -> N/A # v4.0.1 From ce35038780254909f2bc59bf106216074af1482d Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 16 Nov 2017 12:52:47 +0300 Subject: [PATCH 077/201] v 4.1.0 :tada: --- Sources/Info.plist | 2 +- SwifterSwift.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Info.plist b/Sources/Info.plist index 5cd2f72f8..4529bea44 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.0.1 + 4.1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 5226f48e0..8e2a21f16 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwifterSwift' - s.version = '4.0.1' + s.version = '4.1.0' s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. From dd8fde4a80d3aa747180a64adf75e08ea0b32b1e Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Fri, 17 Nov 2017 16:14:52 +0300 Subject: [PATCH 078/201] Update whats new to v4.1.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7cb202cb..ba57f42ab 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### [Whats New in v4.0.1?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v401) +### [Whats New in v4.1.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#410) ## Requirements: - **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ From db5af71d10dbbf282108b16a2aa19da9610a1107 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 22 Nov 2017 13:41:02 +0300 Subject: [PATCH 079/201] Add write() method to NSImage extensions --- CHANGELOG.md | 14 ++++++++++++++ .../Extensions/AppKit/NSImageExtensions.swift | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 591faadb9..6254e91fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,20 @@ All notable changes to this project will be documented in this file. > N/A +# Next Release + +### API Breaking +N/A + +### Enhancements +- New **NSImage** extensions: + - added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). + +### Bugfixes +N/A + + + # 4.1.0 ### API Breaking diff --git a/Sources/Extensions/AppKit/NSImageExtensions.swift b/Sources/Extensions/AppKit/NSImageExtensions.swift index 142132350..039ba07bc 100644 --- a/Sources/Extensions/AppKit/NSImageExtensions.swift +++ b/Sources/Extensions/AppKit/NSImageExtensions.swift @@ -49,6 +49,22 @@ extension NSImage { // Return the new image return imageWithNewSize } + + /// SwifterSwift: Write NSImage to url. + /// + /// - Parameters: + /// - url: Desired file URL. + /// - type: Type of image (default is .jpeg). + /// - compressionFactor: used only for JPEG files. The value is a float between 0.0 and 1.0, with 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. + public func write(to url: URL, fileType type: NSBitmapImageRep.FileType = .jpeg, compressionFactor: NSNumber = 1.0) { + // https://stackoverflow.com/a/45042611/3882644 + + guard let data = tiffRepresentation else { return } + guard let imageRep = NSBitmapImageRep(data: data) else { return } + + guard let imageData = imageRep.representation(using: type, properties: [.compressionFactor : compressionFactor]) else { return } + try? imageData.write(to: url) + } } #endif From 59039fdeaa919256abf7d0d788f8e980bdfa13cf Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 22 Nov 2017 16:41:58 +0300 Subject: [PATCH 080/201] Fixed swiftlint warning --- Sources/Extensions/AppKit/NSImageExtensions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Extensions/AppKit/NSImageExtensions.swift b/Sources/Extensions/AppKit/NSImageExtensions.swift index 039ba07bc..b4e355df4 100644 --- a/Sources/Extensions/AppKit/NSImageExtensions.swift +++ b/Sources/Extensions/AppKit/NSImageExtensions.swift @@ -62,7 +62,7 @@ extension NSImage { guard let data = tiffRepresentation else { return } guard let imageRep = NSBitmapImageRep(data: data) else { return } - guard let imageData = imageRep.representation(using: type, properties: [.compressionFactor : compressionFactor]) else { return } + guard let imageData = imageRep.representation(using: type, properties: [.compressionFactor: compressionFactor]) else { return } try? imageData.write(to: url) } } From ae4d8387c428cb573da4a8dde26aa2357a6dc6f7 Mon Sep 17 00:00:00 2001 From: Phoenix Date: Thu, 30 Nov 2017 03:59:26 +0800 Subject: [PATCH 081/201] Update IntExtensions.swift (#323) * Update IntExtensions.swift fix "isPrime()" bug * Add tests of the func "isPrime()" --- .../SwiftStdlib/IntExtensions.swift | 13 ++++++----- .../SwiftStdlibTests/IntExtensionsTests.swift | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 929b922ec..22eb8941f 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -90,19 +90,20 @@ public extension Int { /// Warning: Using big numbers can be computationally expensive! /// - Returns: true or false depending on prime-ness public func isPrime() -> Bool { - guard self > 1 || self % 2 == 0 else { - return false - } // To improve speed on latter loop :) if self == 2 { - return true + return true } + + guard self > 1 && self % 2 != 0 else { + return false + } // Explanation: It is enough to check numbers until // the square root of that number. If you go up from N by one, // other multiplier will go 1 down to get similar result // (integer-wise operation) such way increases speed of operation - let base = Int(sqrt(Double(self)) + 1) - for i in Swift.stride(from: 3, to: base, by: 2) where self % i == 0 { + let base = Int(sqrt(Double(self))) + for i in Swift.stride(from: 3, through: base, by: 2) where self % i == 0 { return false } return true diff --git a/Tests/SwiftStdlibTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift index 5e603c805..07a29e97f 100644 --- a/Tests/SwiftStdlibTests/IntExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/IntExtensionsTests.swift @@ -97,6 +97,28 @@ final class IntExtensionsTests: XCTestCase { XCTAssertLessThan(Int(randomInRange: 1...5), 6) } + func testIsPrime() { + // Prime number + XCTAssertTrue(2.isPrime()) + XCTAssertTrue(3.isPrime()) + XCTAssertTrue(7.isPrime()) + XCTAssertTrue(19.isPrime()) + XCTAssertTrue(577.isPrime()) + XCTAssertTrue(1999.isPrime()) + + // Composite number + XCTAssertFalse(4.isPrime()) + XCTAssertFalse(21.isPrime()) + XCTAssertFalse(81.isPrime()) + XCTAssertFalse(121.isPrime()) + XCTAssertFalse(9409.isPrime()) + + // Others + XCTAssertFalse((-1).isPrime()) + XCTAssertFalse(0.isPrime()) + XCTAssertFalse(1.isPrime()) + } + func testRomanNumeral() { XCTAssertEqual(10.romanNumeral(), "X") XCTAssertNil((-1).romanNumeral()) From 01db238364132828544fe860db730f6464637cc9 Mon Sep 17 00:00:00 2001 From: Josh Oettinger Date: Sat, 2 Dec 2017 14:55:09 -0600 Subject: [PATCH 082/201] Add lighten and darken methods to Color extension (#325) * Added lighter and darker Color extensions * Renamed lighten and darken * Removed unnecessary if statement in adjust color method * Removed unnecessary semicolon * Removed adjust method, duplicated code into lighten and darken * Added changelog entry --- CHANGELOG.md | 1 + .../Extensions/Shared/ColorExtensions.swift | 36 ++++++++++++++++++- Tests/SharedTests/ColorExtensionsTests.swift | 28 +++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6254e91fb..ef970e427 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ N/A - added `numberOfDaysInMonth` to get number of days in the month for a specified date. [#311](https://github.com/SwifterSwift/SwifterSwift/pull/311) by [chaithanyaprathyush](https://github.com/chaithanyaprathyush). - New **Color** tests - added tests for `cgFloatComponents`. [#297](https://github.com/SwifterSwift/SwifterSwift/pull/297) by [stupergenius](https://github.com/stupergenius). + - added `lighten(by percentage:)` and `darken(by percentage:)` methods to change the hue of a color. [#325](https://github.com/SwifterSwift/SwifterSwift/pull/325) by [oettingerj](https://github.com/oettingerj). - New **CGColor** tests - added tests for `uiColor` and `nsColor`. [#281](https://github.com/SwifterSwift/SwifterSwift/pull/281) by [c1phr](https://github.com/c1phr) - New **Date** tests diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index 714cdb433..fdaff2136 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -214,8 +214,42 @@ public extension Color { let a = level1*a1 + level2*a2 return Color(red: r, green: g, blue: b, alpha: a) + } - + + /// SwifterSwift: Lighten a color + /// + /// let color = Color(red: r, green: g, blue: b, alpha: a) + /// let lighterColor: Color = color.lighten(by: 0.2) + /// + /// - Parameter percentage: Percentage by which to lighten the color + /// - Returns: A lightened color + public func lighten(by percentage: CGFloat = 0.2) -> Color { + // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor + var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 + self.getRed(&r, green: &g, blue: &b, alpha: &a) + return Color(red: min(r + percentage, 1.0), + green: min(g + percentage, 1.0), + blue: min(b + percentage, 1.0), + alpha: a) + } + + /// SwifterSwift: Darken a color + /// + /// let color = Color(red: r, green: g, blue: b, alpha: a) + /// let darkerColor: Color = color.darken(by: 0.2) + /// + /// - Parameter percentage: Percentage by which to darken the color + /// - Returns: A darkened color + public func darken(by percentage: CGFloat = 0.2) -> Color { + // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor + var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 + self.getRed(&r, green: &g, blue: &b, alpha: &a) + return Color(red: max(r - percentage, 0), + green: max(g - percentage, 0), + blue: max(b - percentage, 0), + alpha: a) + } } // MARK: - Initializers diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index 1583ac5d8..6350046a3 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -271,6 +271,34 @@ final class ColorExtensionsTests: XCTestCase { blendColor = Color.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) XCTAssertEqual(blendColor, color1) } + + func testLighten() { + let color = Color.blue + var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0 + color.getRed(&r, green: &g, blue: &b, alpha: nil) + + let lighterColor = color.lighten(by: 0.3) + var lightR: CGFloat = 0, lightG: CGFloat = 0, lightB: CGFloat = 0 + lighterColor.getRed(&lightR, green: &lightG, blue: &lightB, alpha: nil) + + XCTAssertEqual(lightR, min(r + 0.3, 1.0)) + XCTAssertEqual(lightG, min(g + 0.3, 1.0)) + XCTAssertEqual(lightB, min(b + 0.3, 1.0)) + } + + func testDarken() { + let color = Color.blue + var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0 + color.getRed(&r, green: &g, blue: &b, alpha: nil) + + let darkerColor = color.darken(by: 0.3) + var darkR: CGFloat = 0, darkG: CGFloat = 0, darkB: CGFloat = 0 + darkerColor.getRed(&darkR, green: &darkG, blue: &darkB, alpha: nil) + + XCTAssertEqual(darkR, max(r - 0.3, 0)) + XCTAssertEqual(darkG, max(g - 0.3, 0)) + XCTAssertEqual(darkB, max(b - 0.3, 0)) + } // MARK: - Test initializers func testInit() { From 3c6f4881e52e4cfa7678331fd8c04e79486620c4 Mon Sep 17 00:00:00 2001 From: Luciano Date: Mon, 4 Dec 2017 00:12:36 -0200 Subject: [PATCH 083/201] Removing shuffle and shuffled equatable Element constraint. --- .../SwiftStdlib/ArrayExtensions.swift | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 28526c8da..cdcafe0fc 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -404,35 +404,35 @@ public extension Array { public mutating func rotate(by places: Int) { self = rotated(by: places) } + + /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) + /// + /// [1, 2, 3, 4, 5].shuffle() // shuffles array + /// + public mutating func shuffle() { + //http://stackoverflow.com/questions/37843647/shuffle-array-swift-3 + guard count > 1 else { return } + for index in startIndex.. [Element] { + var array = self + array.shuffle() + return array + } } // MARK: - Methods (Equatable) public extension Array where Element: Equatable { - /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) - /// - /// [1, 2, 3, 4, 5].shuffle() // shuffles array - /// - public mutating func shuffle() { - //http://stackoverflow.com/questions/37843647/shuffle-array-swift-3 - guard count > 1 else { return } - for index in startIndex.. [Element] { - var array = self - array.shuffle() - return array - } - /// SwifterSwift: Check if array contains an array of elements. /// /// [1, 2, 3, 4, 5].contains([1, 2]) -> true From 9f6e98f320ac2165912cdaaaa64eb666b1457fc7 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 6 Dec 2017 17:43:55 +0300 Subject: [PATCH 084/201] Fix Swiftlint warnings --- Package.swift | 2 +- Sources/Extensions/UIKit/UIButtonExtensions.swift | 2 +- Sources/Extensions/UIKit/UIViewExtensions.swift | 2 +- Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift | 4 ++-- Tests/UIKitTests/UIFontExtensionsTest.swift | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Package.swift b/Package.swift index e1c9cb618..97527aee3 100644 --- a/Package.swift +++ b/Package.swift @@ -2,5 +2,5 @@ import PackageDescription let package = Package( name: "SwifterSwift", - dependencies : [] + dependencies: [] ) diff --git a/Sources/Extensions/UIKit/UIButtonExtensions.swift b/Sources/Extensions/UIKit/UIButtonExtensions.swift index 296fefd6c..d489e56ce 100644 --- a/Sources/Extensions/UIKit/UIButtonExtensions.swift +++ b/Sources/Extensions/UIKit/UIButtonExtensions.swift @@ -145,7 +145,7 @@ public extension UIButton { /// /// - Parameter image: UIImage. public func setImageForAllStates(_ image: UIImage) { - states.forEach { self.setImage(image, for: $0) } + states.forEach { self.setImage(image, for: $0) } } /// SwifterSwift: Set title color for all states. diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index f8215d19d..92a774147 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -248,7 +248,7 @@ public extension UIView { /// - radius: shadow radius (default is 3). /// - offset: shadow offset (default is .zero). /// - opacity: shadow opacity (default is 0.5). - public func addShadow(ofColor color: UIColor = UIColor(red:0.07, green:0.47, blue:0.57, alpha:1.0), radius: CGFloat = 3, offset: CGSize = .zero, opacity: Float = 0.5) { + public func addShadow(ofColor color: UIColor = UIColor(red: 0.07, green: 0.47, blue: 0.57, alpha: 1.0), radius: CGFloat = 3, offset: CGSize = .zero, opacity: Float = 0.5) { layer.shadowColor = color.cgColor layer.shadowOffset = offset layer.shadowRadius = radius diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 0e17441ed..4cbbc3d9c 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest final class DictionaryExtensionsTests: XCTestCase { - var testDict: [String : Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] + var testDict: [String: Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] func testHasKey() { XCTAssert(testDict.has(key: "testKey")) @@ -19,7 +19,7 @@ final class DictionaryExtensionsTests: XCTestCase { } func testRemoveAll() { - var dict: [String : String] = ["key1": "value1", "key2": "value2", "key3": "value3"] + var dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] dict.removeAll(keys: ["key1", "key2"]) XCTAssertTrue(dict.keys.contains("key3")) XCTAssertFalse(dict.keys.contains("key1")) diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index ac0f9d94d..4862609e7 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -17,7 +17,7 @@ final class UIFontExtension: XCTestCase { let monoFont = font.monospaced let attributes = monoFont.fontDescriptor.fontAttributes - guard let settings = attributes[UIFontDescriptor.AttributeName.featureSettings] as? [[UIFontDescriptor.AttributeName :Int]] else { + guard let settings = attributes[UIFontDescriptor.AttributeName.featureSettings] as? [[UIFontDescriptor.AttributeName: Int]] else { XCTFail("Unable to get settings from font") return } From 8c3207e51378a2de7975c58819330d78dedaaa72 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 10 Dec 2017 21:04:39 +0300 Subject: [PATCH 085/201] New extensions (#335) - Closes #328 - Closes #318 --- CHANGELOG.md | 8 ++++- README.md | 2 +- .../SwiftStdlib/StringExtensions.swift | 17 +++++++++++ .../UIKit/UIDatePickerExtensions.swift | 26 ++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 8 +++++ .../StringExtensionsTests.swift | 12 ++++++++ .../UIDatePickerExtensionsTests.swift | 30 +++++++++++++++++++ 7 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 Sources/Extensions/UIKit/UIDatePickerExtensions.swift create mode 100644 Tests/UIKitTests/UIDatePickerExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index ef970e427..892c418c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,12 @@ All notable changes to this project will be documented in this file. N/A ### Enhancements +- Enhanced **Array** extensions: + - `shuffle` and `shuffled` are no more constrained to Equatable. [#327](https://github.com/SwifterSwift/SwifterSwift/pull/327) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- New **String** extensions: + - added `loremIpsum(ofLength: )` static function to return a lorem ipsum string. [#318](https://github.com/SwifterSwift/SwifterSwift/issues/318) by [omaralbeik](https://github.com/omaralbeik). +- New **UIDatePicker** extensions: + - added `textColor` to get and set the text color of a UIDatePicker. [#328](https://github.com/SwifterSwift/SwifterSwift/issues/328) by [omaralbeik](https://github.com/omaralbeik). - New **NSImage** extensions: - added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). @@ -31,7 +37,7 @@ N/A -# 4.1.0 +# v4.1.0 ### API Breaking - **String** diff --git a/README.md b/README.md index ba57f42ab..fd65abe48 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### [Whats New in v4.1.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#410) +### [Whats New in v4.1.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v410) ## Requirements: - **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 1d5cecfcc..6c07c5c71 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -272,6 +272,23 @@ public extension String { return Int(self) } + /// SwifterSwift: Lorem ipsum string of given length. + /// + /// - Parameter length: number of characters to limit lorem ipsum to (default is 445 - full lorem ipsum). + /// - Returns: Lorem ipsum dolor sit amet... string. + public static func loremIpsum(ofLength length: Int = 445) -> String { + guard length > 0 else { return "" } + + // https://www.lipsum.com/ + let loremIpsum = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + """ + if loremIpsum.count > length { + return String(loremIpsum[loremIpsum.startIndex.. URL(string: "https://google.com") diff --git a/Sources/Extensions/UIKit/UIDatePickerExtensions.swift b/Sources/Extensions/UIKit/UIDatePickerExtensions.swift new file mode 100644 index 000000000..bf7b15360 --- /dev/null +++ b/Sources/Extensions/UIKit/UIDatePickerExtensions.swift @@ -0,0 +1,26 @@ +// +// UIDatePickerExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 12/9/17. +// Copyright © 2017 SwifterSwift +// + +#if os(iOS) +import UIKit + +// MARK: - Properties +public extension UIDatePicker { + + /// SwifterSwift: Text color of UIDatePicker. + public var textColor: UIColor? { + set { + setValue(newValue, forKeyPath: "textColor") + } + get { + return value(forKeyPath: "textColor") as? UIColor + } + } + +} +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 12b42fc2e..6adad5c9e 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -20,6 +20,8 @@ 074EAF1D1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */; }; 074EAF1F1F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */; }; 074EAF201F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */; }; + 076AEC891FDB48580077D153 /* UIDatePickerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */; }; + 076AEC8D1FDB49480077D153 /* UIDatePickerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 076AEC8C1FDB49480077D153 /* UIDatePickerExtensionsTests.swift */; }; 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; @@ -371,6 +373,8 @@ 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensions.swift; sourceTree = ""; }; 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; + 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDatePickerExtensions.swift; sourceTree = ""; }; + 076AEC8C1FDB49480077D153 /* UIDatePickerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDatePickerExtensionsTests.swift; sourceTree = ""; }; 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensions.swift; sourceTree = ""; }; 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; @@ -708,6 +712,7 @@ 07B7F18F1F5EB41600E6F910 /* UITextViewExtensions.swift */, 07B7F1901F5EB41600E6F910 /* UIViewControllerExtensions.swift */, 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */, + 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */, ); path = UIKit; sourceTree = ""; @@ -760,6 +765,7 @@ isa = PBXGroup; children = ( 07C50D0E1F5EB03200F46E5A /* UIAlertControllerExtensionsTests.swift */, + 076AEC8C1FDB49480077D153 /* UIDatePickerExtensionsTests.swift */, 07C50D0F1F5EB03200F46E5A /* UIBarButtonExtensionsTests.swift */, 07C50D101F5EB03200F46E5A /* UIButtonExtensionsTests.swift */, 07C50D111F5EB03200F46E5A /* UICollectionViewExtensionsTests.swift */, @@ -1227,6 +1233,7 @@ 07B7F20E1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */, 07B7F2151F5EB43C00E6F910 /* IntExtensions.swift in Sources */, 07B7F2111F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */, + 076AEC891FDB48580077D153 /* UIDatePickerExtensions.swift in Sources */, 07B7F2301F5EB45100E6F910 /* CGPointExtensions.swift in Sources */, 07B7F1951F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1A31F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, @@ -1467,6 +1474,7 @@ 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */, + 076AEC8D1FDB49480077D153 /* UIDatePickerExtensionsTests.swift in Sources */, 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */, 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index ef167864e..4a05d3cc1 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -315,6 +315,18 @@ final class StringExtensionsTests: XCTestCase { XCTAssertNil("8s".int) } + func testLoremIpsum() { + // https://www.lipsum.com/ + let completeLoremIpsum = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + """ + + XCTAssertEqual(String.loremIpsum(), completeLoremIpsum) + XCTAssertEqual(String.loremIpsum(ofLength: 0), "") + XCTAssertEqual(String.loremIpsum(ofLength: 26), "Lorem ipsum dolor sit amet") + + } + func testUrl() { XCTAssertNil("hello world".url) diff --git a/Tests/UIKitTests/UIDatePickerExtensionsTests.swift b/Tests/UIKitTests/UIDatePickerExtensionsTests.swift new file mode 100644 index 000000000..dbc38133b --- /dev/null +++ b/Tests/UIKitTests/UIDatePickerExtensionsTests.swift @@ -0,0 +1,30 @@ +// +// UIDatePickerExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 12/9/17. +// Copyright © 2017 SwifterSwift +// + +#if os(iOS) + +import XCTest +@testable import SwifterSwift + +final class UIDatePickerExtensionsTests: XCTestCase { + + func testTextColor() { + let datePicker = UIDatePicker() + XCTAssertNil(datePicker.textColor) + + datePicker.textColor = .red + XCTAssertEqual(datePicker.textColor, .red) + + datePicker.textColor = .green + XCTAssertEqual(datePicker.textColor, .green) + + datePicker.textColor = nil + XCTAssertNil(datePicker.textColor) + } +} +#endif From 9bfc690187ecacb862d40cd929399311d2dca708 Mon Sep 17 00:00:00 2001 From: Phoenix Date: Tue, 12 Dec 2017 00:00:43 +0800 Subject: [PATCH 086/201] Correct an error in 'weekday' documentation (#337) --- Sources/Extensions/Foundation/DateExtensions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index ffd244e8b..e80daa8ae 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -146,7 +146,7 @@ public extension Date { /// SwifterSwift: Weekday. /// - /// Date().weekOfMonth -> 5 // fifth day in the current week. + /// Date().weekday -> 5 // fifth day in the current week. /// public var weekday: Int { return Calendar.current.component(.weekday, from: self) From 25e1efce6253aa51a7eb711830c6af63cfbb5b55 Mon Sep 17 00:00:00 2001 From: Haroun SMIDA Date: Wed, 13 Dec 2017 13:10:25 +0100 Subject: [PATCH 087/201] Add string(withFormat:) to DateExtensions (#330) --- CHANGELOG.md | 4 +++- .../Extensions/Foundation/DateExtensions.swift | 16 +++++++++++++++- Tests/FoundationTests/DateExtensionsTests.swift | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 892c418c0..cdce32cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,9 @@ N/A - added `textColor` to get and set the text color of a UIDatePicker. [#328](https://github.com/SwifterSwift/SwifterSwift/issues/328) by [omaralbeik](https://github.com/omaralbeik). - New **NSImage** extensions: - added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). - +- New **Date** extensions + - added `string(withFormat format: String)` method to get a string from a date with the given format + ### Bugfixes N/A diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index e80daa8ae..c873a23ba 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -676,7 +676,21 @@ public extension Date { public func isInCurrent(_ component: Calendar.Component) -> Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: component) } - + + /// SwifterSwift: Date string from date. + /// + /// Date().string(withFormat: "dd/MM/yyyy") -> "1/12/17" + /// Date().string(withFormat: "HH:mm") -> "23:50" + /// Date().string(withFormat: "dd/MM/yyyy HH:mm") -> "1/12/17 23:50" + /// + /// - Parameter format: Date format (default is "dd/MM/yyyy"). + /// - Returns: date string. + public func string(withFormat format: String = "dd/MM/yyyy HH:mm") -> String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = format + return dateFormatter.string(from: self) + } + /// SwifterSwift: Date string from date. /// /// Date().dateString(ofStyle: .short) -> "1/12/17" diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index b061ff411..f77d4ce1f 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -688,6 +688,20 @@ final class DateExtensionsTests: XCTestCase { formatter.dateStyle = .full XCTAssertEqual(date.dateString(ofStyle: .full), formatter.string(from: date)) + + formatter.dateStyle = .none + + formatter.dateFormat = "dd/MM/yyyy" + XCTAssertEqual(date.string(withFormat: "dd/MM/yyyy"), formatter.string(from: date)) + + formatter.dateFormat = "HH:mm" + XCTAssertEqual(date.string(withFormat: "HH:mm"), formatter.string(from: date)) + + formatter.dateFormat = "dd/MM/yyyy HH:mm" + XCTAssertEqual(date.string(withFormat: "dd/MM/yyyy HH:mm"), formatter.string(from: date)) + + formatter.dateFormat = "iiiii" + XCTAssertEqual(date.string(withFormat: "iiiii"), formatter.string(from: date)) } func testDateTimeString() { From 7a1b24c5bcedb319dc6c20d8e511a119b7db0c27 Mon Sep 17 00:00:00 2001 From: Andrii Kuzminskyi Date: Thu, 14 Dec 2017 08:55:41 +0100 Subject: [PATCH 088/201] Add random and randomBetween extensions to Date #326 (#336) * Add random and randomBetween extensions to Date #326 * Update changelog * Replaced external names since->from to->upTo in Date.random extension. Combined tests for Date.radom into single test --- CHANGELOG.md | 1 + .../Foundation/DateExtensions.swift | 26 ++++++++++ .../FoundationTests/DateExtensionsTests.swift | 48 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdce32cbb..2793a2530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ N/A - New **NSImage** extensions: - added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). - New **Date** extensions + - added `random(from: Date, upTo: Date) -> Date` method that return radom date in in the specified range [#336](https://github.com/SwifterSwift/SwifterSwift/pull/336) by [akuzminskyi](https://github.com/akuzminskyi). - added `string(withFormat format: String)` method to get a string from a date with the given format ### Bugfixes diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index c873a23ba..1670ade01 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -847,6 +847,32 @@ public extension Date { let componentValue = components.value(for: component)! return abs(componentValue) <= value } + + /// SwifterSwift: Random date between two dates. + /// + /// Date.random() + /// Date.random(from: Date()) + /// Date.random(upTo: Date()) + /// Date.random(from: Date(), upTo: Date()) + /// + /// - Parameters: + /// - fromDate: minimum date (default is Date.distantPast) + /// - toDate: maximum date (default is Date.distantFuture) + /// - Returns: random date between two dates. + public static func random(from fromDate: Date = Date.distantPast, + upTo toDate: Date = Date.distantFuture) -> Date { + guard fromDate != toDate else { + return fromDate + } + + let diff = llabs(Int64(toDate.timeIntervalSinceReferenceDate - fromDate.timeIntervalSinceReferenceDate)) + var randomValue: Int64 = 0 + arc4random_buf(&randomValue, MemoryLayout.size) + randomValue = llabs(randomValue%diff) + + let startReferenceDate = toDate > fromDate ? fromDate : toDate + return startReferenceDate.addingTimeInterval(TimeInterval(randomValue)) + } } // MARK: - Initializers diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index f77d4ce1f..c5df41981 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -874,4 +874,52 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date, dateFromUnixTimestamp) } + func testRandom() { + var randomDate = Date.random() + XCTAssertTrue(randomDate.isBetween(Date.distantPast, Date.distantFuture, includeBounds: true)) + + var date = Date(timeIntervalSinceReferenceDate: 0) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSince1970: 10000) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSince1970: -10000) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSinceReferenceDate: 0) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + date = Date(timeIntervalSince1970: 10000) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + date = Date(timeIntervalSince1970: -10000) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + var sinceDate = Date(timeIntervalSinceReferenceDate: 0) + var toDate = Date(timeIntervalSinceReferenceDate: 10000) + randomDate = Date.random(from:sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSince1970: -10000) + toDate = Date(timeIntervalSince1970: -10) + randomDate = Date.random(from:sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSinceReferenceDate: -1000) + toDate = Date(timeIntervalSinceReferenceDate: 10000) + randomDate = Date.random(from:sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSinceReferenceDate: 0) + toDate = sinceDate + randomDate = Date.random(from:sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + } } From 455d29a28f81a46f5cc29763027ba25b5f6e0a2d Mon Sep 17 00:00:00 2001 From: Nathan Gelman Date: Fri, 22 Dec 2017 14:49:27 -0800 Subject: [PATCH 089/201] Attributes getter for NSAttributedString Issue #333 (#340) * added attributes property and updated tests * added test * modified test * linting * change log * switched other tests back to original --- CHANGELOG.md | 2 ++ .../NSAttributedStringExtensions.swift | 5 ++++ .../NSAttributedStringExtensionsTests.swift | 27 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2793a2530..7d81bc5cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ All notable changes to this project will be documented in this file. N/A ### Enhancements +- New **NSAttributedString** + - added `attributes' property to get the attributes that apply to a simple NSAttributedString [#333](https://github.com/SwifterSwift/SwifterSwift/issues/333) by [nathanbacon](https://github.com/nathanbacon). - Enhanced **Array** extensions: - `shuffle` and `shuffled` are no more constrained to Equatable. [#327](https://github.com/SwifterSwift/SwifterSwift/pull/327) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - New **String** extensions: diff --git a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift index f43eb5b5f..cfab61f28 100644 --- a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift @@ -38,6 +38,11 @@ public extension NSAttributedString { public var struckthrough: NSAttributedString { return applying(attributes: [.strikethroughStyle: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)]) } + + /// SwifterSwift: Dictionary of the attributes applied across the whole string + public var attributes: [NSAttributedStringKey: Any] { + return attributes(at: 0, effectiveRange: nil) + } } // MARK: - Methods diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index b3911862e..8771d5314 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -118,4 +118,31 @@ final class NSAttributedStringExtensionsTests: XCTestCase { XCTAssertEqual(filteredAttributes.count, 1) } #endif + + #if !os(macOS) && !os(tvOS) + func testAttributes() { + let attrString = NSAttributedString(string: "Test String").bolded.struckthrough.underlined.colored(with: UIColor.blue) + let attributes = attrString.attributes + + XCTAssertEqual(attributes.count, 4) + + let filteredAttributes = attributes.filter { (key, value) -> Bool in + switch key { + case NSAttributedStringKey.underlineStyle: + return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue + case NSAttributedStringKey.strikethroughStyle: + return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue + case NSAttributedStringKey.font: + return (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize) + case NSAttributedStringKey.foregroundColor: + return (value as? UIColor) == .blue + default: + return false + } + } + + XCTAssertEqual(filteredAttributes.count, 4) + + } + #endif } From 5eb6b840544dbdb5aa753bca40930b74b2ca89db Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 28 Dec 2017 21:01:41 +0300 Subject: [PATCH 090/201] Fixed makeTransparent background color (#344) Fixed a bug where makeTransparent was keeping the background color --- .../Extensions/UIKit/UINavigationBarExtensions.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift index 231a7e9af..97c415118 100644 --- a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift @@ -17,7 +17,7 @@ public extension UINavigationBar { /// - Parameters: /// - font: title font /// - color: title text color (default is .black). - public func setTitleFont(_ font: UIFont, color: UIColor = UIColor.black) { + public func setTitleFont(_ font: UIFont, color: UIColor = .black) { var attrs = [NSAttributedStringKey: Any]() attrs[.font] = font attrs[.foregroundColor] = color @@ -28,11 +28,13 @@ public extension UINavigationBar { /// /// - Parameter tint: tint color (default is .white). public func makeTransparent(withTint tint: UIColor = .white) { - setBackgroundImage(UIImage(), for: .default) - shadowImage = UIImage() isTranslucent = true + backgroundColor = .clear + barTintColor = .clear + setBackgroundImage(UIImage(), for: .default) tintColor = tint - titleTextAttributes = [NSAttributedStringKey.foregroundColor: tint] + titleTextAttributes = [.foregroundColor: tint] + shadowImage = UIImage() } /// SwifterSwift: Set navigationBar background and text colors @@ -44,7 +46,7 @@ public extension UINavigationBar { isTranslucent = false backgroundColor = background barTintColor = background - setBackgroundImage(UIImage(), for: UIBarMetrics.default) + setBackgroundImage(UIImage(), for: .default) tintColor = text titleTextAttributes = [.foregroundColor: text] } From ab8af2be13209c56892204091144c44b8a03a154 Mon Sep 17 00:00:00 2001 From: Nathan Gelman Date: Thu, 28 Dec 2017 10:02:01 -0800 Subject: [PATCH 091/201] fixed SwiftLint warnings in date tests (#346) --- Tests/FoundationTests/DateExtensionsTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index c5df41981..b7c939731 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -904,22 +904,22 @@ final class DateExtensionsTests: XCTestCase { var sinceDate = Date(timeIntervalSinceReferenceDate: 0) var toDate = Date(timeIntervalSinceReferenceDate: 10000) - randomDate = Date.random(from:sinceDate, upTo: toDate) + randomDate = Date.random(from: sinceDate, upTo: toDate) XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) sinceDate = Date(timeIntervalSince1970: -10000) toDate = Date(timeIntervalSince1970: -10) - randomDate = Date.random(from:sinceDate, upTo: toDate) + randomDate = Date.random(from: sinceDate, upTo: toDate) XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) sinceDate = Date(timeIntervalSinceReferenceDate: -1000) toDate = Date(timeIntervalSinceReferenceDate: 10000) - randomDate = Date.random(from:sinceDate, upTo: toDate) + randomDate = Date.random(from: sinceDate, upTo: toDate) XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) sinceDate = Date(timeIntervalSinceReferenceDate: 0) toDate = sinceDate - randomDate = Date.random(from:sinceDate, upTo: toDate) + randomDate = Date.random(from: sinceDate, upTo: toDate) XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) } } From 82a3d836a5d94237e9a08dca2ee00f2029370b1b Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 29 Dec 2017 08:45:51 +0300 Subject: [PATCH 092/201] Add Integer literal initializer to DateExtensions (#342) --- Sources/Extensions/Foundation/DateExtensions.swift | 12 +++++++++++- Tests/FoundationTests/DateExtensionsTests.swift | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 1670ade01..28aa441ea 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -950,5 +950,15 @@ public extension Date { public init(unixTimestamp: Double) { self.init(timeIntervalSince1970: unixTimestamp) } - + + /// SwifterSwift: Create date object from Int literal + /// + /// let date = Date(integerLiteral: 2017_12_25) // "2017-12-25 00:00:00 +0000" + /// - Parameter value: Int value, e.g. 20171225, or 2017_12_25 etc. + public init?(integerLiteral value: Int) { + let formatter = DateFormatter() + formatter.dateFormat = "yyyyMMdd" + guard let date = formatter.date(from: String(value)) else { return nil } + self = date + } } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index b7c939731..39f48cb30 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -873,6 +873,18 @@ final class DateExtensionsTests: XCTestCase { let dateFromUnixTimestamp = Date(unixTimestamp: 512) XCTAssertEqual(date, dateFromUnixTimestamp) } + + func testNewDateFromIntegerLiteral() { + let date = Date(integerLiteral: 2017_12_25) + + XCTAssertNotNil(date) + + if let date = date { + XCTAssertEqual(String(describing: date), "2017-12-25 00:00:00 +0000") + } + + XCTAssertNil(Date(integerLiteral: 222)) + } func testRandom() { var randomDate = Date.random() From 6a3e89ada07294d61424ba93493d9fe6a585fac7 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 2 Jan 2018 13:44:11 +0300 Subject: [PATCH 093/201] Fixed currentYear tests in DateExtensionsTests.swift (#349) --- Tests/FoundationTests/DateExtensionsTests.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 39f48cb30..0f0bb4e00 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -556,14 +556,15 @@ final class DateExtensionsTests: XCTestCase { date.add(.month, value: 1) XCTAssertEqual(date.month, 10) - date = Date() + date = Date(timeIntervalSince1970: 1514764800) + date.add(.year, value: -1) - XCTAssertEqual(date.year, 2016) + XCTAssertEqual(date.year, 2017) date.add(.year, value: 0) - XCTAssertEqual(date.year, 2016) + XCTAssertEqual(date.year, 2017) date.add(.year, value: 1) - XCTAssertEqual(date.year, 2017) + XCTAssertEqual(date.year, 2018) } func testChanging() { From c7c92b272ed40b463fd714610e972439a75b4b1e Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 2 Jan 2018 16:20:34 -0200 Subject: [PATCH 094/201] Adding sorted by keyPath array methods. (#343) --- CHANGELOG.md | 4 +- .../SwiftStdlib/ArrayExtensions.swift | 47 ++++++++++++++++- .../ArrayExtensionsTests.swift | 51 +++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d81bc5cb..7b5e29f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ N/A - added `attributes' property to get the attributes that apply to a simple NSAttributedString [#333](https://github.com/SwifterSwift/SwifterSwift/issues/333) by [nathanbacon](https://github.com/nathanbacon). - Enhanced **Array** extensions: - `shuffle` and `shuffled` are no more constrained to Equatable. [#327](https://github.com/SwifterSwift/SwifterSwift/pull/327) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- New **Array** extensions: + - `sort(by: KeyPath)` and `sorted(by: KeyPath)` to sort arrays based on Swift 4 keyPath. [#343](https://github.com/SwifterSwift/SwifterSwift/pull/343) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - New **String** extensions: - added `loremIpsum(ofLength: )` static function to return a lorem ipsum string. [#318](https://github.com/SwifterSwift/SwifterSwift/issues/318) by [omaralbeik](https://github.com/omaralbeik). - New **UIDatePicker** extensions: @@ -36,7 +38,7 @@ N/A - New **Date** extensions - added `random(from: Date, upTo: Date) -> Date` method that return radom date in in the specified range [#336](https://github.com/SwifterSwift/SwifterSwift/pull/336) by [akuzminskyi](https://github.com/akuzminskyi). - added `string(withFormat format: String)` method to get a string from a date with the given format - + ### Bugfixes N/A diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index cdcafe0fc..60fb7b4aa 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -428,6 +428,51 @@ public extension Array { array.shuffle() return array } + + /// SwifterSwift: Return a sorted array based on an optional keypath. + /// + /// - Parameter path: Key path to sort. The key path type must be Comparable. + /// - Parameter ascending: If order must be ascending. + /// - Returns: Sorted array based on keyPath. + public func sorted(by path: KeyPath, ascending: Bool = true) -> [Element] { + return sorted(by: { (lhs, rhs) -> Bool in + guard let lhsValue = lhs[keyPath: path], let rhsValue = rhs[keyPath: path] else { return false } + if ascending { + return lhsValue < rhsValue + } + return lhsValue > rhsValue + }) + } + + /// SwifterSwift: Return a sorted array based on a keypath. + /// + /// - Parameter path: Key path to sort. The key path type must be Comparable. + /// - Parameter ascending: If order must be ascending. + /// - Returns: Sorted array based on keyPath. + public func sorted(by path: KeyPath, ascending: Bool = true) -> [Element] { + return sorted(by: { (lhs, rhs) -> Bool in + if ascending { + return lhs[keyPath: path] < rhs[keyPath: path] + } + return lhs[keyPath: path] > rhs[keyPath: path] + }) + } + + /// SwifterSwift: Sort the array based on an optional keypath. + /// + /// - Parameter path: Key path to sort. The key path type must be Comparable. + /// - Parameter ascending: If order must be ascending. + public mutating func sort(by path: KeyPath, ascending: Bool = true) { + self = sorted(by: path, ascending: ascending) + } + + /// SwifterSwift: Sort the array based on a keypath. + /// + /// - Parameter path: Key path to sort. The key path type must be Comparable. + /// - Parameter ascending: If order must be ascending. + public mutating func sort(by path: KeyPath, ascending: Bool = true) { + self = sorted(by: path, ascending: ascending) + } } // MARK: - Methods (Equatable) @@ -548,5 +593,5 @@ public extension Array where Element: Equatable { } return nil } - + } diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index ec71688b6..656c81de9 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -389,5 +389,56 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(array, [4, 1, 2, 3]) } + + struct Person: Equatable { + var name: String + var age: Int? + + static func == (lhs: Person, rhs: Person) -> Bool { + return lhs.name == rhs.name && lhs.age == rhs.age + } + } + + func testKeyPathSorted() { + + let array = [Person(name: "James", age: 32), + Person(name: "Wade", age: 36), + Person(name: "Rose", age: 29)] + + XCTAssertEqual(array.sorted(by: \Person.name), [Person(name: "James", age: 32), + Person(name: "Rose", age: 29), + Person(name: "Wade", age: 36)]) + XCTAssertEqual(array.sorted(by: \Person.name, ascending: false), [Person(name: "Wade", age: 36), + Person(name: "Rose", age: 29), + Person(name: "James", age: 32)]) + // Testing Optional keyPath + XCTAssertEqual(array.sorted(by: \Person.age), [Person(name: "Rose", age: 29), + Person(name: "James", age: 32), + Person(name: "Wade", age: 36)]) + XCTAssertEqual(array.sorted(by: \Person.age, ascending: false), [Person(name: "Wade", age: 36), + Person(name: "James", age: 32), + Person(name: "Rose", age: 29)]) + + // Testing Mutating + var mutableArray = [Person(name: "James", age: 32), + Person(name: "Wade", age: 36), + Person(name: "Rose", age: 29)] + + mutableArray.sort(by: \Person.name) + XCTAssertEqual(mutableArray, [Person(name: "James", age: 32), + Person(name: "Rose", age: 29), + Person(name: "Wade", age: 36)]) + + // Testing Mutating Optional keyPath + mutableArray.sort(by: \Person.age) + XCTAssertEqual(mutableArray, [Person(name: "Rose", age: 29), + Person(name: "James", age: 32), + Person(name: "Wade", age: 36)]) + + // Testing nil path + let nilArray = [Person(name: "James", age: nil), Person(name: "Wade", age: nil)] + XCTAssertEqual(nilArray.sorted(by: \Person.age), [Person(name: "James", age: nil), + Person(name: "Wade", age: nil)]) + } } From ff0277bd6d84844f332f41140c8bdfa602f63933 Mon Sep 17 00:00:00 2001 From: Nathan Gelman Date: Tue, 2 Jan 2018 10:22:31 -0800 Subject: [PATCH 095/201] Applying attributes to regex patterns and substrings (#341) --- CHANGELOG.md | 3 + .../NSAttributedStringExtensions.swift | 32 +++++++ .../NSAttributedStringExtensionsTests.swift | 86 ++++++++++++++++++- 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5e29f78..3a25b4a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,9 @@ N/A - `sort(by: KeyPath)` and `sorted(by: KeyPath)` to sort arrays based on Swift 4 keyPath. [#343](https://github.com/SwifterSwift/SwifterSwift/pull/343) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - New **String** extensions: - added `loremIpsum(ofLength: )` static function to return a lorem ipsum string. [#318](https://github.com/SwifterSwift/SwifterSwift/issues/318) by [omaralbeik](https://github.com/omaralbeik). +- New **NSAttributedString** extensions: + - added `applying(attributes: , toRangesMatching: )` function to return an attributed string with attributes applied to substrings matching the passed regex pattern by [nathanbacon](https://github.com/nathanbacon). + - added `applying(attributes: , toOccurrencesOf: )` function to return an attributed string with attributes applied to substrings matching the passed string by [nathanbacon](https://github.com/nathanbacon). - New **UIDatePicker** extensions: - added `textColor` to get and set the text color of a UIDatePicker. [#328](https://github.com/SwifterSwift/SwifterSwift/issues/328) by [omaralbeik](https://github.com/omaralbeik). - New **NSImage** extensions: diff --git a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift index cfab61f28..7c0903b26 100644 --- a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift @@ -78,6 +78,38 @@ public extension NSAttributedString { return applying(attributes: [.foregroundColor: color]) } #endif + + /// SwifterSwift: Apply attributes to substrings matching a regular expression + /// + /// - Parameters: + /// - attributes: Dictionary of attributes + /// - pattern: a regular expression to target + /// - Returns: An NSAttributedString with attributes applied to substrings matching the pattern + public func applying(attributes: [NSAttributedStringKey: Any], toRangesMatching pattern: String) -> NSAttributedString { + guard let pattern = try? NSRegularExpression(pattern: pattern, options: []) else { return self } + + let matches = pattern.matches(in: string, options: [], range: NSRange(0..(attributes: [NSAttributedStringKey: Any], toOccurrencesOf target: T) -> NSAttributedString { + let pattern = "\\Q\(target)\\E" + + return applying(attributes: attributes, toRangesMatching: pattern) + } + } // MARK: - Operators diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index 8771d5314..50878cdba 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -82,8 +82,92 @@ final class NSAttributedStringExtensionsTests: XCTestCase { XCTAssertEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, UIColor.blue) XCTAssertNotEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, .red) } + #endif - + + #if !os(macOS) && !os(tvOS) + func testApplyingToRegex() { + let email = "steve.jobs@apple.com" + let testString = NSAttributedString(string: "Your email is \(email)!").bolded + let attributes: [NSAttributedStringKey: Any] = [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, .foregroundColor: UIColor.blue] + let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" + + let attrTestString = testString.applying(attributes: attributes, toRangesMatching: pattern) + + let attrAtBeginning = attrTestString.attributes(at: 0, effectiveRange: nil) + XCTAssert(attrAtBeginning.count == 1) + + var passed = false + // iterate through each range of attributes + attrTestString.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } + + // confirm that the string with the applied attributes is the email + XCTAssertEqual(emailFromRange, email) + + // the range contains the email, check to make sure the attributes are there and correct + for attr in attrs { + if attr.key == .underlineStyle { + XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) + passed = true + } else if attr.key == .foregroundColor { + XCTAssertEqual(attr.value as? UIColor, UIColor.blue) + passed = true + } else if attr.key == .font { + XCTAssertEqual((attr.value as? UIFont), .boldSystemFont(ofSize: UIFont.systemFontSize)) + } else { + passed = false + } + } + + XCTAssert(passed) + } + } + + func testApplyingToOccurrences() { + let name = "Steve Wozniak" + let greeting = "Hello, \(name)." + let attrGreeting = NSAttributedString(string: greeting).italicized.applying( + attributes: [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, + .foregroundColor: UIColor.red], toOccurrencesOf: name) + + let attrAtBeginning = attrGreeting.attributes(at: 0, effectiveRange: nil) + // assert that there is only one attribute at beginning from italics + XCTAssertEqual(attrAtBeginning.count, 1) + + var passed = false + // iterate through each range of attributes + attrGreeting.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } + + // confirm that the attributed string is the name + let stringAtRange = attrGreeting.attributedSubstring(from: range).string + XCTAssertEqual(stringAtRange, name) + + for attr in attrs { + if attr.key == .underlineStyle { + XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) + passed = true + } else if attr.key == .foregroundColor { + XCTAssertEqual(attr.value as? UIColor, UIColor.red) + passed = true + } else if attr.key == .font { + XCTAssertEqual((attr.value as? UIFont), .italicSystemFont(ofSize: UIFont.systemFontSize)) + } else { + passed = false + } + } + } + + XCTAssert(passed) + } + #endif + #if !os(macOS) && !os(tvOS) // MARK: - Operators func testAppending() { From d15761afa942a1dd0b46ea2dec1e1c6b352e4e7a Mon Sep 17 00:00:00 2001 From: yycking Date: Wed, 3 Jan 2018 02:24:58 +0800 Subject: [PATCH 096/201] Add operators for NSPredicate (#345) --- .../Foundation/NSPredicateExtensions.swift | 41 +++++++++++++++++++ .../NSPredicateExtensionsTests.swift | 37 +++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/Sources/Extensions/Foundation/NSPredicateExtensions.swift b/Sources/Extensions/Foundation/NSPredicateExtensions.swift index 81a07cc93..57f309b7d 100644 --- a/Sources/Extensions/Foundation/NSPredicateExtensions.swift +++ b/Sources/Extensions/Foundation/NSPredicateExtensions.swift @@ -38,3 +38,44 @@ public extension NSPredicate { } } + +// MARK: - Operators +public extension NSPredicate { + + /// SwifterSwift: Returns a new predicate formed by NOT-ing the predicate. + /// - Parameters: rhs: NSPredicate to convert. + /// - Returns: NSCompoundPredicate + static public prefix func ! (rhs: NSPredicate) -> NSCompoundPredicate { + return rhs.not + } + + /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. + /// + /// - Parameters: + /// - lhs: NSPredicate. + /// - rhs: NSPredicate. + /// - Returns: NSCompoundPredicate + static public func + (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { + return lhs.and(rhs) + } + + /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. + /// + /// - Parameters: + /// - lhs: NSPredicate. + /// - rhs: NSPredicate. + /// - Returns: NSCompoundPredicate + static public func | (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { + return lhs.or(rhs) + } + + /// SwifterSwift: Returns a new predicate formed by remove the argument to the predicate. + /// + /// - Parameters: + /// - lhs: NSPredicate. + /// - rhs: NSPredicate. + /// - Returns: NSCompoundPredicate + static public func - (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { + return lhs + !rhs + } +} diff --git a/Tests/FoundationTests/NSPredicateExtensionsTests.swift b/Tests/FoundationTests/NSPredicateExtensionsTests.swift index 2ee901dc3..16ea01864 100644 --- a/Tests/FoundationTests/NSPredicateExtensionsTests.swift +++ b/Tests/FoundationTests/NSPredicateExtensionsTests.swift @@ -39,4 +39,41 @@ final class NSPredicateExtensionsTests: XCTestCase { XCTAssertEqual(subpredicates, [predicate1, predicate2]) } } + + func testOperatorNot() { + let predicate = NSPredicate(format: "a < 7") + let notPredicate = !predicate + XCTAssert(notPredicate.compoundPredicateType == .not) + if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate]) + } + } + + func testOperatorAndPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let andPredicate = predicate1 + predicate2 + XCTAssert(andPredicate.compoundPredicateType == .and) + if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOperatorOrPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let orPredicate = predicate1 | predicate2 + XCTAssert(orPredicate.compoundPredicateType == .or) + if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOperatorSubPredicate() { + let predicate1 = NSPredicate(format: "SELF BETWEEN{1,5}") + let predicate2 = NSPredicate(format: "SELF BETWEEN{3,6}") + let subPredicate = predicate1 - predicate2 + XCTAssert(subPredicate.evaluate(with: 2)) + XCTAssertFalse(subPredicate.evaluate(with: 4)) + } } From 215516a6c8e81b32eac34b82fd295170b2aaf775 Mon Sep 17 00:00:00 2001 From: Rich Gabrielli Date: Tue, 2 Jan 2018 16:47:35 -0500 Subject: [PATCH 097/201] Update copyright date to 2018 (#351) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4caea1348..8e34515c0 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2015-2017 SwifterSwift (https://github.com/swifterswift) +Copyright (c) 2015-2018 SwifterSwift (https://github.com/swifterswift) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 65f87a79fa940d60b7c30f7b1b0f39e853d084f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Najdan=20Tomi=C4=87?= Date: Thu, 4 Jan 2018 13:19:18 +0100 Subject: [PATCH 098/201] Renamed indexes(of:) to indices(of:) in ArrayExtension (#355) --- CHANGELOG.md | 3 +- Examples/Examples.md | 4 +-- .../SwiftStdlib/ArrayExtensions.swift | 32 +++++++++---------- .../Deprecated/SwiftStdlibDeprecated.swift | 20 ++++++++++++ .../ArrayExtensionsTests.swift | 5 +++ 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a25b4a35..1a17857e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ All notable changes to this project will be documented in this file. # Next Release ### API Breaking -N/A +- **Array** + - `indexes(of:)` has been renamed to `indices(of:)`. ### Enhancements - New **NSAttributedString** diff --git a/Examples/Examples.md b/Examples/Examples.md index a558f4a84..346890cfa 100644 --- a/Examples/Examples.md +++ b/Examples/Examples.md @@ -10,8 +10,8 @@ Here are some examples: // Remove duplicates from an array [1, 2, 3, 1, 3].removeDuplicates() -> [1, 2, 3] -// Return all indexes of specified item -["h", "e", "l", "l", "o"].indexes(of: "l") -> [2, 3] +// Return all indices of specified item +["h", "e", "l", "l", "o"].indices(of: "l") -> [2, 3] // Shuffle an array ["h", "e", "l", "l", "o"].shuffled() -> ["e", "l", "o", "l", "h"] diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 60fb7b4aa..e0f9c10f7 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -496,22 +496,22 @@ public extension Array where Element: Equatable { } return found } - - /// SwifterSwift: All indexes of specified item. - /// - /// [1, 2, 2, 3, 4, 2, 5].indexes(of 2) -> [1, 2, 5] - /// [1.2, 2.3, 4.5, 3.4, 4.5].indexes(of 2.3) -> [1] - /// ["h", "e", "l", "l", "o"].indexes(of "l") -> [2, 3] - /// - /// - Parameter item: item to check. - /// - Returns: an array with all indexes of the given item. - public func indexes(of item: Element) -> [Int] { - var indexes: [Int] = [] - for index in startIndex.. [1, 2, 5] + /// [1.2, 2.3, 4.5, 3.4, 4.5].indices(of 2.3) -> [1] + /// ["h", "e", "l", "l", "o"].indices(of "l") -> [2, 3] + /// + /// - Parameter item: item to check. + /// - Returns: an array with all indices of the given item. + public func indices(of item: Element) -> [Int] { + var indices: [Int] = [] + for index in startIndex.. [1, 2, 5] + /// [1.2, 2.3, 4.5, 3.4, 4.5].indexes(of 2.3) -> [1] + /// ["h", "e", "l", "l", "o"].indexes(of "l") -> [2, 3] + /// + /// - Parameter item: item to check. + /// - Returns: an array with all indexes of the given item. + @available(*, deprecated: 4.1.1, message: "Use indices(of:) instead", renamed: "indices(of:)") + public func indexes(of item: Element) -> [Int] { + var indexes: [Int] = [] + for index in startIndex.. Date: Thu, 4 Jan 2018 16:01:37 +0300 Subject: [PATCH 099/201] Changelog guidelines (#353) --- .github/PULL_REQUEST_TEMPLATE.md | 1 + CHANGELOG.md | 83 +++++++++++++++++++------------- CHANGELOG_GUIDELINES.md | 71 +++++++++++++++++++++++++++ CONTRIBUTING.md | 9 ++++ README.md | 4 ++ 5 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 CHANGELOG_GUIDELINES.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 356340151..fcc0a732f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,3 +9,4 @@ - [ ] I have added tests for new extensions, and they passed. - [ ] All extensions have a **clear** comments explaining their functionality, all parameters and return type in English. - [ ] All extensions are declared as **public**. +- [ ] I have added a changelog entry describing my changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a17857e5..dc40b9499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,52 +1,67 @@ # CHANGELOG -SwifterSwift adheres to [Semantic Versioning](http://semver.org/) for all versions after v1.6.4. +The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. -All notable changes to this project will be documented in this file. - -# Versions +--- -> # Next Release +> # Upcoming release +> +> ### Added +> +> ### Changed +> +> ### Deprecated > -> ### API Breaking -> N/A +> ### Removed > -> ### Enhancements -> N/A +> ### Fixed > -> ### Bugfixes -> N/A +> ### Security -# Next Release +--- -### API Breaking +## [v4.1.1](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.1.1) + +### Added +- **NSPredicate** + - Added operator `!` to return a new predicate formed by NOT-ing a given predicate. + - Added operator `+` to return a new predicate formed by AND-ing two given predicates. + - Added operator `|` to return a new predicate formed by OR-ing a two given predicates. + - Added operator `-` to return a new predicate formed by removing the argument from the second predicate. [#345](https://github.com/SwifterSwift/SwifterSwift/pull/345) by [yycking](https://github.com/yycking). +- **NSAttributedString** + - Added `attributes` property to get the attributes that apply to a simple NSAttributedString. [#333](https://github.com/SwifterSwift/SwifterSwift/issues/333) by [nathanbacon](https://github.com/nathanbacon). + - Added `applying(attributes: , toRangesMatching: )` function to return an attributed string with attributes applied to substrings matching the passed regex pattern by [nathanbacon](https://github.com/nathanbacon). + - Added `applying(attributes: , toOccurrencesOf: )` function to return an attributed string with attributes applied to substrings matching the passed string by [nathanbacon](https://github.com/nathanbacon). - **Array** - - `indexes(of:)` has been renamed to `indices(of:)`. + - Added `sort(by: KeyPath)` and `sorted(by: KeyPath)` to sort arrays based on Swift 4 keyPath. [#343](https://github.com/SwifterSwift/SwifterSwift/pull/343) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **String** + - Added `loremIpsum(ofLength: )` static function to return a lorem ipsum string. [#318](https://github.com/SwifterSwift/SwifterSwift/issues/318) by [omaralbeik](https://github.com/omaralbeik). +- **UIDatePicker** + - Added `textColor` to get and set the text color of a UIDatePicker. [#328](https://github.com/SwifterSwift/SwifterSwift/issues/328) by [omaralbeik](https://github.com/omaralbeik). +- **NSImage** + - Added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). +- **Date** + - Added `random(from: Date, upTo: Date) -> Date` method that return radom date in in the specified range [#336](https://github.com/SwifterSwift/SwifterSwift/pull/336) by [akuzminskyi](https://github.com/akuzminskyi). + - Added `string(withFormat format: String)` method to get a string from a date with the given format. + - Added `init?(integerLiteral value: Int)` initializer to create date object from Int literal. [#342](https://github.com/SwifterSwift/SwifterSwift/pull/342) by [n0an](https://github.com/n0an). -### Enhancements -- New **NSAttributedString** - - added `attributes' property to get the attributes that apply to a simple NSAttributedString [#333](https://github.com/SwifterSwift/SwifterSwift/issues/333) by [nathanbacon](https://github.com/nathanbacon). -- Enhanced **Array** extensions: +### Changed + +- **Array** + - **Breaking Change** `indexes(of:)` has been renamed to `indices(of:)`. [#355](https://github.com/SwifterSwift/SwifterSwift/pull/355) by [](https://github.com/Najdan) - `shuffle` and `shuffled` are no more constrained to Equatable. [#327](https://github.com/SwifterSwift/SwifterSwift/pull/327) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -- New **Array** extensions: - - `sort(by: KeyPath)` and `sorted(by: KeyPath)` to sort arrays based on Swift 4 keyPath. [#343](https://github.com/SwifterSwift/SwifterSwift/pull/343) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -- New **String** extensions: - - added `loremIpsum(ofLength: )` static function to return a lorem ipsum string. [#318](https://github.com/SwifterSwift/SwifterSwift/issues/318) by [omaralbeik](https://github.com/omaralbeik). -- New **NSAttributedString** extensions: - - added `applying(attributes: , toRangesMatching: )` function to return an attributed string with attributes applied to substrings matching the passed regex pattern by [nathanbacon](https://github.com/nathanbacon). - - added `applying(attributes: , toOccurrencesOf: )` function to return an attributed string with attributes applied to substrings matching the passed string by [nathanbacon](https://github.com/nathanbacon). -- New **UIDatePicker** extensions: - - added `textColor` to get and set the text color of a UIDatePicker. [#328](https://github.com/SwifterSwift/SwifterSwift/issues/328) by [omaralbeik](https://github.com/omaralbeik). -- New **NSImage** extensions: - - added `write(to url: URL, fileType type: _, compressionFactor: _)` to write NSImage to url. [#320](https://github.com/SwifterSwift/SwifterSwift/pulls/320) by [omaralbeik](https://github.com/omaralbeik). -- New **Date** extensions - - added `random(from: Date, upTo: Date) -> Date` method that return radom date in in the specified range [#336](https://github.com/SwifterSwift/SwifterSwift/pull/336) by [akuzminskyi](https://github.com/akuzminskyi). - - added `string(withFormat format: String)` method to get a string from a date with the given format -### Bugfixes -N/A +### Fixed +- **Int** + - Fixed where the base in `isPrime()` was not correct. [#323](https://github.com/SwifterSwift/SwifterSwift/pull/323) by [Asura19](https://github.com/Asura19). +- **UINavigationBar** + - Fixed a bug where makeTransparent was keeping the background color. [#344](https://github.com/SwifterSwift/SwifterSwift/issues/344) by [omaralbeik](https://github.com/omaralbeik). +- **Continuous Integration** + - Fixed swiftlint warning in `NSImageExtensions`. + +--- # v4.1.0 diff --git a/CHANGELOG_GUIDELINES.md b/CHANGELOG_GUIDELINES.md new file mode 100644 index 000000000..3be2c7910 --- /dev/null +++ b/CHANGELOG_GUIDELINES.md @@ -0,0 +1,71 @@ +# Changelog Guidelines + +Here you can find the general guidelines for maintaining the Changelog (or adding new entries). We follow the guidelines from [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) with few additions. + +## Guiding Principles +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each versions is displayed. +- Mention whether you follow Semantic Versioning. + +... with the following **SwifterSwift** specific additions: +- Keep an unreleased section at the top. +- Each release title should link to release's page. +- Add PR number and a GitHub tag at the end of each entry. +- Each breaking change entry should have **Breaking Change** label at the beginning of this entry. +- **Breaking Change** entries should be placed at the top of the section it's in. +- Entries under each category should be grouped by the type they extend. + +## Types of changes +- **Added** for new features. +- **Changed** for changes in existing functionality. +- **Deprecated** for soon-to-be removed features. +- **Removed** for now removed features. +- **Fixed** for any bug fixes. +- **Security** in case of vulnerabilities. + +--- + +## Example: + + +## [v4.1.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.1.0) - Nov 16, 2017 + +### Added + +- **UIDatePicker** + - Added `textColor` property to set and get text color of UIDatePicker. [#335](https://github.com/SwifterSwift/SwifterSwift/pull/335) by [@omaralbeik](https://github.com/omaralbeik). +- **Continuous Integration** + - Added **Danger** to continuous integration. [#252](https://github.com/SwifterSwift/SwifterSwift/pull/252) by [SD10](https://github.com/SD10). + + +### Changed + +- **Date** + - **Breaking Change** The property `weekday` is now a get-only property. [#313](https://github.com/SwifterSwift/SwifterSwift/pull/313) by [kaphacius](https://github.com/kaphacius). + +- **Array** + - `shuffle` and `shuffled` are no more constrained to Equatable. [#327](https://github.com/SwifterSwift/SwifterSwift/pull/327) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). + + +### Deprecated + +- **String** + - `reversed() -> String` is deprecated in favor of Swift 4 new `reversed() -> ReversedCollection`. [#305](https://github.com/SwifterSwift/SwifterSwift/pull/305) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **Date** + - `isInThisWeek` has been renamed to `isInCurrentWeek`. + + +### Removed + +- **UIViewController** + - **Breaking Change** Removed `navigationBar` that was causing iOS apps to crash, thanks to drewpitchford for reporting in [#243](https://github.com/SwifterSwift/SwifterSwift/issues/243). by [drewpitchford](https://github.com/drewpitchford) + + +### Fixed + +- **Tests** + - Fixed a bug where `XCTAssertNotNil` could not handle optionals. [#188](https://github.com/SwifterSwift/SwifterSwift/pull/188). by [omaralbeik](https://github.com/omaralbeik) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0ba9c926..de15e9610 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,6 +8,7 @@ This document contains information and guidelines about contributing to this pro - [Ways to Contribute](#ways-to-contribute) - [Adding new Extensions](#adding-new-extensions) - [Adding documentation](#adding-documentation) +- [Adding changelog entries](#adding-changelog-entries) - [Reporting Issues](#reporting-issues) --- @@ -166,6 +167,14 @@ public func changing(_ component: Calendar.Component, value: Int) -> Date? { In Xcode select a method and press `command` + `alt` + `/` to create a documentation template! +--- + +## Adding changelog entries + +The [Changelog](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md) is a file which contains a curated, chronologically ordered list of notable changes for each version of a project. Please make sure to add a changelog entry describing your contribution to it everyting there is a notable change. + +The [Changelog Guidelines](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG_GUIDELINES.md) contains instructions for maintaining (or adding new entries) to the Changelog. + --- ## Reporting Issues diff --git a/README.md b/README.md index fd65abe48..18c0ebb7b 100755 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ let package = Package( Foundation Extensions
    -
    CoreLocation Extensions
    @@ -201,6 +200,14 @@ let package = Package(
    +
    +MapKit Extensions +
    +
    +
    +
    Misc. Extensions @@ -254,4 +261,4 @@ Special thanks to: ## License -SwifterSwift is released under an MIT license. See [LICENSE](LICENSE) for more information. \ No newline at end of file +SwifterSwift is released under an MIT license. See [LICENSE](LICENSE) for more information. diff --git a/Sources/Info.plist b/Sources/Info.plist index a875ff9ec..dbe38e952 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.1.1 + 4.2.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index da43da83f..c5d6911b2 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwifterSwift' - s.version = '4.1.1' + s.version = '4.2.0' s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 3f0c28d13..1b8e49c87 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -337,9 +337,6 @@ 784C752F2051BD26001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 784C75302051BD4A001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 784C75312051BD4B001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; - 784C75332051BDF0001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; - 784C75342051BDF1001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; - 784C75352051BDF1001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 784C75372051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75382051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75392051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; From 2f2b002aa2805da6dbb5ca55709dedd3fef6a9f8 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 22 Mar 2018 01:41:12 -0300 Subject: [PATCH 130/201] Fix UIView.addShadow extension. (#420) * Fixing UIView.addShadow() extension not adding shadow. * Adding changelog. * Add PR info on changelog. --- CHANGELOG.md | 6 +++++- Sources/Extensions/UIKit/UIViewExtensions.swift | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8444a02e0..0675a33e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,11 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > ### Changed > ### Deprecated > ### Removed -> ### Fixed +> +### Fixed +- **String** + - Fixed UIView extension `addShadow` was not showing the shadow on view bug. [#420](https://github.com/SwifterSwift/SwifterSwift/pull/420) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). + > ### Security --- diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 7f9b9a5d1..9bbd83ce0 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -247,14 +247,14 @@ public extension UIView { layer.shadowOffset = offset layer.shadowRadius = radius layer.shadowOpacity = opacity - layer.masksToBounds = true + layer.masksToBounds = false } /// SwifterSwift: Add array of subviews to view. /// /// - Parameter subviews: array of subviews to add to self. public func addSubviews(_ subviews: [UIView]) { - subviews.forEach({self.addSubview($0)}) + subviews.forEach({ self.addSubview($0) }) } /// SwifterSwift: Fade in view. @@ -297,7 +297,7 @@ public extension UIView { /// SwifterSwift: Remove all subviews in view. public func removeSubviews() { - subviews.forEach({$0.removeFromSuperview()}) + subviews.forEach({ $0.removeFromSuperview() }) } /// SwifterSwift: Remove all gesture recognizers from view. From c260de9326e439282b7825bc2881237e3a58c933 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 1 Apr 2018 13:06:49 +0300 Subject: [PATCH 131/201] String extensions (#430) * StringExtensions.swift: Added public var isSpelledCorrectly: Bool * StringExtensions: added methods deletingPrefix(), deletingSuffix() * PR #430 updated: CHANGELOG updated deletingPrefix, deletingSuffix renamed to removingPrefix, removingSuffix OS preprocessor condition added for isSpelledCorrectly property * CHANGELOG entries fixed. #if os(tvOS) added for testIsSpelledCorrectly() --- CHANGELOG.md | 9 +++-- .../SwiftStdlib/StringExtensions.swift | 34 +++++++++++++++++-- .../StringExtensionsTests.swift | 21 +++++++++++- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0675a33e5..3ac7f839c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,12 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S --- > # Upcoming release > -> ### Added +### Added +- **String** + - added computed property `isSpelledCorrectly` to check if the given string has typos or not. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). + - added `removingPrefix(_ prefix:)` method to remove given prefix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). + - added `removingSuffix(_ suffix:)` method to remove given suffix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). + > ### Changed > ### Deprecated > ### Removed @@ -61,7 +66,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **String** - Fixed `isNumeric` to check if string is a valid Swift number and added isDigits to check if string only contains digits. [#396](https://github.com/SwifterSwift/SwifterSwift/pull/396) by [seifeet](https://github.com/seifeet). -- **Collection** +- **Collection** - Fixed `randomItem` crash with empty array. [#405](https://github.com/SwifterSwift/SwifterSwift/pull/405) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). --- diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index d4ea84ad7..9cfa28097 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -338,6 +338,16 @@ public extension String { public var isWhitespace: Bool { return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } + #if os(iOS) || os(tvOS) + /// SwifterSwift: Check if the given string spelled correctly + public var isSpelledCorrectly: Bool { + let checker = UITextChecker() + let range = NSRange(location: 0, length: self.utf16.count) + + let misspelledRange = checker.rangeOfMisspelledWord(in: self, range: range, startingAt: 0, wrap: false, language: Locale.preferredLanguages.first ?? "en") + return misspelledRange.location == NSNotFound + } + #endif } // MARK: - Methods @@ -856,7 +866,28 @@ public extension String { return self + padding[padding.startIndex.. "World!" + /// + /// - Parameter prefix: Prefix to remove from the string. + /// - Returns: The string after prefix removing. + public func removingPrefix(_ prefix: String) -> String { + guard self.hasPrefix(prefix) else { return self } + return String(self.dropFirst(prefix.count)) + } + + /// SwifterSwift: Removes given suffix from the string. + /// + /// "Hello, World!".removingSuffix(", World!") -> "Hello" + /// + /// - Parameter suffix: Suffix to remove from the string. + /// - Returns: The string after suffix removing. + public func removingSuffix(_ suffix: String) -> String { + guard self.hasSuffix(suffix) else { return self } + return String(self.dropLast(suffix.count)) + } } // MARK: - Operators @@ -1014,5 +1045,4 @@ public extension String { public func appendingPathExtension(_ str: String) -> String? { return (self as NSString).appendingPathExtension(str) } - } diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 2aa2c53fe..9a3e28e04 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -304,7 +304,6 @@ final class StringExtensionsTests: XCTestCase { func testFloat() { XCTAssertNotNil("8".float()) XCTAssertEqual("8".float(), 8) - XCTAssertNotNil("8.23".float(locale: Locale(identifier: "en_US_POSIX"))) XCTAssertEqual("8.23".float(locale: Locale(identifier: "en_US_POSIX")), Float(8.23)) @@ -684,4 +683,24 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(str.isWhitespace, true) } + #if os(iOS) || os(tvOS) + func testIsSpelledCorrectly() { + let strCorrect = "Hello, World!" + + XCTAssertTrue(strCorrect.isSpelledCorrectly) + + let strNonCorrect = "Helol, Wrold!" + XCTAssertFalse(strNonCorrect.isSpelledCorrectly) + } + #endif + + func testRemovingPrefix() { + let inputStr = "Hello, World!" + XCTAssertEqual(inputStr.removingPrefix("Hello, "), "World!") + } + + func testRemovingSuffix() { + let inputStr = "Hello, World!" + XCTAssertEqual(inputStr.removingSuffix(", World!"), "Hello") + } } From f343e38c8c65124a4a08f882a01db2b4dfdb7833 Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Thu, 5 Apr 2018 16:12:41 -0500 Subject: [PATCH 132/201] No Brown M&M's (#431) * No Brown M&M's * Add short code and emoji --- CONTRIBUTING.md | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dedfc9656..0dafacccc 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,31 @@ This also allows us to focus on improving the project for others. --- +## Reporting Issues +A great way to contribute to the project is to send a detailed issue when you encounter an problem. +We always appreciate a well-written, thorough bug report. + +Check that the project issues database doesn't already include that problem or suggestion before submitting an issue. +If you find a match, add a quick "**+1**" or "**I have this problem too**". +Doing this helps prioritize the most common problems and requests. + +--- + +**When reporting issues, please include the following:** + +- What did you do? +- What did you expect to happen? +- What happened instead? +- SwifterSwift version +- Xcode version +- macOS version running Xcode +- Swift version +- Platform(s) running SwifterSwift +- Demo Project (if available) + +This information will help us review and fix your issue faster. + + ## Ways to Contribute @@ -186,25 +211,6 @@ The [Changelog Guidelines](https://github.com/SwifterSwift/SwifterSwift/blob/mas --- -## Reporting Issues -A great way to contribute to the project is to send a detailed issue when you encounter an problem. -We always appreciate a well-written, thorough bug report. - -Check that the project issues database doesn't already include that problem or suggestion before submitting an issue. -If you find a match, add a quick "**+1**" or "**I have this problem too**". -Doing this helps prioritize the most common problems and requests. - - -**When reporting issues, please include the following:** +## [No Brown M&M's](http://en.wikipedia.org/wiki/Van_Halen#Contract_riders) -- What did you do? -- What did you expect to happen? -- What happened instead? -- SwifterSwift version -- Xcode version -- macOS version running Xcode -- Swift version -- Platform(s) running SwifterSwift -- Demo Project (if available) - -This information will help us review and fix your issue faster. +If you made it all the way to the end, bravo dear user, we love you. You can include the 🚀 emoji in the top of your ticket to signal to us that you did in fact read this file and are trying to conform to it as best as possible: `:rocket:`. From cf6f301f7c8f798314f9d8fa05cbccc7cff1bcb5 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 6 Apr 2018 03:55:36 -0300 Subject: [PATCH 133/201] [WIP] Xcode 9.3 Swift 4.1 suport. (#428) --- .swift-version | 2 +- .swiftlint.yml | 8 +- .travis.yml | 3 +- CHANGELOG.md | 58 +- README.md | 5 +- .../Extensions/AppKit/NSImageExtensions.swift | 26 +- .../Extensions/AppKit/NSViewExtensions.swift | 31 +- .../CoreGraphics/CGColorExtensions.swift | 25 +- .../CoreGraphics/CGFloatExtensions.swift | 40 +- .../CoreGraphics/CGPointExtensions.swift | 42 +- .../CoreGraphics/CGSizeExtensions.swift | 26 +- .../CoreLocation/CLLocationExtensions.swift | 35 +- .../Foundation/CalendarExtensions.swift | 8 +- .../Foundation/DataExtensions.swift | 10 +- .../Foundation/DateExtensions.swift | 209 +-- .../Deprecated/FoundationDeprecated.swift | 10 +- .../Foundation/FileManagerExtensions.swift | 91 +- .../Foundation/LocaleExtensions.swift | 6 +- .../NSAttributedStringExtensions.swift | 68 +- .../Foundation/NSPredicateExtensions.swift | 22 +- .../Extensions/Foundation/URLExtensions.swift | 91 +- .../Foundation/URLRequestExtensions.swift | 6 +- .../Foundation/UserDefaultsExtensions.swift | 63 +- .../MapKit/MKPolylineExtensions.swift | 15 +- .../Extensions/Shared/ColorExtensions.swift | 1337 +++++++++-------- .../SwiftStdlib/ArrayExtensions.swift | 261 ++-- .../SwiftStdlib/BoolExtensions.swift | 32 +- .../SwiftStdlib/CharacterExtensions.swift | 52 +- .../SwiftStdlib/CollectionExtensions.swift | 38 +- .../Deprecated/SwiftStdlibDeprecated.swift | 134 +- .../SwiftStdlib/DictionaryExtensions.swift | 342 +++-- .../SwiftStdlib/DoubleExtensions.swift | 14 +- .../SwiftStdlib/FloatExtensions.swift | 22 +- .../SwiftStdlib/FloatingPointExtensions.swift | 32 +- .../SwiftStdlib/IntExtensions.swift | 107 +- .../SwiftStdlib/OptionalExtensions.swift | 16 +- .../SwiftStdlib/SequenceExtensions.swift | 44 + .../SwiftStdlib/SignedIntegerExtensions.swift | 24 +- .../SwiftStdlib/SignedNumericExtensions.swift | 13 +- .../SwiftStdlib/StringExtensions.swift | 563 ++++--- .../StringProtocolExtensions.swift | 4 +- Sources/Extensions/SwifterSwift.swift | 109 +- .../UIKit/Deprecated/UIKitDeprecated.swift | 27 + .../UIKit/UIAlertControllerExtensions.swift | 34 +- .../UIKit/UIBarButtonItemExtensions.swift | 9 +- .../Extensions/UIKit/UIButtonExtensions.swift | 43 +- .../UIKit/UICollectionViewExtensions.swift | 37 +- .../UIKit/UIDatePickerExtensions.swift | 9 +- .../Extensions/UIKit/UIFontExtensions.swift | 12 +- .../Extensions/UIKit/UIImageExtensions.swift | 46 +- .../UIKit/UIImageViewExtensions.swift | 15 +- .../Extensions/UIKit/UILabelExtensions.swift | 11 +- .../UIKit/UINavigationBarExtensions.swift | 13 +- .../UINavigationControllerExtensions.swift | 13 +- .../UIKit/UINavigationItemExtensions.swift | 9 +- .../UIKit/UISearchBarExtensions.swift | 15 +- .../UIKit/UISegmentedControlExtensions.swift | 15 +- .../Extensions/UIKit/UISliderExtensions.swift | 9 +- .../UIKit/UIStackViewExtensions.swift | 10 +- .../UIKit/UIStoryboardExtensions.swift | 23 +- .../Extensions/UIKit/UISwitchExtensions.swift | 9 +- .../Extensions/UIKit/UITabBarExtensions.swift | 45 +- .../UIKit/UITableViewExtensions.swift | 47 +- .../UIKit/UITextFieldExtensions.swift | 38 +- .../UIKit/UITextViewExtensions.swift | 14 +- .../UIKit/UIViewControllerExtensions.swift | 20 +- .../Extensions/UIKit/UIViewExtensions.swift | 108 +- Sources/Info.plist | 2 +- SwifterSwift.podspec | 4 +- SwifterSwift.xcodeproj/project.pbxproj | 62 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/SwifterSwift-iOS.xcscheme | 7 +- .../xcschemes/SwifterSwift-macOS.xcscheme | 6 +- .../xcschemes/SwifterSwift-tvOS.xcscheme | 7 +- .../xcschemes/SwifterSwift-watchOS.xcscheme | 3 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../AppKitTests/NSImageExtensionsTests.swift | 24 +- Tests/AppKitTests/NSViewExtensionsTests.swift | 40 +- .../CGColorExtensionsTests.swift | 36 +- .../CGFloatExtensionsTests.swift | 82 +- .../CGPointExtensionsTests.swift | 22 +- .../CGSizeExtensionsTests.swift | 6 +- .../CLLocationExtensionsTests.swift | 29 +- .../CalendarExtensionTest.swift | 8 +- .../FoundationTests/DataExtensionsTests.swift | 5 +- .../FoundationTests/DateExtensionsTests.swift | 470 +++--- .../FileManagerExtensionsTests.swift | 124 +- .../LocaleExtensionsTests.swift | 10 +- .../NSAttributedStringExtensionsTests.swift | 231 +-- .../NSPredicateExtensionsTests.swift | 132 +- .../FoundationTests/URLExtensionsTests.swift | 53 +- .../URLRequestExtensionsTests.swift | 7 +- .../UserDefaultsExtensionsTests.swift | 50 +- Tests/MapKitTests/MKPolylineTests.swift | 2 + Tests/SharedTests/ColorExtensionsTests.swift | 371 +++-- .../ArrayExtensionsTests.swift | 422 +++--- .../BoolExtensionsTests.swift | 41 +- .../CharacterExtensionsTests.swift | 93 +- .../CollectionExtensionsTests.swift | 24 +- .../DictionaryExtensionsTests.swift | 100 +- .../DoubleExtensionsTests.swift | 104 +- .../FloatExtensionsTests.swift | 104 +- .../FloatingPointExtensionsTests.swift | 93 ++ .../SwiftStdlibTests/IntExtensionsTests.swift | 276 ++-- .../OptionalExtensionsTests.swift | 68 +- .../SequenceExtensionsTests.swift | 28 + .../SignedIntegerExtensionsTests.swift | 60 + .../SignedNumericExtensionsTests.swift | 41 +- .../StringExtensionsTests.swift | 1180 ++++++++------- .../StringProtocolExtensionsTests.swift | 6 +- Tests/SwifterSwiftTests.swift | 8 +- .../UIAlertControllerExtensionsTests.swift | 71 +- .../UIBarButtonExtensionsTests.swift | 16 +- .../UIKitTests/UIButtonExtensionsTests.swift | 93 +- .../UICollectionViewExtensionsTests.swift | 50 +- .../UIDatePickerExtensionsTests.swift | 10 +- Tests/UIKitTests/UIFontExtensionsTest.swift | 39 +- Tests/UIKitTests/UIImageExtensionsTests.swift | 61 +- .../UIImageViewExtensionsTests.swift | 30 +- Tests/UIKitTests/UILabelExtensionsTests.swift | 42 +- .../UINavigationBarExtensionTests.swift | 75 +- ...INavigationControllerExtensionsTests.swift | 63 +- .../UINavigationItemExtensionsTests.swift | 35 +- .../UISearchBarExtensionsTests.swift | 10 +- .../UISegmentedControlExtensionsTests.swift | 31 +- .../UIKitTests/UISliderExtensionsTests.swift | 82 +- .../UIStackViewExtensionsTest.swift | 65 +- .../UIStoryboardExtensionsTests.swift | 17 +- .../UIKitTests/UISwitchExtensionsTests.swift | 4 +- .../UIKitTests/UITabBarExtensionsTests.swift | 17 +- .../UITableViewExtensionsTests.swift | 73 +- .../UITextFieldExtensionsTests.swift | 77 +- .../UITextViewExtensionsTests.swift | 17 +- .../UIViewControllerExtensionsTests.swift | 116 +- Tests/UIKitTests/UIViewExtensionsTests.swift | 95 +- 135 files changed, 5411 insertions(+), 4910 deletions(-) create mode 100644 Sources/Extensions/SwiftStdlib/SequenceExtensions.swift create mode 100644 Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift create mode 100644 SwifterSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 SwifterSwift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Tests/SwiftStdlibTests/FloatingPointExtensionsTests.swift create mode 100644 Tests/SwiftStdlibTests/SequenceExtensionsTests.swift create mode 100644 Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift diff --git a/.swift-version b/.swift-version index 5186d0706..7d5c902e7 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -4.0 +4.1 diff --git a/.swiftlint.yml b/.swiftlint.yml index 1a9461f92..965d20a52 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,11 +1,5 @@ disabled_rules: -- identifier_name -- trailing_whitespace - line_length -- type_body_length - file_length -- cyclomatic_complexity -- function_body_length -- large_tuple - legacy_constructor -- shorthand_operator +- xctfail_message diff --git a/.travis.yml b/.travis.yml index 95bec5217..1fcd4c2ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.1 +osx_image: xcode9.3beta env: global: @@ -24,6 +24,7 @@ before_script: script: - set -o pipefail + - swift --version - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty - bash <(curl -s https://codecov.io/bash) -cF ios -J 'SwifterSwift' - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ac7f839c..a86ba3430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,26 +1,70 @@ # CHANGELOG The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. ---- +# Upcoming release + + > # Upcoming release > +> ### Added > ### Added +> ### Changed +> ### Deprecated +> ### Removed +> ### Fixed +> ### Security + +--- + +# [v4.3.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.3.0) + ### Added +- **Swift 4.1 / Xcode 9.3** + - Added Swift 4.1 support. +- **Linux Support**: + - Updated all swift files to use Swift's 4.1 [`# if canImport(module)`](https://github.com/apple/swift-evolution/blob/master/proposals/0075-import-test.md) statement, which brings the project one step closer to first-class Linux support. +- **Sequence** + - `all()` method moved from ArrayExtensions to SequenceExtensions. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). + - `none()` method moved from ArrayExtensions to SequenceExtensions. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). + - Added `any()` method to return if any element of sequence elements conforms to given condition. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). - **String** - added computed property `isSpelledCorrectly` to check if the given string has typos or not. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). - added `removingPrefix(_ prefix:)` method to remove given prefix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). - added `removingSuffix(_ suffix:)` method to remove given suffix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). +- **SwiftLint**: + - reduced the number of disabled rules in _.swiftlint.yml_, please add `disable` and `enable` statements from now on when needed in code. + +### Changed +- **SignedNumeric**: + - `asLocaleCurrency` now returns an optional string. +- **Array**: + - `rotate` method now returns a `discardableResult`. + - `shuffle` method now returns a `discardableResult`. + - `sort(by:, ascending:)` method now returns a `discardableResult`. + - `keep` method now returns a `discardableResult`. + +### Deprecated +- **UIStoryboard**: + - `mainStoryboard` property has been renamed to `main`. +- **Array**: + - deprecated `pop` method in favor of Swift’s `popLast`. + - deprecated `push` method in favor of Swift’s `append`. + - deprecated `swap` method in favor of Swift’s `swapAt`. + - deprecated `item(at index: Int)` method in favor of `subscript(safe:)`. + - `duplicatesRemoved` method has been renamed to `withoutDuplicates`. +- **Bool**: + - deprecated `toggled` property, use `!self` instead. + - deprecated `toggle` method, use `self = !self` instead. + +### Removed -> ### Changed -> ### Deprecated -> ### Removed -> ### Fixed - **String** - Fixed UIView extension `addShadow` was not showing the shadow on view bug. [#420](https://github.com/SwifterSwift/SwifterSwift/pull/420) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -> ### Security +### Security --- + # [v4.2.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.2.0) ### Added @@ -62,8 +106,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - added `toSlug()` to return a slug version of a given string. [397#](https://github.com/SwifterSwift/SwifterSwift/pull/397) by [FrankKair](https://github.com/FrankKair) - New **UIStackView** - added `init(arrangedSubviews:, axis:, spacing:, alignment:, distribution:)` to directly initialize a `UIStackView` with an array of `UIViews`. [#409](https://github.com/SwifterSwift/SwifterSwift/pull/409) by [BennX](https://github.com/BennX) -### Fixed +### Fixed - **String** - Fixed `isNumeric` to check if string is a valid Swift number and added isDigits to check if string only contains digits. [#396](https://github.com/SwifterSwift/SwifterSwift/pull/396) by [seifeet](https://github.com/seifeet). - **Collection** diff --git a/README.md b/README.md index 18fe6353b..14f4f979d 100755 --- a/README.md +++ b/README.md @@ -19,11 +19,10 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. -### [Whats New in v4.2.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v420) +### [Whats New in v4.3.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v430) ## Requirements: -- **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ -- Xcode 9.0+ +- **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ / **Ubuntu** 14.04+ - Swift 4.0+ diff --git a/Sources/Extensions/AppKit/NSImageExtensions.swift b/Sources/Extensions/AppKit/NSImageExtensions.swift index 679cad8ba..1a8e70d6a 100644 --- a/Sources/Extensions/AppKit/NSImageExtensions.swift +++ b/Sources/Extensions/AppKit/NSImageExtensions.swift @@ -6,12 +6,12 @@ // Copyright © 2017 SwifterSwift // -#if os(macOS) -import AppKit +#if canImport(Cocoa) +import Cocoa // MARK: - Methods extension NSImage { - + /// SwifterSwift: NSImage scaled to maximum size with respect to aspect ratio /// /// - Parameter toMaxSize: maximum size @@ -22,7 +22,7 @@ extension NSImage { let imageHeight = Float(self.size.height) let maxWidth = Float(toMaxSize.width) let maxHeight = Float(toMaxSize.height) - + // Get ratio (landscape or portrait) if imageWidth > imageHeight { // Landscape @@ -31,25 +31,25 @@ extension NSImage { // Portrait ratio = maxHeight / imageHeight } - + // Calculate new size based on the ratio let newWidth = imageWidth * ratio let newHeight = imageHeight * ratio - + // Create a new NSSize object with the newly calculated size let newSize: NSSize = NSSize(width: Int(newWidth), height: Int(newHeight)) - + // Cast the NSImage to a CGImage var imageRect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) let imageRef = self.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) - + // Create NSImage from the CGImage using the new size let imageWithNewSize = NSImage(cgImage: imageRef!, size: newSize) - + // Return the new image return imageWithNewSize } - + /// SwifterSwift: Write NSImage to url. /// /// - Parameters: @@ -58,14 +58,14 @@ extension NSImage { /// - compressionFactor: used only for JPEG files. The value is a float between 0.0 and 1.0, with 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. public func write(to url: URL, fileType type: NSBitmapImageRep.FileType = .jpeg, compressionFactor: NSNumber = 1.0) { // https://stackoverflow.com/a/45042611/3882644 - + guard let data = tiffRepresentation else { return } guard let imageRep = NSBitmapImageRep(data: data) else { return } - + guard let imageData = imageRep.representation(using: type, properties: [.compressionFactor: compressionFactor]) else { return } try? imageData.write(to: url) } - + } #endif diff --git a/Sources/Extensions/AppKit/NSViewExtensions.swift b/Sources/Extensions/AppKit/NSViewExtensions.swift index 534550f5f..8844209c7 100644 --- a/Sources/Extensions/AppKit/NSViewExtensions.swift +++ b/Sources/Extensions/AppKit/NSViewExtensions.swift @@ -6,12 +6,12 @@ // Copyright © 2017 SwifterSwift // -#if os(macOS) +#if canImport(Cocoa) import Cocoa // MARK: - Properties public extension NSView { - + /// SwifterSwift: Border color of view; also inspectable from Storyboard. @IBInspectable public var borderColor: NSColor? { get { @@ -23,7 +23,7 @@ public extension NSView { layer?.borderColor = newValue?.cgColor } } - + /// SwifterSwift: Border width of view; also inspectable from Storyboard. @IBInspectable public var borderWidth: CGFloat { get { @@ -34,7 +34,7 @@ public extension NSView { layer?.borderWidth = newValue } } - + /// SwifterSwift: Corner radius of view; also inspectable from Storyboard. @IBInspectable public var cornerRadius: CGFloat { get { @@ -46,7 +46,7 @@ public extension NSView { layer?.cornerRadius = abs(CGFloat(Int(newValue * 100)) / 100) } } - + // SwifterSwift: Height of view. public var height: CGFloat { get { @@ -56,7 +56,7 @@ public extension NSView { frame.size.height = newValue } } - + /// SwifterSwift: Shadow color of view; also inspectable from Storyboard. @IBInspectable public var shadowColor: NSColor? { get { @@ -68,7 +68,7 @@ public extension NSView { layer?.shadowColor = newValue?.cgColor } } - + /// SwifterSwift: Shadow offset of view; also inspectable from Storyboard. @IBInspectable public var shadowOffset: CGSize { get { @@ -79,7 +79,7 @@ public extension NSView { layer?.shadowOffset = newValue } } - + /// SwifterSwift: Shadow opacity of view; also inspectable from Storyboard. @IBInspectable public var shadowOpacity: Float { get { @@ -90,7 +90,7 @@ public extension NSView { layer?.shadowOpacity = newValue } } - + /// SwifterSwift: Shadow radius of view; also inspectable from Storyboard. @IBInspectable public var shadowRadius: CGFloat { get { @@ -101,7 +101,7 @@ public extension NSView { layer?.shadowRadius = newValue } } - + /// SwifterSwift: Size of view. public var size: CGSize { get { @@ -112,7 +112,7 @@ public extension NSView { height = newValue.height } } - + /// SwifterSwift: Width of view. public var width: CGFloat { get { @@ -122,24 +122,23 @@ public extension NSView { frame.size.width = newValue } } - + } // MARK: - Methods extension NSView { - + /// SwifterSwift: Add array of subviews to view. /// /// - Parameter subviews: array of subviews to add to self. public func addSubviews(_ subviews: [NSView]) { subviews.forEach({self.addSubview($0)}) } - + /// SwifterSwift: Remove all subviews in view. public func removeSubviews() { subviews.forEach({$0.removeFromSuperview()}) } - -} +} #endif diff --git a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift index 15112ff2d..62214e83e 100644 --- a/Sources/Extensions/CoreGraphics/CGColorExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGColorExtensions.swift @@ -6,26 +6,33 @@ // Copyright © 2017 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit +#if canImport(CoreGraphics) +import CoreGraphics + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif +// MARK: - Properties public extension CGColor { - - #if !os(macOS) + + #if canImport(UIKit) /// SwifterSwift: UIColor. public var uiColor: UIColor? { return UIColor(cgColor: self) } #endif - - #if os(macOS) + + #if canImport(Cocoa) /// SwifterSwift: NSColor. public var nsColor: NSColor? { return NSColor(cgColor: self) } #endif - + } +#endif diff --git a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift index 11cd24c70..41bce3d2e 100644 --- a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift @@ -6,70 +6,75 @@ // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit +#if canImport(CoreGraphics) +import CoreGraphics + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif // MARK: - Properties public extension CGFloat { - + /// SwifterSwift: Absolute of CGFloat value. public var abs: CGFloat { return Swift.abs(self) } - + /// SwifterSwift: Ceil of CGFloat value. public var ceil: CGFloat { return Foundation.ceil(self) } - + /// SwifterSwift: Radian value of degree input. public var degreesToRadians: CGFloat { return CGFloat.pi * self / 180.0 } - + /// SwifterSwift: Floor of CGFloat value. public var floor: CGFloat { return Foundation.floor(self) } - + /// SwifterSwift: Check if CGFloat is positive. public var isPositive: Bool { return self > 0 } - + /// SwifterSwift: Check if CGFloat is negative. public var isNegative: Bool { return self < 0 } - + /// SwifterSwift: Int. public var int: Int { return Int(self) } - + /// SwifterSwift: Float. public var float: Float { return Float(self) } - + /// SwifterSwift: Double. public var double: Double { return Double(self) } - + /// SwifterSwift: Degree value of radian input. public var radiansToDegrees: CGFloat { return self * 180 / CGFloat.pi } - + } // MARK: - Methods public extension CGFloat { - + /// SwifterSwift: Random CGFloat between two CGFloat values. /// /// - Parameters: @@ -80,5 +85,6 @@ public extension CGFloat { let delta = max - min return min + CGFloat(arc4random_uniform(UInt32(delta))) } - + } +#endif diff --git a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift index 92a7b2e12..d5784504d 100644 --- a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift @@ -6,15 +6,20 @@ // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit +#if canImport(CoreGraphics) +import CoreGraphics + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif // MARK: - Methods public extension CGPoint { - + /// SwifterSwift: Distance from another CGPoint. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -27,7 +32,7 @@ public extension CGPoint { public func distance(from point: CGPoint) -> CGFloat { return CGPoint.distance(from: self, to: point) } - + /// SwifterSwift: Distance between two CGPoints. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -43,12 +48,12 @@ public extension CGPoint { // http://stackoverflow.com/questions/6416101/calculate-the-distance-between-two-cgpoints return sqrt(pow(point2.x - point1.x, 2) + pow(point2.y - point1.y, 2)) } - + } // MARK: - Operators public extension CGPoint { - + /// SwifterSwift: Add two CGPoints. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -63,7 +68,7 @@ public extension CGPoint { public static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint { return CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y) } - + /// SwifterSwift: Add a CGPoints to self. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -75,9 +80,11 @@ public extension CGPoint { /// - lhs: self /// - rhs: CGPoint to add. public static func += (lhs: inout CGPoint, rhs: CGPoint) { + // swiftlint:disable shorthand_operator lhs = lhs + rhs + // swiftlint:enable shorthand_operator } - + /// SwifterSwift: Subtract two CGPoints. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -92,7 +99,7 @@ public extension CGPoint { public static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint { return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y) } - + /// SwifterSwift: Subtract a CGPoints from self. /// /// let point1 = CGPoint(x: 10, y: 10) @@ -104,9 +111,11 @@ public extension CGPoint { /// - lhs: self /// - rhs: CGPoint to subtract. public static func -= (lhs: inout CGPoint, rhs: CGPoint) { + // swiftlint:disable shorthand_operator lhs = lhs - rhs + // swiftlint:enable shorthand_operator } - + /// SwifterSwift: Multiply a CGPoint with a scalar /// /// let point1 = CGPoint(x: 10, y: 10) @@ -120,7 +129,7 @@ public extension CGPoint { public static func * (point: CGPoint, scalar: CGFloat) -> CGPoint { return CGPoint(x: point.x * scalar, y: point.y * scalar) } - + /// SwifterSwift: Multiply self with a scalar /// /// let point1 = CGPoint(x: 10, y: 10) @@ -132,9 +141,11 @@ public extension CGPoint { /// - scalar: scalar value. /// - Returns: result of multiplication of the given CGPoint with the scalar. public static func *= (point: inout CGPoint, scalar: CGFloat) { + // swiftlint:disable shorthand_operator point = point * scalar + // swiftlint:enable shorthand_operator } - + /// SwifterSwift: Multiply a CGPoint with a scalar /// /// let point1 = CGPoint(x: 10, y: 10) @@ -148,5 +159,6 @@ public extension CGPoint { public static func * (scalar: CGFloat, point: CGPoint) -> CGPoint { return CGPoint(x: point.x * scalar, y: point.y * scalar) } - + } +#endif diff --git a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift index 9b655db36..2fb43f951 100644 --- a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift @@ -6,15 +6,20 @@ // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit +#if canImport(CoreGraphics) +import CoreGraphics + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif // MARK: - Methods public extension CGSize { - + /// SwifterSwift: Aspect fit CGSize. /// /// let rect = CGSize(width: 120, height: 80) @@ -28,7 +33,7 @@ public extension CGSize { let minRatio = min(boundingSize.width / width, boundingSize.height / height) return CGSize(width: width * minRatio, height: height * minRatio) } - + /// SwifterSwift: Aspect fill CGSize. /// /// let rect = CGSize(width: 20, height: 120) @@ -40,9 +45,10 @@ public extension CGSize { /// - Returns: self filled into given bounding size public func aspectFill(to boundingSize: CGSize) -> CGSize { let minRatio = max(boundingSize.width / width, boundingSize.height / height) - let w = min(width * minRatio, boundingSize.width) - let h = min(height * minRatio, boundingSize.height) - return CGSize(width: w, height: h) + let aWidth = min(width * minRatio, boundingSize.width) + let aHeight = min(height * minRatio, boundingSize.height) + return CGSize(width: aWidth, height: aHeight) } - + } +#endif diff --git a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift index 2aaf744e0..061abdd77 100644 --- a/Sources/Extensions/CoreLocation/CLLocationExtensions.swift +++ b/Sources/Extensions/CoreLocation/CLLocationExtensions.swift @@ -6,11 +6,12 @@ // Copyright © 2017 SwifterSwift // +#if canImport(CoreLocation) import CoreLocation // MARK: - Methods public extension CLLocation { - + /// SwifterSwift: Calculate the half-way point along a great circle path between the two points. /// /// - Parameters: @@ -22,22 +23,22 @@ public extension CLLocation { let long1 = Double.pi * start.coordinate.longitude / 180.0 let lat2 = Double.pi * end.coordinate.latitude / 180.0 let long2 = Double.pi * end.coordinate.longitude / 180.0 - + // Formula // Bx = cos φ2 ⋅ cos Δλ // By = cos φ2 ⋅ sin Δλ // φm = atan2( sin φ1 + sin φ2, √(cos φ1 + Bx)² + By² ) // λm = λ1 + atan2(By, cos(φ1)+Bx) // Source: http://www.movable-type.co.uk/scripts/latlong.html - - let bx = cos(lat2) * cos(long2 - long1) - let by = cos(lat2) * sin(long2 - long1) - let mlat = atan2(sin(lat1) + sin(lat2), sqrt((cos(lat1) + bx) * (cos(lat1) + bx) + (by * by))) - let mlong = (long1) + atan2(by, cos(lat1) + bx) - + + let bxLoc = cos(lat2) * cos(long2 - long1) + let byLoc = cos(lat2) * sin(long2 - long1) + let mlat = atan2(sin(lat1) + sin(lat2), sqrt((cos(lat1) + bxLoc) * (cos(lat1) + bxLoc) + (byLoc * byLoc))) + let mlong = (long1) + atan2(byLoc, cos(lat1) + bxLoc) + return CLLocation(latitude: (mlat * 180 / Double.pi), longitude: (mlong * 180 / Double.pi)) } - + /// SwifterSwift: Calculate the half-way point along a great circle path between self and another points. /// /// - Parameter point: End location. @@ -45,7 +46,7 @@ public extension CLLocation { public func midLocation(to point: CLLocation) -> CLLocation { return CLLocation.midLocation(start: self, end: point) } - + /// SwifterSwift: Calculates the bearing to another CLLocation. /// /// - Parameters: @@ -57,15 +58,17 @@ public extension CLLocation { let long1 = Double.pi * coordinate.longitude / 180.0 let lat2 = Double.pi * destination.coordinate.latitude / 180.0 let long2 = Double.pi * destination.coordinate.longitude / 180.0 - + //Formula: θ = atan2( sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ ) //Source: http://www.movable-type.co.uk/scripts/latlong.html - - let rads = atan2(sin(long2 - long1) * cos(lat2), - cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(long2 - long1)) + + let rads = atan2( + sin(long2 - long1) * cos(lat2), + cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(long2 - long1)) let degrees = rads * 180 / Double.pi - + return (degrees+360).truncatingRemainder(dividingBy: 360) } - + } +#endif diff --git a/Sources/Extensions/Foundation/CalendarExtensions.swift b/Sources/Extensions/Foundation/CalendarExtensions.swift index 5d5e4f308..8f49d3e07 100644 --- a/Sources/Extensions/Foundation/CalendarExtensions.swift +++ b/Sources/Extensions/Foundation/CalendarExtensions.swift @@ -6,11 +6,12 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Methods public extension Calendar { - + /// SwifterSwift: Return the number of days in the month for a specified 'Date'. /// /// let date = Date() // "Jan 12, 2017, 7:07 PM" @@ -19,7 +20,8 @@ public extension Calendar { /// - Parameter date: the date form which the number of days in month is calculated. /// - Returns: The number of days in the month of 'Date'. public func numberOfDaysInMonth(for date: Date) -> Int { - return range(of: .day, in: .month, for: date)?.count ?? 0 + return range(of: .day, in: .month, for: date)!.count } - + } +#endif diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index 1a25c3b07..40968e53d 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -6,22 +6,23 @@ // Copyright © 2016 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Properties public extension Data { - + /// SwifterSwift: Return data as an array of bytes. public var bytes: [UInt8] { // http://stackoverflow.com/questions/38097710/swift-3-changes-for-getbytes-method return [UInt8](self) } - + } // MARK: - Methods public extension Data { - + /// SwifterSwift: String by encoding Data using the given encoding (if applicable). /// /// - Parameter encoding: encoding. @@ -29,5 +30,6 @@ public extension Data { public func string(encoding: String.Encoding) -> String? { return String(data: self, encoding: encoding) } - + } +#endif diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index fcc0d6d95..1a797d579 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -6,11 +6,12 @@ // Copyright © 2016 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Enums public extension Date { - + /// SwifterSwift: Day name format. /// /// - threeLetters: 3 letter day abbreviation of day name. @@ -21,7 +22,7 @@ public extension Date { case oneLetter case full } - + /// SwifterSwift: Month name format. /// /// - threeLetters: 3 letter month abbreviation of month name. @@ -32,17 +33,17 @@ public extension Date { case oneLetter case full } - + } // MARK: - Properties public extension Date { - + /// SwifterSwift: User’s current calendar. public var calendar: Calendar { return Calendar.current } - + /// SwifterSwift: Era. /// /// Date().era -> 1 @@ -50,7 +51,7 @@ public extension Date { public var era: Int { return Calendar.current.component(.era, from: self) } - + /// SwifterSwift: Quarter. /// /// Date().quarter -> 3 // date in third quarter of the year. @@ -61,7 +62,7 @@ public extension Date { let numberOfMonthsInQuarter = numberOfMonths / 4 return Int(ceil(month/numberOfMonthsInQuarter)) } - + /// SwifterSwift: Week of year. /// /// Date().weekOfYear -> 2 // second week in the year. @@ -69,7 +70,7 @@ public extension Date { public var weekOfYear: Int { return Calendar.current.component(.weekOfYear, from: self) } - + /// SwifterSwift: Week of month. /// /// Date().weekOfMonth -> 3 // date is in third week of the month. @@ -77,7 +78,7 @@ public extension Date { public var weekOfMonth: Int { return Calendar.current.component(.weekOfMonth, from: self) } - + /// SwifterSwift: Year. /// /// Date().year -> 2017 @@ -98,7 +99,7 @@ public extension Date { } } } - + /// SwifterSwift: Month. /// /// Date().month -> 1 @@ -113,7 +114,7 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .month, in: .year, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentMonth = Calendar.current.component(.month, from: self) let monthsToAdd = newValue - currentMonth if let date = Calendar.current.date(byAdding: .month, value: monthsToAdd, to: self) { @@ -121,7 +122,7 @@ public extension Date { } } } - + /// SwifterSwift: Day. /// /// Date().day -> 12 @@ -136,7 +137,7 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentDay = Calendar.current.component(.day, from: self) let daysToAdd = newValue - currentDay if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) { @@ -144,7 +145,7 @@ public extension Date { } } } - + /// SwifterSwift: Weekday. /// /// Date().weekday -> 5 // fifth day in the current week. @@ -152,7 +153,7 @@ public extension Date { public var weekday: Int { return Calendar.current.component(.weekday, from: self) } - + /// SwifterSwift: Hour. /// /// Date().hour -> 17 // 5 pm @@ -167,7 +168,7 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .hour, in: .day, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentHour = Calendar.current.component(.hour, from: self) let hoursToAdd = newValue - currentHour if let date = Calendar.current.date(byAdding: .hour, value: hoursToAdd, to: self) { @@ -175,7 +176,7 @@ public extension Date { } } } - + /// SwifterSwift: Minutes. /// /// Date().minute -> 39 @@ -190,7 +191,7 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .minute, in: .hour, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentMinutes = Calendar.current.component(.minute, from: self) let minutesToAdd = newValue - currentMinutes if let date = Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) { @@ -198,7 +199,7 @@ public extension Date { } } } - + /// SwifterSwift: Seconds. /// /// Date().second -> 55 @@ -213,7 +214,7 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .second, in: .minute, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentSeconds = Calendar.current.component(.second, from: self) let secondsToAdd = newValue - currentSeconds if let date = Calendar.current.date(byAdding: .second, value: secondsToAdd, to: self) { @@ -221,7 +222,7 @@ public extension Date { } } } - + /// SwifterSwift: Nanoseconds. /// /// Date().nanosecond -> 981379985 @@ -236,16 +237,16 @@ public extension Date { set { let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! guard allowedRange.contains(newValue) else { return } - + let currentNanoseconds = Calendar.current.component(.nanosecond, from: self) let nanosecondsToAdd = newValue - currentNanoseconds - + if let date = Calendar.current.date(byAdding: .nanosecond, value: nanosecondsToAdd, to: self) { self = date } } } - + /// SwifterSwift: Milliseconds. /// /// Date().millisecond -> 68 @@ -258,16 +259,16 @@ public extension Date { return Calendar.current.component(.nanosecond, from: self) / 1000000 } set { - let ns = newValue * 1000000 + let nanoSeconds = newValue * 1000000 let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! - guard allowedRange.contains(ns) else { return } - - if let date = Calendar.current.date(bySetting: .nanosecond, value: ns, of: self) { + guard allowedRange.contains(nanoSeconds) else { return } + + if let date = Calendar.current.date(bySetting: .nanosecond, value: nanoSeconds, of: self) { self = date } } } - + /// SwifterSwift: Check if date is in future. /// /// Date(timeInterval: 100, since: Date()).isInFuture -> true @@ -275,7 +276,7 @@ public extension Date { public var isInFuture: Bool { return self > Date() } - + /// SwifterSwift: Check if date is in past. /// /// Date(timeInterval: -100, since: Date()).isInPast -> true @@ -283,7 +284,7 @@ public extension Date { public var isInPast: Bool { return self < Date() } - + /// SwifterSwift: Check if date is within today. /// /// Date().isInToday -> true @@ -291,7 +292,7 @@ public extension Date { public var isInToday: Bool { return Calendar.current.isDateInToday(self) } - + /// SwifterSwift: Check if date is within yesterday. /// /// Date().isInYesterday -> false @@ -299,7 +300,7 @@ public extension Date { public var isInYesterday: Bool { return Calendar.current.isDateInYesterday(self) } - + /// SwifterSwift: Check if date is within tomorrow. /// /// Date().isInTomorrow -> false @@ -307,32 +308,32 @@ public extension Date { public var isInTomorrow: Bool { return Calendar.current.isDateInTomorrow(self) } - + /// SwifterSwift: Check if date is within a weekend period. public var isInWeekend: Bool { return Calendar.current.isDateInWeekend(self) } - + /// SwifterSwift: Check if date is within a weekday period. public var isWorkday: Bool { return !Calendar.current.isDateInWeekend(self) } - + /// SwifterSwift: Check if date is within the current week. public var isInCurrentWeek: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) } - + /// SwifterSwift: Check if date is within the current month. public var isInCurrentMonth: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) } - + /// SwifterSwift: Check if date is within the current year. public var isInCurrentYear: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) } - + /// SwifterSwift: ISO8601 string of format (yyyy-MM-dd'T'HH:mm:ss.SSS) from date. /// /// Date().iso8601String -> "2017-01-12T14:51:29.574Z" @@ -343,10 +344,10 @@ public extension Date { dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.timeZone = TimeZone(abbreviation: "GMT") dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" - + return dateFormatter.string(from: self).appending("Z") } - + /// SwifterSwift: Nearest five minutes to date. /// /// var date = Date() // "5:54 PM" @@ -364,7 +365,7 @@ public extension Date { components.nanosecond = 0 return Calendar.current.date(from: components)! } - + /// SwifterSwift: Nearest ten minutes to date. /// /// var date = Date() // "5:57 PM" @@ -382,7 +383,7 @@ public extension Date { components.nanosecond = 0 return Calendar.current.date(from: components)! } - + /// SwifterSwift: Nearest quarter hour to date. /// /// var date = Date() // "5:57 PM" @@ -400,7 +401,7 @@ public extension Date { components.nanosecond = 0 return Calendar.current.date(from: components)! } - + /// SwifterSwift: Nearest half hour to date. /// /// var date = Date() // "6:07 PM" @@ -418,7 +419,7 @@ public extension Date { components.nanosecond = 0 return Calendar.current.date(from: components)! } - + /// SwifterSwift: Nearest hour to date. /// /// var date = Date() // "6:17 PM" @@ -431,13 +432,13 @@ public extension Date { let min = Calendar.current.component(.minute, from: self) let components: Set = [.year, .month, .day, .hour] let date = Calendar.current.date(from: Calendar.current.dateComponents(components, from: self))! - + if min < 30 { return date } return Calendar.current.date(byAdding: .hour, value: 1, to: date)! } - + /// SwifterSwift: Time zone used currently by system. /// /// Date().timeZone -> Europe/Istanbul (current) @@ -445,7 +446,7 @@ public extension Date { public var timeZone: TimeZone { return Calendar.current.timeZone } - + /// SwifterSwift: UNIX timestamp from date. /// /// Date().unixTimestamp -> 1484233862.826291 @@ -453,12 +454,12 @@ public extension Date { public var unixTimestamp: Double { return timeIntervalSince1970 } - + } // MARK: - Methods public extension Date { - + /// SwifterSwift: Date by adding multiples of calendar component. /// /// let date = Date() // "Jan 12, 2017, 7:07 PM" @@ -474,7 +475,7 @@ public extension Date { public func adding(_ component: Calendar.Component, value: Int) -> Date { return Calendar.current.date(byAdding: component, value: value, to: self)! } - + /// SwifterSwift: Add calendar component to date. /// /// var date = Date() // "Jan 12, 2017, 7:07 PM" @@ -491,7 +492,9 @@ public extension Date { self = date } } - + + // swiftlint:disable function_body_length, function_body_length + // swiftlint:disable cyclomatic_complexity /// SwifterSwift: Date by changing value of calendar component. /// /// let date = Date() // "Jan 12, 2017, 7:07 PM" @@ -504,7 +507,7 @@ public extension Date { /// - component: component type. /// - value: new value of compnenet to change. /// - Returns: original date after changing given component to given value. - public func changing(_ component: Calendar.Component, value: Int) -> Date? { + public func changing(_ component: Calendar.Component, value: Int) -> Date? { switch component { case .nanosecond: let allowedRange = Calendar.current.range(of: .nanosecond, in: .second, for: self)! @@ -512,53 +515,54 @@ public extension Date { let currentNanoseconds = Calendar.current.component(.nanosecond, from: self) let nanosecondsToAdd = value - currentNanoseconds return Calendar.current.date(byAdding: .nanosecond, value: nanosecondsToAdd, to: self) - + case .second: let allowedRange = Calendar.current.range(of: .second, in: .minute, for: self)! guard allowedRange.contains(value) else { return nil } let currentSeconds = Calendar.current.component(.second, from: self) let secondsToAdd = value - currentSeconds return Calendar.current.date(byAdding: .second, value: secondsToAdd, to: self) - + case .minute: let allowedRange = Calendar.current.range(of: .minute, in: .hour, for: self)! guard allowedRange.contains(value) else { return nil } let currentMinutes = Calendar.current.component(.minute, from: self) let minutesToAdd = value - currentMinutes return Calendar.current.date(byAdding: .minute, value: minutesToAdd, to: self) - + case .hour: let allowedRange = Calendar.current.range(of: .hour, in: .day, for: self)! guard allowedRange.contains(value) else { return nil } let currentHour = Calendar.current.component(.hour, from: self) let hoursToAdd = value - currentHour return Calendar.current.date(byAdding: .hour, value: hoursToAdd, to: self) - + case .day: let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)! guard allowedRange.contains(value) else { return nil } let currentDay = Calendar.current.component(.day, from: self) let daysToAdd = value - currentDay return Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) - + case .month: let allowedRange = Calendar.current.range(of: .month, in: .year, for: self)! guard allowedRange.contains(value) else { return nil } let currentMonth = Calendar.current.component(.month, from: self) let monthsToAdd = value - currentMonth return Calendar.current.date(byAdding: .month, value: monthsToAdd, to: self) - + case .year: guard value > 0 else { return nil } let currentYear = Calendar.current.component(.year, from: self) let yearsToAdd = value - currentYear return Calendar.current.date(byAdding: .year, value: yearsToAdd, to: self) - + default: return Calendar.current.date(bySetting: component, value: value, of: self) } } - + // swiftlint:enable cyclomatic_complexity, function_body_length + /// SwifterSwift: Data at the beginning of calendar component. /// /// let date = Date() // "Jan 12, 2017, 7:14 PM" @@ -572,36 +576,37 @@ public extension Date { if component == .day { return Calendar.current.startOfDay(for: self) } - + var components: Set { switch component { case .second: return [.year, .month, .day, .hour, .minute, .second] - + case .minute: return [.year, .month, .day, .hour, .minute] - + case .hour: return [.year, .month, .day, .hour] - + case .weekOfYear, .weekOfMonth: return [.yearForWeekOfYear, .weekOfYear] - + case .month: return [.year, .month] - + case .year: return [.year] - + default: return [] } } - + guard !components.isEmpty else { return nil } return Calendar.current.date(from: Calendar.current.dateComponents(components, from: self)) } - + + // swiftlint:disable function_body_length /// SwifterSwift: Date at the end of calendar component. /// /// let date = Date() // "Jan 12, 2017, 7:27 PM" @@ -619,53 +624,54 @@ public extension Date { Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date))! date.add(.second, value: -1) return date - + case .minute: var date = adding(.minute, value: 1) let after = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: date))! date = after.adding(.second, value: -1) return date - + case .hour: var date = adding(.hour, value: 1) let after = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day, .hour], from: date))! date = after.adding(.second, value: -1) return date - + case .day: var date = adding(.day, value: 1) date = Calendar.current.startOfDay(for: date) date.add(.second, value: -1) return date - + case .weekOfYear, .weekOfMonth: var date = self let beginningOfWeek = Calendar.current.date(from: Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: date))! date = beginningOfWeek.adding(.day, value: 7).adding(.second, value: -1) return date - + case .month: var date = adding(.month, value: 1) let after = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: date))! date = after.adding(.second, value: -1) return date - + case .year: var date = adding(.year, value: 1) let after = Calendar.current.date(from: Calendar.current.dateComponents([.year], from: date))! date = after.adding(.second, value: -1) return date - + default: return nil } } - + // swiftlint:enable function_body_length + /// SwifterSwift: Check if date is in current given calendar component. /// /// Date().isInCurrent(.day) -> true @@ -676,7 +682,7 @@ public extension Date { public func isInCurrent(_ component: Calendar.Component) -> Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: component) } - + /// SwifterSwift: Date string from date. /// /// Date().string(withFormat: "dd/MM/yyyy") -> "1/12/17" @@ -690,7 +696,7 @@ public extension Date { dateFormatter.dateFormat = format return dateFormatter.string(from: self) } - + /// SwifterSwift: Date string from date. /// /// Date().dateString(ofStyle: .short) -> "1/12/17" @@ -706,7 +712,7 @@ public extension Date { dateFormatter.dateStyle = style return dateFormatter.string(from: self) } - + /// SwifterSwift: Date and time string from date. /// /// Date().dateTimeString(ofStyle: .short) -> "1/12/17, 7:32 PM" @@ -722,7 +728,7 @@ public extension Date { dateFormatter.dateStyle = style return dateFormatter.string(from: self) } - + /// SwifterSwift: Time string from date /// /// Date().timeString(ofStyle: .short) -> "7:37 PM" @@ -738,7 +744,7 @@ public extension Date { dateFormatter.dateStyle = .none return dateFormatter.string(from: self) } - + /// SwifterSwift: Day name from date. /// /// Date().dayName(ofStyle: .oneLetter) -> "T" @@ -763,7 +769,7 @@ public extension Date { dateFormatter.setLocalizedDateFormatFromTemplate(format) return dateFormatter.string(from: self) } - + /// SwifterSwift: Month name from date. /// /// Date().monthName(ofStyle: .oneLetter) -> "J" @@ -788,7 +794,7 @@ public extension Date { dateFormatter.setLocalizedDateFormatFromTemplate(format) return dateFormatter.string(from: self) } - + /// SwifterSwift: get number of seconds between two date /// /// - Parameter date: date to compate self to. @@ -796,7 +802,7 @@ public extension Date { public func secondsSince(_ date: Date) -> Double { return timeIntervalSince(date) } - + /// SwifterSwift: get number of minutes between two date /// /// - Parameter date: date to compate self to. @@ -804,7 +810,7 @@ public extension Date { public func minutesSince(_ date: Date) -> Double { return timeIntervalSince(date)/60 } - + /// SwifterSwift: get number of hours between two date /// /// - Parameter date: date to compate self to. @@ -812,7 +818,7 @@ public extension Date { public func hoursSince(_ date: Date) -> Double { return timeIntervalSince(date)/3600 } - + /// SwifterSwift: get number of days between two date /// /// - Parameter date: date to compate self to. @@ -820,7 +826,7 @@ public extension Date { public func daysSince(_ date: Date) -> Double { return timeIntervalSince(date)/(3600*24) } - + /// SwifterSwift: check if a date is between two other dates /// /// - Parameters: @@ -834,7 +840,7 @@ public extension Date { } return startDate.compare(self).rawValue * compare(endDate).rawValue > 0 } - + /// SwifterSwift: check if a date is a number of date components of another date /// /// - Parameters: @@ -847,7 +853,7 @@ public extension Date { let componentValue = components.value(for: component)! return abs(componentValue) <= value } - + /// SwifterSwift: Random date between two dates. /// /// Date.random() @@ -863,21 +869,21 @@ public extension Date { guard fromDate != toDate else { return fromDate } - + let diff = llabs(Int64(toDate.timeIntervalSinceReferenceDate - fromDate.timeIntervalSinceReferenceDate)) var randomValue: Int64 = 0 arc4random_buf(&randomValue, MemoryLayout.size) randomValue = llabs(randomValue%diff) - + let startReferenceDate = toDate > fromDate ? fromDate : toDate return startReferenceDate.addingTimeInterval(TimeInterval(randomValue)) } - + } // MARK: - Initializers public extension Date { - + /// SwifterSwift: Create a new date form calendar components. /// /// let date = Date(year: 2010, month: 1, day: 12) // "Jan 12, 2010, 7:45 PM" @@ -904,7 +910,7 @@ public extension Date { minute: Int? = Date().minute, second: Int? = Date().second, nanosecond: Int? = Date().nanosecond) { - + var components = DateComponents() components.calendar = calendar components.timeZone = timeZone @@ -916,14 +922,14 @@ public extension Date { components.minute = minute components.second = second components.nanosecond = nanosecond - + if let date = calendar?.date(from: components) { self = date } else { return nil } } - + /// SwifterSwift: Create date object from ISO8601 string. /// /// let date = Date(iso8601String: "2017-01-12T16:48:00.959Z") // "Jan 12, 2017, 7:48 PM" @@ -941,7 +947,7 @@ public extension Date { return nil } } - + /// SwifterSwift: Create new date object from UNIX timestamp. /// /// let date = Date(unixTimestamp: 1484239783.922743) // "Jan 12, 2017, 7:49 PM" @@ -950,7 +956,7 @@ public extension Date { public init(unixTimestamp: Double) { self.init(timeIntervalSince1970: unixTimestamp) } - + /// SwifterSwift: Create date object from Int literal /// /// let date = Date(integerLiteral: 2017_12_25) // "2017-12-25 00:00:00 +0000" @@ -961,5 +967,6 @@ public extension Date { guard let date = formatter.date(from: String(value)) else { return nil } self = date } - + } +#endif diff --git a/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift b/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift index d44ae40f3..f5e4f71a4 100644 --- a/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift +++ b/Sources/Extensions/Foundation/Deprecated/FoundationDeprecated.swift @@ -6,27 +6,29 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Properties public extension Date { - + /// SwifterSwift: Check if date is within the current week. @available(*, deprecated: 4.1.0, message: "Use isInCurrentWeek instead", renamed: "isInCurrentWeek") public var isInThisWeek: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .weekOfYear) } - + /// SwifterSwift: Check if date is within the current month. @available(*, deprecated: 4.1.0, message: "Use isInCurrentMonth instead", renamed: "isInCurrentMonth") public var isInThisMonth: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .month) } - + /// SwifterSwift: Check if date is within the current year. @available(*, deprecated: 4.1.0, message: "Use isInCurrentYear instead", renamed: "isInCurrentYear") public var isInThisYear: Bool { return Calendar.current.isDate(self, equalTo: Date(), toGranularity: .year) } - + } +#endif diff --git a/Sources/Extensions/Foundation/FileManagerExtensions.swift b/Sources/Extensions/Foundation/FileManagerExtensions.swift index 929d7874d..dcc322db3 100644 --- a/Sources/Extensions/Foundation/FileManagerExtensions.swift +++ b/Sources/Extensions/Foundation/FileManagerExtensions.swift @@ -6,50 +6,55 @@ // Copyright © 2018 SwifterSwift // +#if canImport(Foundation) import Foundation public extension FileManager { - - /// SwifterSwift: Read from a JSON file at a given path. - /// - /// - Parameters: - /// - path: JSON file path. - /// - options: JSONSerialization reading options. - /// - Returns: Optional dictionary. - /// - Throws: Throws any errors thrown by Data creation or JSON serialization. - public func jsonFromFile(atPath path: String, - readingOptions: JSONSerialization.ReadingOptions = .allowFragments) throws -> [String: Any]? { - let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) - let json = try JSONSerialization.jsonObject(with: data, options: readingOptions) - - return json as? [String: Any] - } - - /// SwifterSwift: Read from a JSON file with a given filename. - /// - /// - Parameters: - /// - filename: File to read. - /// - bundleClass: Bundle where the file is associated. - /// - readingOptions: JSONSerialization reading options. - /// - Returns: Optional dictionary. - /// - Throws: Throws any errors thrown by Data creation or JSON serialization. - public func jsonFromFile(withFilename filename: String, - at bundleClass: AnyClass? = nil, - readingOptions: JSONSerialization.ReadingOptions = .allowFragments) throws -> [String: Any]? { - // https://stackoverflow.com/questions/24410881/reading-in-a-json-file-using-swift - - // To handle cases that provided filename has an extension - let name = filename.components(separatedBy: ".")[0] - let bundle = bundleClass != nil ? Bundle(for: bundleClass!) : Bundle.main - - if let path = bundle.path(forResource: name, ofType: "json") { - let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) - let json = try JSONSerialization.jsonObject(with: data, options: readingOptions) - - return json as? [String: Any] - } - - return nil - } - + + /// SwifterSwift: Read from a JSON file at a given path. + /// + /// - Parameters: + /// - path: JSON file path. + /// - options: JSONSerialization reading options. + /// - Returns: Optional dictionary. + /// - Throws: Throws any errors thrown by Data creation or JSON serialization. + public func jsonFromFile( + atPath path: String, + readingOptions: JSONSerialization.ReadingOptions = .allowFragments) throws -> [String: Any]? { + + let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) + let json = try JSONSerialization.jsonObject(with: data, options: readingOptions) + + return json as? [String: Any] + } + + /// SwifterSwift: Read from a JSON file with a given filename. + /// + /// - Parameters: + /// - filename: File to read. + /// - bundleClass: Bundle where the file is associated. + /// - readingOptions: JSONSerialization reading options. + /// - Returns: Optional dictionary. + /// - Throws: Throws any errors thrown by Data creation or JSON serialization. + public func jsonFromFile( + withFilename filename: String, + at bundleClass: AnyClass? = nil, + readingOptions: JSONSerialization.ReadingOptions = .allowFragments) throws -> [String: Any]? { + // https://stackoverflow.com/questions/24410881/reading-in-a-json-file-using-swift + + // To handle cases that provided filename has an extension + let name = filename.components(separatedBy: ".")[0] + let bundle = bundleClass != nil ? Bundle(for: bundleClass!) : Bundle.main + + if let path = bundle.path(forResource: name, ofType: "json") { + let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) + let json = try JSONSerialization.jsonObject(with: data, options: readingOptions) + + return json as? [String: Any] + } + + return nil + } + } +#endif diff --git a/Sources/Extensions/Foundation/LocaleExtensions.swift b/Sources/Extensions/Foundation/LocaleExtensions.swift index c19d93a05..05b9932d5 100644 --- a/Sources/Extensions/Foundation/LocaleExtensions.swift +++ b/Sources/Extensions/Foundation/LocaleExtensions.swift @@ -6,14 +6,16 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Properties public extension Locale { - + /// SwifterSwift: UNIX representation of locale usually used for normalizing. public static var posix: Locale { return Locale(identifier: "en_US_POSIX") } - + } +#endif diff --git a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift index 3a985895e..b1b5785e3 100644 --- a/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift +++ b/Sources/Extensions/Foundation/NSAttributedStringExtensions.swift @@ -6,49 +6,54 @@ // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit +#if canImport(Foundation) +import Foundation + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif // MARK: - Properties public extension NSAttributedString { - + #if os(iOS) /// SwifterSwift: Bolded string. public var bolded: NSAttributedString { return applying(attributes: [.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) } #endif - + /// SwifterSwift: Underlined string. public var underlined: NSAttributedString { return applying(attributes: [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) } - + #if os(iOS) /// SwifterSwift: Italicized string. public var italicized: NSAttributedString { return applying(attributes: [.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) } #endif - + /// SwifterSwift: Struckthrough string. public var struckthrough: NSAttributedString { return applying(attributes: [.strikethroughStyle: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)]) } - + /// SwifterSwift: Dictionary of the attributes applied across the whole string public var attributes: [NSAttributedStringKey: Any] { return attributes(at: 0, effectiveRange: nil) } - + } // MARK: - Methods public extension NSAttributedString { - + /// SwifterSwift: Applies given attributes to the new instance of NSAttributedString initialized with self object /// /// - Parameter attributes: Dictionary of attributes @@ -57,10 +62,10 @@ public extension NSAttributedString { let copy = NSMutableAttributedString(attributedString: self) let range = (string as NSString).range(of: string) copy.addAttributes(attributes, range: range) - + return copy } - + #if os(macOS) /// SwifterSwift: Add color to NSAttributedString. /// @@ -78,7 +83,7 @@ public extension NSAttributedString { return applying(attributes: [.foregroundColor: color]) } #endif - + /// SwifterSwift: Apply attributes to substrings matching a regular expression /// /// - Parameters: @@ -87,17 +92,17 @@ public extension NSAttributedString { /// - Returns: An NSAttributedString with attributes applied to substrings matching the pattern public func applying(attributes: [NSAttributedStringKey: Any], toRangesMatching pattern: String) -> NSAttributedString { guard let pattern = try? NSRegularExpression(pattern: pattern, options: []) else { return self } - + let matches = pattern.matches(in: string, options: [], range: NSRange(0..(attributes: [NSAttributedStringKey: Any], toOccurrencesOf target: T) -> NSAttributedString { let pattern = "\\Q\(target)\\E" - + return applying(attributes: attributes, toRangesMatching: pattern) } - + } // MARK: - Operators public extension NSAttributedString { - + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString. /// /// - Parameters: /// - lhs: NSAttributedString to add to. /// - rhs: NSAttributedString to add. public static func += (lhs: inout NSAttributedString, rhs: NSAttributedString) { - let ns = NSMutableAttributedString(attributedString: lhs) - ns.append(rhs) - lhs = ns + let string = NSMutableAttributedString(attributedString: lhs) + string.append(rhs) + lhs = string } - + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString and return a new NSAttributedString instance. /// /// - Parameters: @@ -133,11 +138,11 @@ public extension NSAttributedString { /// - rhs: NSAttributedString to add. /// - Returns: New instance with added NSAttributedString. public static func + (lhs: NSAttributedString, rhs: NSAttributedString) -> NSAttributedString { - let ns = NSMutableAttributedString(attributedString: lhs) - ns.append(rhs) - return NSAttributedString(attributedString: ns) + let string = NSMutableAttributedString(attributedString: lhs) + string.append(rhs) + return NSAttributedString(attributedString: string) } - + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString. /// /// - Parameters: @@ -146,7 +151,7 @@ public extension NSAttributedString { public static func += (lhs: inout NSAttributedString, rhs: String) { lhs += NSAttributedString(string: rhs) } - + /// SwifterSwift: Add a NSAttributedString to another NSAttributedString and return a new NSAttributedString instance. /// /// - Parameters: @@ -156,5 +161,6 @@ public extension NSAttributedString { public static func + (lhs: NSAttributedString, rhs: String) -> NSAttributedString { return lhs + NSAttributedString(string: rhs) } - + } +#endif diff --git a/Sources/Extensions/Foundation/NSPredicateExtensions.swift b/Sources/Extensions/Foundation/NSPredicateExtensions.swift index ba6b9e1cf..308130800 100644 --- a/Sources/Extensions/Foundation/NSPredicateExtensions.swift +++ b/Sources/Extensions/Foundation/NSPredicateExtensions.swift @@ -6,21 +6,22 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Properties public extension NSPredicate { - + /// SwifterSwift: Returns a new predicate formed by NOT-ing the predicate. public var not: NSCompoundPredicate { return NSCompoundPredicate(notPredicateWithSubpredicate: self) } - + } // MARK: - Methods public extension NSPredicate { - + /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. /// /// - Parameter predicate: NSPredicate @@ -28,7 +29,7 @@ public extension NSPredicate { public func and(_ predicate: NSPredicate) -> NSCompoundPredicate { return NSCompoundPredicate(andPredicateWithSubpredicates: [self, predicate]) } - + /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. /// /// - Parameter predicate: NSPredicate @@ -36,19 +37,19 @@ public extension NSPredicate { public func or(_ predicate: NSPredicate) -> NSCompoundPredicate { return NSCompoundPredicate(orPredicateWithSubpredicates: [self, predicate]) } - + } // MARK: - Operators public extension NSPredicate { - + /// SwifterSwift: Returns a new predicate formed by NOT-ing the predicate. /// - Parameters: rhs: NSPredicate to convert. /// - Returns: NSCompoundPredicate static public prefix func ! (rhs: NSPredicate) -> NSCompoundPredicate { return rhs.not } - + /// SwifterSwift: Returns a new predicate formed by AND-ing the argument to the predicate. /// /// - Parameters: @@ -58,7 +59,7 @@ public extension NSPredicate { static public func + (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { return lhs.and(rhs) } - + /// SwifterSwift: Returns a new predicate formed by OR-ing the argument to the predicate. /// /// - Parameters: @@ -68,7 +69,7 @@ public extension NSPredicate { static public func | (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { return lhs.or(rhs) } - + /// SwifterSwift: Returns a new predicate formed by remove the argument to the predicate. /// /// - Parameters: @@ -78,5 +79,6 @@ public extension NSPredicate { static public func - (lhs: NSPredicate, rhs: NSPredicate) -> NSCompoundPredicate { return lhs + !rhs } - + } +#endif diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 8e6fab4e2..79b57fc72 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -6,28 +6,35 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation +#if canImport(UIKit) && canImport(AVFoundation) +import UIKit +import AVFoundation +#endif + // MARK: - Properties public extension URL { - - /// SwifterSwift: Dictionary of the URL's query parameters - public var queryParameters: [String: String]? { - guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false), let queryItems = components.queryItems else { return nil } - - var items: [String: String] = [:] - - for queryItem in queryItems { - items[queryItem.name] = queryItem.value - } - - return items - } + + /// SwifterSwift: Dictionary of the URL's query parameters + public var queryParameters: [String: String]? { + guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false), let queryItems = components.queryItems else { return nil } + + var items: [String: String] = [:] + + for queryItem in queryItems { + items[queryItem.name] = queryItem.value + } + + return items + } + } // MARK: - Methods public extension URL { - + /// SwifterSwift: URL with appending query parameters. /// /// let url = URL(string: "https://google.com")! @@ -43,7 +50,7 @@ public extension URL { urlComponents.queryItems = items return urlComponents.url! } - + /// SwifterSwift: Append query parameters to URL. /// /// var url = URL(string: "https://google.com")! @@ -55,36 +62,36 @@ public extension URL { public mutating func appendQueryParameters(_ parameters: [String: String]) { self = appendingQueryParameters(parameters) } + } -#if os(iOS) || os(tvOS) -import UIKit -import AVFoundation - // MARK: - Methods public extension URL { - - /// Generate a thumbnail image from given url. Returns nil if no thumbnail could be created. This function may take some time to complete. It's recommended to dispatch the call if the thumbnail is not generated from a local resource. - /// - /// var url = URL(string: "https://video.golem.de/files/1/1/20637/wrkw0718-sd.mp4")! - /// var thumbnail = url.thumbnail() - /// thumbnail = url.thumbnail(fromTime: 5) - /// - /// DisptachQueue.main.async { - /// someImageView.image = url.thumbnail() - /// } - /// - /// - Parameter time: Seconds into the video where the image should be generated. - /// - Returns: The UIImage result of the AVAssetImageGenerator - public func thumbnail(fromTime time: Float64 = 0) -> UIImage? { - let imageGenerator = AVAssetImageGenerator(asset: AVAsset(url: self)) - let time = CMTimeMakeWithSeconds(time, 1) - var actualTime = CMTimeMake(0, 0) - - guard let cgImage = try? imageGenerator.copyCGImage(at: time, actualTime: &actualTime) else { - return nil - } - return UIImage(cgImage: cgImage) - } + + #if os(iOS) || os(tvOS) + /// Generate a thumbnail image from given url. Returns nil if no thumbnail could be created. This function may take some time to complete. It's recommended to dispatch the call if the thumbnail is not generated from a local resource. + /// + /// var url = URL(string: "https://video.golem.de/files/1/1/20637/wrkw0718-sd.mp4")! + /// var thumbnail = url.thumbnail() + /// thumbnail = url.thumbnail(fromTime: 5) + /// + /// DisptachQueue.main.async { + /// someImageView.image = url.thumbnail() + /// } + /// + /// - Parameter time: Seconds into the video where the image should be generated. + /// - Returns: The UIImage result of the AVAssetImageGenerator + public func thumbnail(fromTime time: Float64 = 0) -> UIImage? { + let imageGenerator = AVAssetImageGenerator(asset: AVAsset(url: self)) + let time = CMTimeMakeWithSeconds(time, 1) + var actualTime = CMTimeMake(0, 0) + + guard let cgImage = try? imageGenerator.copyCGImage(at: time, actualTime: &actualTime) else { + return nil + } + return UIImage(cgImage: cgImage) + } + #endif + } #endif diff --git a/Sources/Extensions/Foundation/URLRequestExtensions.swift b/Sources/Extensions/Foundation/URLRequestExtensions.swift index 7296fc699..48df2399b 100644 --- a/Sources/Extensions/Foundation/URLRequestExtensions.swift +++ b/Sources/Extensions/Foundation/URLRequestExtensions.swift @@ -6,11 +6,12 @@ // Copyright © 2017 SwifterSwift // +#if canImport(Foundation) import Foundation // MARK: - Initializers public extension URLRequest { - + /// SwifterSwift: Create URLRequest from URL string. /// /// - Parameter urlString: URL string to initialize URL request from @@ -18,5 +19,6 @@ public extension URLRequest { guard let url = URL(string: urlString) else { return nil } self.init(url: url) } - + } +#endif diff --git a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift index c618fc1ed..82797d64e 100644 --- a/Sources/Extensions/Foundation/UserDefaultsExtensions.swift +++ b/Sources/Extensions/Foundation/UserDefaultsExtensions.swift @@ -5,11 +5,13 @@ // Created by Omar Albeik on 9/5/17. // Copyright © 2017 SwifterSwift // + +#if canImport(Foundation) import Foundation // MARK: - Methods public extension UserDefaults { - + /// SwifterSwift: get object from UserDefaults by using subscript /// /// - Parameter key: key in the current user's defaults database. @@ -21,7 +23,7 @@ public extension UserDefaults { set(newValue, forKey: key) } } - + /// SwifterSwift: Float from UserDefaults. /// /// - Parameter forKey: key to find float for. @@ -29,7 +31,7 @@ public extension UserDefaults { public func float(forKey key: String) -> Float? { return object(forKey: key) as? Float } - + /// SwifterSwift: Date from UserDefaults. /// /// - Parameter forKey: key to find date for. @@ -37,34 +39,29 @@ public extension UserDefaults { public func date(forKey key: String) -> Date? { return object(forKey: key) as? Date } - - /// SwifterSwift: Retrieves a Codable object from UserDefaults. - /// - /// - Parameters: - /// - type: Class that conforms to the Codable protocol. - /// - key: Identifier of the object. - /// - decoder: Custom JSONDecoder instance. Defaults to `JSONDecoder()`. - /// - Returns: Codable object for key (if exists). - public func object(_ type: T.Type, - with key: String, - usingDecoder decoder: JSONDecoder = JSONDecoder()) -> T? { - guard let data = self.value(forKey: key) as? Data else { return nil } - - return try? decoder.decode(type.self, from: data) - } - - /// SwifterSwift: Allows storing of Codable objects to UserDefaults. - /// - /// - Parameters: - /// - object: Codable object to store. - /// - key: Identifier of the object. - /// - encoder: Custom JSONEncoder instance. Defaults to `JSONEncoder()`. - public func set(object: T, - forKey key: String, - usingEncoder encoder: JSONEncoder = JSONEncoder()) { - let data = try? encoder.encode(object) - - self.set(data, forKey: key) - } - + + /// SwifterSwift: Retrieves a Codable object from UserDefaults. + /// + /// - Parameters: + /// - type: Class that conforms to the Codable protocol. + /// - key: Identifier of the object. + /// - decoder: Custom JSONDecoder instance. Defaults to `JSONDecoder()`. + /// - Returns: Codable object for key (if exists). + public func object(_ type: T.Type, with key: String, usingDecoder decoder: JSONDecoder = JSONDecoder()) -> T? { + guard let data = self.value(forKey: key) as? Data else { return nil } + return try? decoder.decode(type.self, from: data) + } + + /// SwifterSwift: Allows storing of Codable objects to UserDefaults. + /// + /// - Parameters: + /// - object: Codable object to store. + /// - key: Identifier of the object. + /// - encoder: Custom JSONEncoder instance. Defaults to `JSONEncoder()`. + public func set(object: T, forKey key: String, usingEncoder encoder: JSONEncoder = JSONEncoder()) { + let data = try? encoder.encode(object) + self.set(data, forKey: key) + } + } +#endif diff --git a/Sources/Extensions/MapKit/MKPolylineExtensions.swift b/Sources/Extensions/MapKit/MKPolylineExtensions.swift index 2528d90d7..e072e8372 100644 --- a/Sources/Extensions/MapKit/MKPolylineExtensions.swift +++ b/Sources/Extensions/MapKit/MKPolylineExtensions.swift @@ -6,11 +6,11 @@ // Copyright © 2018 SwifterSwift // -#if !os(watchOS) - +#if canImport(MapKit) import MapKit // MARK: - Initializers +#if !os(watchOS) @available(tvOS 9.2, *) public extension MKPolyline { @@ -19,24 +19,25 @@ public extension MKPolyline { /// - Parameter coordinates: Array of CLLocationCoordinate2D(s). public convenience init(coordinates: [CLLocationCoordinate2D]) { var refCoordinates = coordinates - self.init(coordinates: &refCoordinates, count: refCoordinates.count) } + } +#endif +#if !os(watchOS) // MARK: - Properties @available(tvOS 9.2, *) public extension MKPolyline { /// SwifterSwift: Return an Array of coordinates representing the provided polyline. public var coordinates: [CLLocationCoordinate2D] { - var coords = [CLLocationCoordinate2D](repeating: kCLLocationCoordinate2DInvalid, - count: pointCount) - + var coords = [CLLocationCoordinate2D](repeating: kCLLocationCoordinate2DInvalid, count: pointCount) getCoordinates(&coords, range: NSRange(location: 0, length: pointCount)) - return coords } + } +#endif #endif diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index 8e97fa792..c91c6be66 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -6,29 +6,33 @@ // Copyright © 2017 SwifterSwift // -#if os(macOS) - import Cocoa - public typealias Color = NSColor -#else - import UIKit - public typealias Color = UIColor +#if canImport(UIKit) +import UIKit +public typealias Color = UIColor +#endif + +#if canImport(Cocoa) +import Cocoa +public typealias Color = NSColor #endif #if !os(watchOS) - import CoreImage +import CoreImage #endif +#if !os(Linux) // MARK: - Properties public extension Color { - + /// SwifterSwift: Random color. public static var random: Color { - let r = Int(arc4random_uniform(255)) - let g = Int(arc4random_uniform(255)) - let b = Int(arc4random_uniform(255)) - return Color(red: r, green: g, blue: b)! + let red = Int(arc4random_uniform(255)) + let green = Int(arc4random_uniform(255)) + let blue = Int(arc4random_uniform(255)) + return Color(red: red, green: green, blue: blue)! } - + + // swiftlint:disable large_tuple /// SwifterSwift: RGB components for a Color (between 0 and 255). /// /// UIColor.red.rgbComponents.red -> 255 @@ -37,18 +41,18 @@ public extension Color { /// public var rgbComponents: (red: Int, green: Int, blue: Int) { var components: [CGFloat] { - let c = cgColor.components! - if c.count == 4 { - return c - } - return [c[0], c[0], c[0], c[1]] + let comps = cgColor.components! + if comps.count == 4 { return comps } + return [comps[0], comps[0], comps[0], comps[1]] } - let r = components[0] - let g = components[1] - let b = components[2] - return (red: Int(r * 255.0), green: Int(g * 255.0), blue: Int(b * 255.0)) + let red = components[0] + let green = components[1] + let blue = components[2] + return (red: Int(red * 255.0), green: Int(green * 255.0), blue: Int(blue * 255.0)) } - + // swiftlint:enable large_tuple + + // swiftlint:disable large_tuple /// SwifterSwift: RGB components for a Color represented as CGFloat numbers (between 0 and 1) /// /// UIColor.red.rgbComponents.red -> 1.0 @@ -57,39 +61,40 @@ public extension Color { /// public var cgFloatComponents: (red: CGFloat, green: CGFloat, blue: CGFloat) { var components: [CGFloat] { - let c = cgColor.components! - if c.count == 4 { - return c - } - return [c[0], c[0], c[0], c[1]] + let comps = cgColor.components! + if comps.count == 4 { return comps } + return [comps[0], comps[0], comps[0], comps[1]] } - let r = components[0] - let g = components[1] - let b = components[2] - return (red: r, green: g, blue: b) + let red = components[0] + let green = components[1] + let blue = components[2] + return (red: red, green: green, blue: blue) } - + // swiftlint:enable large_tuple + + // swiftlint:disable large_tuple /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { - var h: CGFloat = 0.0 - var s: CGFloat = 0.0 - var b: CGFloat = 0.0 - var a: CGFloat = 0.0 - - self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) - return (hue: h, saturation: s, brightness: b, alpha: a) + var hue: CGFloat = 0.0 + var saturation: CGFloat = 0.0 + var brightness: CGFloat = 0.0 + var alpha: CGFloat = 0.0 + + getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + return (hue: hue, saturation: saturation, brightness: brightness, alpha: alpha) } - + // swiftlint:enable large_tuple + /// SwifterSwift: Hexadecimal value string (read-only). public var hexString: String { - let components: [Int] = { - let c = cgColor.components! - let components = c.count == 4 ? c : [c[0], c[0], c[0], c[1]] - return components.map { Int($0 * 255.0) } - }() - return String(format: "#%02X%02X%02X", components[0], components[1], components[2]) + let components: [Int] = { + let comps = cgColor.components! + let components = comps.count == 4 ? comps : [comps[0], comps[0], comps[0], comps[1]] + return components.map { Int($0 * 255.0) } + }() + return String(format: "#%02X%02X%02X", components[0], components[1], components[2]) } - + /// SwifterSwift: Short hexadecimal value string (read-only, if applicable). public var shortHexString: String? { let string = hexString.replacingOccurrences(of: "#", with: "") @@ -97,78 +102,78 @@ public extension Color { guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return nil } return "#\(chrs[0])\(chrs[2])\(chrs[4])" } - + /// SwifterSwift: Short hexadecimal value string, or full hexadecimal string if not possible (read-only). public var shortHexOrHexString: String { - let components: [Int] = { - let c = cgColor.components! - let components = c.count == 4 ? c : [c[0], c[0], c[0], c[1]] - return components.map { Int($0 * 255.0) } - }() - let hexString = String(format: "#%02X%02X%02X", components[0], components[1], components[2]) - let string = hexString.replacingOccurrences(of: "#", with: "") - let chrs = Array(string) - guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return hexString } - return "#\(chrs[0])\(chrs[2])\(chrs[4])" + let components: [Int] = { + let comps = cgColor.components! + let components = comps.count == 4 ? comps : [comps[0], comps[0], comps[0], comps[1]] + return components.map { Int($0 * 255.0) } + }() + let hexString = String(format: "#%02X%02X%02X", components[0], components[1], components[2]) + let string = hexString.replacingOccurrences(of: "#", with: "") + let chrs = Array(string) + guard chrs[0] == chrs[1], chrs[2] == chrs[3], chrs[4] == chrs[5] else { return hexString } + return "#\(chrs[0])\(chrs[2])\(chrs[4])" } - + /// SwifterSwift: Alpha of Color (read-only). public var alpha: CGFloat { return cgColor.alpha } - + #if !os(watchOS) /// SwifterSwift: CoreImage.CIColor (read-only) public var coreImageColor: CoreImage.CIColor? { return CoreImage.CIColor(color: self) } #endif - + /// SwifterSwift: Get UInt representation of a Color (read-only). public var uInt: UInt { - let c: [CGFloat] = { - let c = cgColor.components! - return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] - }() - + let comps: [CGFloat] = { + let comps = cgColor.components! + return comps.count == 4 ? comps : [comps[0], comps[0], comps[0], comps[1]] + }() + var colorAsUInt32: UInt32 = 0 - colorAsUInt32 += UInt32(c[0] * 255.0) << 16 - colorAsUInt32 += UInt32(c[1] * 255.0) << 8 - colorAsUInt32 += UInt32(c[2] * 255.0) - + colorAsUInt32 += UInt32(comps[0] * 255.0) << 16 + colorAsUInt32 += UInt32(comps[1] * 255.0) << 8 + colorAsUInt32 += UInt32(comps[2] * 255.0) + return UInt(colorAsUInt32) } - + /// SwifterSwift: Get color complementary (read-only, if applicable). public var complementary: Color? { - let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() - let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in - if self.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { - let oldComponents = self.cgColor.components - let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] - let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) - let colorOut = Color(cgColor: colorRef!) - return colorOut - } else { - return self - } - } - - let c = convertColorToRGBSpace(self) - guard let componentColors = c?.cgColor.components else { return nil } - - let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 - let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 - let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 - - return Color(red: r, green: g, blue: b, alpha: 1.0) + let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() + let convertColorToRGBSpace: ((_ color: Color) -> Color?) = { color -> Color? in + if self.cgColor.colorSpace!.model == CGColorSpaceModel.monochrome { + let oldComponents = self.cgColor.components + let components: [CGFloat] = [ oldComponents![0], oldComponents![0], oldComponents![0], oldComponents![1]] + let colorRef = CGColor(colorSpace: colorSpaceRGB, components: components) + let colorOut = Color(cgColor: colorRef!) + return colorOut + } else { + return self + } + } + + let color = convertColorToRGBSpace(self) + guard let componentColors = color?.cgColor.components else { return nil } + + let red: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 + let green: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 + let blue: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 + + return Color(red: red, green: green, blue: blue, alpha: 1.0) } - + } // MARK: - Methods public extension Color { - + /// SwifterSwift: Blend two Colors /// /// - Parameters: @@ -179,82 +184,83 @@ public extension Color { /// - Returns: Color created by blending first and seond colors. public static func blend(_ color1: Color, intensity1: CGFloat = 0.5, with color2: Color, intensity2: CGFloat = 0.5) -> Color { // http://stackoverflow.com/questions/27342715/blend-uicolors-in-swift - + let total = intensity1 + intensity2 let level1 = intensity1/total let level2 = intensity2/total - + guard level1 > 0 else { return color2 } guard level2 > 0 else { return color1 } - - let components1: [CGFloat] = { - let c = color1.cgColor.components! - return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] - }() - let components2: [CGFloat] = { - let c = color2.cgColor.components! - return c.count == 4 ? c : [c[0], c[0], c[0], c[1]] - }() - - let r1 = components1[0] - let r2 = components2[0] - - let g1 = components1[1] - let g2 = components2[1] - - let b1 = components1[2] - let b2 = components2[2] - - let a1 = color1.cgColor.alpha - let a2 = color2.cgColor.alpha - - let r = level1*r1 + level2*r2 - let g = level1*g1 + level2*g2 - let b = level1*b1 + level2*b2 - let a = level1*a1 + level2*a2 - - return Color(red: r, green: g, blue: b, alpha: a) - + + let components1: [CGFloat] = { + let comps = color1.cgColor.components! + return comps.count == 4 ? comps : [comps[0], comps[0], comps[0], comps[1]] + }() + + let components2: [CGFloat] = { + let comps = color2.cgColor.components! + return comps.count == 4 ? comps : [comps[0], comps[0], comps[0], comps[1]] + }() + + let red1 = components1[0] + let red2 = components2[0] + + let green1 = components1[1] + let green2 = components2[1] + + let blue1 = components1[2] + let blue2 = components2[2] + + let alpha1 = color1.cgColor.alpha + let alpha2 = color2.cgColor.alpha + + let red = level1*red1 + level2*red2 + let green = level1*green1 + level2*green2 + let blue = level1*blue1 + level2*blue2 + let alpha = level1*alpha1 + level2*alpha2 + + return Color(red: red, green: green, blue: blue, alpha: alpha) + } + + /// SwifterSwift: Lighten a color + /// + /// let color = Color(red: r, green: g, blue: b, alpha: a) + /// let lighterColor: Color = color.lighten(by: 0.2) + /// + /// - Parameter percentage: Percentage by which to lighten the color + /// - Returns: A lightened color + public func lighten(by percentage: CGFloat = 0.2) -> Color { + // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 + self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return Color(red: min(red + percentage, 1.0), + green: min(green + percentage, 1.0), + blue: min(blue + percentage, 1.0), + alpha: alpha) + } + + /// SwifterSwift: Darken a color + /// + /// let color = Color(red: r, green: g, blue: b, alpha: a) + /// let darkerColor: Color = color.darken(by: 0.2) + /// + /// - Parameter percentage: Percentage by which to darken the color + /// - Returns: A darkened color + public func darken(by percentage: CGFloat = 0.2) -> Color { + // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 + self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return Color(red: max(red - percentage, 0), + green: max(green - percentage, 0), + blue: max(blue - percentage, 0), + alpha: alpha) } - - /// SwifterSwift: Lighten a color - /// - /// let color = Color(red: r, green: g, blue: b, alpha: a) - /// let lighterColor: Color = color.lighten(by: 0.2) - /// - /// - Parameter percentage: Percentage by which to lighten the color - /// - Returns: A lightened color - public func lighten(by percentage: CGFloat = 0.2) -> Color { - // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor - var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 - self.getRed(&r, green: &g, blue: &b, alpha: &a) - return Color(red: min(r + percentage, 1.0), - green: min(g + percentage, 1.0), - blue: min(b + percentage, 1.0), - alpha: a) - } - - /// SwifterSwift: Darken a color - /// - /// let color = Color(red: r, green: g, blue: b, alpha: a) - /// let darkerColor: Color = color.darken(by: 0.2) - /// - /// - Parameter percentage: Percentage by which to darken the color - /// - Returns: A darkened color - public func darken(by percentage: CGFloat = 0.2) -> Color { - // https://stackoverflow.com/questions/38435308/swift-get-lighter-and-darker-color-variations-for-a-given-uicolor - var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 - self.getRed(&r, green: &g, blue: &b, alpha: &a) - return Color(red: max(r - percentage, 0), - green: max(g - percentage, 0), - blue: max(b - percentage, 0), - alpha: a) - } + } // MARK: - Initializers public extension Color { - + /// SwifterSwift: Create Color from RGB values with optional transparency. /// /// - Parameters: @@ -266,14 +272,14 @@ public extension Color { guard red >= 0 && red <= 255 else { return nil } guard green >= 0 && green <= 255 else { return nil } guard blue >= 0 && blue <= 255 else { return nil } - + var trans = transparency if trans < 0 { trans = 0 } if trans > 1 { trans = 1 } - + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) } - + /// SwifterSwift: Create Color from hexadecimal value with optional transparency. /// /// - Parameters: @@ -283,13 +289,13 @@ public extension Color { var trans = transparency if trans < 0 { trans = 0 } if trans > 1 { trans = 1 } - + let red = (hex >> 16) & 0xff let green = (hex >> 8) & 0xff let blue = hex & 0xff self.init(red: red, green: green, blue: blue, transparency: trans) } - + /// SwifterSwift: Create Color from hexadecimal string with optional transparency (if applicable). /// /// - Parameters: @@ -304,25 +310,25 @@ public extension Color { } else { string = hexString } - + if string.count == 3 { // convert hex to 6 digit format if in short format var str = "" string.forEach { str.append(String(repeating: String($0), count: 2)) } string = str } - + guard let hexValue = Int(string, radix: 16) else { return nil } - - var trans = transparency - if trans < 0 { trans = 0 } - if trans > 1 { trans = 1 } - - let red = (hexValue >> 16) & 0xff - let green = (hexValue >> 8) & 0xff - let blue = hexValue & 0xff - self.init(red: red, green: green, blue: blue, transparency: trans) + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + let red = (hexValue >> 16) & 0xff + let green = (hexValue >> 8) & 0xff + let blue = hexValue & 0xff + self.init(red: red, green: green, blue: blue, transparency: trans) } - + /// SwifterSwift: Create Color from a complementary of a Color (if applicable). /// /// - Parameter color: color of which opposite color is desired. @@ -339,1461 +345,1464 @@ public extension Color { return color } } - - let c = convertColorToRGBSpace(color) - guard let componentColors = c?.cgColor.components else { return nil } - - let r: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 - let g: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 - let b: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 - self.init(red: r, green: g, blue: b, alpha: 1.0) + + let color = convertColorToRGBSpace(color) + guard let componentColors = color?.cgColor.components else { return nil } + + let red: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[0]*255), 2.0))/255 + let green: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[1]*255), 2.0))/255 + let blue: CGFloat = sqrt(pow(255.0, 2.0) - pow((componentColors[2]*255), 2.0))/255 + self.init(red: red, green: green, blue: blue, alpha: 1.0) } - + } +// swiftlint:disable type_body_length // MARK: - Social public extension Color { - + /// SwifterSwift: Brand identity color of popular social media platform. public struct Social { // https://www.lockedowndesign.com/social-media-colors/ - + /// red: 59, green: 89, blue: 152 public static let facebook = Color(red: 59, green: 89, blue: 152)! - + /// red: 0, green: 182, blue: 241 public static let twitter = Color(red: 0, green: 182, blue: 241)! - + /// red: 223, green: 74, blue: 50 public static let googlePlus = Color(red: 223, green: 74, blue: 50)! - + /// red: 0, green: 123, blue: 182 public static let linkedIn = Color(red: 0, green: 123, blue: 182)! - + /// red: 69, green: 187, blue: 255 public static let vimeo = Color(red: 69, green: 187, blue: 255)! - + /// red: 179, green: 18, blue: 23 public static let youtube = Color(red: 179, green: 18, blue: 23)! - + /// red: 195, green: 42, blue: 163 public static let instagram = Color(red: 195, green: 42, blue: 163)! - + /// red: 203, green: 32, blue: 39 public static let pinterest = Color(red: 203, green: 32, blue: 39)! - + /// red: 244, green: 0, blue: 131 public static let flickr = Color(red: 244, green: 0, blue: 131)! - + /// red: 67, green: 2, blue: 151 public static let yahoo = Color(red: 67, green: 2, blue: 151)! - + /// red: 67, green: 2, blue: 151 public static let soundCloud = Color(red: 67, green: 2, blue: 151)! - + /// red: 44, green: 71, blue: 98 public static let tumblr = Color(red: 44, green: 71, blue: 98)! - + /// red: 252, green: 69, blue: 117 public static let foursquare = Color(red: 252, green: 69, blue: 117)! - + /// red: 255, green: 176, blue: 0 public static let swarm = Color(red: 255, green: 176, blue: 0)! - + /// red: 234, green: 76, blue: 137 public static let dribbble = Color(red: 234, green: 76, blue: 137)! - + /// red: 255, green: 87, blue: 0 public static let reddit = Color(red: 255, green: 87, blue: 0)! - + /// red: 74, green: 93, blue: 78 public static let devianArt = Color(red: 74, green: 93, blue: 78)! - + /// red: 238, green: 64, blue: 86 public static let pocket = Color(red: 238, green: 64, blue: 86)! - + /// red: 170, green: 34, blue: 182 public static let quora = Color(red: 170, green: 34, blue: 182)! - + /// red: 247, green: 146, blue: 30 public static let slideShare = Color(red: 247, green: 146, blue: 30)! - + /// red: 0, green: 153, blue: 229 public static let px500 = Color(red: 0, green: 153, blue: 229)! - + /// red: 223, green: 109, blue: 70 public static let listly = Color(red: 223, green: 109, blue: 70)! - + /// red: 0, green: 180, blue: 137 public static let vine = Color(red: 0, green: 180, blue: 137)! - + /// red: 0, green: 175, blue: 240 public static let skype = Color(red: 0, green: 175, blue: 240)! - + /// red: 235, green: 73, blue: 36 public static let stumbleUpon = Color(red: 235, green: 73, blue: 36)! - + /// red: 255, green: 252, blue: 0 public static let snapchat = Color(red: 255, green: 252, blue: 0)! } - + } // MARK: - Material colors public extension Color { - + /// SwifterSwift: Google Material design colors palette. public struct Material { // https://material.google.com/style/color.html - + /// SwifterSwift: color red500 public static let red = red500 - + /// SwifterSwift: hex #FFEBEE public static let red50 = Color(hex: 0xFFEBEE)! - + /// SwifterSwift: hex #FFCDD2 public static let red100 = Color(hex: 0xFFCDD2)! - + /// SwifterSwift: hex #EF9A9A public static let red200 = Color(hex: 0xEF9A9A)! - + /// SwifterSwift: hex #E57373 public static let red300 = Color(hex: 0xE57373)! - + /// SwifterSwift: hex #EF5350 public static let red400 = Color(hex: 0xEF5350)! - + /// SwifterSwift: hex #F44336 public static let red500 = Color(hex: 0xF44336)! - + /// SwifterSwift: hex #E53935 public static let red600 = Color(hex: 0xE53935)! - + /// SwifterSwift: hex #D32F2F public static let red700 = Color(hex: 0xD32F2F)! - + /// SwifterSwift: hex #C62828 public static let red800 = Color(hex: 0xC62828)! - + /// SwifterSwift: hex #B71C1C public static let red900 = Color(hex: 0xB71C1C)! - + /// SwifterSwift: hex #FF8A80 public static let redA100 = Color(hex: 0xFF8A80)! - + /// SwifterSwift: hex #FF5252 public static let redA200 = Color(hex: 0xFF5252)! - + /// SwifterSwift: hex #FF1744 public static let redA400 = Color(hex: 0xFF1744)! - + /// SwifterSwift: hex #D50000 public static let redA700 = Color(hex: 0xD50000)! - + /// SwifterSwift: color pink500 public static let pink = pink500 - + /// SwifterSwift: hex #FCE4EC public static let pink50 = Color(hex: 0xFCE4EC)! - + /// SwifterSwift: hex #F8BBD0 public static let pink100 = Color(hex: 0xF8BBD0)! - + /// SwifterSwift: hex #F48FB1 public static let pink200 = Color(hex: 0xF48FB1)! - + /// SwifterSwift: hex #F06292 public static let pink300 = Color(hex: 0xF06292)! - + /// SwifterSwift: hex #EC407A public static let pink400 = Color(hex: 0xEC407A)! - + /// SwifterSwift: hex #E91E63 public static let pink500 = Color(hex: 0xE91E63)! - + /// SwifterSwift: hex #D81B60 public static let pink600 = Color(hex: 0xD81B60)! - + /// SwifterSwift: hex #C2185B public static let pink700 = Color(hex: 0xC2185B)! - + /// SwifterSwift: hex #AD1457 public static let pink800 = Color(hex: 0xAD1457)! - + /// SwifterSwift: hex #880E4F public static let pink900 = Color(hex: 0x880E4F)! - + /// SwifterSwift: hex #FF80AB public static let pinkA100 = Color(hex: 0xFF80AB)! - + /// SwifterSwift: hex #FF4081 public static let pinkA200 = Color(hex: 0xFF4081)! - + /// SwifterSwift: hex #F50057 public static let pinkA400 = Color(hex: 0xF50057)! - + /// SwifterSwift: hex #C51162 public static let pinkA700 = Color(hex: 0xC51162)! - + /// SwifterSwift: color purple500 public static let purple = purple500 - + /// SwifterSwift: hex #F3E5F5 public static let purple50 = Color(hex: 0xF3E5F5)! - + /// SwifterSwift: hex #E1BEE7 public static let purple100 = Color(hex: 0xE1BEE7)! - + /// SwifterSwift: hex #CE93D8 public static let purple200 = Color(hex: 0xCE93D8)! - + /// SwifterSwift: hex #BA68C8 public static let purple300 = Color(hex: 0xBA68C8)! - + /// SwifterSwift: hex #AB47BC public static let purple400 = Color(hex: 0xAB47BC)! - + /// SwifterSwift: hex #9C27B0 public static let purple500 = Color(hex: 0x9C27B0)! - + /// SwifterSwift: hex #8E24AA public static let purple600 = Color(hex: 0x8E24AA)! - + /// SwifterSwift: hex #7B1FA2 public static let purple700 = Color(hex: 0x7B1FA2)! - + /// SwifterSwift: hex #6A1B9A public static let purple800 = Color(hex: 0x6A1B9A)! - + /// SwifterSwift: hex #4A148C public static let purple900 = Color(hex: 0x4A148C)! - + /// SwifterSwift: hex #EA80FC public static let purpleA100 = Color(hex: 0xEA80FC)! - + /// SwifterSwift: hex #E040FB public static let purpleA200 = Color(hex: 0xE040FB)! - + /// SwifterSwift: hex #D500F9 public static let purpleA400 = Color(hex: 0xD500F9)! - + /// SwifterSwift: hex #AA00FF public static let purpleA700 = Color(hex: 0xAA00FF)! - + /// SwifterSwift: color deepPurple500 public static let deepPurple = deepPurple500 - + /// SwifterSwift: hex #EDE7F6 public static let deepPurple50 = Color(hex: 0xEDE7F6)! - + /// SwifterSwift: hex #D1C4E9 public static let deepPurple100 = Color(hex: 0xD1C4E9)! - + /// SwifterSwift: hex #B39DDB public static let deepPurple200 = Color(hex: 0xB39DDB)! - + /// SwifterSwift: hex #9575CD public static let deepPurple300 = Color(hex: 0x9575CD)! - + /// SwifterSwift: hex #7E57C2 public static let deepPurple400 = Color(hex: 0x7E57C2)! - + /// SwifterSwift: hex #673AB7 public static let deepPurple500 = Color(hex: 0x673AB7)! - + /// SwifterSwift: hex #5E35B1 public static let deepPurple600 = Color(hex: 0x5E35B1)! - + /// SwifterSwift: hex #512DA8 public static let deepPurple700 = Color(hex: 0x512DA8)! - + /// SwifterSwift: hex #4527A0 public static let deepPurple800 = Color(hex: 0x4527A0)! - + /// SwifterSwift: hex #311B92 public static let deepPurple900 = Color(hex: 0x311B92)! - + /// SwifterSwift: hex #B388FF public static let deepPurpleA100 = Color(hex: 0xB388FF)! - + /// SwifterSwift: hex #7C4DFF public static let deepPurpleA200 = Color(hex: 0x7C4DFF)! - + /// SwifterSwift: hex #651FFF public static let deepPurpleA400 = Color(hex: 0x651FFF)! - + /// SwifterSwift: hex #6200EA public static let deepPurpleA700 = Color(hex: 0x6200EA)! - + /// SwifterSwift: color indigo500 public static let indigo = indigo500 - + /// SwifterSwift: hex #E8EAF6 public static let indigo50 = Color(hex: 0xE8EAF6)! - + /// SwifterSwift: hex #C5CAE9 public static let indigo100 = Color(hex: 0xC5CAE9)! - + /// SwifterSwift: hex #9FA8DA public static let indigo200 = Color(hex: 0x9FA8DA)! - + /// SwifterSwift: hex #7986CB public static let indigo300 = Color(hex: 0x7986CB)! - + /// SwifterSwift: hex #5C6BC0 public static let indigo400 = Color(hex: 0x5C6BC0)! - + /// SwifterSwift: hex #3F51B5 public static let indigo500 = Color(hex: 0x3F51B5)! - + /// SwifterSwift: hex #3949AB public static let indigo600 = Color(hex: 0x3949AB)! - + /// SwifterSwift: hex #303F9F public static let indigo700 = Color(hex: 0x303F9F)! - + /// SwifterSwift: hex #283593 public static let indigo800 = Color(hex: 0x283593)! - + /// SwifterSwift: hex #1A237E public static let indigo900 = Color(hex: 0x1A237E)! - + /// SwifterSwift: hex #8C9EFF public static let indigoA100 = Color(hex: 0x8C9EFF)! - + /// SwifterSwift: hex #536DFE public static let indigoA200 = Color(hex: 0x536DFE)! - + /// SwifterSwift: hex #3D5AFE public static let indigoA400 = Color(hex: 0x3D5AFE)! - + /// SwifterSwift: hex #304FFE public static let indigoA700 = Color(hex: 0x304FFE)! - + /// SwifterSwift: color blue500 public static let blue = blue500 - + /// SwifterSwift: hex #E3F2FD public static let blue50 = Color(hex: 0xE3F2FD)! - + /// SwifterSwift: hex #BBDEFB public static let blue100 = Color(hex: 0xBBDEFB)! - + /// SwifterSwift: hex #90CAF9 public static let blue200 = Color(hex: 0x90CAF9)! - + /// SwifterSwift: hex #64B5F6 public static let blue300 = Color(hex: 0x64B5F6)! - + /// SwifterSwift: hex #42A5F5 public static let blue400 = Color(hex: 0x42A5F5)! - + /// SwifterSwift: hex #2196F3 public static let blue500 = Color(hex: 0x2196F3)! - + /// SwifterSwift: hex #1E88E5 public static let blue600 = Color(hex: 0x1E88E5)! - + /// SwifterSwift: hex #1976D2 public static let blue700 = Color(hex: 0x1976D2)! - + /// SwifterSwift: hex #1565C0 public static let blue800 = Color(hex: 0x1565C0)! - + /// SwifterSwift: hex #0D47A1 public static let blue900 = Color(hex: 0x0D47A1)! - + /// SwifterSwift: hex #82B1FF public static let blueA100 = Color(hex: 0x82B1FF)! - + /// SwifterSwift: hex #448AFF public static let blueA200 = Color(hex: 0x448AFF)! - + /// SwifterSwift: hex #2979FF public static let blueA400 = Color(hex: 0x2979FF)! - + /// SwifterSwift: hex #2962FF public static let blueA700 = Color(hex: 0x2962FF)! - + /// SwifterSwift: color lightBlue500 public static let lightBlue = lightBlue500 - + /// SwifterSwift: hex #E1F5FE public static let lightBlue50 = Color(hex: 0xE1F5FE)! - + /// SwifterSwift: hex #B3E5FC public static let lightBlue100 = Color(hex: 0xB3E5FC)! - + /// SwifterSwift: hex #81D4FA public static let lightBlue200 = Color(hex: 0x81D4FA)! - + /// SwifterSwift: hex #4FC3F7 public static let lightBlue300 = Color(hex: 0x4FC3F7)! - + /// SwifterSwift: hex #29B6F6 public static let lightBlue400 = Color(hex: 0x29B6F6)! - + /// SwifterSwift: hex #03A9F4 public static let lightBlue500 = Color(hex: 0x03A9F4)! - + /// SwifterSwift: hex #039BE5 public static let lightBlue600 = Color(hex: 0x039BE5)! - + /// SwifterSwift: hex #0288D1 public static let lightBlue700 = Color(hex: 0x0288D1)! - + /// SwifterSwift: hex #0277BD public static let lightBlue800 = Color(hex: 0x0277BD)! - + /// SwifterSwift: hex #01579B public static let lightBlue900 = Color(hex: 0x01579B)! - + /// SwifterSwift: hex #80D8FF public static let lightBlueA100 = Color(hex: 0x80D8FF)! - + /// SwifterSwift: hex #40C4FF public static let lightBlueA200 = Color(hex: 0x40C4FF)! - + /// SwifterSwift: hex #00B0FF public static let lightBlueA400 = Color(hex: 0x00B0FF)! - + /// SwifterSwift: hex #0091EA public static let lightBlueA700 = Color(hex: 0x0091EA)! - + /// SwifterSwift: color cyan500 public static let cyan = cyan500 - + /// SwifterSwift: hex #E0F7FA public static let cyan50 = Color(hex: 0xE0F7FA)! - + /// SwifterSwift: hex #B2EBF2 public static let cyan100 = Color(hex: 0xB2EBF2)! - + /// SwifterSwift: hex #80DEEA public static let cyan200 = Color(hex: 0x80DEEA)! - + /// SwifterSwift: hex #4DD0E1 public static let cyan300 = Color(hex: 0x4DD0E1)! - + /// SwifterSwift: hex #26C6DA public static let cyan400 = Color(hex: 0x26C6DA)! - + /// SwifterSwift: hex #00BCD4 public static let cyan500 = Color(hex: 0x00BCD4)! - + /// SwifterSwift: hex #00ACC1 public static let cyan600 = Color(hex: 0x00ACC1)! - + /// SwifterSwift: hex #0097A7 public static let cyan700 = Color(hex: 0x0097A7)! - + /// SwifterSwift: hex #00838F public static let cyan800 = Color(hex: 0x00838F)! - + /// SwifterSwift: hex #006064 public static let cyan900 = Color(hex: 0x006064)! - + /// SwifterSwift: hex #84FFFF public static let cyanA100 = Color(hex: 0x84FFFF)! - + /// SwifterSwift: hex #18FFFF public static let cyanA200 = Color(hex: 0x18FFFF)! - + /// SwifterSwift: hex #00E5FF public static let cyanA400 = Color(hex: 0x00E5FF)! - + /// SwifterSwift: hex #00B8D4 public static let cyanA700 = Color(hex: 0x00B8D4)! - + /// SwifterSwift: color teal500 public static let teal = teal500 - + /// SwifterSwift: hex #E0F2F1 public static let teal50 = Color(hex: 0xE0F2F1)! - + /// SwifterSwift: hex #B2DFDB public static let teal100 = Color(hex: 0xB2DFDB)! - + /// SwifterSwift: hex #80CBC4 public static let teal200 = Color(hex: 0x80CBC4)! - + /// SwifterSwift: hex #4DB6AC public static let teal300 = Color(hex: 0x4DB6AC)! - + /// SwifterSwift: hex #26A69A public static let teal400 = Color(hex: 0x26A69A)! - + /// SwifterSwift: hex #009688 public static let teal500 = Color(hex: 0x009688)! - + /// SwifterSwift: hex #00897B public static let teal600 = Color(hex: 0x00897B)! - + /// SwifterSwift: hex #00796B public static let teal700 = Color(hex: 0x00796B)! - + /// SwifterSwift: hex #00695C public static let teal800 = Color(hex: 0x00695C)! - + /// SwifterSwift: hex #004D40 public static let teal900 = Color(hex: 0x004D40)! - + /// SwifterSwift: hex #A7FFEB public static let tealA100 = Color(hex: 0xA7FFEB)! - + /// SwifterSwift: hex #64FFDA public static let tealA200 = Color(hex: 0x64FFDA)! - + /// SwifterSwift: hex #1DE9B6 public static let tealA400 = Color(hex: 0x1DE9B6)! - + /// SwifterSwift: hex #00BFA5 public static let tealA700 = Color(hex: 0x00BFA5)! - + /// SwifterSwift: color green500 public static let green = green500 - + /// SwifterSwift: hex #E8F5E9 public static let green50 = Color(hex: 0xE8F5E9)! - + /// SwifterSwift: hex #C8E6C9 public static let green100 = Color(hex: 0xC8E6C9)! - + /// SwifterSwift: hex #A5D6A7 public static let green200 = Color(hex: 0xA5D6A7)! - + /// SwifterSwift: hex #81C784 public static let green300 = Color(hex: 0x81C784)! - + /// SwifterSwift: hex #66BB6A public static let green400 = Color(hex: 0x66BB6A)! - + /// SwifterSwift: hex #4CAF50 public static let green500 = Color(hex: 0x4CAF50)! - + /// SwifterSwift: hex #43A047 public static let green600 = Color(hex: 0x43A047)! - + /// SwifterSwift: hex #388E3C public static let green700 = Color(hex: 0x388E3C)! - + /// SwifterSwift: hex #2E7D32 public static let green800 = Color(hex: 0x2E7D32)! - + /// SwifterSwift: hex #1B5E20 public static let green900 = Color(hex: 0x1B5E20)! - + /// SwifterSwift: hex #B9F6CA public static let greenA100 = Color(hex: 0xB9F6CA)! - + /// SwifterSwift: hex #69F0AE public static let greenA200 = Color(hex: 0x69F0AE)! - + /// SwifterSwift: hex #00E676 public static let greenA400 = Color(hex: 0x00E676)! - + /// SwifterSwift: hex #00C853 public static let greenA700 = Color(hex: 0x00C853)! - + /// SwifterSwift: color lightGreen500 public static let lightGreen = lightGreen500 - + /// SwifterSwift: hex #F1F8E9 public static let lightGreen50 = Color(hex: 0xF1F8E9)! - + /// SwifterSwift: hex #DCEDC8 public static let lightGreen100 = Color(hex: 0xDCEDC8)! - + /// SwifterSwift: hex #C5E1A5 public static let lightGreen200 = Color(hex: 0xC5E1A5)! - + /// SwifterSwift: hex #AED581 public static let lightGreen300 = Color(hex: 0xAED581)! - + /// SwifterSwift: hex #9CCC65 public static let lightGreen400 = Color(hex: 0x9CCC65)! - + /// SwifterSwift: hex #8BC34A public static let lightGreen500 = Color(hex: 0x8BC34A)! - + /// SwifterSwift: hex #7CB342 public static let lightGreen600 = Color(hex: 0x7CB342)! - + /// SwifterSwift: hex #689F38 public static let lightGreen700 = Color(hex: 0x689F38)! - + /// SwifterSwift: hex #558B2F public static let lightGreen800 = Color(hex: 0x558B2F)! - + /// SwifterSwift: hex #33691E public static let lightGreen900 = Color(hex: 0x33691E)! - + /// SwifterSwift: hex #CCFF90 public static let lightGreenA100 = Color(hex: 0xCCFF90)! - + /// SwifterSwift: hex #B2FF59 public static let lightGreenA200 = Color(hex: 0xB2FF59)! - + /// SwifterSwift: hex #76FF03 public static let lightGreenA400 = Color(hex: 0x76FF03)! - + /// SwifterSwift: hex #64DD17 public static let lightGreenA700 = Color(hex: 0x64DD17)! - + /// SwifterSwift: color lime500 public static let lime = lime500 - + /// SwifterSwift: hex #F9FBE7 public static let lime50 = Color(hex: 0xF9FBE7)! - + /// SwifterSwift: hex #F0F4C3 public static let lime100 = Color(hex: 0xF0F4C3)! - + /// SwifterSwift: hex #E6EE9C public static let lime200 = Color(hex: 0xE6EE9C)! - + /// SwifterSwift: hex #DCE775 public static let lime300 = Color(hex: 0xDCE775)! - + /// SwifterSwift: hex #D4E157 public static let lime400 = Color(hex: 0xD4E157)! - + /// SwifterSwift: hex #CDDC39 public static let lime500 = Color(hex: 0xCDDC39)! - + /// SwifterSwift: hex #C0CA33 public static let lime600 = Color(hex: 0xC0CA33)! - + /// SwifterSwift: hex #AFB42B public static let lime700 = Color(hex: 0xAFB42B)! - + /// SwifterSwift: hex #9E9D24 public static let lime800 = Color(hex: 0x9E9D24)! - + /// SwifterSwift: hex #827717 public static let lime900 = Color(hex: 0x827717)! - + /// SwifterSwift: hex #F4FF81 public static let limeA100 = Color(hex: 0xF4FF81)! - + /// SwifterSwift: hex #EEFF41 public static let limeA200 = Color(hex: 0xEEFF41)! - + /// SwifterSwift: hex #C6FF00 public static let limeA400 = Color(hex: 0xC6FF00)! - + /// SwifterSwift: hex #AEEA00 public static let limeA700 = Color(hex: 0xAEEA00)! - + /// SwifterSwift: color yellow500 public static let yellow = yellow500 - + /// SwifterSwift: hex #FFFDE7 public static let yellow50 = Color(hex: 0xFFFDE7)! - + /// SwifterSwift: hex #FFF9C4 public static let yellow100 = Color(hex: 0xFFF9C4)! - + /// SwifterSwift: hex #FFF59D public static let yellow200 = Color(hex: 0xFFF59D)! - + /// SwifterSwift: hex #FFF176 public static let yellow300 = Color(hex: 0xFFF176)! - + /// SwifterSwift: hex #FFEE58 public static let yellow400 = Color(hex: 0xFFEE58)! - + /// SwifterSwift: hex #FFEB3B public static let yellow500 = Color(hex: 0xFFEB3B)! - + /// SwifterSwift: hex #FDD835 public static let yellow600 = Color(hex: 0xFDD835)! - + /// SwifterSwift: hex #FBC02D public static let yellow700 = Color(hex: 0xFBC02D)! - + /// SwifterSwift: hex #F9A825 public static let yellow800 = Color(hex: 0xF9A825)! - + /// SwifterSwift: hex #F57F17 public static let yellow900 = Color(hex: 0xF57F17)! - + /// SwifterSwift: hex #FFFF8D public static let yellowA100 = Color(hex: 0xFFFF8D)! - + /// SwifterSwift: hex #FFFF00 public static let yellowA200 = Color(hex: 0xFFFF00)! - + /// SwifterSwift: hex #FFEA00 public static let yellowA400 = Color(hex: 0xFFEA00)! - + /// SwifterSwift: hex #FFD600 public static let yellowA700 = Color(hex: 0xFFD600)! - + /// SwifterSwift: color amber500 public static let amber = amber500 - + /// SwifterSwift: hex #FFF8E1 public static let amber50 = Color(hex: 0xFFF8E1)! - + /// SwifterSwift: hex #FFECB3 public static let amber100 = Color(hex: 0xFFECB3)! - + /// SwifterSwift: hex #FFE082 public static let amber200 = Color(hex: 0xFFE082)! - + /// SwifterSwift: hex #FFD54F public static let amber300 = Color(hex: 0xFFD54F)! - + /// SwifterSwift: hex #FFCA28 public static let amber400 = Color(hex: 0xFFCA28)! - + /// SwifterSwift: hex #FFC107 public static let amber500 = Color(hex: 0xFFC107)! - + /// SwifterSwift: hex #FFB300 public static let amber600 = Color(hex: 0xFFB300)! - + /// SwifterSwift: hex #FFA000 public static let amber700 = Color(hex: 0xFFA000)! - + /// SwifterSwift: hex #FF8F00 public static let amber800 = Color(hex: 0xFF8F00)! - + /// SwifterSwift: hex #FF6F00 public static let amber900 = Color(hex: 0xFF6F00)! - + /// SwifterSwift: hex #FFE57F public static let amberA100 = Color(hex: 0xFFE57F)! - + /// SwifterSwift: hex #FFD740 public static let amberA200 = Color(hex: 0xFFD740)! - + /// SwifterSwift: hex #FFC400 public static let amberA400 = Color(hex: 0xFFC400)! - + /// SwifterSwift: hex #FFAB00 public static let amberA700 = Color(hex: 0xFFAB00)! - + /// SwifterSwift: color orange500 public static let orange = orange500 - + /// SwifterSwift: hex #FFF3E0 public static let orange50 = Color(hex: 0xFFF3E0)! - + /// SwifterSwift: hex #FFE0B2 public static let orange100 = Color(hex: 0xFFE0B2)! - + /// SwifterSwift: hex #FFCC80 public static let orange200 = Color(hex: 0xFFCC80)! - + /// SwifterSwift: hex #FFB74D public static let orange300 = Color(hex: 0xFFB74D)! - + /// SwifterSwift: hex #FFA726 public static let orange400 = Color(hex: 0xFFA726)! - + /// SwifterSwift: hex #FF9800 public static let orange500 = Color(hex: 0xFF9800)! - + /// SwifterSwift: hex #FB8C00 public static let orange600 = Color(hex: 0xFB8C00)! - + /// SwifterSwift: hex #F57C00 public static let orange700 = Color(hex: 0xF57C00)! - + /// SwifterSwift: hex #EF6C00 public static let orange800 = Color(hex: 0xEF6C00)! - + /// SwifterSwift: hex #E65100 public static let orange900 = Color(hex: 0xE65100)! - + /// SwifterSwift: hex #FFD180 public static let orangeA100 = Color(hex: 0xFFD180)! - + /// SwifterSwift: hex #FFAB40 public static let orangeA200 = Color(hex: 0xFFAB40)! - + /// SwifterSwift: hex #FF9100 public static let orangeA400 = Color(hex: 0xFF9100)! - + /// SwifterSwift: hex #FF6D00 public static let orangeA700 = Color(hex: 0xFF6D00)! - + /// SwifterSwift: color deepOrange500 public static let deepOrange = deepOrange500 - + /// SwifterSwift: hex #FBE9E7 public static let deepOrange50 = Color(hex: 0xFBE9E7)! - + /// SwifterSwift: hex #FFCCBC public static let deepOrange100 = Color(hex: 0xFFCCBC)! - + /// SwifterSwift: hex #FFAB91 public static let deepOrange200 = Color(hex: 0xFFAB91)! - + /// SwifterSwift: hex #FF8A65 public static let deepOrange300 = Color(hex: 0xFF8A65)! - + /// SwifterSwift: hex #FF7043 public static let deepOrange400 = Color(hex: 0xFF7043)! - + /// SwifterSwift: hex #FF5722 public static let deepOrange500 = Color(hex: 0xFF5722)! - + /// SwifterSwift: hex #F4511E public static let deepOrange600 = Color(hex: 0xF4511E)! - + /// SwifterSwift: hex #E64A19 public static let deepOrange700 = Color(hex: 0xE64A19)! - + /// SwifterSwift: hex #D84315 public static let deepOrange800 = Color(hex: 0xD84315)! - + /// SwifterSwift: hex #BF360C public static let deepOrange900 = Color(hex: 0xBF360C)! - + /// SwifterSwift: hex #FF9E80 public static let deepOrangeA100 = Color(hex: 0xFF9E80)! - + /// SwifterSwift: hex #FF6E40 public static let deepOrangeA200 = Color(hex: 0xFF6E40)! - + /// SwifterSwift: hex #FF3D00 public static let deepOrangeA400 = Color(hex: 0xFF3D00)! - + /// SwifterSwift: hex #DD2C00 public static let deepOrangeA700 = Color(hex: 0xDD2C00)! - + /// SwifterSwift: color brown500 public static let brown = brown500 - + /// SwifterSwift: hex #EFEBE9 public static let brown50 = Color(hex: 0xEFEBE9)! - + /// SwifterSwift: hex #D7CCC8 public static let brown100 = Color(hex: 0xD7CCC8)! - + /// SwifterSwift: hex #BCAAA4 public static let brown200 = Color(hex: 0xBCAAA4)! - + /// SwifterSwift: hex #A1887F public static let brown300 = Color(hex: 0xA1887F)! - + /// SwifterSwift: hex #8D6E63 public static let brown400 = Color(hex: 0x8D6E63)! - + /// SwifterSwift: hex #795548 public static let brown500 = Color(hex: 0x795548)! - + /// SwifterSwift: hex #6D4C41 public static let brown600 = Color(hex: 0x6D4C41)! - + /// SwifterSwift: hex #5D4037 public static let brown700 = Color(hex: 0x5D4037)! - + /// SwifterSwift: hex #4E342E public static let brown800 = Color(hex: 0x4E342E)! - + /// SwifterSwift: hex #3E2723 public static let brown900 = Color(hex: 0x3E2723)! - + /// SwifterSwift: color grey500 public static let grey = grey500 - + /// SwifterSwift: hex #FAFAFA public static let grey50 = Color(hex: 0xFAFAFA)! - + /// SwifterSwift: hex #F5F5F5 public static let grey100 = Color(hex: 0xF5F5F5)! - + /// SwifterSwift: hex #EEEEEE public static let grey200 = Color(hex: 0xEEEEEE)! - + /// SwifterSwift: hex #E0E0E0 public static let grey300 = Color(hex: 0xE0E0E0)! - + /// SwifterSwift: hex #BDBDBD public static let grey400 = Color(hex: 0xBDBDBD)! - + /// SwifterSwift: hex #9E9E9E public static let grey500 = Color(hex: 0x9E9E9E)! - + /// SwifterSwift: hex #757575 public static let grey600 = Color(hex: 0x757575)! - + /// SwifterSwift: hex #616161 public static let grey700 = Color(hex: 0x616161)! - + /// SwifterSwift: hex #424242 public static let grey800 = Color(hex: 0x424242)! - + /// SwifterSwift: hex #212121 public static let grey900 = Color(hex: 0x212121)! - + /// SwifterSwift: color blueGrey500 public static let blueGrey = blueGrey500 - + /// SwifterSwift: hex #ECEFF1 public static let blueGrey50 = Color(hex: 0xECEFF1)! - + /// SwifterSwift: hex #CFD8DC public static let blueGrey100 = Color(hex: 0xCFD8DC)! - + /// SwifterSwift: hex #B0BEC5 public static let blueGrey200 = Color(hex: 0xB0BEC5)! - + /// SwifterSwift: hex #90A4AE public static let blueGrey300 = Color(hex: 0x90A4AE)! - + /// SwifterSwift: hex #78909C public static let blueGrey400 = Color(hex: 0x78909C)! - + /// SwifterSwift: hex #607D8B public static let blueGrey500 = Color(hex: 0x607D8B)! - + /// SwifterSwift: hex #546E7A public static let blueGrey600 = Color(hex: 0x546E7A)! - + /// SwifterSwift: hex #455A64 public static let blueGrey700 = Color(hex: 0x455A64)! - + /// SwifterSwift: hex #37474F public static let blueGrey800 = Color(hex: 0x37474F)! - + /// SwifterSwift: hex #263238 public static let blueGrey900 = Color(hex: 0x263238)! - + /// SwifterSwift: hex #000000 public static let black = Color(hex: 0x000000)! - + /// SwifterSwift: hex #FFFFFF public static let white = Color(hex: 0xFFFFFF)! } - + } // MARK: - CSS colors public extension Color { - + /// SwifterSwift: CSS colors. public struct CSS { // http://www.w3schools.com/colors/colors_names.asp - + /// SwifterSwift: hex #F0F8FF public static let aliceBlue = Color(hex: 0xF0F8FF)! - + /// SwifterSwift: hex #FAEBD7 public static let antiqueWhite = Color(hex: 0xFAEBD7)! - + /// SwifterSwift: hex #00FFFF public static let aqua = Color(hex: 0x00FFFF)! - + /// SwifterSwift: hex #7FFFD4 public static let aquamarine = Color(hex: 0x7FFFD4)! - + /// SwifterSwift: hex #F0FFFF public static let azure = Color(hex: 0xF0FFFF)! - + /// SwifterSwift: hex #F5F5DC public static let beige = Color(hex: 0xF5F5DC)! - + /// SwifterSwift: hex #FFE4C4 public static let bisque = Color(hex: 0xFFE4C4)! - + /// SwifterSwift: hex #000000 public static let black = Color(hex: 0x000000)! - + /// SwifterSwift: hex #FFEBCD public static let blanchedAlmond = Color(hex: 0xFFEBCD)! - + /// SwifterSwift: hex #0000FF public static let blue = Color(hex: 0x0000FF)! - + /// SwifterSwift: hex #8A2BE2 public static let blueViolet = Color(hex: 0x8A2BE2)! - + /// SwifterSwift: hex #A52A2A public static let brown = Color(hex: 0xA52A2A)! - + /// SwifterSwift: hex #DEB887 public static let burlyWood = Color(hex: 0xDEB887)! - + /// SwifterSwift: hex #5F9EA0 public static let cadetBlue = Color(hex: 0x5F9EA0)! - + /// SwifterSwift: hex #7FFF00 public static let chartreuse = Color(hex: 0x7FFF00)! - + /// SwifterSwift: hex #D2691E public static let chocolate = Color(hex: 0xD2691E)! - + /// SwifterSwift: hex #FF7F50 public static let coral = Color(hex: 0xFF7F50)! - + /// SwifterSwift: hex #6495ED public static let cornflowerBlue = Color(hex: 0x6495ED)! - + /// SwifterSwift: hex #FFF8DC public static let cornsilk = Color(hex: 0xFFF8DC)! - + /// SwifterSwift: hex #DC143C public static let crimson = Color(hex: 0xDC143C)! - + /// SwifterSwift: hex #00FFFF public static let cyan = Color(hex: 0x00FFFF)! - + /// SwifterSwift: hex #00008B public static let darkBlue = Color(hex: 0x00008B)! - + /// SwifterSwift: hex #008B8B public static let darkCyan = Color(hex: 0x008B8B)! - + /// SwifterSwift: hex #B8860B public static let darkGoldenRod = Color(hex: 0xB8860B)! - + /// SwifterSwift: hex #A9A9A9 public static let darkGray = Color(hex: 0xA9A9A9)! - + /// SwifterSwift: hex #A9A9A9 public static let darkGrey = Color(hex: 0xA9A9A9)! - + /// SwifterSwift: hex #006400 public static let darkGreen = Color(hex: 0x006400)! - + /// SwifterSwift: hex #BDB76B public static let darkKhaki = Color(hex: 0xBDB76B)! - + /// SwifterSwift: hex #8B008B public static let darkMagenta = Color(hex: 0x8B008B)! - + /// SwifterSwift: hex #556B2F public static let darkOliveGreen = Color(hex: 0x556B2F)! - + /// SwifterSwift: hex #FF8C00 public static let darkOrange = Color(hex: 0xFF8C00)! - + /// SwifterSwift: hex #9932CC public static let darkOrchid = Color(hex: 0x9932CC)! - + /// SwifterSwift: hex #8B0000 public static let darkRed = Color(hex: 0x8B0000)! - + /// SwifterSwift: hex #E9967A public static let darkSalmon = Color(hex: 0xE9967A)! - + /// SwifterSwift: hex #8FBC8F public static let darkSeaGreen = Color(hex: 0x8FBC8F)! - + /// SwifterSwift: hex #483D8B public static let darkSlateBlue = Color(hex: 0x483D8B)! - + /// SwifterSwift: hex #2F4F4F public static let darkSlateGray = Color(hex: 0x2F4F4F)! - + /// SwifterSwift: hex #2F4F4F public static let darkSlateGrey = Color(hex: 0x2F4F4F)! - + /// SwifterSwift: hex #00CED1 public static let darkTurquoise = Color(hex: 0x00CED1)! - + /// SwifterSwift: hex #9400D3 public static let darkViolet = Color(hex: 0x9400D3)! - + /// SwifterSwift: hex #FF1493 public static let deepPink = Color(hex: 0xFF1493)! - + /// SwifterSwift: hex #00BFFF public static let deepSkyBlue = Color(hex: 0x00BFFF)! - + /// SwifterSwift: hex #696969 public static let dimGray = Color(hex: 0x696969)! - + /// SwifterSwift: hex #696969 public static let dimGrey = Color(hex: 0x696969)! - + /// SwifterSwift: hex #1E90FF public static let dodgerBlue = Color(hex: 0x1E90FF)! - + /// SwifterSwift: hex #B22222 public static let fireBrick = Color(hex: 0xB22222)! - + /// SwifterSwift: hex #FFFAF0 public static let floralWhite = Color(hex: 0xFFFAF0)! - + /// SwifterSwift: hex #228B22 public static let forestGreen = Color(hex: 0x228B22)! - + /// SwifterSwift: hex #FF00FF public static let fuchsia = Color(hex: 0xFF00FF)! - + /// SwifterSwift: hex #DCDCDC public static let gainsboro = Color(hex: 0xDCDCDC)! - + /// SwifterSwift: hex #F8F8FF public static let ghostWhite = Color(hex: 0xF8F8FF)! - + /// SwifterSwift: hex #FFD700 public static let gold = Color(hex: 0xFFD700)! - + /// SwifterSwift: hex #DAA520 public static let goldenRod = Color(hex: 0xDAA520)! - + /// SwifterSwift: hex #808080 public static let gray = Color(hex: 0x808080)! - + /// SwifterSwift: hex #808080 public static let grey = Color(hex: 0x808080)! - + /// SwifterSwift: hex #008000 public static let green = Color(hex: 0x008000)! - + /// SwifterSwift: hex #ADFF2F public static let greenYellow = Color(hex: 0xADFF2F)! - + /// SwifterSwift: hex #F0FFF0 public static let honeyDew = Color(hex: 0xF0FFF0)! - + /// SwifterSwift: hex #FF69B4 public static let hotPink = Color(hex: 0xFF69B4)! - + /// SwifterSwift: hex #CD5C5C public static let indianRed = Color(hex: 0xCD5C5C)! - + /// SwifterSwift: hex #4B0082 public static let indigo = Color(hex: 0x4B0082)! - + /// SwifterSwift: hex #FFFFF0 public static let ivory = Color(hex: 0xFFFFF0)! - + /// SwifterSwift: hex #F0E68C public static let khaki = Color(hex: 0xF0E68C)! - + /// SwifterSwift: hex #E6E6FA public static let lavender = Color(hex: 0xE6E6FA)! - + /// SwifterSwift: hex #FFF0F5 public static let lavenderBlush = Color(hex: 0xFFF0F5)! - + /// SwifterSwift: hex #7CFC00 public static let lawnGreen = Color(hex: 0x7CFC00)! - + /// SwifterSwift: hex #FFFACD public static let lemonChiffon = Color(hex: 0xFFFACD)! - + /// SwifterSwift: hex #ADD8E6 public static let lightBlue = Color(hex: 0xADD8E6)! - + /// SwifterSwift: hex #F08080 public static let lightCoral = Color(hex: 0xF08080)! - + /// SwifterSwift: hex #E0FFFF public static let lightCyan = Color(hex: 0xE0FFFF)! - + /// SwifterSwift: hex #FAFAD2 public static let lightGoldenRodYellow = Color(hex: 0xFAFAD2)! - + /// SwifterSwift: hex #D3D3D3 public static let lightGray = Color(hex: 0xD3D3D3)! - + /// SwifterSwift: hex #D3D3D3 public static let lightGrey = Color(hex: 0xD3D3D3)! - + /// SwifterSwift: hex #90EE90 public static let lightGreen = Color(hex: 0x90EE90)! - + /// SwifterSwift: hex #FFB6C1 public static let lightPink = Color(hex: 0xFFB6C1)! - + /// SwifterSwift: hex #FFA07A public static let lightSalmon = Color(hex: 0xFFA07A)! - + /// SwifterSwift: hex #20B2AA public static let lightSeaGreen = Color(hex: 0x20B2AA)! - + /// SwifterSwift: hex #87CEFA public static let lightSkyBlue = Color(hex: 0x87CEFA)! - + /// SwifterSwift: hex #778899 public static let lightSlateGray = Color(hex: 0x778899)! - + /// SwifterSwift: hex #778899 public static let lightSlateGrey = Color(hex: 0x778899)! - + /// SwifterSwift: hex #B0C4DE public static let lightSteelBlue = Color(hex: 0xB0C4DE)! - + /// SwifterSwift: hex #FFFFE0 public static let lightYellow = Color(hex: 0xFFFFE0)! - + /// SwifterSwift: hex #00FF00 public static let lime = Color(hex: 0x00FF00)! - + /// SwifterSwift: hex #32CD32 public static let limeGreen = Color(hex: 0x32CD32)! - + /// SwifterSwift: hex #FAF0E6 public static let linen = Color(hex: 0xFAF0E6)! - + /// SwifterSwift: hex #FF00FF public static let magenta = Color(hex: 0xFF00FF)! - + /// SwifterSwift: hex #800000 public static let maroon = Color(hex: 0x800000)! - + /// SwifterSwift: hex #66CDAA public static let mediumAquaMarine = Color(hex: 0x66CDAA)! - + /// SwifterSwift: hex #0000CD public static let mediumBlue = Color(hex: 0x0000CD)! - + /// SwifterSwift: hex #BA55D3 public static let mediumOrchid = Color(hex: 0xBA55D3)! - + /// SwifterSwift: hex #9370DB public static let mediumPurple = Color(hex: 0x9370DB)! - + /// SwifterSwift: hex #3CB371 public static let mediumSeaGreen = Color(hex: 0x3CB371)! - + /// SwifterSwift: hex #7B68EE public static let mediumSlateBlue = Color(hex: 0x7B68EE)! - + /// SwifterSwift: hex #00FA9A public static let mediumSpringGreen = Color(hex: 0x00FA9A)! - + /// SwifterSwift: hex #48D1CC public static let mediumTurquoise = Color(hex: 0x48D1CC)! - + /// SwifterSwift: hex #C71585 public static let mediumVioletRed = Color(hex: 0xC71585)! - + /// SwifterSwift: hex #191970 public static let midnightBlue = Color(hex: 0x191970)! - + /// SwifterSwift: hex #F5FFFA public static let mintCream = Color(hex: 0xF5FFFA)! - + /// SwifterSwift: hex #FFE4E1 public static let mistyRose = Color(hex: 0xFFE4E1)! - + /// SwifterSwift: hex #FFE4B5 public static let moccasin = Color(hex: 0xFFE4B5)! - + /// SwifterSwift: hex #FFDEAD public static let navajoWhite = Color(hex: 0xFFDEAD)! - + /// SwifterSwift: hex #000080 public static let navy = Color(hex: 0x000080)! - + /// SwifterSwift: hex #FDF5E6 public static let oldLace = Color(hex: 0xFDF5E6)! - + /// SwifterSwift: hex #808000 public static let olive = Color(hex: 0x808000)! - + /// SwifterSwift: hex #6B8E23 public static let oliveDrab = Color(hex: 0x6B8E23)! - + /// SwifterSwift: hex #FFA500 public static let orange = Color(hex: 0xFFA500)! - + /// SwifterSwift: hex #FF4500 public static let orangeRed = Color(hex: 0xFF4500)! - + /// SwifterSwift: hex #DA70D6 public static let orchid = Color(hex: 0xDA70D6)! - + /// SwifterSwift: hex #EEE8AA public static let paleGoldenRod = Color(hex: 0xEEE8AA)! - + /// SwifterSwift: hex #98FB98 public static let paleGreen = Color(hex: 0x98FB98)! - + /// SwifterSwift: hex #AFEEEE public static let paleTurquoise = Color(hex: 0xAFEEEE)! - + /// SwifterSwift: hex #DB7093 public static let paleVioletRed = Color(hex: 0xDB7093)! - + /// SwifterSwift: hex #FFEFD5 public static let papayaWhip = Color(hex: 0xFFEFD5)! - + /// SwifterSwift: hex #FFDAB9 public static let peachPuff = Color(hex: 0xFFDAB9)! - + /// SwifterSwift: hex #CD853F public static let peru = Color(hex: 0xCD853F)! - + /// SwifterSwift: hex #FFC0CB public static let pink = Color(hex: 0xFFC0CB)! - + /// SwifterSwift: hex #DDA0DD public static let plum = Color(hex: 0xDDA0DD)! - + /// SwifterSwift: hex #B0E0E6 public static let powderBlue = Color(hex: 0xB0E0E6)! - + /// SwifterSwift: hex #800080 public static let purple = Color(hex: 0x800080)! - + /// SwifterSwift: hex #663399 public static let rebeccaPurple = Color(hex: 0x663399)! - + /// SwifterSwift: hex #FF0000 public static let red = Color(hex: 0xFF0000)! - + /// SwifterSwift: hex #BC8F8F public static let rosyBrown = Color(hex: 0xBC8F8F)! - + /// SwifterSwift: hex #4169E1 public static let royalBlue = Color(hex: 0x4169E1)! - + /// SwifterSwift: hex #8B4513 public static let saddleBrown = Color(hex: 0x8B4513)! - + /// SwifterSwift: hex #FA8072 public static let salmon = Color(hex: 0xFA8072)! - + /// SwifterSwift: hex #F4A460 public static let sandyBrown = Color(hex: 0xF4A460)! - + /// SwifterSwift: hex #2E8B57 public static let seaGreen = Color(hex: 0x2E8B57)! - + /// SwifterSwift: hex #FFF5EE public static let seaShell = Color(hex: 0xFFF5EE)! - + /// SwifterSwift: hex #A0522D public static let sienna = Color(hex: 0xA0522D)! - + /// SwifterSwift: hex #C0C0C0 public static let silver = Color(hex: 0xC0C0C0)! - + /// SwifterSwift: hex #87CEEB public static let skyBlue = Color(hex: 0x87CEEB)! - + /// SwifterSwift: hex #6A5ACD public static let slateBlue = Color(hex: 0x6A5ACD)! - + /// SwifterSwift: hex #708090 public static let slateGray = Color(hex: 0x708090)! - + /// SwifterSwift: hex #708090 public static let slateGrey = Color(hex: 0x708090)! - + /// SwifterSwift: hex #FFFAFA public static let snow = Color(hex: 0xFFFAFA)! - + /// SwifterSwift: hex #00FF7F public static let springGreen = Color(hex: 0x00FF7F)! - + /// SwifterSwift: hex #4682B4 public static let steelBlue = Color(hex: 0x4682B4)! - + /// SwifterSwift: hex #D2B48C public static let tan = Color(hex: 0xD2B48C)! - + /// SwifterSwift: hex #008080 public static let teal = Color(hex: 0x008080)! - + /// SwifterSwift: hex #D8BFD8 public static let thistle = Color(hex: 0xD8BFD8)! - + /// SwifterSwift: hex #FF6347 public static let tomato = Color(hex: 0xFF6347)! - + /// SwifterSwift: hex #40E0D0 public static let turquoise = Color(hex: 0x40E0D0)! - + /// SwifterSwift: hex #EE82EE public static let violet = Color(hex: 0xEE82EE)! - + /// SwifterSwift: hex #F5DEB3 public static let wheat = Color(hex: 0xF5DEB3)! - + /// SwifterSwift: hex #FFFFFF public static let white = Color(hex: 0xFFFFFF)! - + /// SwifterSwift: hex #F5F5F5 public static let whiteSmoke = Color(hex: 0xF5F5F5)! - + /// SwifterSwift: hex #FFFF00 public static let yellow = Color(hex: 0xFFFF00)! - + /// SwifterSwift: hex #9ACD32 public static let yellowGreen = Color(hex: 0x9ACD32)! } - + } // MARK: - Flat UI colors public extension Color { - + /// SwifterSwift: Flat UI colors public struct FlatUI { // http://flatuicolors.com. - + /// SwifterSwift: hex #1ABC9C public static let turquoise = Color(hex: 0x1abc9c)! - + /// SwifterSwift: hex #16A085 public static let greenSea = Color(hex: 0x16a085)! - + /// SwifterSwift: hex #2ECC71 public static let emerald = Color(hex: 0x2ecc71)! - + /// SwifterSwift: hex #27AE60 public static let nephritis = Color(hex: 0x27ae60)! - + /// SwifterSwift: hex #3498DB public static let peterRiver = Color(hex: 0x3498db)! - + /// SwifterSwift: hex #2980B9 public static let belizeHole = Color(hex: 0x2980b9)! - + /// SwifterSwift: hex #9B59B6 public static let amethyst = Color(hex: 0x9b59b6)! - + /// SwifterSwift: hex #8E44AD public static let wisteria = Color(hex: 0x8e44ad)! - + /// SwifterSwift: hex #34495E public static let wetAsphalt = Color(hex: 0x34495e)! - + /// SwifterSwift: hex #2C3E50 public static let midnightBlue = Color(hex: 0x2c3e50)! - + /// SwifterSwift: hex #F1C40F public static let sunFlower = Color(hex: 0xf1c40f)! - + /// SwifterSwift: hex #F39C12 public static let flatOrange = Color(hex: 0xf39c12)! - + /// SwifterSwift: hex #E67E22 public static let carrot = Color(hex: 0xe67e22)! - + /// SwifterSwift: hex #D35400 public static let pumkin = Color(hex: 0xd35400)! - + /// SwifterSwift: hex #E74C3C public static let alizarin = Color(hex: 0xe74c3c)! - + /// SwifterSwift: hex #C0392B public static let pomegranate = Color(hex: 0xc0392b)! - + /// SwifterSwift: hex #ECF0F1 public static let clouds = Color(hex: 0xecf0f1)! - + /// SwifterSwift: hex #BDC3C7 public static let silver = Color(hex: 0xbdc3c7)! - + /// SwifterSwift: hex #7F8C8D public static let asbestos = Color(hex: 0x7f8c8d)! - + /// SwifterSwift: hex #95A5A6 public static let concerte = Color(hex: 0x95a5a6)! } - + } +#endif +// swiftlint:enable type_body_length diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 8fd167011..e2080a02b 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -6,9 +6,9 @@ // Copyright © 2016 SwifterSwift // -// MARK: - Methods (Integer) +// MARK: - Methods (Numeric) public extension Array where Element: Numeric { - + /// SwifterSwift: Sum of all elements in array. /// /// [1, 2, 3, 4, 5].sum() -> 15 @@ -16,17 +16,17 @@ public extension Array where Element: Numeric { /// - Returns: sum of the array's elements. public func sum() -> Element { var total: Element = 0 - for i in 0.. Element { guard !isEmpty else { return 0 } var total: Element = 0 - for i in 0.. 3 - /// [1.2, 2.3, 4.5, 3.4, 4.5].item(at: 3) -> 3.4 - /// ["h", "e", "l", "l", "o"].item(at: 10) -> nil - /// - /// - Parameter index: index of element. - /// - Returns: optional element (if exists). - public func item(at index: Int) -> Element? { - guard startIndex.. Element? { - return popLast() - } - + /// SwifterSwift: Insert an element at the beginning of array. /// /// [2, 3, 4, 5].prepend(1) -> [1, 2, 3, 4, 5] @@ -78,17 +55,7 @@ public extension Array { public mutating func prepend(_ newElement: Element) { insert(newElement, at: 0) } - - /// SwifterSwift: Insert an element to the end of array. - /// - /// [1, 2, 3, 4].push(5) -> [1, 2, 3, 4, 5] - /// ["h", "e", "l", "l"].push("o") -> ["h", "e", "l", "l", "o"] - /// - /// - Parameter newElement: element to insert. - public mutating func push(_ newElement: Element) { - append(newElement) - } - + /// SwifterSwift: Safely Swap values at index positions. /// /// [1, 2, 3, 4, 5].safeSwap(from: 3, to: 0) -> [4, 2, 3, 1, 5] @@ -97,87 +64,53 @@ public extension Array { /// - Parameters: /// - index: index of first element. /// - otherIndex: index of other element. - public mutating func safeSwap(from index: Int, to otherIndex: Int) { + public mutating func safeSwap(from index: Index, to otherIndex: Index) { guard index != otherIndex, startIndex.. [4, 2, 3, 1, 5] - /// ["h", "e", "l", "l", "o"].swap(from: 1, to: 0) -> ["e", "h", "l", "l", "o"] - /// - /// - Parameters: - /// - index: index of first element. - /// - otherIndex: index of other element. - public mutating func swap(from index: Int, to otherIndex: Int) { - swapAt(index, otherIndex) - } - + /// SwifterSwift: Get first index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 6].firstIndex { $0 % 2 == 0 } -> 3 /// /// - Parameter condition: condition to evaluate each element against. /// - Returns: first index where the specified condition evaluates to true. (optional) - public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { - for (index, value) in lazy.enumerated() { - if try condition(value) { return index } + public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { + for (index, value) in lazy.enumerated() where try condition(value) { + return index } return nil } - + /// SwifterSwift: Get last index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 8].lastIndex { $0 % 2 == 0 } -> 6 /// /// - Parameter condition: condition to evaluate each element against. /// - Returns: last index where the specified condition evaluates to true. (optional) - public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Int? { - for (index, value) in lazy.enumerated().reversed() { - if try condition(value) { return index } + public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { + for (index, value) in lazy.enumerated().reversed() where try condition(value) { + return index } return nil } - + /// SwifterSwift: Get all indices where condition is met. /// /// [1, 7, 1, 2, 4, 1, 8].indices(where: { $0 == 1 }) -> [0, 2, 5] /// /// - Parameter condition: condition to evaluate each element against. /// - Returns: all indices where the specified condition evaluates to true. (optional) - public func indices(where condition: (Element) throws -> Bool) rethrows -> [Int]? { - var indicies: [Int] = [] - for (index, value) in lazy.enumerated() { - if try condition(value) { indicies.append(index) } + public func indices(where condition: (Element) throws -> Bool) rethrows -> [Index]? { + var indicies: [Index] = [] + for (index, value) in lazy.enumerated() where try condition(value) { + indicies.append(index) } return indicies.isEmpty ? nil : indicies } - - /// SwifterSwift: Check if all elements in array match a conditon. - /// - /// [2, 2, 4].all(matching: {$0 % 2 == 0}) -> true - /// [1,2, 2, 4].all(matching: {$0 % 2 == 0}) -> false - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: true when all elements in the array match the specified condition. - public func all(matching condition: (Element) throws -> Bool) rethrows -> Bool { - return try !contains { try !condition($0) } - } - - /// SwifterSwift: Check if no elements in array match a conditon. - /// - /// [2, 2, 4].none(matching: {$0 % 2 == 0}) -> false - /// [1, 3, 5, 7].none(matching: {$0 % 2 == 0}) -> true - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: true when no elements in the array match the specified condition. - public func none(matching condition: (Element) throws -> Bool) rethrows -> Bool { - return try !contains { try condition($0) } - } - + /// SwifterSwift: Get last element that satisfies a conditon. /// /// [2, 2, 4, 7].last(where: {$0 % 2 == 0}) -> 4 @@ -190,7 +123,7 @@ public extension Array { } return nil } - + /// SwifterSwift: Filter elements based on a rejection condition. /// /// [2, 2, 4, 7].reject(where: {$0 % 2 == 0}) -> [7] @@ -200,7 +133,7 @@ public extension Array { public func reject(where condition: (Element) throws -> Bool) rethrows -> [Element] { return try filter { return try !condition($0) } } - + /// SwifterSwift: Get element count based on condition. /// /// [2, 2, 4, 7].count(where: {$0 % 2 == 0}) -> 3 @@ -214,7 +147,7 @@ public extension Array { } return count } - + /// SwifterSwift: Iterate over a collection in reverse order. (right to left) /// /// [0, 2, 4, 7].forEachReversed({ print($0)}) -> //Order of print: 7,4,2,0 @@ -223,7 +156,7 @@ public extension Array { public func forEachReversed(_ body: (Element) throws -> Void) rethrows { try reversed().forEach { try body($0) } } - + /// SwifterSwift: Calls given closure with each element where condition is true. /// /// [0, 2, 4, 7].forEach(where: {$0 % 2 == 0}, body: { print($0)}) -> //print: 0, 2, 4 @@ -236,7 +169,7 @@ public extension Array { try body(element) } } - + /// SwifterSwift: Reduces an array while returning each interim combination. /// /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] @@ -252,7 +185,7 @@ public extension Array { return runningTotal } } - + /// SwifterSwift: Filtered and map in a single operation. /// /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] @@ -262,28 +195,28 @@ public extension Array { /// - transform: transform element function to evaluate every element. /// - Returns: Return an filtered and mapped array. public func filtered(_ isIncluded: (Element) throws -> Bool, map transform: (Element) throws -> T) rethrows -> [T] { - return try flatMap({ + return try compactMap({ if try isIncluded($0) { return try transform($0) } return nil }) } - + + @discardableResult /// SwifterSwift: Keep elements of Array while condition is true. /// /// [0, 2, 4, 7].keep( where: {$0 % 2 == 0}) -> [0, 2, 4] /// /// - Parameter condition: condition to evaluate each element against. - public mutating func keep(while condition: (Element) throws -> Bool) rethrows { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - self = Array(self[startIndex.. Bool) rethrows -> [Element] { + for (index, element) in lazy.enumerated() where try !condition(element) { + self = Array(self[startIndex.. [0, 2, 4] @@ -291,14 +224,12 @@ public extension Array { /// - Parameter condition: condition to evaluate each element against. /// - Returns: All elements up until condition evaluates to false. public func take(while condition: (Element) throws -> Bool) rethrows -> [Element] { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - return Array(self[startIndex.. [6, 8] @@ -306,14 +237,12 @@ public extension Array { /// - Parameter condition: condition to evaluate each element against. /// - Returns: All elements after the condition evaluates to false. public func skip(while condition: (Element) throws-> Bool) rethrows -> [Element] { - for (index, element) in lazy.enumerated() { - if try !condition(element) { - return Array(self[index.. //print: [0, 2], [4, 7] @@ -324,21 +253,21 @@ public extension Array { /// - body: a closure that takes an array of slice size as a parameter. public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { guard slice > 0, !isEmpty else { return } - + var value: Int = 0 while value < count { try body(Array(self[Swift.max(value, startIndex).. [[0, 2], [4, 7]] /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] /// - /// - Parameters: - /// - size: The size of the slices to be returned. + /// - Parameter size: The size of the slices to be returned. + /// - Returns: grouped self. public func group(by size: Int) -> [[Element]]? { //Inspired by: https://lodash.com/docs/4.17.4#chunk guard size > 0, !isEmpty else { return nil } @@ -350,7 +279,7 @@ public extension Array { } return slices } - + /// SwifterSwift: Group the elements of the array in a dictionary. /// /// [0, 2, 5, 4, 7].groupByKey { $0%2 ? "evens" : "odds" } -> [ "evens" : [0, 2, 4], "odds" : [5, 7] ] @@ -396,9 +325,7 @@ public extension Array { /// - Returns: The new rotated array public func rotated(by places: Int) -> [Element] { //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate - guard places != 0 && places < count else { - return self - } + guard places != 0 && places < count else { return self } var array: [Element] = self if places > 0 { let range = (array.count - places).. [4,1,2,3] @@ -421,23 +349,29 @@ public extension Array { /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - public mutating func rotate(by places: Int) { + /// + /// - Returns: self after rotating + public mutating func rotate(by places: Int) -> [Element] { self = rotated(by: places) + return self } - + + @discardableResult /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) /// /// [1, 2, 3, 4, 5].shuffle() // shuffles array /// - public mutating func shuffle() { + /// - Returns: self after shuffling + public mutating func shuffle() -> [Element] { // http://stackoverflow.com/questions/37843647/shuffle-array-swift-3 - guard count > 1 else { return } + guard count > 1 else { return self } for index in startIndex.. [Element] { var array = self - array.shuffle() - return array + return array.shuffle() } - + /// SwifterSwift: Return a sorted array based on an optional keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. @@ -463,7 +396,7 @@ public extension Array { return lhsValue > rhsValue }) } - + /// SwifterSwift: Return a sorted array based on a keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. @@ -477,28 +410,32 @@ public extension Array { return lhs[keyPath: path] > rhs[keyPath: path] }) } - + + @discardableResult /// SwifterSwift: Sort the array based on an optional keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. /// - Parameter ascending: If order must be ascending. - public mutating func sort(by path: KeyPath, ascending: Bool = true) { + public mutating func sort(by path: KeyPath, ascending: Bool = true) -> [Element] { self = sorted(by: path, ascending: ascending) + return self } - + + @discardableResult /// SwifterSwift: Sort the array based on a keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. /// - Parameter ascending: If order must be ascending. - public mutating func sort(by path: KeyPath, ascending: Bool = true) { + public mutating func sort(by path: KeyPath, ascending: Bool = true) -> [Element] { self = sorted(by: path, ascending: ascending) + return self } - + } // MARK: - Methods (Equatable) public extension Array where Element: Equatable { - + /// SwifterSwift: Check if array contains an array of elements. /// /// [1, 2, 3, 4, 5].contains([1, 2]) -> true @@ -517,7 +454,7 @@ public extension Array where Element: Equatable { } return found } - + /// SwifterSwift: All indices of specified item. /// /// [1, 2, 2, 3, 4, 2, 5].indices(of 2) -> [1, 2, 5] @@ -526,35 +463,41 @@ public extension Array where Element: Equatable { /// /// - Parameter item: item to check. /// - Returns: an array with all indices of the given item. - public func indices(of item: Element) -> [Int] { - var indices: [Int] = [] + public func indices(of item: Element) -> [Index] { + var indices: [Index] = [] for index in startIndex.. [1, 3, 4, 5] /// ["h", "e", "l", "l", "o"].removeAll("l") -> ["h", "e", "o"] /// /// - Parameter item: item to remove. - public mutating func removeAll(_ item: Element) { + /// - Returns: self after removing all instances of item. + public mutating func removeAll(_ item: Element) -> [Element] { self = filter { $0 != item } + return self } - + + @discardableResult /// SwifterSwift: Remove all instances contained in items parameter from array. /// /// [1, 2, 2, 3, 4, 5].removeAll([2,5]) -> [1, 3, 4] /// ["h", "e", "l", "l", "o"].removeAll(["l", "h"]) -> ["e", "o"] /// /// - Parameter items: items to remove. - public mutating func removeAll(_ items: [Element]) { - guard !items.isEmpty else { return } + /// - Returns: self after removing all instances of all items in given array. + public mutating func removeAll(_ items: [Element]) -> [Element] { + guard !items.isEmpty else { return self } self = filter { !items.contains($0) } + return self } - + /// SwifterSwift: Remove all duplicate elements from Array. /// /// [1, 2, 2, 3, 4, 5].removeDuplicates() -> [1, 2, 3, 4, 5] @@ -568,7 +511,7 @@ public extension Array where Element: Equatable { } } } - + /// SwifterSwift: Return array with all duplicate elements removed. /// /// [1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved() -> [1, 2, 3, 4, 5]) @@ -576,15 +519,15 @@ public extension Array where Element: Equatable { /// /// - Returns: an array of unique elements. /// - public func duplicatesRemoved() -> [Element] { - // Thanks to https://github.com/sairamkotha for improving the property + public func withoutDuplicates() -> [Element] { + // Thanks to https://github.com/sairamkotha for improving the method return reduce(into: [Element]()) { if !$0.contains($1) { $0.append($1) } } } - + /// SwifterSwift: First index of a given item in an array. /// /// [1, 2, 2, 3, 4, 2, 5].firstIndex(of: 2) -> 1 @@ -593,13 +536,13 @@ public extension Array where Element: Equatable { /// /// - Parameter item: item to check. /// - Returns: first index of item in array (if exists). - public func firstIndex(of item: Element) -> Int? { + public func firstIndex(of item: Element) -> Index? { for (index, value) in lazy.enumerated() where value == item { return index } return nil } - + /// SwifterSwift: Last index of element in array. /// /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of: 2) -> 5 @@ -608,11 +551,11 @@ public extension Array where Element: Equatable { /// /// - Parameter item: item to check. /// - Returns: last index of item in array (if exists). - public func lastIndex(of item: Element) -> Int? { + public func lastIndex(of item: Element) -> Index? { for (index, value) in lazy.enumerated().reversed() where value == item { return index } return nil } - + } diff --git a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift index 23ed6f068..6059b25a0 100644 --- a/Sources/Extensions/SwiftStdlib/BoolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/BoolExtensions.swift @@ -8,7 +8,7 @@ // MARK: - Properties public extension Bool { - + /// SwifterSwift: Return 1 if true, or 0 if false. /// /// false.int -> 0 @@ -17,7 +17,7 @@ public extension Bool { public var int: Int { return self ? 1 : 0 } - + /// SwifterSwift: Return "true" if true, or "false" if false. /// /// false.string -> "false" @@ -26,16 +26,7 @@ public extension Bool { public var string: String { return description } - - /// SwifterSwift: Return inversed value of bool. - /// - /// false.toggled -> true - /// true.toggled -> false - /// - public var toggled: Bool { - return !self - } - + /// SwifterSwift: Returns a random boolean value. /// /// Bool.random -> true @@ -44,22 +35,5 @@ public extension Bool { public static var random: Bool { return arc4random_uniform(2) == 1 } - -} -// MARK: - Methods -public extension Bool { - - /// SwifterSwift: Toggle value for bool. - /// - /// var bool = false - /// bool.toggle() - /// print(bool) -> true - /// - /// - Returns: inversed value of bool. - @discardableResult public mutating func toggle() -> Bool { - self = !self - return self - } - } diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index 1ef02647a..017d3417e 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -8,7 +8,7 @@ // MARK: - Properties public extension Character { - + /// SwifterSwift: Check if character is emoji. /// /// Character("😀").isEmoji -> true @@ -27,7 +27,7 @@ public extension Character { return false } } - + /// SwifterSwift: Check if character is number. /// /// Character("1").isNumber -> true @@ -36,7 +36,7 @@ public extension Character { public var isNumber: Bool { return Int(String(self)) != nil } - + /// SwifterSwift: Check if character is a letter. /// /// Character("4").isLetter -> false @@ -45,7 +45,16 @@ public extension Character { public var isLetter: Bool { return String(self).rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil } - + + /// SwifterSwift: Check if character is lowercased. + /// + /// Character("a").isLowercased -> true + /// Character("A").isLowercased -> false + /// + public var isLowercased: Bool { + return String(self) == String(self).lowercased() + } + /// SwifterSwift: Check if character is uppercased. /// /// Character("a").isUppercased -> false @@ -54,16 +63,7 @@ public extension Character { public var isUppercased: Bool { return String(self) == String(self).uppercased() } - - /// SwifterSwift: Check if character is lowercased. - /// - /// Character("a").isLowercased -> true - /// Character("A").isLowercased -> false - /// - public var isLowercased: Bool { - return String(self) == String(self).lowercased() - } - + /// SwifterSwift: Check if character is white space. /// /// Character(" ").isWhiteSpace -> true @@ -72,7 +72,7 @@ public extension Character { public var isWhiteSpace: Bool { return String(self) == " " } - + /// SwifterSwift: Integer from character (if applicable). /// /// Character("1").int -> 1 @@ -81,7 +81,7 @@ public extension Character { public var int: Int? { return Int(String(self)) } - + /// SwifterSwift: String from character. /// /// Character("a").string -> "a" @@ -89,7 +89,7 @@ public extension Character { public var string: String { return String(self) } - + /// SwifterSwift: Return the character lowercased. /// /// Character("A").lowercased -> Character("a") @@ -97,7 +97,7 @@ public extension Character { public var lowercased: Character { return String(self).lowercased().first! } - + /// SwifterSwift: Return the character uppercased. /// /// Character("a").uppercased -> Character("A") @@ -105,12 +105,12 @@ public extension Character { public var uppercased: Character { return String(self).uppercased().first! } - + } // MARK: - Operators public extension Character { - + /// SwifterSwift: Repeat character multiple times. /// /// Character("-") * 10 -> "----------" @@ -120,12 +120,10 @@ public extension Character { /// - rhs: number of times to repeat character. /// - Returns: string with character repeated n times. public static func * (lhs: Character, rhs: Int) -> String { - guard rhs > 0 else { - return "" - } + guard rhs > 0 else { return "" } return String(repeating: String(lhs), count: rhs) } - + /// SwifterSwift: Repeat character multiple times. /// /// 10 * Character("-") -> "----------" @@ -135,10 +133,8 @@ public extension Character { /// - rhs: character to repeat. /// - Returns: string with character repeated n times. public static func * (lhs: Int, rhs: Character) -> String { - guard lhs > 0 else { - return "" - } + guard lhs > 0 else { return "" } return String(repeating: String(rhs), count: lhs) } - + } diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index 7db18ddd5..b724b34f9 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -8,17 +8,7 @@ // MARK: - Methods public extension Collection { - - private func indicesArray() -> [Self.Index] { - var indices: [Self.Index] = [] - var anIndex = startIndex - while anIndex != endIndex { - indices.append(anIndex) - anIndex = index(after: anIndex) - } - return indices - } - + /// SwifterSwift: Performs `each` closure for each element of collection in parallel. /// /// array.forEachInParallel { item in @@ -27,14 +17,14 @@ public extension Collection { /// /// - Parameter each: closure to run for each element. public func forEachInParallel(_ each: (Self.Iterator.Element) -> Void) { - let indices = indicesArray() - - DispatchQueue.concurrentPerform(iterations: indices.count) { (index) in - let elementIndex = indices[index] + let indicesArray = Array(indices) + + DispatchQueue.concurrentPerform(iterations: indicesArray.count) { (index) in + let elementIndex = indicesArray[index] each(self[elementIndex]) } } - + /// SwifterSwift: Safe protects the array from out of bounds by use of optional. /// /// let arr = [1, 2, 3, 4, 5] @@ -45,30 +35,30 @@ public extension Collection { public subscript(safe index: Index) -> Iterator.Element? { return indices.contains(index) ? self[index] : nil } - + } // MARK: - Methods (Int) -public extension Collection where Index == Int, IndexDistance == Int { - +public extension Collection where Index == Int { + /// SwifterSwift: Random item from array. public var randomItem: Element? { guard !isEmpty else { return nil } let index = Int(arc4random_uniform(UInt32(count))) return self[index] } - + } // MARK: - Methods (Integer) -public extension Collection where Iterator.Element == Int, Index == Int { - +public extension Collection where Iterator.Element == IntegerLiteralType, Index == Int { + /// SwifterSwift: Average of all elements in array. /// /// - Returns: the average of the array's elements. public func average() -> Double { // http://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift - return isEmpty ? 0 : Double(reduce(0, +)) / Double(endIndex-startIndex) + return isEmpty ? 0 : Double(reduce(0, +)) / Double(count) } - + } diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index 50803a254..d183cd606 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -5,31 +5,68 @@ // Copyright © 2016 SwifterSwift // +// MARK: - Properties +public extension Bool { + + /// SwifterSwift: Return inversed value of bool. + /// + /// false.toggled -> true + /// true.toggled -> false + /// + @available(*, deprecated: 4.3, message: "Use !self instead.") + public var toggled: Bool { + return !self + } + +} + +// MARK: - Methods +public extension Bool { + + @discardableResult + /// SwifterSwift: Toggle value for bool. + /// + /// var bool = false + /// bool.toggle() + /// print(bool) -> true + /// + /// - Returns: inversed value of bool. + @available(*, deprecated: 4.3, message: "Use !self instead.") + public mutating func toggle() -> Bool { + self = !self + return self + } + +} + + extension String { - + /// SwifterSwift: Number of characters in string. /// /// "Hello world!".length -> 12 /// - @available(*, deprecated: 4.1.0, message: "This extension is deprecated, please use .count instead.") + @available(*, deprecated: 4.1.0, message: "Use .count instead.") public var length: Int { return count } - + + // swiftlint:disable identifier_name /// SwifterSwift: Sliced string from a start index. /// /// "Hello World".slicing(at: 6) -> "World" /// /// - Parameter i: string index the slicing should start from. /// - Returns: sliced substring starting from start index (if applicable) (example: "Hello world".slicing(at: 6) -> "world") - @available(*, deprecated: 4.1.0, message: "Please use string[safe: i] instead.") + @available(*, deprecated: 4.1.0, message: "Use string[safe: i] instead.") public func slicing(at i: Int) -> String? { guard i < count else { return nil } return self[safe: i.. "World" @@ -38,14 +75,14 @@ extension String { /// - start: string index the slicing should start from. /// - end: string index the slicing should end at. /// - Returns: sliced substring starting from start index, and ends at end index (if applicable) (example: "Hello World".slicing(from: 6, to: 11) -> "World") - @available(*, deprecated: 4.1.0, message: "Please use string[safe: start.. String? { guard end >= start else { return nil } return self[safe: start.. 2 @@ -53,28 +90,64 @@ extension String { /// /// - Parameter string: substring to search for. /// - Returns: first index of substring in string (if applicable). - @available(*, deprecated: 4.1.0, message: "Please use string.index(of: Character) or string.range(of: StringProtocol) instead.") + @available(*, deprecated: 4.1.0, message: "Use string.index(of: Character) or string.range(of: StringProtocol) instead.") public func firstIndex(of string: String) -> Int? { return map({ String($0) }).index(of: string) } - + // - + /// SwifterSwift: Array of strings separated by given string. /// /// "hello World".splited(by: " ") -> ["hello", "World"] /// /// - Parameter separator: separator to split string by. /// - Returns: array of strings separated by given string. - @available(*, deprecated: 4.1.0, message: "Please use string.split(separator: Character) instead.") + @available(*, deprecated: 4.1.0, message: "Use string.split(separator: Character) instead.") public func splitted(by separator: Character) -> [String] { return split { $0 == separator }.map(String.init) } - + +} + +public extension Array { + + /// SwifterSwift: Element at the given index if it exists. + /// + /// [1, 2, 3, 4, 5].item(at: 2) -> 3 + /// [1.2, 2.3, 4.5, 3.4, 4.5].item(at: 3) -> 3.4 + /// ["h", "e", "l", "l", "o"].item(at: 10) -> nil + /// + /// - Parameter index: index of element. + /// - Returns: optional element (if exists). + @available(*, deprecated: 4.3, message: "Use subscript(safe:) instead", renamed: "subscript(safe:)") + public func item(at index: Int) -> Element? { + guard startIndex.. [1, 2, 3, 4, 5]) + /// ["h", "e", "l", "l", "o"].duplicatesRemoved() -> ["h", "e", "l", "o"]) + /// + /// - Returns: an array of unique elements. + /// + @available(*, deprecated: 4.3, message: "Use withoutDuplicates() instead", renamed: "withoutDuplicates") + public func duplicatesRemoved() -> [Element] { + // Thanks to https://github.com/sairamkotha for improving the method + return reduce(into: [Element]()) { + if !$0.contains($1) { + $0.append($1) + } + } + } + /// SwifterSwift: All indexes of specified item. /// /// [1, 2, 2, 3, 4, 2, 5].indexes(of 2) -> [1, 2, 5] @@ -91,5 +164,40 @@ public extension Array where Element: Equatable { } return indexes } - + + /// SwifterSwift: Remove last element from array and return it. + /// + /// [1, 2, 3, 4, 5].pop() // returns 5 and remove it from the array. + /// [].pop() // returns nil since the array is empty. + /// + /// - Returns: last element in array (if applicable). + @available(*, deprecated: 4.3, message: "Use popLast() instead") + @discardableResult public mutating func pop() -> Element? { + return popLast() + } + + /// SwifterSwift: Insert an element to the end of array. + /// + /// [1, 2, 3, 4].push(5) -> [1, 2, 3, 4, 5] + /// ["h", "e", "l", "l"].push("o") -> ["h", "e", "l", "l", "o"] + /// + /// - Parameter newElement: element to insert. + @available(*, deprecated: 4.3, message: "Use append() instead") + public mutating func push(_ newElement: Element) { + append(newElement) + } + + /// SwifterSwift: Swap values at index positions. + /// + /// [1, 2, 3, 4, 5].swap(from: 3, to: 0) -> [4, 2, 3, 1, 5] + /// ["h", "e", "l", "l", "o"].swap(from: 1, to: 0) -> ["e", "h", "l", "l", "o"] + /// + /// - Parameters: + /// - index: index of first element. + /// - otherIndex: index of other element. + @available(*, deprecated: 4.3, message: "Use swapAt() instead") + public mutating func swap(from index: Int, to otherIndex: Int) { + swapAt(index, otherIndex) + } + } diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 577acc1aa..d710eb72f 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -8,181 +8,179 @@ // MARK: - Methods public extension Dictionary { - - /// SwifterSwift: Check if key exists in dictionary. - /// - /// let dict: [String : Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] - /// dict.has(key: "testKey") -> true - /// dict.has(key: "anotherKey") -> false - /// - /// - Parameter key: key to search for - /// - Returns: true if key exists in dictionary. - public func has(key: Key) -> Bool { - return index(forKey: key) != nil - } - - /// SwifterSwift: Remove all keys of the dictionary. - /// - /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] - /// dict.removeAll(keys: ["key1", "key2"]) - /// dict.keys.contains("key3") -> true - /// dict.keys.contains("key1") -> false - /// dict.keys.contains("key2") -> false - /// - /// - Parameter keys: keys to be removed - public mutating func removeAll(keys: [Key]) { - keys.forEach({ removeValue(forKey: $0)}) - } - - /// SwifterSwift: JSON Data from dictionary. - /// - /// - Parameter prettify: set true to prettify data (default is false). - /// - Returns: optional JSON Data (if applicable). - public func jsonData(prettify: Bool = false) -> Data? { - guard JSONSerialization.isValidJSONObject(self) else { - return nil - } - let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() - return try? JSONSerialization.data(withJSONObject: self, options: options) - } - - /// SwifterSwift: JSON String from dictionary. - /// - /// dict.jsonString() -> "{"testKey":"testValue","testArrayKey":[1,2,3,4,5]}" - /// - /// dict.jsonString(prettify: true) - /// /* - /// returns the following string: - /// - /// "{ - /// "testKey" : "testValue", - /// "testArrayKey" : [ - /// 1, - /// 2, - /// 3, - /// 4, - /// 5 - /// ] - /// }" - /// - /// */ - /// - /// - Parameter prettify: set true to prettify string (default is false). - /// - Returns: optional JSON String (if applicable). - public func jsonString(prettify: Bool = false) -> String? { - guard JSONSerialization.isValidJSONObject(self) else { - return nil - } - let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() - guard let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) else { return nil } - return String(data: jsonData, encoding: .utf8) - } - - /// SwifterSwift: Count dictionary entries that where function returns true. - /// - /// - Parameter where: condition to evaluate each tuple entry against. - /// - Returns: Count of entries that matches the where clousure. - public func count(where condition: @escaping ((key: Key, value: Value)) throws -> Bool) rethrows -> Int { - var count: Int = 0 - try self.forEach { - if try condition($0) { - count += 1 - } - } - return count - } - -} -// MARK: - Operators -public extension Dictionary { - - /// SwifterSwift: Merge the keys/values of two dictionaries. - /// - /// let dict : [String : String] = ["key1" : "value1"] - /// let dict2 : [String : String] = ["key2" : "value2"] - /// let result = dict + dict2 - /// result["key1"] -> "value1" - /// result["key2"] -> "value2" - /// - /// - Parameters: - /// - lhs: dictionary - /// - rhs: dictionary - /// - Returns: An dictionary with keys and values from both. - public static func + (lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] { - var result = lhs - rhs.forEach { result[$0] = $1 } - return result - } - - // MARK: - Operators - - /// SwifterSwift: Append the keys and values from the second dictionary into the first one. - /// - /// var dict : [String : String] = ["key1" : "value1"] - /// let dict2 : [String : String] = ["key2" : "value2"] - /// dict += dict2 - /// dict["key1"] -> "value1" - /// dict["key2"] -> "value2" - /// - /// - Parameters: - /// - lhs: dictionary - /// - rhs: dictionary - public static func += (lhs: inout [Key: Value], rhs: [Key: Value]) { - rhs.forEach { lhs[$0] = $1} - } - - /// SwifterSwift: Remove contained in the array from the dictionary - /// - /// let dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] - /// let result = dict-["key1", "key2"] - /// result.keys.contains("key3") -> true - /// result.keys.contains("key1") -> false - /// result.keys.contains("key2") -> false - /// - /// - Parameters: - /// - lhs: dictionary - /// - rhs: array with the keys to be removed. - /// - Returns: a new dictionary with keys removed. - public static func - (lhs: [Key: Value], keys: [Key]) -> [Key: Value] { - var result = lhs - result.removeAll(keys: keys) - return result - } - - /// SwifterSwift: Remove contained in the array from the dictionary - /// - /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] - /// dict-=["key1", "key2"] - /// dict.keys.contains("key3") -> true - /// dict.keys.contains("key1") -> false - /// dict.keys.contains("key2") -> false - /// - /// - Parameters: - /// - lhs: dictionary - /// - rhs: array with the keys to be removed. - public static func -= (lhs: inout [Key: Value], keys: [Key]) { - lhs.removeAll(keys: keys) - } - + /// SwifterSwift: Check if key exists in dictionary. + /// + /// let dict: [String : Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] + /// dict.has(key: "testKey") -> true + /// dict.has(key: "anotherKey") -> false + /// + /// - Parameter key: key to search for + /// - Returns: true if key exists in dictionary. + public func has(key: Key) -> Bool { + return index(forKey: key) != nil + } + + /// SwifterSwift: Remove all keys of the dictionary. + /// + /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + /// dict.removeAll(keys: ["key1", "key2"]) + /// dict.keys.contains("key3") -> true + /// dict.keys.contains("key1") -> false + /// dict.keys.contains("key2") -> false + /// + /// - Parameter keys: keys to be removed + public mutating func removeAll(keys: [Key]) { + keys.forEach({ removeValue(forKey: $0)}) + } + + /// SwifterSwift: JSON Data from dictionary. + /// + /// - Parameter prettify: set true to prettify data (default is false). + /// - Returns: optional JSON Data (if applicable). + public func jsonData(prettify: Bool = false) -> Data? { + guard JSONSerialization.isValidJSONObject(self) else { + return nil + } + let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() + return try? JSONSerialization.data(withJSONObject: self, options: options) + } + + /// SwifterSwift: JSON String from dictionary. + /// + /// dict.jsonString() -> "{"testKey":"testValue","testArrayKey":[1,2,3,4,5]}" + /// + /// dict.jsonString(prettify: true) + /// /* + /// returns the following string: + /// + /// "{ + /// "testKey" : "testValue", + /// "testArrayKey" : [ + /// 1, + /// 2, + /// 3, + /// 4, + /// 5 + /// ] + /// }" + /// + /// */ + /// + /// - Parameter prettify: set true to prettify string (default is false). + /// - Returns: optional JSON String (if applicable). + public func jsonString(prettify: Bool = false) -> String? { + guard JSONSerialization.isValidJSONObject(self) else { return nil } + let options = (prettify == true) ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions() + guard let jsonData = try? JSONSerialization.data(withJSONObject: self, options: options) else { return nil } + return String(data: jsonData, encoding: .utf8) + } + + /// SwifterSwift: Count dictionary entries that where function returns true. + /// + /// - Parameter where: condition to evaluate each tuple entry against. + /// - Returns: Count of entries that matches the where clousure. + public func count(where condition: @escaping ((key: Key, value: Value)) throws -> Bool) rethrows -> Int { + var count: Int = 0 + try self.forEach { + if try condition($0) { + count += 1 + } + } + return count + } + } // MARK: - Methods (ExpressibleByStringLiteral) public extension Dictionary where Key: ExpressibleByStringLiteral { - - /// SwifterSwift: Lowercase all keys in dictionary. - /// - /// var dict = ["tEstKeY": "value"] - /// dict.lowercaseAllKeys() - /// print(dict) // prints "["testkey": "value"]" - /// - public mutating func lowercaseAllKeys() { - // http://stackoverflow.com/questions/33180028/extend-dictionary-where-key-is-of-type-string - for key in keys { - if let lowercaseKey = String(describing: key).lowercased() as? Key { - self[lowercaseKey] = removeValue(forKey: key) - } - } - } - + + /// SwifterSwift: Lowercase all keys in dictionary. + /// + /// var dict = ["tEstKeY": "value"] + /// dict.lowercaseAllKeys() + /// print(dict) // prints "["testkey": "value"]" + /// + public mutating func lowercaseAllKeys() { + // http://stackoverflow.com/questions/33180028/extend-dictionary-where-key-is-of-type-string + for key in keys { + if let lowercaseKey = String(describing: key).lowercased() as? Key { + self[lowercaseKey] = removeValue(forKey: key) + } + } + } + +} + +// MARK: - Operators +public extension Dictionary { + + /// SwifterSwift: Merge the keys/values of two dictionaries. + /// + /// let dict : [String : String] = ["key1" : "value1"] + /// let dict2 : [String : String] = ["key2" : "value2"] + /// let result = dict + dict2 + /// result["key1"] -> "value1" + /// result["key2"] -> "value2" + /// + /// - Parameters: + /// - lhs: dictionary + /// - rhs: dictionary + /// - Returns: An dictionary with keys and values from both. + public static func + (lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] { + var result = lhs + rhs.forEach { result[$0] = $1 } + return result + } + + // MARK: - Operators + + /// SwifterSwift: Append the keys and values from the second dictionary into the first one. + /// + /// var dict : [String : String] = ["key1" : "value1"] + /// let dict2 : [String : String] = ["key2" : "value2"] + /// dict += dict2 + /// dict["key1"] -> "value1" + /// dict["key2"] -> "value2" + /// + /// - Parameters: + /// - lhs: dictionary + /// - rhs: dictionary + public static func += (lhs: inout [Key: Value], rhs: [Key: Value]) { + rhs.forEach { lhs[$0] = $1} + } + + /// SwifterSwift: Remove contained in the array from the dictionary + /// + /// let dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + /// let result = dict-["key1", "key2"] + /// result.keys.contains("key3") -> true + /// result.keys.contains("key1") -> false + /// result.keys.contains("key2") -> false + /// + /// - Parameters: + /// - lhs: dictionary + /// - rhs: array with the keys to be removed. + /// - Returns: a new dictionary with keys removed. + public static func - (lhs: [Key: Value], keys: [Key]) -> [Key: Value] { + var result = lhs + result.removeAll(keys: keys) + return result + } + + /// SwifterSwift: Remove contained in the array from the dictionary + /// + /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] + /// dict-=["key1", "key2"] + /// dict.keys.contains("key3") -> true + /// dict.keys.contains("key1") -> false + /// dict.keys.contains("key2") -> false + /// + /// - Parameters: + /// - lhs: dictionary + /// - rhs: array with the keys to be removed. + public static func -= (lhs: inout [Key: Value], keys: [Key]) { + lhs.removeAll(keys: keys) + } + } diff --git a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift index ac4ebd3b9..02f04c586 100755 --- a/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DoubleExtensions.swift @@ -6,26 +6,30 @@ // Copyright © 2016 SwifterSwift // +#if canImport(CoreGraphics) import CoreGraphics +#endif // MARK: - Properties public extension Double { - + /// SwifterSwift: Int. public var int: Int { return Int(self) } - + /// SwifterSwift: Float. public var float: Float { return Float(self) } - + + #if canImport(CoreGraphics) /// SwifterSwift: CGFloat. public var cgFloat: CGFloat { return CGFloat(self) } - + #endif + } // MARK: - Operators @@ -43,6 +47,7 @@ public func ** (lhs: Double, rhs: Double) -> Double { return pow(lhs, rhs) } +// swiftlint:disable identifier_name prefix operator √ /// SwifterSwift: Square root of double. /// @@ -52,3 +57,4 @@ public prefix func √ (double: Double) -> Double { // http://nshipster.com/swift-operators/ return sqrt(double) } +// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift index 206c08f19..e72f1ee99 100755 --- a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift @@ -6,26 +6,30 @@ // Copyright © 2016 SwifterSwift // +#if canImport(CoreGraphics) import CoreGraphics +#endif // MARK: - Properties public extension Float { - + /// SwifterSwift: Int. public var int: Int { return Int(self) } - + /// SwifterSwift: Double. public var double: Double { return Double(self) } - + + #if canImport(CoreGraphics) /// SwifterSwift: CGFloat. public var cgFloat: CGFloat { return CGFloat(self) } - + #endif + } // MARK: - Operators @@ -39,16 +43,18 @@ infix operator ** : PowerPrecedence /// - rhs: exponent float. /// - Returns: exponentiation result (4.4 ** 0.5 = 2.0976176963). public func ** (lhs: Float, rhs: Float) -> Float { - // http://nshipster.com/swift-operators/ - return pow(lhs, rhs) + // http://nshipster.com/swift-operators/ + return pow(lhs, rhs) } +// swiftlint:disable identifier_name prefix operator √ /// SwifterSwift: Square root of float. /// /// - Parameter float: float value to find square root for /// - Returns: square root of given float. public prefix func √ (float: Float) -> Float { - // http://nshipster.com/swift-operators/ - return sqrt(float) + // http://nshipster.com/swift-operators/ + return sqrt(float) } +// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index 0034e0165..7ce0807bd 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -8,47 +8,47 @@ // MARK: - Properties public extension FloatingPoint { - + /// SwifterSwift: Absolute value of integer number. public var abs: Self { return Swift.abs(self) } - + /// SwifterSwift: Check if integer is positive. public var isPositive: Bool { return self > 0 } - + /// SwifterSwift: Check if integer is negative. public var isNegative: Bool { return self < 0 } - + /// SwifterSwift: Ceil of number. public var ceil: Self { return Foundation.ceil(self) } - + /// SwifterSwift: Radian value of degree input. public var degreesToRadians: Self { return Self.pi * self / Self(180) } - + /// SwifterSwift: Floor of number. public var floor: Self { return Foundation.floor(self) } - + /// SwifterSwift: Degree value of radian input. public var radiansToDegrees: Self { return self * Self(180) / Self.pi } - + } // MARK: - Methods public extension FloatingPoint { - + /// SwifterSwift: Random number between two number. /// /// - Parameters: @@ -61,7 +61,7 @@ public extension FloatingPoint { let delta = aMax - aMin return Self(arc4random()) / Self(UInt64(UINT32_MAX)) * delta + aMin } - + /// SwifterSwift: Random number in a closed interval range. /// /// - Parameter range: closed interval range. @@ -70,12 +70,12 @@ public extension FloatingPoint { let delta = range.upperBound - range.lowerBound return Self(arc4random()) / Self(UInt64(UINT32_MAX)) * delta + range.lowerBound } - + } // MARK: - Initializers public extension FloatingPoint { - + /// SwifterSwift: Created a random number between two numbers. /// /// - Parameters: @@ -87,7 +87,7 @@ public extension FloatingPoint { let delta = aMax - aMin self = Self(arc4random()) / Self(UInt64(UINT32_MAX)) * delta + aMin } - + /// SwifterSwift: Create a random number in a closed interval range. /// /// - Parameter range: closed interval range. @@ -95,11 +95,12 @@ public extension FloatingPoint { let delta = range.upperBound - range.lowerBound self = Self(arc4random()) / Self(UInt64(UINT32_MAX)) * delta + range.lowerBound } - + } // MARK: - Operators +// swiftlint:disable identifier_name infix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -111,7 +112,9 @@ public func ± (lhs: T, rhs: T) -> (T, T) { // http://nshipster.com/swift-operators/ return (lhs + rhs, lhs - rhs) } +// swiftlint:enable identifier_name +// swiftlint:disable identifier_name prefix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -121,3 +124,4 @@ public prefix func ± (number: T) -> (T, T) { // http://nshipster.com/swift-operators/ return 0 ± number } +// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 94779ec6e..b41bcf249 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -6,46 +6,50 @@ // Copyright © 2016 SwifterSwift // +#if canImport(CoreGraphics) import CoreGraphics +#endif // MARK: - Properties public extension Int { - + /// SwifterSwift: CountableRange 0.. { return 0.. Int { return random(inRange: min...max) } - + /// SwifterSwift: Random integer in a closed interval range. /// /// - Parameter range: closed interval range. @@ -107,7 +112,7 @@ public extension Int { let delta = UInt32(range.upperBound - range.lowerBound + 1) return range.lowerBound + Int(arc4random_uniform(delta)) } - + /// SwifterSwift: check if given integer prime or not. /// Warning: Using big numbers can be computationally expensive! /// - Returns: true or false depending on prime-ness @@ -116,7 +121,7 @@ public extension Int { if self == 2 { return true } - + guard self > 1 && self % 2 != 0 else { return false } @@ -125,15 +130,15 @@ public extension Int { // other multiplier will go 1 down to get similar result // (integer-wise operation) such way increases speed of operation let base = Int(sqrt(Double(self))) - for i in Swift.stride(from: 3, through: base, by: 2) where self % i == 0 { + for int in Swift.stride(from: 3, through: base, by: 2) where self % int == 0 { return false } return true } - + /// SwifterSwift: Roman numeral string from integer (if applicable). /// - /// 10.romanNumeral() -> "X" + ///10.romanNumeral() -> "X" /// /// - Returns: The roman numeral string. public func romanNumeral() -> String? { @@ -143,10 +148,10 @@ public extension Int { } let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] - + var romanValue = "" var startingValue = self - + for (index, romanChar) in romanValues.enumerated() { let arabicValue = arabicValues[index] let div = startingValue / arabicValue @@ -159,17 +164,19 @@ public extension Int { } return romanValue } - - /// SwifterSwift: Rounds to the closest multiple of n - public func roundToNearest(_ n: Int) -> Int { - return n == 0 ? self : Int(round(Double(self) / Double(n))) * n - } + + // swiftlint:disable identifier_name + /// SwifterSwift: Rounds to the closest multiple of n + public func roundToNearest(_ n: Int) -> Int { + return n == 0 ? self : Int(round(Double(self) / Double(n))) * n + } + // swiftlint:enable identifier_name } // MARK: - Initializers public extension Int { - + /// SwifterSwift: Created a random integer between two integer values. /// /// - Parameters: @@ -178,14 +185,14 @@ public extension Int { public init(randomBetween min: Int, and max: Int) { self = Int.random(between: min, and: max) } - + /// SwifterSwift: Create a random integer in a closed interval range. /// /// - Parameter range: closed interval range. public init(randomInRange range: ClosedRange) { self = Int.random(inRange: range) } - + } // MARK: - Operators @@ -203,6 +210,7 @@ public func ** (lhs: Int, rhs: Int) -> Double { return pow(Double(lhs), Double(rhs)) } +// swiftlint:disable identifier_name prefix operator √ /// SwifterSwift: Square root of integer. /// @@ -212,7 +220,9 @@ public prefix func √ (int: Int) -> Double { // http://nshipster.com/swift-operators/ return sqrt(Double(int)) } +// swiftlint:enable identifier_name +// swiftlint:disable identifier_name infix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -224,7 +234,9 @@ public func ± (lhs: Int, rhs: Int) -> (Int, Int) { // http://nshipster.com/swift-operators/ return (lhs + rhs, lhs - rhs) } +// swiftlint:enable identifier_name +// swiftlint:disable identifier_name prefix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -234,3 +246,4 @@ public prefix func ± (int: Int) -> (Int, Int) { // http://nshipster.com/swift-operators/ return 0 ± int } +// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index 5f57cf17a..f396229b9 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -8,7 +8,7 @@ // MARK: - Methods public extension Optional { - + /// SwifterSwift: Get self of default value (if self is nil). /// /// let foo: String? = nil @@ -23,8 +23,8 @@ public extension Optional { // http://www.russbishop.net/improving-optionals return self ?? defaultValue } - - /// SwifterSwift: Gets the wrapped value of an optional. If the optional is `nil`, throw a custom error. + + /// SwifterSwift: Gets the wrapped value of an optional. If the optional is `nil`, throw a custom error. /// /// let foo: String? = nil /// try print(foo.unwrapped(or: MyError.notFound)) -> error: MyError.notFound @@ -36,12 +36,10 @@ public extension Optional { /// - Returns: The value wrapped by the optional. /// - Throws: The error passed in. public func unwrapped(or error: Error) throws -> Wrapped { - guard let wrapped = self else { - throw error - } + guard let wrapped = self else { throw error } return wrapped } - + /// SwifterSwift: Runs a block to Wrapped if not nil /// /// let foo: String? = nil @@ -61,7 +59,7 @@ public extension Optional { // http://www.russbishop.net/improving-optionals _ = self.map(block) } - + /// SwifterSwift: Assign an optional value to a variable only if the value is not nil. /// /// let someParameter: String? = nil @@ -75,7 +73,7 @@ public extension Optional { guard let rhs = rhs else { return } lhs = rhs } - + } // MARK: - Operators diff --git a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift new file mode 100644 index 000000000..5b6f3746a --- /dev/null +++ b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift @@ -0,0 +1,44 @@ +// +// SequenceExtensions.swift +// SwifterSwift +// +// Created by Anton Novoselov on 04/04/2018. +// Copyright © 2018 SwifterSwift +// + +import Foundation + +public extension Sequence { + /// SwifterSwift: Check if all elements in collection match a conditon. + /// + /// [2, 2, 4].all(matching: {$0 % 2 == 0}) -> true + /// [1,2, 2, 4].all(matching: {$0 % 2 == 0}) -> false + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: true when all elements in the array match the specified condition. + public func all(matching condition: (Element) throws -> Bool) rethrows -> Bool { + return try !contains { try !condition($0) } + } + + /// SwifterSwift: Check if no elements in collection match a conditon. + /// + /// [2, 2, 4].none(matching: {$0 % 2 == 0}) -> false + /// [1, 3, 5, 7].none(matching: {$0 % 2 == 0}) -> true + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: true when no elements in the array match the specified condition. + public func none(matching condition: (Element) throws -> Bool) rethrows -> Bool { + return try !contains { try condition($0) } + } + + /// SwifterSwift: Check if any element in collection match a conditon. + /// + /// [2, 2, 4].any(matching: {$0 % 2 == 0}) -> false + /// [1, 3, 5, 7].any(matching: {$0 % 2 == 0}) -> true + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: true when no elements in the array match the specified condition. + public func any(matching condition: (Element) throws -> Bool) rethrows -> Bool { + return try contains { try condition($0) } + } +} diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index 5c4e95f83..e6e149eca 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -8,27 +8,27 @@ // MARK: - Properties public extension SignedInteger { - + /// SwifterSwift: Absolute value of integer number. public var abs: Self { return Swift.abs(self) } - + /// SwifterSwift: Check if integer is positive. public var isPositive: Bool { return self > 0 } - + /// SwifterSwift: Check if integer is negative. public var isNegative: Bool { return self < 0 } - + /// SwifterSwift: Check if integer is even. public var isEven: Bool { return (self % 2) == 0 } - + /// SwifterSwift: Check if integer is odd. public var isOdd: Bool { return (self % 2) != 0 @@ -47,18 +47,19 @@ public extension SignedInteger { } let hours = self / 3600 let mins = (self % 3600) / 60 - + if hours != 0 && mins == 0 { return "\(hours)h" } return "\(hours)h \(mins)m" } - + } // MARK: - Methods public extension SignedInteger { - + + // swiftlint:disable identifier_name /// SwifterSwift: Greatest common divisor of integer value and n. /// /// - Parameter n: integer value to find gcd with. @@ -66,7 +67,9 @@ public extension SignedInteger { public func gcd(of n: Self) -> Self { return n == 0 ? self : n.gcd(of: self % n) } - + // swiftlint:enable identifier_name + + // swiftlint:disable identifier_name /// SwifterSwift: Least common multiple of integer and n. /// /// - Parameter n: integer value to find lcm with. @@ -74,5 +77,6 @@ public extension SignedInteger { public func lcm(of n: Self) -> Self { return (self * n).abs / gcd(of: n) } - + // swiftlint:enable identifier_name + } diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index 3495808d4..9238f21fe 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -8,19 +8,20 @@ // MARK: - Properties public extension SignedNumeric { - + /// SwifterSwift: String. public var string: String { return String(describing: self) } - + /// SwifterSwift: String with number and current locale currency. - public var asLocaleCurrency: String { + public var asLocaleCurrency: String? { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current - guard let number = self as? NSNumber else { return "" } - return formatter.string(from: number) ?? "" + // swiftlint:disable force_cast + return formatter.string(from: self as! NSNumber) + // swiftlint:enable force_cast } - + } diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 9cfa28097..520ab8111 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -5,15 +5,27 @@ // Created by Omar Albeik on 8/5/16. // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#else - import UIKit + +#if canImport(Foundation) +import Foundation +#endif + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(Cocoa) +import Cocoa +#endif + +#if canImport(CoreGraphics) +import CoreGraphics #endif // MARK: - Properties public extension String { - + + #if canImport(Foundation) /// SwifterSwift: String decoded from base64 (if applicable). /// /// "SGVsbG8gV29ybGQh".base64Decoded = Optional("Hello World!") @@ -23,7 +35,9 @@ public extension String { guard let decodedData = Data(base64Encoded: self) else { return nil } return String(data: decodedData, encoding: .utf8) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: String encoded in base64 (if applicable). /// /// "Hello World!".base64Encoded -> Optional("SGVsbG8gV29ybGQh") @@ -33,13 +47,15 @@ public extension String { let plainData = data(using: .utf8) return plainData?.base64EncodedString() } - + #endif + /// SwifterSwift: Array of characters of a string. /// public var charactersArray: [Character] { return Array(self) } - + + #if canImport(Foundation) /// SwifterSwift: CamelCase of string. /// /// "sOme vAriable naMe".camelCased -> "someVariableName" @@ -56,7 +72,8 @@ public extension String { let rest = String(source.dropFirst()) return first + rest } - + #endif + /// SwifterSwift: Check if string contains one or more emojis. /// /// "Hello 😀".containEmoji -> true @@ -77,7 +94,7 @@ public extension String { } return false } - + /// SwifterSwift: First character of string (if applicable). /// /// "Hello".firstCharacterAsString -> Optional("H") @@ -87,7 +104,8 @@ public extension String { guard let first = self.first else { return nil } return String(first) } - + + #if canImport(Foundation) /// SwifterSwift: Check if string contains one or more letters. /// /// "123abc".hasLetters -> true @@ -96,7 +114,9 @@ public extension String { public var hasLetters: Bool { return rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string contains one or more numbers. /// /// "abcd".hasNumbers -> false @@ -105,7 +125,9 @@ public extension String { public var hasNumbers: Bool { return rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string contains only letters. /// /// "abc".isAlphabetic -> true @@ -116,7 +138,9 @@ public extension String { let hasNumbers = rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil return hasLetters && !hasNumbers } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string contains at least one letter and one number. /// /// // useful for passwords @@ -129,16 +153,21 @@ public extension String { let comps = components(separatedBy: .alphanumerics) return comps.joined(separator: "").count == 0 && hasLetters && hasNumbers } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is valid email format. /// /// "john@doe.com".isEmail -> true /// public var isEmail: Bool { // http://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift - return matches(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}") + return range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", + options: .regularExpression, range: nil, locale: nil) != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid URL. /// /// "https://google.com".isValidUrl -> true @@ -146,7 +175,9 @@ public extension String { public var isValidUrl: Bool { return URL(string: self) != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid schemed URL. /// /// "https://google.com".isValidSchemedUrl -> true @@ -156,7 +187,9 @@ public extension String { guard let url = URL(string: self) else { return false } return url.scheme != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid https URL. /// /// "https://google.com".isValidHttpsUrl -> true @@ -165,7 +198,9 @@ public extension String { guard let url = URL(string: self) else { return false } return url.scheme == "https" } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid http URL. /// /// "http://google.com".isValidHttpUrl -> true @@ -174,7 +209,9 @@ public extension String { guard let url = URL(string: self) else { return false } return url.scheme == "http" } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid file URL. /// /// "file://Documents/file.txt".isValidFileUrl -> true @@ -182,34 +219,39 @@ public extension String { public var isValidFileUrl: Bool { return URL(string: self)?.isFileURL ?? false } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Check if string is a valid Swift number. /// - /// Note: - /// In North America, "." is the decimal separator, - /// while in many parts of Europe "," is used, - /// + /// Note: + /// In North America, "." is the decimal separator, + /// while in many parts of Europe "," is used, + /// /// "123".isNumeric -> true - /// "1.3".isNumeric -> true (en_US) - /// "1,3".isNumeric -> true (fr_FR) + /// "1.3".isNumeric -> true (en_US) + /// "1,3".isNumeric -> true (fr_FR) /// "abc".isNumeric -> false /// - public var isNumeric: Bool { - let scanner = Scanner(string: self) - scanner.locale = NSLocale.current - return scanner.scanDecimal(nil) && scanner.isAtEnd - } - - /// SwifterSwift: Check if string only contains digits. - /// - /// "123".isDigits -> true - /// "1.3".isDigits -> false - /// "abc".isDigits -> false - /// - public var isDigits: Bool { - return CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: self)) - } - + public var isNumeric: Bool { + let scanner = Scanner(string: self) + scanner.locale = NSLocale.current + return scanner.scanDecimal(nil) && scanner.isAtEnd + } + #endif + + #if canImport(Foundation) + /// SwifterSwift: Check if string only contains digits. + /// + /// "123".isDigits -> true + /// "1.3".isDigits -> false + /// "abc".isDigits -> false + /// + public var isDigits: Bool { + return CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: self)) + } + #endif + /// SwifterSwift: Last character of string (if applicable). /// /// "Hello".lastCharacterAsString -> Optional("o") @@ -219,7 +261,8 @@ public extension String { guard let last = self.last else { return nil } return String(last) } - + + #if canImport(Foundation) /// SwifterSwift: Latinized string. /// /// "Hèllö Wórld!".latinized -> "Hello World!" @@ -227,7 +270,9 @@ public extension String { public var latinized: String { return folding(options: .diacriticInsensitive, locale: Locale.current) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Bool value from string (if applicable). /// /// "1".bool -> true @@ -235,7 +280,7 @@ public extension String { /// "Hello".bool = nil /// public var bool: Bool? { - let selfLowercased = trimmed.lowercased() + let selfLowercased = trimmingCharacters(in: .whitespacesAndNewlines).lowercased() if selfLowercased == "true" || selfLowercased == "1" { return true } else if selfLowercased == "false" || selfLowercased == "0" { @@ -243,31 +288,36 @@ public extension String { } return nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Date object from "yyyy-MM-dd" formatted string. /// /// "2007-06-29".date -> Optional(Date) /// public var date: Date? { - let selfLowercased = trimmed.lowercased() + let selfLowercased = trimmingCharacters(in: .whitespacesAndNewlines).lowercased() let formatter = DateFormatter() formatter.timeZone = TimeZone.current formatter.dateFormat = "yyyy-MM-dd" return formatter.date(from: selfLowercased) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Date object from "yyyy-MM-dd HH:mm:ss" formatted string. /// /// "2007-06-29 14:23:09".dateTime -> Optional(Date) /// public var dateTime: Date? { - let selfLowercased = trimmed.lowercased() + let selfLowercased = trimmingCharacters(in: .whitespacesAndNewlines).lowercased() let formatter = DateFormatter() formatter.timeZone = TimeZone.current formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" return formatter.date(from: selfLowercased) } - + #endif + /// SwifterSwift: Integer value from string (if applicable). /// /// "101".int -> 101 @@ -275,14 +325,14 @@ public extension String { public var int: Int? { return Int(self) } - + /// SwifterSwift: Lorem ipsum string of given length. /// /// - Parameter length: number of characters to limit lorem ipsum to (default is 445 - full lorem ipsum). /// - Returns: Lorem ipsum dolor sit amet... string. public static func loremIpsum(ofLength length: Int = 445) -> String { guard length > 0 else { return "" } - + // https://www.lipsum.com/ let loremIpsum = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. @@ -292,7 +342,8 @@ public extension String { } return loremIpsum } - + + #if canImport(Foundation) /// SwifterSwift: URL from string (if applicable). /// /// "https://google.com".url -> URL(string: "https://google.com") @@ -301,7 +352,9 @@ public extension String { public var url: URL? { return URL(string: self) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: String with no spaces or new lines in beginning and end. /// /// " hello \n".trimmed -> "hello" @@ -309,7 +362,9 @@ public extension String { public var trimmed: String { return trimmingCharacters(in: .whitespacesAndNewlines) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Readable string from a URL string. /// /// "it's%20easy%20to%20decode%20strings".urlDecoded -> "it's easy to decode strings" @@ -317,7 +372,9 @@ public extension String { public var urlDecoded: String { return removingPercentEncoding ?? self } - + #endif + + #if canImport(Foundation) /// SwifterSwift: URL escaped string. /// /// "it's easy to encode strings".urlEncoded -> "it's%20easy%20to%20encode%20strings" @@ -325,7 +382,9 @@ public extension String { public var urlEncoded: String { return addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)! } - + #endif + + #if canImport(Foundation) /// SwifterSwift: String without spaces and new lines. /// /// " \n Swifter \n Swift ".withoutSpacesAndNewLines -> "SwifterSwift" @@ -333,26 +392,32 @@ public extension String { public var withoutSpacesAndNewLines: String { return replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "") } - - /// SwifterSwift: Check if the given string contains only white spaces - public var isWhitespace: Bool { - return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty - } + #endif + + #if canImport(Foundation) + /// SwifterSwift: Check if the given string contains only white spaces + public var isWhitespace: Bool { + return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty + } + #endif + #if os(iOS) || os(tvOS) /// SwifterSwift: Check if the given string spelled correctly public var isSpelledCorrectly: Bool { let checker = UITextChecker() let range = NSRange(location: 0, length: self.utf16.count) - + let misspelledRange = checker.rangeOfMisspelledWord(in: self, range: range, startingAt: 0, wrap: false, language: Locale.preferredLanguages.first ?? "en") return misspelledRange.location == NSNotFound } #endif + } // MARK: - Methods public extension String { - + + #if canImport(Foundation) /// Float value from string (if applicable). /// /// - Parameter locale: Locale (default is Locale.current) @@ -361,9 +426,11 @@ public extension String { let formatter = NumberFormatter() formatter.locale = locale formatter.allowsFloats = true - return formatter.number(from: self) as? Float + return formatter.number(from: self)?.floatValue } - + #endif + + #if canImport(Foundation) /// Double value from string (if applicable). /// /// - Parameter locale: Locale (default is Locale.current) @@ -372,9 +439,11 @@ public extension String { let formatter = NumberFormatter() formatter.locale = locale formatter.allowsFloats = true - return formatter.number(from: self) as? Double + return formatter.number(from: self)?.doubleValue } - + #endif + + #if canImport(CoreGraphics) && canImport(Foundation) /// CGFloat value from string (if applicable). /// /// - Parameter locale: Locale (default is Locale.current) @@ -385,7 +454,9 @@ public extension String { formatter.allowsFloats = true return formatter.number(from: self) as? CGFloat } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Array of strings separated by new lines. /// /// "Hello\ntest".lines() -> ["Hello", "test"] @@ -398,7 +469,9 @@ public extension String { } return result } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Returns a localized string, with an optional comment for translators. /// /// "Hello world".localized -> Hallo Welt @@ -406,7 +479,8 @@ public extension String { public func localized(comment: String = "") -> String { return NSLocalizedString(self, comment: comment) } - + #endif + /// SwifterSwift: The most common character in string. /// /// "This is a test, since e is appearing everywhere e should be the common character".mostCommonCharacter() -> "e" @@ -417,19 +491,20 @@ public extension String { let count = $0[$1] ?? 0 $0[$1] = count + 1 }.max { $0.1 < $1.1 }?.0 - + return mostCommon } - + /// SwifterSwift: Array with unicodes for all characters in a string. /// /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] /// /// - Returns: The unicodes for all characters in a string. public func unicodeArray() -> [Int] { - return unicodeScalars.map({ $0.hashValue }) + return unicodeScalars.map { $0.hashValue } } - + + #if canImport(Foundation) /// SwifterSwift: an array of all words in a string /// /// "Swift is amazing".words() -> ["Swift", "is", "amazing"] @@ -441,7 +516,9 @@ public extension String { let comps = components(separatedBy: chararacterSet) return comps.filter { !$0.isEmpty } } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Count of words in a string. /// /// "Swift is amazing".wordsCount() -> 3 @@ -449,37 +526,44 @@ public extension String { /// - Returns: The count of words contained in a string. public func wordCount() -> Int { // https://stackoverflow.com/questions/42822838 - return words().count + let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters) + let comps = components(separatedBy: chararacterSet) + let words = comps.filter { !$0.isEmpty } + return words.count } + #endif - /// SwifterSwift: Transforms the string into a slug string. - /// - /// "Swift is amazing".toSlug() -> "swift-is-amazing" - /// - /// - Returns: The string in slug format. - public func toSlug() -> String { - let lowercased = self.lowercased() - let latinized = lowercased.latinized - let withDashes = latinized.replacingOccurrences(of: " ", with: "-") - - let alphanumerics = NSCharacterSet.alphanumerics - var filtered = withDashes.filter { - guard String($0) != "-" else { return true } - guard String($0) != "&" else { return true } - return String($0).rangeOfCharacter(from: alphanumerics) != nil - } - - while filtered.lastCharacterAsString == "-" { - filtered = String(filtered.dropLast()) - } - - while filtered.firstCharacterAsString == "-" { - filtered = String(filtered.dropFirst()) - } - - return filtered.replacingOccurrences(of: "--", with: "-") - } - + #if canImport(Foundation) + /// SwifterSwift: Transforms the string into a slug string. + /// + /// "Swift is amazing".toSlug() -> "swift-is-amazing" + /// + /// - Returns: The string in slug format. + public func toSlug() -> String { + let lowercased = self.lowercased() + let latinized = lowercased.latinized + let withDashes = latinized.replacingOccurrences(of: " ", with: "-") + + let alphanumerics = NSCharacterSet.alphanumerics + var filtered = withDashes.filter { + guard String($0) != "-" else { return true } + guard String($0) != "&" else { return true } + return String($0).rangeOfCharacter(from: alphanumerics) != nil + } + + while filtered.lastCharacterAsString == "-" { + filtered = String(filtered.dropLast()) + } + + while filtered.firstCharacterAsString == "-" { + filtered = String(filtered.dropFirst()) + } + + return filtered.replacingOccurrences(of: "--", with: "-") + } + #endif + + // swiftlint:disable identifier_name /// SwifterSwift: Safely subscript string with index. /// /// "Hello World!"[3] -> "l" @@ -490,7 +574,8 @@ public extension String { guard i >= 0 && i < count else { return nil } return self[index(startIndex, offsetBy: i)] } - + // swiftlint:enable identifier_name + /// SwifterSwift: Safely subscript string within a half-open range. /// /// "Hello World!"[6..<11] -> "World" @@ -502,7 +587,7 @@ public extension String { guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) else { return nil } return String(self[lowerIndex.. "World!" @@ -514,7 +599,7 @@ public extension String { guard let upperIndex = index(lowerIndex, offsetBy: range.upperBound - range.lowerBound + 1, limitedBy: endIndex) else { return nil } return String(self[lowerIndex.. Bool { @@ -551,7 +647,8 @@ public extension String { } return true } - + + #if canImport(Foundation) /// SwifterSwift: Check if string contains one or more instance of substring. /// /// "Hello World!".contain("O") -> false @@ -567,7 +664,9 @@ public extension String { } return range(of: string) != nil } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Count of substring in string. /// /// "Hello World!".count(of: "o") -> 2 @@ -583,7 +682,8 @@ public extension String { } return components(separatedBy: string).count - 1 } - + #endif + /// SwifterSwift: Check if string ends with substring. /// /// "Hello World!".ends(with: "!") -> true @@ -599,7 +699,8 @@ public extension String { } return hasSuffix(suffix) } - + + #if canImport(Foundation) /// SwifterSwift: Latinize string. /// /// var str = "Hèllö Wórld!" @@ -607,9 +708,10 @@ public extension String { /// print(str) // prints "Hello World!" /// public mutating func latinize() { - self = latinized + self = folding(options: .diacriticInsensitive, locale: Locale.current) } - + #endif + /// SwifterSwift: Random string of given length. /// /// String.random(ofLength: 18) -> "u7MMZYvGo9obcOcPj8" @@ -627,13 +729,14 @@ public extension String { } return randomString } - + /// SwifterSwift: Reverse string. public mutating func reverse() { let chars: [Character] = reversed() self = String(chars) } - + + // swiftlint:disable identifier_name /// SwifterSwift: Sliced string from a start index with length. /// /// "Hello World".slicing(from: 6, length: 5) -> "World" @@ -650,7 +753,9 @@ public extension String { guard length > 0 else { return "" } return self[safe: i.. true @@ -711,7 +819,8 @@ public extension String { } return hasPrefix(prefix) } - + + #if canImport(Foundation) /// SwifterSwift: Date object from string of date format. /// /// "2017-01-15".date(withFormat: "yyyy-MM-dd") -> Date set to Jan 15, 2017 @@ -724,7 +833,9 @@ public extension String { dateFormatter.dateFormat = format return dateFormatter.date(from: self) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Removes spaces and new lines in beginning and end of string. /// /// var str = " \n Hello World \n\n\n" @@ -734,7 +845,8 @@ public extension String { public mutating func trim() { self = trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) } - + #endif + /// SwifterSwift: Truncate string (cut it to a given number of characters). /// /// var str = "This is a very long sentence" @@ -750,7 +862,7 @@ public extension String { self = self[startIndex.. "This is a very..." @@ -764,7 +876,8 @@ public extension String { guard 1.. Bool { - return range(of: pattern, - options: String.CompareOptions.regularExpression, - range: nil, locale: nil) != nil + return range(of: pattern, options: .regularExpression, range: nil, locale: nil) != nil } - + #endif + /// SwifterSwift: Pad string to fit the length parameter size with another string in the start. /// /// "hue".padStart(10) -> " hue" @@ -809,7 +925,7 @@ public extension String { public mutating func padStart(_ length: Int, with string: String = " ") { self = paddingStart(length, with: string) } - + /// SwifterSwift: Returns a string by padding to fit the length parameter size with another string in the start. /// /// "hue".paddingStart(10) -> " hue" @@ -820,7 +936,7 @@ public extension String { /// - Returns: The string with the padding on the start. public func paddingStart(_ length: Int, with string: String = " ") -> String { guard count < length else { return self } - + let padLength = length - count if padLength < string.count { return string[string.startIndex.. "hue " @@ -843,7 +959,7 @@ public extension String { public mutating func padEnd(_ length: Int, with string: String = " ") { self = paddingEnd(length, with: string) } - + /// SwifterSwift: Returns a string by padding to fit the length parameter size with another string in the end. /// /// "hue".paddingEnd(10) -> "hue " @@ -854,7 +970,7 @@ public extension String { /// - Returns: The string with the padding on the end. public func paddingEnd(_ length: Int, with string: String = " ") -> String { guard count < length else { return self } - + let padLength = length - count if padLength < string.count { return self + string[string.startIndex.. "World!" @@ -874,10 +990,10 @@ public extension String { /// - Parameter prefix: Prefix to remove from the string. /// - Returns: The string after prefix removing. public func removingPrefix(_ prefix: String) -> String { - guard self.hasPrefix(prefix) else { return self } - return String(self.dropFirst(prefix.count)) + guard hasPrefix(prefix) else { return self } + return String(dropFirst(prefix.count)) } - + /// SwifterSwift: Removes given suffix from the string. /// /// "Hello, World!".removingSuffix(", World!") -> "Hello" @@ -885,45 +1001,16 @@ public extension String { /// - Parameter suffix: Suffix to remove from the string. /// - Returns: The string after suffix removing. public func removingSuffix(_ suffix: String) -> String { - guard self.hasSuffix(suffix) else { return self } - return String(self.dropLast(suffix.count)) + guard hasSuffix(suffix) else { return self } + return String(dropLast(suffix.count)) } -} -// MARK: - Operators -public extension String { - - /// SwifterSwift: Repeat string multiple times. - /// - /// 'bar' * 3 -> "barbarbar" - /// - /// - Parameters: - /// - lhs: string to repeat. - /// - rhs: number of times to repeat character. - /// - Returns: new string with given string repeated n times. - public static func * (lhs: String, rhs: Int) -> String { - guard rhs > 0 else { return "" } - return String(repeating: lhs, count: rhs) - } - - /// SwifterSwift: Repeat string multiple times. - /// - /// 3 * 'bar' -> "barbarbar" - /// - /// - Parameters: - /// - lhs: number of times to repeat character. - /// - rhs: string to repeat. - /// - Returns: new string with given string repeated n times. - public static func * (lhs: Int, rhs: String) -> String { - guard lhs > 0 else { return "" } - return String(repeating: rhs, count: lhs) - } - } // MARK: - Initializers public extension String { - + + #if canImport(Foundation) /// SwifterSwift: Create a new string from a base64 string (if applicable). /// /// String(base64: "SGVsbG8gV29ybGQh") = "Hello World!" @@ -931,105 +1018,161 @@ public extension String { /// /// - Parameter base64: base64 string. public init?(base64: String) { - guard let str = base64.base64Decoded else { return nil } + guard let decodedData = Data(base64Encoded: base64) else { return nil } + guard let str = String(data: decodedData, encoding: .utf8) else { return nil } self.init(str) } - + #endif + /// SwifterSwift: Create a new random string of given length. /// /// String(randomOfLength: 10) -> "gY8r3MHvlQ" /// /// - Parameter length: number of characters in string. public init(randomOfLength length: Int) { - self = String.random(ofLength: length) + guard length > 0 else { + self.init() + return + } + + let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + var randomString = "" + for _ in 1...length { + let randomIndex = arc4random_uniform(UInt32(base.count)) + let randomCharacter = Array(base)[Int(randomIndex)] + randomString.append(randomCharacter) + } + self = randomString } - + } // MARK: - NSAttributedString extensions public extension String { - - #if !os(tvOS) && !os(watchOS) + + #if canImport(UIKit) + private typealias Font = UIFont + #endif + + #if canImport(Cocoa) + private typealias Font = NSFont + #endif + + #if os(iOS) || os(macOS) /// SwifterSwift: Bold string. public var bold: NSAttributedString { - #if os(macOS) - return NSMutableAttributedString(string: self, attributes: [.font: NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)]) - #else - return NSMutableAttributedString(string: self, attributes: [.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) - #endif + return NSMutableAttributedString(string: self, attributes: [.font: Font.boldSystemFont(ofSize: Font.systemFontSize)]) } #endif - + + #if canImport(Foundation) /// SwifterSwift: Underlined string public var underline: NSAttributedString { return NSAttributedString(string: self, attributes: [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) } - + #endif + + #if canImport(Foundation) /// SwifterSwift: Strikethrough string. public var strikethrough: NSAttributedString { return NSAttributedString(string: self, attributes: [.strikethroughStyle: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)]) } - + #endif + #if os(iOS) /// SwifterSwift: Italic string. public var italic: NSAttributedString { return NSMutableAttributedString(string: self, attributes: [.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) } #endif - - #if os(macOS) + + #if canImport(UIKit) /// SwifterSwift: Add color to string. /// /// - Parameter color: text color. /// - Returns: a NSAttributedString versions of string colored with given color. - public func colored(with color: NSColor) -> NSAttributedString { + public func colored(with color: UIColor) -> NSAttributedString { return NSMutableAttributedString(string: self, attributes: [.foregroundColor: color]) } - #else + #endif + + #if canImport(Cocoa) /// SwifterSwift: Add color to string. /// /// - Parameter color: text color. /// - Returns: a NSAttributedString versions of string colored with given color. - public func colored(with color: UIColor) -> NSAttributedString { + public func colored(with color: NSColor) -> NSAttributedString { return NSMutableAttributedString(string: self, attributes: [.foregroundColor: color]) } #endif - + +} + +// MARK: - Operators +public extension String { + + /// SwifterSwift: Repeat string multiple times. + /// + /// 'bar' * 3 -> "barbarbar" + /// + /// - Parameters: + /// - lhs: string to repeat. + /// - rhs: number of times to repeat character. + /// - Returns: new string with given string repeated n times. + public static func * (lhs: String, rhs: Int) -> String { + guard rhs > 0 else { return "" } + return String(repeating: lhs, count: rhs) + } + + /// SwifterSwift: Repeat string multiple times. + /// + /// 3 * 'bar' -> "barbarbar" + /// + /// - Parameters: + /// - lhs: number of times to repeat character. + /// - rhs: string to repeat. + /// - Returns: new string with given string repeated n times. + public static func * (lhs: Int, rhs: String) -> String { + guard lhs > 0 else { return "" } + return String(repeating: rhs, count: lhs) + } + } +#if canImport(Foundation) // MARK: - NSString extensions public extension String { - + /// SwifterSwift: NSString from a string. public var nsString: NSString { return NSString(string: self) } - + /// SwifterSwift: NSString lastPathComponent. public var lastPathComponent: String { return (self as NSString).lastPathComponent } - + /// SwifterSwift: NSString pathExtension. public var pathExtension: String { return (self as NSString).pathExtension } - + /// SwifterSwift: NSString deletingLastPathComponent. public var deletingLastPathComponent: String { return (self as NSString).deletingLastPathComponent } - + /// SwifterSwift: NSString deletingPathExtension. public var deletingPathExtension: String { return (self as NSString).deletingPathExtension } - + /// SwifterSwift: NSString pathComponents. public var pathComponents: [String] { return (self as NSString).pathComponents } - + /// SwifterSwift: NSString appendingPathComponent(str: String) /// /// - Parameter str: the path component to append to the receiver. @@ -1037,7 +1180,7 @@ public extension String { public func appendingPathComponent(_ str: String) -> String { return (self as NSString).appendingPathComponent(str) } - + /// SwifterSwift: NSString appendingPathExtension(str: String) /// /// - Parameter str: The extension to append to the receiver. @@ -1045,4 +1188,6 @@ public extension String { public func appendingPathExtension(_ str: String) -> String? { return (self as NSString).appendingPathExtension(str) } + } +#endif diff --git a/Sources/Extensions/SwiftStdlib/StringProtocolExtensions.swift b/Sources/Extensions/SwiftStdlib/StringProtocolExtensions.swift index 19fc630dc..9f7a556f5 100644 --- a/Sources/Extensions/SwiftStdlib/StringProtocolExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringProtocolExtensions.swift @@ -9,7 +9,7 @@ import Foundation public extension StringProtocol where Index == String.Index { - + /// SwifterSwift: The longest common suffix. /// /// "Hello world!".commonSuffix(with: "It's cold!") = "ld!" @@ -22,5 +22,5 @@ public extension StringProtocol where Index == String.Index { let reversedSuffix = String(reversed()).commonPrefix(with: String(aString.reversed()), options: options) return String(reversedSuffix.reversed()) } - + } diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 7c675568d..4f60068df 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -5,18 +5,24 @@ // Created by Omar Albeik on 8/8/16. // Copyright © 2016 SwifterSwift // -#if os(macOS) - import Cocoa -#elseif os(watchOS) - import WatchKit -#else - import UIKit + +#if canImport(UIKit) +import UIKit +#endif + +#if canImport(WatchKit) +import WatchKit +#endif + +#if canImport(Cocoa) +import Cocoa #endif +#if !os(Linux) // MARK: - Properties /// SwifterSwift: Common usefull properties and methods. public struct SwifterSwift { - + #if !os(macOS) /// SwifterSwift: App's name (if applicable). public static var appDisplayName: String? { @@ -24,28 +30,28 @@ public struct SwifterSwift { return Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String } #endif - + #if !os(macOS) /// SwifterSwift: App's bundle ID (if applicable). public static var appBundleID: String? { return Bundle.main.bundleIdentifier } #endif - + #if os(iOS) /// SwifterSwift: StatusBar height public static var statusBarHeight: CGFloat { - return UIApplication.shared.statusBarFrame.height + return UIApplication.shared.statusBarFrame.height } #endif - + #if !os(macOS) /// SwifterSwift: App current build number (if applicable). public static var appBuild: String? { return Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Application icon badge current number. public static var applicationIconBadgeNumber: Int { @@ -57,21 +63,21 @@ public struct SwifterSwift { } } #endif - + #if !os(macOS) /// SwifterSwift: App's current version (if applicable). public static var appVersion: String? { return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String } #endif - + #if os(iOS) /// SwifterSwift: Current battery level. public static var batteryLevel: Float { return UIDevice.current.batteryLevel } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Shared instance of current device. public static var currentDevice: UIDevice { @@ -80,63 +86,63 @@ public struct SwifterSwift { #elseif os(watchOS) /// SwifterSwift: Shared instance of current device. public static var currentDevice: WKInterfaceDevice { - return WKInterfaceDevice.current() + return WKInterfaceDevice.current() } #endif - + #if !os(macOS) /// SwifterSwift: Screen height. public static var screenHeight: CGFloat { #if os(iOS) || os(tvOS) - return UIScreen.main.bounds.height + return UIScreen.main.bounds.height #elseif os(watchOS) - return currentDevice.screenBounds.height + return currentDevice.screenBounds.height #endif } #endif - + #if !os(macOS) /// SwifterSwift: Current device model. public static var deviceModel: String { return currentDevice.model } #endif - + #if !os(macOS) /// SwifterSwift: Current device name. public static var deviceName: String { return currentDevice.name } #endif - + #if os(iOS) /// SwifterSwift: Current orientation of device. public static var deviceOrientation: UIDeviceOrientation { return currentDevice.orientation } #endif - + #if !os(macOS) /// SwifterSwift: Screen width. public static var screenWidth: CGFloat { #if os(iOS) || os(tvOS) - return UIScreen.main.bounds.width + return UIScreen.main.bounds.width #elseif os(watchOS) - return currentDevice.screenBounds.width + return currentDevice.screenBounds.width #endif } #endif - + /// SwifterSwift: Check if app is running in debug mode. public static var isInDebuggingMode: Bool { // http://stackoverflow.com/questions/9063100/xcode-ios-how-to-determine-whether-code-is-running-in-debug-release-build #if DEBUG - return true + return true #else - return false + return false #endif } - + #if !os(macOS) /// SwifterSwift: Check if app is running in TestFlight mode. public static var isInTestFlight: Bool { @@ -144,14 +150,14 @@ public struct SwifterSwift { return Bundle.main.appStoreReceiptURL?.path.contains("sandboxReceipt") == true } #endif - + #if os(iOS) /// SwifterSwift: Check if multitasking is supported in current device. public static var isMultitaskingSupported: Bool { return UIDevice.current.isMultitaskingSupported } #endif - + #if os(iOS) /// SwifterSwift: Current status bar network activity indicator state. public static var isNetworkActivityIndicatorVisible: Bool { @@ -163,38 +169,38 @@ public struct SwifterSwift { } } #endif - + #if os(iOS) /// SwifterSwift: Check if device is iPad. public static var isPad: Bool { return UIDevice.current.userInterfaceIdiom == .pad } #endif - + #if os(iOS) /// SwifterSwift: Check if device is iPhone. public static var isPhone: Bool { return UIDevice.current.userInterfaceIdiom == .phone } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Check if device is registered for remote notifications for current app (read-only). public static var isRegisteredForRemoteNotifications: Bool { return UIApplication.shared.isRegisteredForRemoteNotifications } #endif - + /// SwifterSwift: Check if application is running on simulator (read-only). public static var isRunningOnSimulator: Bool { // http://stackoverflow.com/questions/24869481/detect-if-app-is-being-built-for-device-or-simulator-in-swift - #if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS)) - return true + #if targetEnvironment(simulator) + return true #else - return false + return false #endif } - + #if os(iOS) /// SwifterSwift: Status bar visibility state. public static var isStatusBarHidden: Bool { @@ -206,14 +212,14 @@ public struct SwifterSwift { } } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Key window (read only, if applicable). public static var keyWindow: UIView? { return UIApplication.shared.keyWindow } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Most top view controller (if applicable). public static var mostTopViewController: UIViewController? { @@ -225,14 +231,14 @@ public struct SwifterSwift { } } #endif - + #if os(iOS) || os(tvOS) /// SwifterSwift: Shared instance UIApplication. public static var sharedApplication: UIApplication { return UIApplication.shared } #endif - + #if os(iOS) /// SwifterSwift: Current status bar style (if applicable). public static var statusBarStyle: UIStatusBarStyle? { @@ -246,19 +252,19 @@ public struct SwifterSwift { } } #endif - + #if !os(macOS) /// SwifterSwift: System current version (read-only). public static var systemVersion: String { return currentDevice.systemVersion } #endif - + } // MARK: - Methods public extension SwifterSwift { - + /// SwifterSwift: Delay function or closure call. /// /// - Parameters: @@ -271,7 +277,7 @@ public extension SwifterSwift { queue.asyncAfter(deadline: .now() + (milliseconds/1000), execute: task) return task } - + /// SwifterSwift: Debounce function or closure call. /// /// - Parameters: @@ -282,7 +288,7 @@ public extension SwifterSwift { // http://stackoverflow.com/questions/27116684/how-can-i-debounce-a-method-call var lastFireTime = DispatchTime.now() let dispatchDelay = DispatchTimeInterval.milliseconds(millisecondsDelay) - + return { let dispatchTime: DispatchTime = lastFireTime + dispatchDelay queue.asyncAfter(deadline: dispatchTime) { @@ -295,7 +301,7 @@ public extension SwifterSwift { } } } - + #if os(iOS) || os(tvOS) /// SwifterSwift: Called when user takes a screenshot /// @@ -307,7 +313,7 @@ public extension SwifterSwift { } } #endif - + /// SwifterSwift: Class name of object as string. /// /// - Parameter object: Any object to find its class name. @@ -316,5 +322,6 @@ public extension SwifterSwift { let objectType = type(of: object.self) return String.init(describing: objectType) } - + } +#endif diff --git a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift new file mode 100644 index 000000000..76d8b8ed8 --- /dev/null +++ b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift @@ -0,0 +1,27 @@ +// +// UIKitDeprecated.swift +// SwifterSwift +// +// Created by Omar Albeik on 5.04.2018. +// Copyright © 2018 ___ORGANIZATIONNAME___ +// + +#if canImport(UIKit) +import UIKit + +#if !os(watchOS) +public extension UIStoryboard { + + /// SwifterSwift: Check if date is within the current week. + @available(*, deprecated: 4.3, message: "Use main instead", renamed: "main") + /// SwifterSwift: Get main storyboard for application + public static var mainStoryboard: UIStoryboard? { + let bundle = Bundle.main + guard let name = bundle.object(forInfoDictionaryKey: "UIMainStoryboardFile") as? String else { return nil } + return UIStoryboard(name: name, bundle: bundle) + } + +} +#endif + +#endif diff --git a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift index fc5c6cab6..65c8a2092 100644 --- a/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIAlertControllerExtensions.swift @@ -6,13 +6,17 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) +#if canImport(UIKit) import UIKit + +#if canImport(AudioToolbox) import AudioToolbox +#endif -// MARK: - Methods +#if !os(watchOS) +// MARK: - Methodss public extension UIAlertController { - + /// SwifterSwift: Present alert view controller in the current view controller. /// /// - Parameters: @@ -22,10 +26,12 @@ public extension UIAlertController { public func show(animated: Bool = true, vibrate: Bool = false, completion: (() -> Void)? = nil) { UIApplication.shared.keyWindow?.rootViewController?.present(self, animated: animated, completion: completion) if vibrate { + #if canImport(AudioToolbox) AudioServicesPlayAlertSound(kSystemSoundID_Vibrate) + #endif } } - + /// SwifterSwift: Add an action to Alert /// /// - Parameters: @@ -40,7 +46,7 @@ public extension UIAlertController { addAction(action) return action } - + /// SwifterSwift: Add a text field to Alert /// /// - Parameters: @@ -49,20 +55,20 @@ public extension UIAlertController { /// - editingChangedTarget: an optional target for text field's editingChanged /// - editingChangedSelector: an optional selector for text field's editingChanged public func addTextField(text: String? = nil, placeholder: String? = nil, editingChangedTarget: Any?, editingChangedSelector: Selector?) { - addTextField { tf in - tf.text = text - tf.placeholder = placeholder + addTextField { textField in + textField.text = text + textField.placeholder = placeholder if let target = editingChangedTarget, let selector = editingChangedSelector { - tf.addTarget(target, action: selector, for: .editingChanged) + textField.addTarget(target, action: selector, for: .editingChanged) } } } - + } // MARK: - Initializers public extension UIAlertController { - + /// SwifterSwift: Create new alert view controller with default OK action. /// /// - Parameters: @@ -78,7 +84,7 @@ public extension UIAlertController { view.tintColor = color } } - + /// SwifterSwift: Create new error alert view controller from Error with default OK action. /// /// - Parameters: @@ -94,6 +100,8 @@ public extension UIAlertController { view.tintColor = color } } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift index e7bceb1a9..1d68a29bc 100644 --- a/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift +++ b/Sources/Extensions/UIKit/UIBarButtonItemExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UIBarButtonItem { - + /// SwifterSwift: Add Target to UIBarButtonItem /// /// - Parameters: @@ -21,6 +22,8 @@ public extension UIBarButtonItem { self.target = target self.action = action } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UIButtonExtensions.swift b/Sources/Extensions/UIKit/UIButtonExtensions.swift index 96d86ed2c..6d1aae628 100644 --- a/Sources/Extensions/UIKit/UIButtonExtensions.swift +++ b/Sources/Extensions/UIKit/UIButtonExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UIButton { - + /// SwifterSwift: Image of disabled state for button; also inspectable from Storyboard. @IBInspectable public var imageForDisabled: UIImage? { get { @@ -21,7 +22,7 @@ public extension UIButton { setImage(newValue, for: .disabled) } } - + /// SwifterSwift: Image of highlighted state for button; also inspectable from Storyboard. @IBInspectable public var imageForHighlighted: UIImage? { get { @@ -31,7 +32,7 @@ public extension UIButton { setImage(newValue, for: .highlighted) } } - + /// SwifterSwift: Image of normal state for button; also inspectable from Storyboard. @IBInspectable public var imageForNormal: UIImage? { get { @@ -41,7 +42,7 @@ public extension UIButton { setImage(newValue, for: .normal) } } - + /// SwifterSwift: Image of selected state for button; also inspectable from Storyboard. @IBInspectable public var imageForSelected: UIImage? { get { @@ -51,7 +52,7 @@ public extension UIButton { setImage(newValue, for: .selected) } } - + /// SwifterSwift: Title color of disabled state for button; also inspectable from Storyboard. @IBInspectable public var titleColorForDisabled: UIColor? { get { @@ -61,7 +62,7 @@ public extension UIButton { setTitleColor(newValue, for: .disabled) } } - + /// SwifterSwift: Title color of highlighted state for button; also inspectable from Storyboard. @IBInspectable public var titleColorForHighlighted: UIColor? { get { @@ -71,7 +72,7 @@ public extension UIButton { setTitleColor(newValue, for: .highlighted) } } - + /// SwifterSwift: Title color of normal state for button; also inspectable from Storyboard. @IBInspectable public var titleColorForNormal: UIColor? { get { @@ -81,7 +82,7 @@ public extension UIButton { setTitleColor(newValue, for: .normal) } } - + /// SwifterSwift: Title color of selected state for button; also inspectable from Storyboard. @IBInspectable public var titleColorForSelected: UIColor? { get { @@ -91,7 +92,7 @@ public extension UIButton { setTitleColor(newValue, for: .selected) } } - + /// SwifterSwift: Title of disabled state for button; also inspectable from Storyboard. @IBInspectable public var titleForDisabled: String? { get { @@ -101,7 +102,7 @@ public extension UIButton { setTitle(newValue, for: .disabled) } } - + /// SwifterSwift: Title of highlighted state for button; also inspectable from Storyboard. @IBInspectable public var titleForHighlighted: String? { get { @@ -111,7 +112,7 @@ public extension UIButton { setTitle(newValue, for: .highlighted) } } - + /// SwifterSwift: Title of normal state for button; also inspectable from Storyboard. @IBInspectable public var titleForNormal: String? { get { @@ -121,7 +122,7 @@ public extension UIButton { setTitle(newValue, for: .normal) } } - + /// SwifterSwift: Title of selected state for button; also inspectable from Storyboard. @IBInspectable public var titleForSelected: String? { get { @@ -131,37 +132,37 @@ public extension UIButton { setTitle(newValue, for: .selected) } } - + } // MARK: - Methods public extension UIButton { - + private var states: [UIControlState] { return [.normal, .selected, .highlighted, .disabled] } - + /// SwifterSwift: Set image for all states. /// /// - Parameter image: UIImage. public func setImageForAllStates(_ image: UIImage) { states.forEach { self.setImage(image, for: $0) } } - + /// SwifterSwift: Set title color for all states. /// /// - Parameter color: UIColor. public func setTitleColorForAllStates(_ color: UIColor) { states.forEach { self.setTitleColor(color, for: $0) } } - + /// SwifterSwift: Set title for all states. /// /// - Parameter title: title string. public func setTitleForAllStates(_ title: String) { states.forEach { self.setTitle(title, for: $0) } } - + /// SwifterSwift: Center align title text and image on UIButton /// /// - Parameter spacing: spacing between UIButton title text and UIButton Image. @@ -171,6 +172,8 @@ public extension UIButton { titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount) contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount) } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index d0a69525e..ea7c33418 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -6,27 +6,28 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UICollectionView { - + /// SwifterSwift: Index path of last item in collectionView. public var indexPathForLastItem: IndexPath? { return indexPathForLastItem(inSection: lastSection) } - + /// SwifterSwift: Index of last section in collectionView. public var lastSection: Int { return numberOfSections > 0 ? numberOfSections - 1 : 0 } - + } // MARK: - Methods public extension UICollectionView { - + /// SwifterSwift: Number of all items in all sections of collectionView. /// /// - Returns: The count of all rows in the collectionView. @@ -39,7 +40,7 @@ public extension UICollectionView { } return itemsCount } - + /// SwifterSwift: IndexPath for last item in section. /// /// - Parameter section: section to get last item in. @@ -56,7 +57,7 @@ public extension UICollectionView { } return IndexPath(item: numberOfItems(inSection: section) - 1, section: section) } - + /// SwifterSwift: Reload data with a completion handler. /// /// - Parameter completion: completion handler to run after reloadData finishes. @@ -67,7 +68,7 @@ public extension UICollectionView { completion() }) } - + /// SwifterSwift: Dequeue reusable UICollectionViewCell using class name. /// /// - Parameters: @@ -77,7 +78,7 @@ public extension UICollectionView { public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { return dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as? T } - + /// SwifterSwift: Dequeue reusable UICollectionReusableView using class name. /// /// - Parameters: @@ -88,7 +89,7 @@ public extension UICollectionView { public func dequeueReusableSupplementaryView(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T? { return dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as? T } - + /// SwifterSwift: Register UICollectionReusableView using class name. /// /// - Parameters: @@ -97,7 +98,7 @@ public extension UICollectionView { public func register(supplementaryViewOfKind kind: String, withClass name: T.Type) { register(T.self, forSupplementaryViewOfKind: kind, withReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UICollectionViewCell using class name. /// /// - Parameters: @@ -106,14 +107,14 @@ public extension UICollectionView { public func register(nib: UINib?, forCellWithClass name: T.Type) { register(nib, forCellWithReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UICollectionViewCell using class name. /// /// - Parameter name: UICollectionViewCell type. public func register(cellWithClass name: T.Type) { register(T.self, forCellWithReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UICollectionReusableView using class name. /// /// - Parameters: @@ -123,7 +124,7 @@ public extension UICollectionView { public func register(nib: UINib?, forSupplementaryViewOfKind kind: String, withClass name: T.Type) { register(nib, forSupplementaryViewOfKind: kind, withReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UICollectionViewCell with .xib file using only its corresponding class. /// Assumes that the .xib filename and cell class has the same name. /// @@ -133,13 +134,15 @@ public extension UICollectionView { public func register(nibWithCellClass name: T.Type, at bundleClass: AnyClass? = nil) { let identifier = String(describing: name) var bundle: Bundle? = nil - + if let bundleName = bundleClass { bundle = Bundle(for: bundleName) } - + register(UINib(nibName: identifier, bundle: bundle), forCellWithReuseIdentifier: identifier) } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UIDatePickerExtensions.swift b/Sources/Extensions/UIKit/UIDatePickerExtensions.swift index bf7b15360..8cb7cb625 100644 --- a/Sources/Extensions/UIKit/UIDatePickerExtensions.swift +++ b/Sources/Extensions/UIKit/UIDatePickerExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2017 SwifterSwift // -#if os(iOS) +#if canImport(UIKit) import UIKit +#if os(iOS) // MARK: - Properties public extension UIDatePicker { - + /// SwifterSwift: Text color of UIDatePicker. public var textColor: UIColor? { set { @@ -21,6 +22,8 @@ public extension UIDatePicker { return value(forKeyPath: "textColor") as? UIColor } } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UIFontExtensions.swift b/Sources/Extensions/UIKit/UIFontExtensions.swift index 0ecb54e74..4a8043bf9 100644 --- a/Sources/Extensions/UIKit/UIFontExtensions.swift +++ b/Sources/Extensions/UIKit/UIFontExtensions.swift @@ -6,33 +6,33 @@ // Copyright © 2017 SwifterSwift // -#if os(iOS) || os(tvOS) || os(watchOS) +#if canImport(UIKit) import UIKit // MARK: - Properties public extension UIFont { - + /// SwifterSwift: Font as bold font public var bold: UIFont { return UIFont(descriptor: fontDescriptor.withSymbolicTraits(.traitBold)!, size: 0) } - + /// SwifterSwift: Font as italic font public var italic: UIFont { return UIFont(descriptor: fontDescriptor.withSymbolicTraits(.traitItalic)!, size: 0) } - + /// SwifterSwift: Font as monospaced font /// /// UIFont.preferredFont(forTextStyle: .body).monospaced /// public var monospaced: UIFont { let settings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType, UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector]] - + let attributes = [UIFontDescriptor.AttributeName.featureSettings: settings] let newDescriptor = fontDescriptor.addingAttributes(attributes) return UIFont(descriptor: newDescriptor, size: 0) } - + } #endif diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index 6c7e0e1ea..c9018d852 100644 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -6,37 +6,37 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) || os(watchOS) +#if canImport(UIKit) import UIKit // MARK: - Properties public extension UIImage { - + /// SwifterSwift: Size in bytes of UIImage public var bytesSize: Int { return UIImageJPEGRepresentation(self, 1)?.count ?? 0 } - + /// SwifterSwift: Size in kilo bytes of UIImage public var kilobytesSize: Int { return bytesSize / 1024 } - + /// SwifterSwift: UIImage with .alwaysOriginal rendering mode. public var original: UIImage { return withRenderingMode(.alwaysOriginal) } - + /// SwifterSwift: UIImage with .alwaysTemplate rendering mode. public var template: UIImage { return withRenderingMode(.alwaysTemplate) } - + } // MARK: - Methods public extension UIImage { - + /// SwifterSwift: Compressed UIImage from original UIImage. /// /// - Parameter quality: The quality of the resulting JPEG image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality), (default is 0.5). @@ -45,7 +45,7 @@ public extension UIImage { guard let data = compressedData(quality: quality) else { return nil } return UIImage(data: data) } - + /// SwifterSwift: Compressed UIImage data from original UIImage. /// /// - Parameter quality: The quality of the resulting JPEG image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality), (default is 0.5). @@ -53,7 +53,7 @@ public extension UIImage { public func compressedData(quality: CGFloat = 0.5) -> Data? { return UIImageJPEGRepresentation(self, quality) } - + /// SwifterSwift: UIImage Cropped to CGRect. /// /// - Parameter rect: CGRect to crop UIImage to. @@ -63,7 +63,7 @@ public extension UIImage { guard let image: CGImage = cgImage?.cropping(to: rect) else { return self } return UIImage(cgImage: image) } - + /// SwifterSwift: UIImage scaled to height with respect to aspect ratio. /// /// - Parameters: @@ -79,7 +79,7 @@ public extension UIImage { UIGraphicsEndImageContext() return newImage } - + /// SwifterSwift: UIImage scaled to width with respect to aspect ratio. /// /// - Parameters: @@ -95,7 +95,7 @@ public extension UIImage { UIGraphicsEndImageContext() return newImage } - + /// SwifterSwift: UIImage filled with color /// /// - Parameter color: color to fill image with. @@ -104,21 +104,21 @@ public extension UIImage { UIGraphicsBeginImageContextWithOptions(size, false, scale) color.setFill() guard let context = UIGraphicsGetCurrentContext() else { return self } - + context.translateBy(x: 0, y: size.height) context.scaleBy(x: 1.0, y: -1.0) context.setBlendMode(CGBlendMode.normal) - + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) guard let mask = self.cgImage else { return self } context.clip(to: rect, mask: mask) context.fill(rect) - + let newImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } - + /// SwifterSwift: UIImage tinted with color /// /// - Parameters: @@ -137,7 +137,7 @@ public extension UIImage { UIGraphicsEndImageContext() return tintedImage! } - + /// SwifterSwift: UIImage with rounded corners /// /// - Parameters: @@ -151,23 +151,23 @@ public extension UIImage { } else { cornerRadius = maxRadius } - + UIGraphicsBeginImageContextWithOptions(size, false, scale) - + let rect = CGRect(origin: .zero, size: size) UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip() draw(in: rect) - + let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } - + } // MARK: - Initializers public extension UIImage { - + /// SwifterSwift: Create UIImage from color and size. /// /// - Parameters: @@ -188,6 +188,6 @@ public extension UIImage { } self.init(cgImage: aCgImage) } - + } #endif diff --git a/Sources/Extensions/UIKit/UIImageViewExtensions.swift b/Sources/Extensions/UIKit/UIImageViewExtensions.swift index 31864bd4b..0b06e084d 100644 --- a/Sources/Extensions/UIKit/UIImageViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageViewExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UIImageView { - + /// SwifterSwift: Set image from a URL. /// /// - Parameters: @@ -24,7 +25,7 @@ public extension UIImageView { contentMode: UIViewContentMode = .scaleAspectFit, placeholder: UIImage? = nil, completionHandler: ((UIImage?) -> Void)? = nil) { - + image = placeholder self.contentMode = contentMode URLSession.shared.dataTask(with: url) { (data, response, _) in @@ -43,7 +44,7 @@ public extension UIImageView { } }.resume() } - + /// SwifterSwift: Make image view blurry /// /// - Parameter style: UIBlurEffectStyle (default is .light). @@ -55,7 +56,7 @@ public extension UIImageView { addSubview(blurEffectView) clipsToBounds = true } - + /// SwifterSwift: Blurred version of an image view /// /// - Parameter style: UIBlurEffectStyle (default is .light). @@ -65,6 +66,8 @@ public extension UIImageView { imgView.blur(withStyle: style) return imgView } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UILabelExtensions.swift b/Sources/Extensions/UIKit/UILabelExtensions.swift index 38beb7fc4..51ec506a9 100644 --- a/Sources/Extensions/UIKit/UILabelExtensions.swift +++ b/Sources/Extensions/UIKit/UILabelExtensions.swift @@ -6,18 +6,19 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UILabel { - + /// SwifterSwift: Initialize a UILabel with text public convenience init(text: String?) { self.init() self.text = text } - + /// SwifterSwift: Required height for a label public var requiredHeight: CGFloat { let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: CGFloat.greatestFiniteMagnitude)) @@ -29,6 +30,8 @@ public extension UILabel { label.sizeToFit() return label.frame.height } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift index ed9ec8d5f..2637e1db4 100644 --- a/Sources/Extensions/UIKit/UINavigationBarExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationBarExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UINavigationBar { - + /// SwifterSwift: Set Navigation Bar title, title color and font. /// /// - Parameters: @@ -23,7 +24,7 @@ public extension UINavigationBar { attrs[.foregroundColor] = color titleTextAttributes = attrs } - + /// SwifterSwift: Make navigation bar transparent. /// /// - Parameter tint: tint color (default is .white). @@ -36,7 +37,7 @@ public extension UINavigationBar { titleTextAttributes = [.foregroundColor: tint] shadowImage = UIImage() } - + /// SwifterSwift: Set navigationBar background and text colors /// /// - Parameters: @@ -50,6 +51,8 @@ public extension UINavigationBar { tintColor = text titleTextAttributes = [.foregroundColor: text] } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift index 59669eefc..780c38816 100755 --- a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UINavigationController { - + /// SwifterSwift: Pop ViewController with completion handler. /// /// - Parameter completion: optional completion handler (default is nil). @@ -22,7 +23,7 @@ public extension UINavigationController { popViewController(animated: true) CATransaction.commit() } - + /// SwifterSwift: Push ViewController with completion handler. /// /// - Parameters: @@ -35,7 +36,7 @@ public extension UINavigationController { pushViewController(viewController, animated: true) CATransaction.commit() } - + /// SwifterSwift: Make navigation controller's navigation bar transparent. /// /// - Parameter tint: tint color (default is .white). @@ -46,6 +47,8 @@ public extension UINavigationController { navigationBar.tintColor = tint navigationBar.titleTextAttributes = [.foregroundColor: tint] } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift index 3989bc6c9..25156d939 100644 --- a/Sources/Extensions/UIKit/UINavigationItemExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationItemExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UINavigationItem { - + /// SwifterSwift: Replace title label with an image in navigation item. /// /// - Parameter image: UIImage to replace title with. @@ -21,6 +22,8 @@ public extension UINavigationItem { logoImageView.image = image titleView = logoImageView } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index 5ee0b4ba1..60f98cd55 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UISearchBar { - + /// SwifterSwift: Text field inside search bar (if applicable). public var textField: UITextField? { let subViews = subviews.flatMap { $0.subviews } @@ -20,21 +21,23 @@ public extension UISearchBar { } return textField } - + /// SwifterSwift: Text with no spaces or new lines in beginning and end (if applicable). public var trimmedText: String? { return text?.trimmingCharacters(in: .whitespacesAndNewlines) } - + } // MARK: - Methods public extension UISearchBar { - + /// SwifterSwift: Clear text. public func clear() { text = "" } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift index a6a52880e..8d7f75362 100644 --- a/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift +++ b/Sources/Extensions/UIKit/UISegmentedControlExtensions.swift @@ -6,17 +6,18 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UISegmentedControl { - + /// SwifterSwift: Segments titles. public var segmentTitles: [String] { get { let range = 0..(withClass name: T.Type) -> T? { return instantiateViewController(withIdentifier: String(describing: name)) as? T } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UISwitchExtensions.swift b/Sources/Extensions/UIKit/UISwitchExtensions.swift index 371dcc9e1..17fd6cf33 100644 --- a/Sources/Extensions/UIKit/UISwitchExtensions.swift +++ b/Sources/Extensions/UIKit/UISwitchExtensions.swift @@ -6,18 +6,21 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) +#if canImport(UIKit) import UIKit +#if os(iOS) // MARK: - Methods public extension UISwitch { - + /// SwifterSwift: Toggle a UISwitch /// /// - Parameter animated: set true to animate the change (default is true) public func toggle(animated: Bool = true) { setOn(!isOn, animated: animated) } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UITabBarExtensions.swift b/Sources/Extensions/UIKit/UITabBarExtensions.swift index fe854aa65..03ba2d23e 100644 --- a/Sources/Extensions/UIKit/UITabBarExtensions.swift +++ b/Sources/Extensions/UIKit/UITabBarExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UITabBar { - + /// SwifterSwift: Set tabBar colors. /// /// - Parameters: @@ -24,68 +25,60 @@ public extension UITabBar { selectedBackground: UIColor? = nil, item: UIColor? = nil, selectedItem: UIColor? = nil) { - + // background barTintColor = background ?? barTintColor - + // selectedItem tintColor = selectedItem ?? tintColor // shadowImage = UIImage() backgroundImage = UIImage() isTranslucent = false - + // selectedBackgoundColor guard let barItems = items else { return } - + if let selectedbg = selectedBackground { let rect = CGSize(width: frame.width/CGFloat(barItems.count), height: frame.height) selectionIndicatorImage = { (color: UIColor, size: CGSize) -> UIImage in UIGraphicsBeginImageContextWithOptions(size, false, 1) color.setFill() UIRectFill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) - guard let image = UIGraphicsGetImageFromCurrentImageContext() else { - return UIImage() - } + guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage() } UIGraphicsEndImageContext() - guard let aCgImage = image.cgImage else { - return UIImage() - } + guard let aCgImage = image.cgImage else { return UIImage() } return UIImage(cgImage: aCgImage) }(selectedbg, rect) } - + if let itemColor = item { for barItem in barItems as [UITabBarItem] { // item - guard let image = barItem.image else { - continue - } - + guard let image = barItem.image else { continue } + barItem.image = { (image: UIImage, color: UIColor) -> UIImage in UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) color.setFill() guard let context = UIGraphicsGetCurrentContext() else { return image } - + context.translateBy(x: 0, y: image.size.height) context.scaleBy(x: 1.0, y: -1.0) context.setBlendMode(CGBlendMode.normal) - + let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) - guard let mask = image.cgImage else { - return image - } + guard let mask = image.cgImage else { return image } context.clip(to: rect, mask: mask) context.fill(rect) - + let newImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage }(image, itemColor).withRenderingMode(.alwaysOriginal) - + barItem.setTitleTextAttributes([.foregroundColor: itemColor], for: .normal) if let selected = selectedItem { barItem.setTitleTextAttributes([.foregroundColor: selected], for: .selected) @@ -93,6 +86,8 @@ public extension UITabBar { } } } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index 0cbb459a8..c17bd9559 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -6,27 +6,28 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UITableView { - + /// SwifterSwift: Index path of last row in tableView. public var indexPathForLastRow: IndexPath? { return indexPathForLastRow(inSection: lastSection) } - + /// SwifterSwift: Index of last section in tableView. public var lastSection: Int { return numberOfSections > 0 ? numberOfSections - 1 : 0 } - + } // MARK: - Methods public extension UITableView { - + /// SwifterSwift: Number of all rows in all sections of tableView. /// /// - Returns: The count of all rows in the tableView. @@ -39,7 +40,7 @@ public extension UITableView { } return rowCount } - + /// SwifterSwift: IndexPath for last row in section. /// /// - Parameter section: section to get last row in. @@ -51,7 +52,7 @@ public extension UITableView { } return IndexPath(row: numberOfRows(inSection: section) - 1, section: section) } - + /// Reload data with a completion handler. /// /// - Parameter completion: completion handler to run after reloadData finishes. @@ -62,17 +63,17 @@ public extension UITableView { completion() }) } - + /// SwifterSwift: Remove TableFooterView. public func removeTableFooterView() { tableFooterView = nil } - + /// SwifterSwift: Remove TableHeaderView. public func removeTableHeaderView() { tableHeaderView = nil } - + /// SwifterSwift: Scroll to bottom of TableView. /// /// - Parameter animated: set true to animate scroll (default is true). @@ -80,14 +81,14 @@ public extension UITableView { let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height) setContentOffset(bottomOffset, animated: animated) } - + /// SwifterSwift: Scroll to top of TableView. /// /// - Parameter animated: set true to animate scroll (default is true). public func scrollToTop(animated: Bool = true) { setContentOffset(CGPoint.zero, animated: animated) } - + /// SwifterSwift: Dequeue reusable UITableViewCell using class name /// /// - Parameter name: UITableViewCell type @@ -95,7 +96,7 @@ public extension UITableView { public func dequeueReusableCell(withClass name: T.Type) -> T? { return dequeueReusableCell(withIdentifier: String(describing: name)) as? T } - + /// SwiferSwift: Dequeue reusable UITableViewCell using class name for indexPath /// /// - Parameters: @@ -105,7 +106,7 @@ public extension UITableView { public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { return dequeueReusableCell(withIdentifier: String(describing: name), for: indexPath) as? T } - + /// SwiferSwift: Dequeue reusable UITableViewHeaderFooterView using class name /// /// - Parameter name: UITableViewHeaderFooterView type @@ -113,7 +114,7 @@ public extension UITableView { public func dequeueReusableHeaderFooterView(withClass name: T.Type) -> T? { return dequeueReusableHeaderFooterView(withIdentifier: String(describing: name)) as? T } - + /// SwifterSwift: Register UITableViewHeaderFooterView using class name /// /// - Parameters: @@ -122,21 +123,21 @@ public extension UITableView { public func register(nib: UINib?, withHeaderFooterViewClass name: T.Type) { register(nib, forHeaderFooterViewReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UITableViewHeaderFooterView using class name /// /// - Parameter name: UITableViewHeaderFooterView type public func register(headerFooterViewClassWith name: T.Type) { register(T.self, forHeaderFooterViewReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UITableViewCell using class name /// /// - Parameter name: UITableViewCell type public func register(cellWithClass name: T.Type) { register(T.self, forCellReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UITableViewCell using class name /// /// - Parameters: @@ -145,7 +146,7 @@ public extension UITableView { public func register(nib: UINib?, withCellClass name: T.Type) { register(nib, forCellReuseIdentifier: String(describing: name)) } - + /// SwifterSwift: Register UITableViewCell with .xib file using only its corresponding class. /// Assumes that the .xib filename and cell class has the same name. /// @@ -155,13 +156,15 @@ public extension UITableView { public func register(nibWithCellClass name: T.Type, at bundleClass: AnyClass? = nil) { let identifier = String(describing: name) var bundle: Bundle? = nil - + if let bundleName = bundleClass { bundle = Bundle(for: bundleName) } - + register(UINib(nibName: identifier, bundle: bundle), forCellReuseIdentifier: identifier) } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index c5d1f3d11..f785583d1 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -6,12 +6,13 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Enums public extension UITextField { - + /// SwifterSwift: UITextField text type. /// /// - emailAddress: UITextField is used to enter email addresses. @@ -22,12 +23,12 @@ public extension UITextField { case password case generic } - + } // MARK: - Properties public extension UITextField { - + /// SwifterSwift: Set textField for common text types. public var textType: TextType { get { @@ -46,31 +47,30 @@ public extension UITextField { autocapitalizationType = .none isSecureTextEntry = false placeholder = "Email Address" - + case .password: keyboardType = .asciiCapable autocorrectionType = .no autocapitalizationType = .none isSecureTextEntry = true placeholder = "Password" - + case .generic: isSecureTextEntry = false - } } } - + /// SwifterSwift: Check if text field is empty. public var isEmpty: Bool { return text?.isEmpty == true } - + /// SwifterSwift: Return text with no spaces or new lines in beginning and end. public var trimmedText: String? { return text?.trimmingCharacters(in: .whitespacesAndNewlines) } - + /// SwifterSwift: Check if textFields text is a valid email format. /// /// textField.text = "john@doe.com" @@ -85,7 +85,7 @@ public extension UITextField { options: String.CompareOptions.regularExpression, range: nil, locale: nil) != nil } - + /// SwifterSwift: Left view tint color. @IBInspectable public var leftViewTintColor: UIColor? { get { @@ -98,7 +98,7 @@ public extension UITextField { iconView.tintColor = newValue } } - + /// SwifterSwift: Right view tint color. @IBInspectable public var rightViewTintColor: UIColor? { get { @@ -111,18 +111,18 @@ public extension UITextField { iconView.tintColor = newValue } } - + } // MARK: - Methods public extension UITextField { - + /// SwifterSwift: Clear text. public func clear() { text = "" attributedText = NSAttributedString(string: "") } - + /// SwifterSwift: Set placeholder text color. /// /// - Parameter color: placeholder text color. @@ -130,7 +130,7 @@ public extension UITextField { guard let holder = placeholder, !holder.isEmpty else { return } self.attributedPlaceholder = NSAttributedString(string: holder, attributes: [.foregroundColor: color]) } - + /// SwifterSwift: Add padding to the left of the textfield rect. /// /// - Parameter padding: amount of padding to apply to the left of the textfield rect. @@ -139,7 +139,7 @@ public extension UITextField { leftView = paddingView leftViewMode = .always } - + /// SwifterSwift: Add padding to the left of the textfield rect. /// /// - Parameters: @@ -152,7 +152,9 @@ public extension UITextField { self.leftView?.frame.size = CGSize(width: image.size.width + padding, height: image.size.height) self.leftViewMode = UITextFieldViewMode.always } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UITextViewExtensions.swift b/Sources/Extensions/UIKit/UITextViewExtensions.swift index 24437eb09..9e53dadee 100644 --- a/Sources/Extensions/UIKit/UITextViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITextViewExtensions.swift @@ -6,30 +6,32 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Methods public extension UITextView { - + /// SwifterSwift: Clear text. public func clear() { text = "" attributedText = NSAttributedString(string: "") } - + /// SwifterSwift: Scroll to the bottom of text view public func scrollToBottom() { let range = NSMakeRange((text as NSString).length - 1, 1) scrollRangeToVisible(range) - } - + /// SwifterSwift: Scroll to the top of text view public func scrollToTop() { let range = NSMakeRange(0, 1) scrollRangeToVisible(range) } - + } #endif + +#endif diff --git a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift index bebee0352..9b873b2ca 100755 --- a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift @@ -6,23 +6,24 @@ // Copyright © 2016 SwifterSwift // -#if os(iOS) || os(tvOS) +#if canImport(UIKit) import UIKit +#if !os(watchOS) // MARK: - Properties public extension UIViewController { - + /// SwifterSwift: Check if ViewController is onscreen and not hidden. public var isVisible: Bool { // http://stackoverflow.com/questions/2777438/how-to-tell-if-uiviewcontrollers-view-is-visible return self.isViewLoaded && view.window != nil } - + } // MARK: - Methods public extension UIViewController { - + /// SwifterSwift: Assign as listener to notification. /// /// - Parameters: @@ -31,19 +32,19 @@ public extension UIViewController { public func addNotificationObserver(name: Notification.Name, selector: Selector) { NotificationCenter.default.addObserver(self, selector: selector, name: name, object: nil) } - + /// SwifterSwift: Unassign as listener to notification. /// /// - Parameter name: notification name. public func removeNotificationObserver(name: Notification.Name) { NotificationCenter.default.removeObserver(self, name: name, object: nil) } - + /// SwifterSwift: Unassign as listener from all notifications. public func removeNotificationsObserver() { NotificationCenter.default.removeObserver(self) } - + /// SwifterSwift: Helper method to display an alert on any UIViewController subclass. Uses UIAlertController to show an alert /// /// - Parameters: @@ -59,7 +60,7 @@ public extension UIViewController { if allButtons.count == 0 { allButtons.append("OK") } - + for index in 0.. UIView? { return UINib(nibName: name, bundle: bundle).instantiate(withOwner: nil, options: nil)[0] as? UIView } - + /// SwifterSwift: Remove all subviews in view. public func removeSubviews() { subviews.forEach({ $0.removeFromSuperview() }) } - + /// SwifterSwift: Remove all gesture recognizers from view. public func removeGestureRecognizers() { gestureRecognizers?.forEach(removeGestureRecognizer) } - + /// SwifterSwift: Rotate view by angle on relative axis. /// /// - Parameters: @@ -320,7 +327,7 @@ public extension UIView { self.transform = self.transform.rotated(by: angleWithType) }, completion: completion) } - + /// SwifterSwift: Rotate view to angle on fixed axis. /// /// - Parameters: @@ -336,7 +343,7 @@ public extension UIView { self.transform = self.transform.concatenating(CGAffineTransform(rotationAngle: angleWithType)) }, completion: completion) } - + /// SwifterSwift: Scale view by offset. /// /// - Parameters: @@ -354,7 +361,7 @@ public extension UIView { completion?(true) } } - + /// SwifterSwift: Shake view. /// /// - Parameters: @@ -363,7 +370,6 @@ public extension UIView { /// - animationType: shake animation type (default is .easeOut). /// - completion: optional completion handler to run with animation finishes (default is nil). public func shake(direction: ShakeDirection = .horizontal, duration: TimeInterval = 1, animationType: ShakeAnimationType = .easeOut, completion:(() -> Void)? = nil) { - CATransaction.begin() let animation: CAKeyframeAnimation switch direction { @@ -388,7 +394,7 @@ public extension UIView { layer.add(animation, forKey: "shake") CATransaction.commit() } - + /// SwifterSwift: Add Visual Format constraints. /// /// - Parameters: @@ -404,7 +410,7 @@ public extension UIView { } addConstraints(NSLayoutConstraint.constraints(withVisualFormat: withFormat, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary)) } - + /// SwifterSwift: Anchor all sides of the view into it's superview. @available(iOS 9, *) public func fillToSuperview() { // https://videos.letsbuildthatapp.com/ @@ -416,7 +422,7 @@ public extension UIView { bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true } } - + /// SwifterSwift: Add anchors from any side of the current view into the specified anchors and returns the newly added constraints. /// /// - Parameters: @@ -444,38 +450,38 @@ public extension UIView { heightConstant: CGFloat = 0) -> [NSLayoutConstraint] { // https://videos.letsbuildthatapp.com/ translatesAutoresizingMaskIntoConstraints = false - + var anchors = [NSLayoutConstraint]() - + if let top = top { anchors.append(topAnchor.constraint(equalTo: top, constant: topConstant)) } - + if let left = left { anchors.append(leftAnchor.constraint(equalTo: left, constant: leftConstant)) } - + if let bottom = bottom { anchors.append(bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant)) } - + if let right = right { anchors.append(rightAnchor.constraint(equalTo: right, constant: -rightConstant)) } - + if widthConstant > 0 { anchors.append(widthAnchor.constraint(equalToConstant: widthConstant)) } - + if heightConstant > 0 { anchors.append(heightAnchor.constraint(equalToConstant: heightConstant)) } - + anchors.forEach({$0.isActive = true}) - + return anchors } - + /// SwifterSwift: Anchor center X into current view's superview with a constant margin value. /// /// - Parameter constant: constant of the anchor constraint (default is 0). @@ -486,7 +492,7 @@ public extension UIView { centerXAnchor.constraint(equalTo: anchor, constant: constant).isActive = true } } - + /// SwifterSwift: Anchor center Y into current view's superview with a constant margin value. /// /// - Parameter withConstant: constant of the anchor constraint (default is 0). @@ -497,13 +503,15 @@ public extension UIView { centerYAnchor.constraint(equalTo: anchor, constant: constant).isActive = true } } - + /// SwifterSwift: Anchor center X and Y into current view's superview @available(iOS 9, *) public func anchorCenterSuperview() { // https://videos.letsbuildthatapp.com/ anchorCenterXToSuperview() anchorCenterYToSuperview() } - + } #endif + +#endif diff --git a/Sources/Info.plist b/Sources/Info.plist index dbe38e952..0caec9254 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.2.0 + 4.3.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index c5d6911b2..c188f4fe2 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwifterSwift' - s.version = '4.2.0' + s.version = '4.3.0' s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.source = { git: 'https://github.com/SwifterSwift/SwifterSwift.git', tag: s.version.to_s } s.source_files = 'Sources/**/*.swift' s.pod_target_xcconfig = { - 'SWIFT_VERSION' => '4.0' + 'SWIFT_VERSION' => '4.1' } s.documentation_url = 'http://swifterswift.com/docs' diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 1b8e49c87..1394d756f 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 074EAF201F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */; }; 076AEC891FDB48580077D153 /* UIDatePickerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */; }; 076AEC8D1FDB49480077D153 /* UIDatePickerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 076AEC8C1FDB49480077D153 /* UIDatePickerExtensionsTests.swift */; }; + 0770035920729B040095F09A /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; 077BA08C1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0891F6BE81F00D9C4AC /* URLRequestExtensions.swift */; }; @@ -36,10 +37,20 @@ 077BA0B91F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; 077BA0BA1F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; 077BA0BB1F6BEA6B00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */; }; + 078916DA2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916D92076077000AC0665 /* FloatingPointExtensionsTests.swift */; }; + 078916DB2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916D92076077000AC0665 /* FloatingPointExtensionsTests.swift */; }; + 078916DC2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916D92076077000AC0665 /* FloatingPointExtensionsTests.swift */; }; + 078916DE20760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916DD20760DA700AC0665 /* SignedIntegerExtensionsTests.swift */; }; + 078916DF20760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916DD20760DA700AC0665 /* SignedIntegerExtensionsTests.swift */; }; + 078916E020760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078916DD20760DA700AC0665 /* SignedIntegerExtensionsTests.swift */; }; 07898B901F278F0800558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07898B911F278F0C00558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07898B921F278F1000558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 07898B931F278F1300558C97 /* SwifterSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 07898B8F1F278E6300558C97 /* SwifterSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 078CE29F207643F8001720DF /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078CE29E207643F8001720DF /* UIKitDeprecated.swift */; }; + 078CE2A0207643F8001720DF /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078CE29E207643F8001720DF /* UIKitDeprecated.swift */; }; + 078CE2A1207643F8001720DF /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078CE29E207643F8001720DF /* UIKitDeprecated.swift */; }; + 078CE2A2207643F8001720DF /* UIKitDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 078CE29E207643F8001720DF /* UIKitDeprecated.swift */; }; 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */; }; 07B7F1931F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */; }; 07B7F1941F5EB42000E6F910 /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */; }; @@ -321,6 +332,13 @@ 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; + 18C8E5DE2074C58100F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; + 18C8E5DF2074C60C00F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; + 18C8E5E02074C60C00F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; + 18C8E5E12074C60C00F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; + 18C8E5E32074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5E22074C67000F8AF51 /* SequenceExtensionsTests.swift */; }; + 18C8E5E42074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5E22074C67000F8AF51 /* SequenceExtensionsTests.swift */; }; + 18C8E5E52074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5E22074C67000F8AF51 /* SequenceExtensionsTests.swift */; }; 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */; }; 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */; }; 426951C720448F5200D85CE2 /* big_buck_bunny_720p_1mb.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 426951C620448F5100D85CE2 /* big_buck_bunny_720p_1mb.mp4 */; }; @@ -407,12 +425,15 @@ 077BA08E1F6BE83600D9C4AC /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; 077BA0941F6BE98500D9C4AC /* URLRequestExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestExtensionsTests.swift; sourceTree = ""; }; 077BA0991F6BE99F00D9C4AC /* UserDefaultsExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensionsTests.swift; sourceTree = ""; }; + 078916D92076077000AC0665 /* FloatingPointExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingPointExtensionsTests.swift; sourceTree = ""; }; + 078916DD20760DA700AC0665 /* SignedIntegerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedIntegerExtensionsTests.swift; sourceTree = ""; }; 07898B5D1F278D7600558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07898B6B1F278D9700558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07898B781F278DBC00558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07898B851F278DD200558C97 /* SwifterSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwifterSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 07898B8E1F278E6300558C97 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 07898B8F1F278E6300558C97 /* SwifterSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwifterSwift.h; sourceTree = ""; }; + 078CE29E207643F8001720DF /* UIKitDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitDeprecated.swift; sourceTree = ""; }; 07B7F15B1F5EB41600E6F910 /* SwifterSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwifterSwift.swift; sourceTree = ""; }; 07B7F15D1F5EB41600E6F910 /* CGColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensions.swift; sourceTree = ""; }; 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGFloatExtensions.swift; sourceTree = ""; }; @@ -512,6 +533,8 @@ 07C50D2A1F5EB03200F46E5A /* NSViewExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSViewExtensionsTests.swift; sourceTree = ""; }; 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedNumericExtensionsTests.swift; sourceTree = ""; }; 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGColorExtensionsTests.swift; sourceTree = ""; }; + 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SequenceExtensions.swift; sourceTree = ""; }; + 18C8E5E22074C67000F8AF51 /* SequenceExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SequenceExtensionsTests.swift; sourceTree = ""; }; 278CA08C1F9A9232004918BD /* NSImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensions.swift; sourceTree = ""; }; 278CA0901F9A9679004918BD /* NSImageExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImageExtensionsTests.swift; sourceTree = ""; }; 426951C620448F5100D85CE2 /* big_buck_bunny_720p_1mb.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = big_buck_bunny_720p_1mb.mp4; sourceTree = ""; }; @@ -625,10 +648,11 @@ 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */, 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */, 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */, + 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */, 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */, - 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */, 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */, 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */, + 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */, B23678EA1FB116680027C931 /* Deprecated */, ); path = SwiftStdlib; @@ -644,8 +668,11 @@ 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */, 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */, 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */, + 078916D92076077000AC0665 /* FloatingPointExtensionsTests.swift */, 07C50D031F5EB03200F46E5A /* IntExtensionsTests.swift */, 07C50D051F5EB03200F46E5A /* OptionalExtensionsTests.swift */, + 18C8E5E22074C67000F8AF51 /* SequenceExtensionsTests.swift */, + 078916DD20760DA700AC0665 /* SignedIntegerExtensionsTests.swift */, 07C50D061F5EB03200F46E5A /* StringExtensionsTests.swift */, 9D9784DF1FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift */, 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */, @@ -703,6 +730,14 @@ path = Extensions; sourceTree = ""; }; + 078CE29D207643A2001720DF /* Deprecated */ = { + isa = PBXGroup; + children = ( + 078CE29E207643F8001720DF /* UIKitDeprecated.swift */, + ); + path = Deprecated; + sourceTree = ""; + }; 07B7F15C1F5EB41600E6F910 /* AppKit */ = { isa = PBXGroup; children = ( @@ -733,6 +768,7 @@ 07B7F1791F5EB41600E6F910 /* UIKit */ = { isa = PBXGroup; children = ( + 078CE29D207643A2001720DF /* Deprecated */, 07B7F17C1F5EB41600E6F910 /* UIAlertControllerExtensions.swift */, 07B7F17D1F5EB41600E6F910 /* UIBarButtonItemExtensions.swift */, 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */, @@ -1096,7 +1132,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0900; - LastUpgradeCheck = 0910; + LastUpgradeCheck = 0930; TargetAttributes = { 07898B5C1F278D7600558C97 = { CreatedOnToolsVersion = 9.0; @@ -1315,6 +1351,7 @@ 07B7F1A31F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, 077BA08F1F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1A11F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, + 078CE29F207643F8001720DF /* UIKitDeprecated.swift in Sources */, 07B7F1A41F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */, 07B7F20B1F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F1A01F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */, @@ -1336,6 +1373,7 @@ 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F2131F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, + 18C8E5DE2074C58100F8AF51 /* SequenceExtensions.swift in Sources */, 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, 074EAF1B1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, @@ -1373,6 +1411,7 @@ 07B7F1FC1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */, 07B7F2031F5EB43C00E6F910 /* IntExtensions.swift in Sources */, 07B7F1FF1F5EB43C00E6F910 /* DictionaryExtensions.swift in Sources */, + 18C8E5DF2074C60C00F8AF51 /* SequenceExtensions.swift in Sources */, 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */, 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, @@ -1388,6 +1427,7 @@ 07B7F1B51F5EB42000E6F910 /* UISliderExtensions.swift in Sources */, 07B7F1A91F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */, 07B7F1B81F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */, + 078CE2A0207643F8001720DF /* UIKitDeprecated.swift in Sources */, 07B7F1BC1F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */, 07B7F2371F5EB45200E6F910 /* CGSizeExtensions.swift in Sources */, 07B7F1FB1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */, @@ -1429,6 +1469,7 @@ 9D9784DD1FCAE42600D988E7 /* StringProtocolExtensions.swift in Sources */, 07B7F1E81F5EB43B00E6F910 /* BoolExtensions.swift in Sources */, A9AEB78720283ACC0021AACF /* FileManagerExtensions.swift in Sources */, + 0770035920729B040095F09A /* MKPolylineExtensions.swift in Sources */, 07B7F2291F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */, 07B7F1C41F5EB42200E6F910 /* UIImageViewExtensions.swift in Sources */, 07B7F22C1F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */, @@ -1450,6 +1491,7 @@ 07B7F1CB1F5EB42200E6F910 /* UISliderExtensions.swift in Sources */, 07B7F1BF1F5EB42200E6F910 /* UIBarButtonItemExtensions.swift in Sources */, 07B7F1CE1F5EB42200E6F910 /* UITabBarExtensions.swift in Sources */, + 078CE2A1207643F8001720DF /* UIKitDeprecated.swift in Sources */, 07B7F1D21F5EB42200E6F910 /* UIViewControllerExtensions.swift in Sources */, 07B7F22B1F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */, 07B7F1E91F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */, @@ -1464,6 +1506,7 @@ 07B7F1EE1F5EB43B00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F1F31F5EB43B00E6F910 /* OptionalExtensions.swift in Sources */, 074EAF1D1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, + 18C8E5E02074C60C00F8AF51 /* SequenceExtensions.swift in Sources */, 07B7F1BE1F5EB42200E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2281F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21D1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, @@ -1499,6 +1542,7 @@ 07B7F2221F5EB44600E6F910 /* CGPointExtensions.swift in Sources */, 07B7F2251F5EB44600E6F910 /* NSAttributedStringExtensions.swift in Sources */, 077BA08D1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + 18C8E5E12074C60C00F8AF51 /* SequenceExtensions.swift in Sources */, 784C75302051BD4A001C48DD /* MKPolylineExtensions.swift in Sources */, 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, @@ -1511,6 +1555,7 @@ 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, + 078CE2A2207643F8001720DF /* UIKitDeprecated.swift in Sources */, B23678EF1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, 07B7F1D91F5EB43B00E6F910 /* DataExtensions.swift in Sources */, 07B7F1E41F5EB43B00E6F910 /* StringExtensions.swift in Sources */, @@ -1533,6 +1578,7 @@ 077BA09E1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D2E1F5EB04600F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, 07C50D3C1F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, + 078916DE20760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */, 07C50D381F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, 07C50D2F1F5EB04600F46E5A /* ColorExtensionsTests.swift in Sources */, 07C50D331F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, @@ -1574,11 +1620,13 @@ 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, + 18C8E5E32074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */, 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D611F5EB05000F46E5A /* LocaleExtensionsTests.swift in Sources */, 07C50D901F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, 07C50D3B1F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */, + 078916DA2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1594,6 +1642,7 @@ 077BA09F1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, 07C50D521F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, + 078916DB2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */, 07C50D4E1F5EB04700F46E5A /* UISliderExtensionsTests.swift in Sources */, 07C50D451F5EB04700F46E5A /* ColorExtensionsTests.swift in Sources */, 784C75382051BE1D001C48DD /* MKPolylineTests.swift in Sources */, @@ -1623,6 +1672,7 @@ 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, A94AA78B202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, + 078916DF20760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */, 07C50D431F5EB04700F46E5A /* UIButtonExtensionsTests.swift in Sources */, 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, @@ -1637,6 +1687,7 @@ 07C50D691F5EB05100F46E5A /* DataExtensionsTests.swift in Sources */, 07C50D6F1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, 07C50D8B1F5EB06000F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, + 18C8E5E42074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */, 07C50D511F5EB04700F46E5A /* UITabBarExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1653,6 +1704,7 @@ 07C50D761F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, 07C50D841F5EB05800F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D741F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */, + 078916E020760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */, 07C50D861F5EB05800F46E5A /* NSViewExtensionsTests.swift in Sources */, 07C50D851F5EB05800F46E5A /* NSAttributedStringExtensionsTests.swift in Sources */, 07C50D7C1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */, @@ -1661,6 +1713,7 @@ 07C50D7F1F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, 07C50D7A1F5EB05100F46E5A /* DoubleExtensionsTests.swift in Sources */, + 18C8E5E52074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */, 278CA0911F9A9679004918BD /* NSImageExtensionsTests.swift in Sources */, 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */, 077BA0A01F6BEA4A00D9C4AC /* URLRequestExtensionsTests.swift in Sources */, @@ -1677,6 +1730,7 @@ 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, A94AA78C202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, + 078916DC2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1708,11 +1762,13 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -1742,11 +1798,13 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; diff --git a/SwifterSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SwifterSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/SwifterSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme index 96d47c9cf..5446842aa 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-iOS.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -58,7 +58,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme index 22a36084b..3a18419b0 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-macOS.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme index ee4cddcec..e155192d4 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-tvOS.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -58,7 +58,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme index a022363ae..bdca5c637 100644 --- a/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme +++ b/SwifterSwift.xcodeproj/xcshareddata/xcschemes/SwifterSwift-watchOS.xcscheme @@ -1,6 +1,6 @@ + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Tests/AppKitTests/NSImageExtensionsTests.swift b/Tests/AppKitTests/NSImageExtensionsTests.swift index ac1eab51f..e27ffe3e6 100644 --- a/Tests/AppKitTests/NSImageExtensionsTests.swift +++ b/Tests/AppKitTests/NSImageExtensionsTests.swift @@ -7,22 +7,22 @@ // #if os(macOS) - + import XCTest @testable import SwifterSwift final class NSImageExtensionsTests: XCTestCase { - - func testScaledToMaxSize() { - let bundle = Bundle.init(for: NSImageExtensionsTests.self) - let image = bundle.image(forResource: NSImage.Name(rawValue: "TestImage")) - XCTAssertNotNil(image) - - let scaledImage = image!.scaled(toMaxSize: NSSize(width: 150, height: 150)) - XCTAssertNotNil(scaledImage) - XCTAssertEqual(scaledImage.size.width, 150) - } - + + func testScaledToMaxSize() { + let bundle = Bundle.init(for: NSImageExtensionsTests.self) + let image = bundle.image(forResource: NSImage.Name(rawValue: "TestImage")) + XCTAssertNotNil(image) + + let scaledImage = image!.scaled(toMaxSize: NSSize(width: 150, height: 150)) + XCTAssertNotNil(scaledImage) + XCTAssertEqual(scaledImage.size.width, 150) + } + } #endif diff --git a/Tests/AppKitTests/NSViewExtensionsTests.swift b/Tests/AppKitTests/NSViewExtensionsTests.swift index 6f46f38b6..87452df2c 100644 --- a/Tests/AppKitTests/NSViewExtensionsTests.swift +++ b/Tests/AppKitTests/NSViewExtensionsTests.swift @@ -7,43 +7,43 @@ // #if os(macOS) - + import XCTest @testable import SwifterSwift final class NSViewExtensionsTests: XCTestCase { - + func testBorderColor() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) view.borderColor = nil XCTAssertNil(view.layer?.borderColor) - + view.borderColor = NSColor.red XCTAssertNotNil(view.layer?.borderColor) XCTAssertEqual(view.borderColor, NSColor.red) XCTAssertEqual(view.layer?.borderColor?.nsColor, NSColor.red) } - + func testBorderWidth() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) view.borderWidth = 0 XCTAssertEqual(view.layer?.borderWidth, 0) - + view.borderWidth = 5 XCTAssertEqual(view.borderWidth, 5) } - + func testCornerRadius() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) XCTAssertNil(view.layer?.cornerRadius) - + view.cornerRadius = 50 XCTAssertEqual(view.cornerRadius, 50) } - + func testHeight() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -51,7 +51,7 @@ final class NSViewExtensionsTests: XCTestCase { view.height = 150 XCTAssertEqual(view.frame.size.height, 150) } - + func testShadowColor() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -61,7 +61,7 @@ final class NSViewExtensionsTests: XCTestCase { XCTAssertNotNil(view.layer?.shadowColor) XCTAssertEqual(view.layer?.shadowColor?.nsColor, NSColor.orange) } - + func testShadowOffset() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -71,7 +71,7 @@ final class NSViewExtensionsTests: XCTestCase { view.shadowOffset = size XCTAssertEqual(view.layer?.shadowOffset, size) } - + func testShadowOpacity() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -80,7 +80,7 @@ final class NSViewExtensionsTests: XCTestCase { view.shadowOpacity = 0.5 XCTAssertEqual(view.layer?.shadowOpacity, 0.5) } - + func testShadowRadius() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -89,17 +89,17 @@ final class NSViewExtensionsTests: XCTestCase { view.shadowRadius = 0.5 XCTAssertEqual(view.layer?.shadowRadius, 0.5) } - + func testSize() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) XCTAssertEqual(view.size, view.frame.size) - + view.size = CGSize(width: 50, height: 50) XCTAssertEqual(view.frame.size.width, 50) XCTAssertEqual(view.frame.size.height, 50) } - + func testWidth() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) @@ -107,23 +107,23 @@ final class NSViewExtensionsTests: XCTestCase { view.width = 150 XCTAssertEqual(view.frame.size.width, 150) } - + func testAddSubviews() { let frame = CGRect(x: 0, y: 0, width: 100, height: 100) let view = NSView(frame: frame) XCTAssertEqual(view.subviews.count, 0) - + view.addSubviews([NSView(), NSView()]) XCTAssertEqual(view.subviews.count, 2) } - + func testRemoveSubviews() { let view = NSView() view.addSubviews([NSView(), NSView()]) view.removeSubviews() XCTAssertEqual(view.subviews.count, 0) } - + } - + #endif diff --git a/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift index e613177c8..c10f83e57 100644 --- a/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGColorExtensionsTests.swift @@ -8,26 +8,28 @@ import XCTest #if os(macOS) - import Cocoa +import Cocoa #else - import UIKit +import UIKit #endif @testable import SwifterSwift final class CGColorExtensionsTests: XCTestCase { - #if !os(macOS) - func testUiColor() { - let red = UIColor.red - let cgRed = red.cgColor - XCTAssertEqual(cgRed.uiColor, red) - } - #endif - - #if os(macOS) - func testNsColor() { - let red = NSColor.red - let cgRed = red.cgColor - XCTAssertEqual(cgRed.nsColor, red) - } - #endif + + #if !os(macOS) + func testUiColor() { + let red = UIColor.red + let cgRed = red.cgColor + XCTAssertEqual(cgRed.uiColor, red) + } + #endif + + #if os(macOS) + func testNsColor() { + let red = NSColor.red + let cgRed = red.cgColor + XCTAssertEqual(cgRed.nsColor, red) + } + #endif + } diff --git a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift index 7cb20a879..ba14c0902 100644 --- a/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGFloatExtensionsTests.swift @@ -10,76 +10,76 @@ import XCTest @testable import SwifterSwift final class CGFloatExtensionsTests: XCTestCase { - + #if !os(macOS) func testAbs() { XCTAssertEqual(CGFloat(-9.3).abs, CGFloat(9.3)) } #endif - + #if !os(macOS) func testCeil() { XCTAssertEqual(CGFloat(9.3).ceil, CGFloat(10.0)) } #endif - + #if !os(macOS) func testDegreesToRadians() { XCTAssertEqual(CGFloat(180).degreesToRadians, CGFloat.pi) } #endif - - #if !os(macOS) - func testIsPositive() { - XCTAssert(CGFloat(9.3).isPositive) - XCTAssertFalse(CGFloat(0).isPositive) - XCTAssertFalse(CGFloat(-9.2).isPositive) - } - #endif - - #if !os(macOS) - func testIsNegative() { - XCTAssert(CGFloat(-9.3).isNegative) - XCTAssertFalse(CGFloat(0).isNegative) - XCTAssertFalse(CGFloat(9.3).isNegative) - } - #endif - - #if !os(macOS) - func testInt() { - XCTAssertEqual(CGFloat(9.3).int, Int(9)) - } - #endif - - #if !os(macOS) - func testDouble() { - XCTAssertEqual(CGFloat(9.3).double, Double(9.3)) - } - #endif - - #if !os(macOS) - func testFloat() { - XCTAssertEqual(CGFloat(9.3).float, Float(9.3)) - } - #endif - + + #if !os(macOS) + func testIsPositive() { + XCTAssert(CGFloat(9.3).isPositive) + XCTAssertFalse(CGFloat(0).isPositive) + XCTAssertFalse(CGFloat(-9.2).isPositive) + } + #endif + + #if !os(macOS) + func testIsNegative() { + XCTAssert(CGFloat(-9.3).isNegative) + XCTAssertFalse(CGFloat(0).isNegative) + XCTAssertFalse(CGFloat(9.3).isNegative) + } + #endif + + #if !os(macOS) + func testInt() { + XCTAssertEqual(CGFloat(9.3).int, Int(9)) + } + #endif + + #if !os(macOS) + func testDouble() { + XCTAssertEqual(CGFloat(9.3).double, Double(9.3)) + } + #endif + + #if !os(macOS) + func testFloat() { + XCTAssertEqual(CGFloat(9.3).float, Float(9.3)) + } + #endif + #if !os(macOS) func testRandomBetween() { XCTAssertGreaterThan(CGFloat.randomBetween(min: 1, max: 5), 0) XCTAssertLessThan(CGFloat.randomBetween(min: 1, max: 5), 5) } #endif - + #if !os(macOS) func testFloor() { XCTAssertEqual(CGFloat(9.3).floor, CGFloat(9.0)) } #endif - + #if !os(macOS) func testRadiansToDegrees() { XCTAssertEqual(CGFloat.pi.radiansToDegrees, CGFloat(180)) } #endif - + } diff --git a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift index fbdea8e43..30bab1e1e 100644 --- a/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGPointExtensionsTests.swift @@ -10,61 +10,61 @@ import XCTest @testable import SwifterSwift final class CGPointExtensionsTests: XCTestCase { - + let point1 = CGPoint(x: 10, y: 10) let point2 = CGPoint(x: 30, y: 30) - + func testDistanceFromPoint() { let distance = point1.distance(from: point2) XCTAssertEqual(distance, 28.28, accuracy: 0.01) } - + func testStaticDistance() { let distance = CGPoint.distance(from: point2, to: point1) XCTAssertEqual(distance, 28.28, accuracy: 0.01) } - + func testAdd() { let point = point1 + point2 let result = CGPoint(x: 40, y: 40) XCTAssertEqual(point, result) } - + func testAddEqual() { var point = point1 point += point2 let result = CGPoint(x: 40, y: 40) XCTAssertEqual(point, result) } - + func testSubtract() { let point = point1 - point2 let result = CGPoint(x: -20, y: -20) XCTAssertEqual(point, result) } - + func testSubtractEqual() { var point = point1 point -= point2 let result = CGPoint(x: -20, y: -20) XCTAssertEqual(point, result) } - + func testScalarMultiply() { let point = 5 * point1 let result = CGPoint(x: 50, y: 50) XCTAssertEqual(point, result) - + let point2 = 5 * point1 let result2 = CGPoint(x: 50, y: 50) XCTAssertEqual(point2, result2) } - + func testScalarMultiplyEqual() { var point = point1 point *= 5 let result = CGPoint(x: 50, y: 50) XCTAssertEqual(point, result) } - + } diff --git a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift index aea54682e..8ff4561e9 100644 --- a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift final class CGSizeExtensionsTests: XCTestCase { - + func testAspectFit() { let rect = CGSize(width: 120, height: 80) let parentRect = CGSize(width: 100, height: 50) @@ -18,7 +18,7 @@ final class CGSizeExtensionsTests: XCTestCase { XCTAssertEqual(newRect.width, 75) XCTAssertEqual(newRect.height, 50) } - + func testAspectFill() { let rect = CGSize(width: 20, height: 120) let parentRect = CGSize(width: 100, height: 60) @@ -26,5 +26,5 @@ final class CGSizeExtensionsTests: XCTestCase { XCTAssertEqual(newRect.width, 100) XCTAssertEqual(newRect.height, 60) } - + } diff --git a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift index 3df09405a..6d27e5690 100644 --- a/Tests/CoreLocationTests/CLLocationExtensionsTests.swift +++ b/Tests/CoreLocationTests/CLLocationExtensionsTests.swift @@ -10,26 +10,25 @@ import XCTest import CoreLocation final class CLLocationExtensionsTests: XCTestCase { - + func testMidLocation() { - let a = CLLocation(latitude: -15.822877, longitude: -47.941839) - let b = CLLocation(latitude: -15.692030, longitude: -47.594397) - let mid = CLLocation.midLocation(start: a, end: b) - + let aLoc = CLLocation(latitude: -15.822877, longitude: -47.941839) + let bLoc = CLLocation(latitude: -15.692030, longitude: -47.594397) + let mid = CLLocation.midLocation(start: aLoc, end: bLoc) + XCTAssertEqual(mid.coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) XCTAssertEqual(mid.coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) - - XCTAssertEqual(a.midLocation(to: b).coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) - XCTAssertEqual(a.midLocation(to: b).coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) - + + XCTAssertEqual(aLoc.midLocation(to: bLoc).coordinate.latitude, -15.7575223324019, accuracy: 0.0000000000001) + XCTAssertEqual(aLoc.midLocation(to: bLoc).coordinate.longitude, -47.7680620274339, accuracy: 0.0000000000001) } - + func testBearing() { - let a = CLLocation(latitude: 38.6318909290283, longitude: -90.2828979492187) - let b = CLLocation(latitude: 38.5352759115441, longitude: -89.8448181152343) - let bearing = a.bearing(to: b) - + let aLoc = CLLocation(latitude: 38.6318909290283, longitude: -90.2828979492187) + let bLoc = CLLocation(latitude: 38.5352759115441, longitude: -89.8448181152343) + let bearing = aLoc.bearing(to: bLoc) + XCTAssertEqual(bearing, 105.619, accuracy: 0.001) } - + } diff --git a/Tests/FoundationTests/CalendarExtensionTest.swift b/Tests/FoundationTests/CalendarExtensionTest.swift index 667640c8d..7cba81ca7 100644 --- a/Tests/FoundationTests/CalendarExtensionTest.swift +++ b/Tests/FoundationTests/CalendarExtensionTest.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift class CalendarExtensionTests: XCTestCase { - + func testNumberOfDaysInAMonth() { let calendar = Calendar(identifier: .gregorian) let longMonths = [1, 3, 5, 7, 8, 10, 12] @@ -21,12 +21,12 @@ class CalendarExtensionTests: XCTestCase { let leapYearDate = calendar.date(from: leapYearDateComponent)! let longMonthsDateComponents = longMonths.map { DateComponents(year: 2015, month: $0) } let shortMonthsDateComponents = shortMonths.map { DateComponents(year: 2015, month: $0) } - let longMonthDates = longMonthsDateComponents.flatMap { calendar.date(from: $0) } - let shortMonthDates = shortMonthsDateComponents.flatMap { calendar.date(from: $0) } + let longMonthDates = longMonthsDateComponents.compactMap { calendar.date(from: $0) } + let shortMonthDates = shortMonthsDateComponents.compactMap { calendar.date(from: $0) } longMonthDates.forEach { XCTAssert(calendar.numberOfDaysInMonth(for: $0) == 31) } shortMonthDates.forEach { XCTAssert(calendar.numberOfDaysInMonth(for: $0) == 30) } XCTAssert(calendar.numberOfDaysInMonth(for: febDate) == 28) XCTAssert(calendar.numberOfDaysInMonth(for: leapYearDate) == 29) } - + } diff --git a/Tests/FoundationTests/DataExtensionsTests.swift b/Tests/FoundationTests/DataExtensionsTests.swift index dae2e5458..fdd047958 100644 --- a/Tests/FoundationTests/DataExtensionsTests.swift +++ b/Tests/FoundationTests/DataExtensionsTests.swift @@ -10,18 +10,19 @@ import XCTest @testable import SwifterSwift final class DataExtensionsTests: XCTestCase { - + func testString() { let dataFromString = "hello".data(using: .utf8) XCTAssertNotNil(dataFromString) XCTAssertNotNil(dataFromString?.string(encoding: .utf8)) XCTAssertEqual(dataFromString?.string(encoding: .utf8), "hello") } - + func testBytes() { let dataFromString = "hello".data(using: .utf8) let bytes = dataFromString?.bytes XCTAssertNotNil(bytes) XCTAssertEqual(bytes?.count, 5) } + } diff --git a/Tests/FoundationTests/DateExtensionsTests.swift b/Tests/FoundationTests/DateExtensionsTests.swift index 0f0bb4e00..8c4dff814 100644 --- a/Tests/FoundationTests/DateExtensionsTests.swift +++ b/Tests/FoundationTests/DateExtensionsTests.swift @@ -8,13 +8,15 @@ import XCTest @testable import SwifterSwift +// swiftlint:disable type_body_length final class DateExtensionsTests: XCTestCase { - + override func setUp() { super.setUp() NSTimeZone.default = TimeZone(abbreviation: "UTC")! } - + + // swiftlint:disable cyclomatic_complexity func testCalendar() { switch Calendar.current.identifier { case .buddhist: @@ -51,12 +53,13 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(Date().calendar.identifier, Calendar(identifier: .republicOfChina).identifier) } } - + // swiftlint:enable cyclomatic_complexity + func testEra() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.era, 1) } - + func testQuarter() { let date1 = Date(timeIntervalSince1970: 0) XCTAssertEqual(date1.quarter, 1) @@ -70,33 +73,33 @@ final class DateExtensionsTests: XCTestCase { let date4 = Calendar.current.date(byAdding: .month, value: 11, to: date1) XCTAssertEqual(date4?.quarter, 4) } - + func testWeekOfYear() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.weekOfYear, 1) - + let dateAfter7Days = Calendar.current.date(byAdding: .day, value: 7, to: date) XCTAssertEqual(dateAfter7Days?.weekOfYear, 2) - + let originalDate = Calendar.current.date(byAdding: .day, value: -7, to: dateAfter7Days!) XCTAssertEqual(originalDate?.weekOfYear, 1) } - + func testWeekOfMonth() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.weekOfMonth, 1) - + let dateAfter7Days = Calendar.current.date(byAdding: .day, value: 7, to: date) XCTAssertEqual(dateAfter7Days?.weekOfMonth, 2) - + let originalDate = Calendar.current.date(byAdding: .day, value: -7, to: dateAfter7Days!) XCTAssertEqual(originalDate?.weekOfMonth, 1) } - + func testYear() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.year, 1970) - + var isLowerComponentsValid: Bool { guard date.month == 1 else { return false } guard date.day == 2 else { return false } @@ -106,32 +109,32 @@ final class DateExtensionsTests: XCTestCase { guard date.nanosecond == 123450040 else { return false } return true } - + date.year = 2000 XCTAssertEqual(date.year, 2000) XCTAssert(isLowerComponentsValid) - + date.year = 2017 XCTAssertEqual(date.year, 2017) XCTAssert(isLowerComponentsValid) - + date.year = 1988 XCTAssertEqual(date.year, 1988) XCTAssert(isLowerComponentsValid) - + date.year = -100 XCTAssertEqual(date.year, 1988) XCTAssert(isLowerComponentsValid) - + date.year = 0 XCTAssertEqual(date.year, 1988) XCTAssert(isLowerComponentsValid) } - + func testMonth() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.month, 1) - + var isLowerComponentsValid: Bool { guard date.day == 2 else { return false } guard date.hour == 3 else { return false } @@ -140,31 +143,31 @@ final class DateExtensionsTests: XCTestCase { guard date.nanosecond == 123450040 else { return false } return true } - + date.month = 2 XCTAssert(isLowerComponentsValid) date.month = 14 XCTAssertEqual(date.month, 2) XCTAssert(isLowerComponentsValid) - + date.month = 1 XCTAssertEqual(date.month, 1) XCTAssert(isLowerComponentsValid) - + date.month = 0 XCTAssertEqual(date.month, 1) XCTAssert(isLowerComponentsValid) - + date.month = -3 XCTAssertEqual(date.month, 1) XCTAssert(isLowerComponentsValid) } - + func testDay() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.day, 2) - + var isLowerComponentsValid: Bool { guard date.hour == 3 else { return false } guard date.minute == 46 else { return false } @@ -172,7 +175,7 @@ final class DateExtensionsTests: XCTestCase { guard date.nanosecond == 123450040 else { return false } return true } - + date.day = 4 XCTAssertEqual(date.day, 4) XCTAssert(isLowerComponentsValid) @@ -193,27 +196,27 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.day, 1) XCTAssert(isLowerComponentsValid) } - + func testWeekday() { let date = Date(timeIntervalSince1970: 100000) XCTAssertEqual(date.weekday, 6) } - + func testHour() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.hour, 3) - + var isLowerComponentsValid: Bool { guard date.minute == 46 else { return false } guard date.second == 40 else { return false } guard date.nanosecond == 123450040 else { return false } return true } - + date.hour = -3 XCTAssertEqual(date.hour, 3) XCTAssert(isLowerComponentsValid) - + date.hour = 25 XCTAssertEqual(date.hour, 3) XCTAssert(isLowerComponentsValid) @@ -226,17 +229,17 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.hour, 1) XCTAssert(isLowerComponentsValid) } - + func testMinute() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.minute, 46) - + var isLowerComponentsValid: Bool { guard date.second == 40 else { return false } guard date.nanosecond == 123450040 else { return false } return true } - + date.minute = -3 XCTAssertEqual(date.minute, 46) XCTAssert(isLowerComponentsValid) @@ -253,16 +256,16 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.minute, 1) XCTAssert(isLowerComponentsValid) } - + func testSecond() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.second, 40) - + var isLowerComponentsValid: Bool { guard date.nanosecond == 123450040 else { return false } return true } - + date.second = -3 XCTAssertEqual(date.second, 40) XCTAssert(isLowerComponentsValid) @@ -279,51 +282,51 @@ final class DateExtensionsTests: XCTestCase { XCTAssertEqual(date.second, 1) XCTAssert(isLowerComponentsValid) } - + func testNanosecond() { var date = Date(timeIntervalSince1970: 100000.123450040) XCTAssertEqual(date.nanosecond, 123450040) - + date.nanosecond = -3 XCTAssertEqual(date.nanosecond, 123450040) - + date.nanosecond = 10000 XCTAssert(date.nanosecond >= 1000) XCTAssert(date.nanosecond <= 100000) } - + func testMillisecond() { var date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.millisecond, 0) - + date.millisecond = -3 XCTAssertEqual(date.millisecond, 0) - + date.millisecond = 10 XCTAssert(date.millisecond >= 9) XCTAssert(date.millisecond <= 11) - + date.millisecond = 3 XCTAssert(date.millisecond >= 2) XCTAssert(date.millisecond <= 4) } - + func testIsInFuture() { let oldDate = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z let futureDate = Date(timeIntervalSinceNow: 512) - + XCTAssert(futureDate.isInFuture) XCTAssertFalse(oldDate.isInFuture) } - + func testIsInPast() { let oldDate = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z let futureDate = Date(timeIntervalSinceNow: 512) - + XCTAssert(oldDate.isInPast) XCTAssertFalse(futureDate.isInPast) } - + func testIsInToday() { XCTAssert(Date().isInToday) let tomorrow = Date().adding(.day, value: 1) @@ -331,7 +334,7 @@ final class DateExtensionsTests: XCTestCase { let yesterday = Date().adding(.day, value: -1) XCTAssertFalse(yesterday.isInToday) } - + func testIsInYesterday() { XCTAssertFalse(Date().isInYesterday) let tomorrow = Date().adding(.day, value: 1) @@ -339,7 +342,7 @@ final class DateExtensionsTests: XCTestCase { let yesterday = Date().adding(.day, value: -1) XCTAssert(yesterday.isInYesterday) } - + func testIsInTomorrow() { XCTAssertFalse(Date().isInTomorrow) let tomorrow = Date().adding(.day, value: 1) @@ -347,229 +350,231 @@ final class DateExtensionsTests: XCTestCase { let yesterday = Date().adding(.day, value: -1) XCTAssertFalse(yesterday.isInTomorrow) } - + func testIsInWeekend() { let date = Date() XCTAssertEqual(date.isInWeekend, Calendar.current.isDateInWeekend(date)) } - + func testIsWorkday() { let date = Date() XCTAssertEqual(date.isWorkday, !Calendar.current.isDateInWeekend(date)) } - + func testIsInCurrentWeek() { let date = Date() XCTAssert(date.isInCurrentWeek) let dateOneYearFromNow = date.adding(.year, value: 1) XCTAssertFalse(dateOneYearFromNow.isInCurrentWeek) } - + func testIsInCurrentMonth() { let date = Date() XCTAssert(date.isInCurrentMonth) let dateOneYearFromNow = date.adding(.year, value: 1) XCTAssertFalse(dateOneYearFromNow.isInCurrentMonth) } - + func testIsInCurrentYear() { let date = Date() XCTAssert(date.isInCurrentYear) let dateOneYearFromNow = date.adding(.year, value: 1) XCTAssertFalse(dateOneYearFromNow.isInCurrentYear) } - + func testIso8601String() { let date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z XCTAssertEqual(date.iso8601String, "1970-01-01T00:08:32.000Z") } - + func testNearestFiveMinutes() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.nearestFiveMinutes, date) - + let date2 = date.adding(.minute, value: 4) // adding 4 minutes XCTAssertNotEqual(date2.nearestFiveMinutes, date2) XCTAssertEqual(date2.nearestFiveMinutes, date2.adding(.minute, value: 1)) - + let date3 = date.adding(.minute, value: 7) // adding 7 minutes XCTAssertEqual(date3.nearestFiveMinutes, date3.adding(.minute, value: -2)) - + let date4 = date.adding(.hour, value: 1).adding(.minute, value: 2) // adding 1 hour and 2 minutes XCTAssertEqual(date4.nearestFiveMinutes, date.adding(.hour, value: 1)) } - + func testNearestTenMinutes() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.nearestTenMinutes, date) - + let date2 = date.adding(.minute, value: 4) // adding 4 minutes XCTAssertEqual(date2.nearestTenMinutes, date) - + let date3 = date.adding(.minute, value: 7) // adding 7 minutes XCTAssertEqual(date3.nearestTenMinutes, date.adding(.minute, value: 10)) - + let date4 = date.adding(.hour, value: 1).adding(.minute, value: 2) // adding 1 hour and 2 minutes XCTAssertEqual(date4.nearestTenMinutes, date.adding(.hour, value: 1)) } - + func testNearestQuarterHour() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.nearestQuarterHour, date) - + let date2 = date.adding(.minute, value: 4) // adding 4 minutes XCTAssertEqual(date2.nearestQuarterHour, date) - + let date3 = date.adding(.minute, value: 12) // adding 12 minutes XCTAssertEqual(date3.nearestQuarterHour, date.adding(.minute, value: 15)) - + let date4 = date.adding(.hour, value: 1).adding(.minute, value: 2) // adding 1 hour and 2 minutes XCTAssertEqual(date4.nearestQuarterHour, date.adding(.hour, value: 1)) } - + func testNearestHalfHour() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.nearestHalfHour, date) - + let date2 = date.adding(.minute, value: 4) // adding 4 minutes XCTAssertEqual(date2.nearestHalfHour, date) - + let date3 = date.adding(.minute, value: 19) // adding 19 minutes XCTAssertEqual(date3.nearestHalfHour, date.adding(.minute, value: 30)) - + let date4 = date.adding(.hour, value: 1).adding(.minute, value: 2) // adding 1 hour and 2 minutes XCTAssertEqual(date4.nearestHalfHour, date.adding(.hour, value: 1)) } - + func testNearestHour() { let date = Date(timeIntervalSince1970: 0) XCTAssertEqual(date.nearestHour, date) - + let date2 = date.adding(.minute, value: 4) // adding 4 minutes XCTAssertEqual(date2.nearestHour, date) - + let date3 = date.adding(.minute, value: 34) // adding 34 minutes XCTAssertEqual(date3.nearestHour, date.adding(.hour, value: 1)) } - + func testTimezone() { XCTAssertEqual(Date().timeZone, Calendar.current.timeZone) } - + func testUnixTimestamp() { let date = Date() XCTAssertEqual(date.unixTimestamp, date.timeIntervalSince1970) - + let date2 = Date(timeIntervalSince1970: 100) XCTAssertEqual(date2.unixTimestamp, 100) } - + func testAdding() { let date = Date(timeIntervalSince1970: 3610) // Jan 1, 1970, 3:00:10 AM - + XCTAssertEqual(date.adding(.second, value: 0), date) let date1 = date.adding(.second, value: 10) XCTAssertEqual(date1.second, date.second + 10) XCTAssertEqual(date1.adding(.second, value: -10), date) - + XCTAssertEqual(date.adding(.minute, value: 0), date) let date2 = date.adding(.minute, value: 10) XCTAssertEqual(date2.minute, date.minute + 10) XCTAssertEqual(date2.adding(.minute, value: -10), date) - + XCTAssertEqual(date.adding(.hour, value: 0), date) let date3 = date.adding(.hour, value: 2) XCTAssertEqual(date3.hour, date.hour + 2) XCTAssertEqual(date3.adding(.hour, value: -2), date) - + XCTAssertEqual(date.adding(.day, value: 0), date) let date4 = date.adding(.day, value: 2) XCTAssertEqual(date4.day, date.day + 2) XCTAssertEqual(date4.adding(.day, value: -2), date) - + XCTAssertEqual(date.adding(.weekOfYear, value: 0), date) let date5 = date.adding(.weekOfYear, value: 1) XCTAssertEqual(date5.day, date.day + 7) XCTAssertEqual(date5.adding(.weekOfYear, value: -1), date) - + XCTAssertEqual(date.adding(.weekOfMonth, value: 0), date) let date6 = date.adding(.weekOfMonth, value: 1) XCTAssertEqual(date6.day, date.day + 7) XCTAssertEqual(date6.adding(.weekOfMonth, value: -1), date) - + XCTAssertEqual(date.adding(.month, value: 0), date) let date7 = date.adding(.month, value: 2) XCTAssertEqual(date7.month, date.month + 2) XCTAssertEqual(date7.adding(.month, value: -2), date) - + XCTAssertEqual(date.adding(.year, value: 0), date) let date8 = date.adding(.year, value: 4) XCTAssertEqual(date8.year, date.year + 4) XCTAssertEqual(date8.adding(.year, value: -4), date) } - + + // swiftlint:disable function_body_length func testAdd() { var date = Date(timeIntervalSince1970: 0) - + date.second = 10 date.add(.second, value: -1) XCTAssertEqual(date.second, 9) date.add(.second, value: 0) XCTAssertEqual(date.second, 9) - + date.add(.second, value: 1) XCTAssertEqual(date.second, 10) - + date.minute = 10 date.add(.minute, value: -1) XCTAssertEqual(date.minute, 9) date.add(.minute, value: 0) XCTAssertEqual(date.minute, 9) - + date.add(.minute, value: 1) XCTAssertEqual(date.minute, 10) - + date.hour = 10 date.add(.hour, value: -1) XCTAssertEqual(date.hour, 9) date.add(.hour, value: 0) XCTAssertEqual(date.hour, 9) - + date.add(.hour, value: 1) XCTAssertEqual(date.hour, 10) - + date.day = 10 date.add(.day, value: -1) XCTAssertEqual(date.day, 9) date.add(.day, value: 0) XCTAssertEqual(date.day, 9) - + date.add(.day, value: 1) XCTAssertEqual(date.day, 10) - + date.month = 10 date.add(.month, value: -1) XCTAssertEqual(date.month, 9) date.add(.month, value: 0) XCTAssertEqual(date.month, 9) - + date.add(.month, value: 1) XCTAssertEqual(date.month, 10) - - date = Date(timeIntervalSince1970: 1514764800) + + date = Date(timeIntervalSince1970: 1514764800) date.add(.year, value: -1) XCTAssertEqual(date.year, 2017) date.add(.year, value: 0) XCTAssertEqual(date.year, 2017) - + date.add(.year, value: 1) XCTAssertEqual(date.year, 2018) } - + // swiftlint:enable function_body_length + func testChanging() { let date = Date(timeIntervalSince1970: 0) - + XCTAssertNil(date.changing(.nanosecond, value: -10)) XCTAssertNotNil(date.changing(.nanosecond, value: 123450040)) XCTAssertEqual(date.changing(.nanosecond, value: 123450040)?.nanosecond, 123450040) @@ -578,118 +583,119 @@ final class DateExtensionsTests: XCTestCase { XCTAssertNil(date.changing(.second, value: 70)) XCTAssertNotNil(date.changing(.second, value: 20)) XCTAssertEqual(date.changing(.second, value: 20)?.second, 20) - + XCTAssertNil(date.changing(.minute, value: -10)) XCTAssertNil(date.changing(.minute, value: 70)) XCTAssertNotNil(date.changing(.minute, value: 20)) XCTAssertEqual(date.changing(.minute, value: 20)?.minute, 20) - + XCTAssertNil(date.changing(.hour, value: -2)) XCTAssertNil(date.changing(.hour, value: 25)) XCTAssertNotNil(date.changing(.hour, value: 6)) XCTAssertEqual(date.changing(.hour, value: 6)?.hour, 6) - + XCTAssertNil(date.changing(.day, value: -2)) XCTAssertNil(date.changing(.day, value: 35)) XCTAssertNotNil(date.changing(.day, value: 6)) XCTAssertEqual(date.changing(.day, value: 6)?.day, 6) - + XCTAssertNil(date.changing(.month, value: -2)) XCTAssertNil(date.changing(.month, value: 13)) XCTAssertNotNil(date.changing(.month, value: 6)) XCTAssertEqual(date.changing(.month, value: 6)?.month, 6) - + XCTAssertNil(date.changing(.year, value: -2)) XCTAssertNil(date.changing(.year, value: 0)) XCTAssertNotNil(date.changing(.year, value: 2015)) XCTAssertEqual(date.changing(.year, value: 2015)?.year, 2015) - + let date1 = Date() let date2 = date1.changing(.weekOfYear, value: 10) XCTAssertEqual(date2, Calendar.current.date(bySetting: .weekOfYear, value: 10, of: date1)) } - + func testBeginning() { let date = Date() - + XCTAssertNotNil(date.beginning(of: .second)) XCTAssertEqual(date.beginning(of: .second)?.nanosecond, 0) - + XCTAssertNotNil(date.beginning(of: .minute)) XCTAssertEqual(date.beginning(of: .minute)?.second, 0) - + XCTAssertNotNil(date.beginning(of: .hour)) XCTAssertEqual(date.beginning(of: .hour)?.minute, 0) - + XCTAssertNotNil(date.beginning(of: .day)) XCTAssertEqual(date.beginning(of: .day)?.hour, 0) XCTAssertEqual(date.beginning(of: .day)?.isInToday, true) - - let beginningOfWeek = Calendar.current.date(from: Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: date)) + + let comps = Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: date) + let beginningOfWeek = Calendar.current.date(from: comps) XCTAssertNotNil(date.beginning(of: .weekOfMonth)) XCTAssertNotNil(beginningOfWeek) XCTAssertEqual(date.beginning(of: .weekOfMonth)?.day, beginningOfWeek?.day) - + let beginningOfMonth = Date(year: 2016, month: 8, day: 1, hour: 5) XCTAssertNotNil(date.beginning(of: .month)) XCTAssertNotNil(beginningOfMonth) XCTAssertEqual(date.beginning(of: .month)?.day, beginningOfMonth?.day) - + let beginningOfYear = Date(year: 2016, month: 1, day: 1, hour: 5) XCTAssertNotNil(date.beginning(of: .year)) XCTAssertNotNil(beginningOfYear) XCTAssertEqual(date.beginning(of: .year)?.day, beginningOfYear?.day) - + XCTAssertNil(date.beginning(of: .quarter)) } - + func testEnd() { let date = Date(timeIntervalSince1970: 512) // January 1, 1970 at 2:08:32 AM GMT+2 - + XCTAssertEqual(date.end(of: .second)?.second, 32) XCTAssertEqual(date.end(of: .hour)?.minute, 59) XCTAssertEqual(date.end(of: .minute)?.second, 59) - + XCTAssertEqual(date.end(of: .day)?.hour, 23) XCTAssertEqual(date.end(of: .day)?.minute, 59) XCTAssertEqual(date.end(of: .day)?.second, 59) - + var endOfWeek = date.beginning(of: .weekOfYear) endOfWeek?.add(.day, value: 7) endOfWeek?.add(.second, value: -1) XCTAssertEqual(date.end(of: .weekOfYear), endOfWeek) - + XCTAssertEqual(date.end(of: .month)?.day, 31) XCTAssertEqual(date.end(of: .month)?.hour, 23) XCTAssertEqual(date.end(of: .month)?.minute, 59) XCTAssertEqual(date.end(of: .month)?.second, 59) - + XCTAssertEqual(date.end(of: .year)?.month, 12) XCTAssertEqual(date.end(of: .year)?.day, 31) XCTAssertEqual(date.end(of: .year)?.hour, 23) XCTAssertEqual(date.end(of: .year)?.minute, 59) XCTAssertEqual(date.end(of: .year)?.second, 59) - + XCTAssertNil(date.end(of: .quarter)) } - + func testDateString() { let date = Date(timeIntervalSince1970: 512) let formatter = DateFormatter() formatter.timeStyle = .none - + formatter.dateStyle = .short XCTAssertEqual(date.dateString(ofStyle: .short), formatter.string(from: date)) - + formatter.dateStyle = .medium XCTAssertEqual(date.dateString(ofStyle: .medium), formatter.string(from: date)) - + formatter.dateStyle = .long XCTAssertEqual(date.dateString(ofStyle: .long), formatter.string(from: date)) - + formatter.dateStyle = .full XCTAssertEqual(date.dateString(ofStyle: .full), formatter.string(from: date)) - + formatter.dateStyle = .none formatter.dateFormat = "dd/MM/yyyy" @@ -704,235 +710,237 @@ final class DateExtensionsTests: XCTestCase { formatter.dateFormat = "iiiii" XCTAssertEqual(date.string(withFormat: "iiiii"), formatter.string(from: date)) } - + func testDateTimeString() { let date = Date(timeIntervalSince1970: 512) let formatter = DateFormatter() - + formatter.timeStyle = .short formatter.dateStyle = .short XCTAssertEqual(date.dateTimeString(ofStyle: .short), formatter.string(from: date)) - + formatter.timeStyle = .medium formatter.dateStyle = .medium XCTAssertEqual(date.dateTimeString(ofStyle: .medium), formatter.string(from: date)) - + formatter.timeStyle = .long formatter.dateStyle = .long XCTAssertEqual(date.dateTimeString(ofStyle: .long), formatter.string(from: date)) - + formatter.timeStyle = .full formatter.dateStyle = .full XCTAssertEqual(date.dateTimeString(ofStyle: .full), formatter.string(from: date)) } - + func testIsInCurrent() { let date = Date() let oldDate = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z - + XCTAssert(date.isInCurrent(.second)) XCTAssertFalse(oldDate.isInCurrent(.second)) - + XCTAssert(date.isInCurrent(.minute)) XCTAssertFalse(oldDate.isInCurrent(.minute)) - + XCTAssert(date.isInCurrent(.hour)) XCTAssertFalse(oldDate.isInCurrent(.hour)) - + XCTAssert(date.isInCurrent(.day)) XCTAssertFalse(oldDate.isInCurrent(.day)) - + XCTAssert(date.isInCurrent(.weekOfMonth)) XCTAssertFalse(oldDate.isInCurrent(.weekOfMonth)) - + XCTAssert(date.isInCurrent(.month)) XCTAssertFalse(oldDate.isInCurrent(.month)) - + XCTAssert(date.isInCurrent(.year)) XCTAssertFalse(oldDate.isInCurrent(.year)) - + XCTAssert(date.isInCurrent(.era)) } - + func testTimeString() { let date = Date(timeIntervalSince1970: 512) let formatter = DateFormatter() formatter.dateStyle = .none - + formatter.timeStyle = .short XCTAssertEqual(date.timeString(ofStyle: .short), formatter.string(from: date)) - + formatter.timeStyle = .medium XCTAssertEqual(date.timeString(ofStyle: .medium), formatter.string(from: date)) - + formatter.timeStyle = .long XCTAssertEqual(date.timeString(ofStyle: .long), formatter.string(from: date)) - + formatter.timeStyle = .full XCTAssertEqual(date.timeString(ofStyle: .full), formatter.string(from: date)) } - + func testDayName() { let date = Date(timeIntervalSince1970: 1486121165) XCTAssertEqual(date.dayName(ofStyle: .full), "Friday") XCTAssertEqual(date.dayName(ofStyle: .threeLetters), "Fri") XCTAssertEqual(date.dayName(ofStyle: .oneLetter), "F") } - + func testMonthName() { let date = Date(timeIntervalSince1970: 1486121165) XCTAssertEqual(date.monthName(ofStyle: .full), "February") XCTAssertEqual(date.monthName(ofStyle: .threeLetters), "Feb") XCTAssertEqual(date.monthName(ofStyle: .oneLetter), "F") } - + func testSecondsSince() { let date1 = Date(timeIntervalSince1970: 100) let date2 = Date(timeIntervalSince1970: 180) XCTAssertEqual(date2.secondsSince(date1), 80) XCTAssertEqual(date1.secondsSince(date2), -80) } - + func testMinutesSince() { let date1 = Date(timeIntervalSince1970: 120) let date2 = Date(timeIntervalSince1970: 180) XCTAssertEqual(date2.minutesSince(date1), 1) XCTAssertEqual(date1.minutesSince(date2), -1) } - + func testHoursSince() { let date1 = Date(timeIntervalSince1970: 3600) let date2 = Date(timeIntervalSince1970: 7200) XCTAssertEqual(date2.hoursSince(date1), 1) XCTAssertEqual(date1.hoursSince(date2), -1) } - + func testDaysSince() { let date1 = Date(timeIntervalSince1970: 0) let date2 = Date(timeIntervalSince1970: 86400) XCTAssertEqual(date2.daysSince(date1), 1) XCTAssertEqual(date1.daysSince(date2), -1) } - + func testIsBetween() { let date1 = Date(timeIntervalSince1970: 0) let date2 = date1.addingTimeInterval(60) let date3 = date2.addingTimeInterval(60) - + XCTAssert(date2.isBetween(date1, date3)) XCTAssertFalse(date1.isBetween(date2, date3)) XCTAssert(date1.isBetween(date1, date2, includeBounds: true)) XCTAssertFalse(date1.isBetween(date1, date2)) } - + func testIsWithin() { let date1 = Date(timeIntervalSince1970: 60 * 60 * 24) // 1970-01-01T00:00:00.000Z let date2 = date1.addingTimeInterval(60 * 60) // 1970-01-01T00:01:00.000Z, one hour later than date1 - + // The regular XCTAssertFalse(date1.isWithin(1, .second, of: date2)) XCTAssertFalse(date1.isWithin(1, .minute, of: date2)) XCTAssert(date1.isWithin(1, .hour, of: date2)) XCTAssert(date1.isWithin(1, .day, of: date2)) - + // The other way around XCTAssertFalse(date2.isWithin(1, .second, of: date1)) XCTAssertFalse(date2.isWithin(1, .minute, of: date1)) XCTAssert(date2.isWithin(1, .hour, of: date1)) XCTAssert(date2.isWithin(1, .day, of: date1)) - + // With itself XCTAssert(date1.isWithin(1, .second, of: date1)) XCTAssert(date1.isWithin(1, .minute, of: date1)) XCTAssert(date1.isWithin(1, .hour, of: date1)) XCTAssert(date1.isWithin(1, .day, of: date1)) - + // Invalid XCTAssertFalse(Date().isWithin(1, .calendar, of: Date())) } - + func testNewDateFromComponenets() { let date = Date(calendar: Date().calendar, timeZone: Date().timeZone, era: Date().era, year: Date().year, month: Date().month, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNotNil(date) let date1 = Date(timeIntervalSince1970: date!.timeIntervalSince1970) - + XCTAssertEqual(date?.timeIntervalSince1970, date1.timeIntervalSince1970) - + let date2 = Date(calendar: nil, timeZone: Date().timeZone, era: Date().era, year: nil, month: nil, day: Date().day, hour: Date().hour, minute: Date().minute, second: Date().second, nanosecond: Date().nanosecond) XCTAssertNil(date2) } - + func testNewDateFromIso8601String() { let date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z let dateFromIso8601 = Date(iso8601String: "1970-01-01T00:08:32.000Z") XCTAssertEqual(date, dateFromIso8601) XCTAssertNil(Date(iso8601String: "hello")) } - + func testNewDateFromUnixTimestamp() { let date = Date(timeIntervalSince1970: 512) // 1970-01-01T00:08:32.000Z let dateFromUnixTimestamp = Date(unixTimestamp: 512) XCTAssertEqual(date, dateFromUnixTimestamp) } - - func testNewDateFromIntegerLiteral() { - let date = Date(integerLiteral: 2017_12_25) - - XCTAssertNotNil(date) - - if let date = date { - XCTAssertEqual(String(describing: date), "2017-12-25 00:00:00 +0000") - } - - XCTAssertNil(Date(integerLiteral: 222)) - } - - func testRandom() { - var randomDate = Date.random() - XCTAssertTrue(randomDate.isBetween(Date.distantPast, Date.distantFuture, includeBounds: true)) - - var date = Date(timeIntervalSinceReferenceDate: 0) - randomDate = Date.random(from: date) - XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) - - date = Date(timeIntervalSince1970: 10000) - randomDate = Date.random(from: date) - XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) - - date = Date(timeIntervalSince1970: -10000) - randomDate = Date.random(from: date) - XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) - - date = Date(timeIntervalSinceReferenceDate: 0) - randomDate = Date.random(upTo: date) - XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) - - date = Date(timeIntervalSince1970: 10000) - randomDate = Date.random(upTo: date) - XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) - - date = Date(timeIntervalSince1970: -10000) - randomDate = Date.random(upTo: date) - XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) - - var sinceDate = Date(timeIntervalSinceReferenceDate: 0) - var toDate = Date(timeIntervalSinceReferenceDate: 10000) - randomDate = Date.random(from: sinceDate, upTo: toDate) - XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) - - sinceDate = Date(timeIntervalSince1970: -10000) - toDate = Date(timeIntervalSince1970: -10) - randomDate = Date.random(from: sinceDate, upTo: toDate) - XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) - - sinceDate = Date(timeIntervalSinceReferenceDate: -1000) - toDate = Date(timeIntervalSinceReferenceDate: 10000) - randomDate = Date.random(from: sinceDate, upTo: toDate) - XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) - - sinceDate = Date(timeIntervalSinceReferenceDate: 0) - toDate = sinceDate - randomDate = Date.random(from: sinceDate, upTo: toDate) - XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) - } + + func testNewDateFromIntegerLiteral() { + let date = Date(integerLiteral: 2017_12_25) + + XCTAssertNotNil(date) + + if let date = date { + XCTAssertEqual(String(describing: date), "2017-12-25 00:00:00 +0000") + } + + XCTAssertNil(Date(integerLiteral: 222)) + } + + func testRandom() { + var randomDate = Date.random() + XCTAssertTrue(randomDate.isBetween(Date.distantPast, Date.distantFuture, includeBounds: true)) + + var date = Date(timeIntervalSinceReferenceDate: 0) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSince1970: 10000) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSince1970: -10000) + randomDate = Date.random(from: date) + XCTAssertTrue(randomDate.isBetween(date, Date.distantFuture, includeBounds: true)) + + date = Date(timeIntervalSinceReferenceDate: 0) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + date = Date(timeIntervalSince1970: 10000) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + date = Date(timeIntervalSince1970: -10000) + randomDate = Date.random(upTo: date) + XCTAssertTrue(randomDate.isBetween(Date.distantPast, date, includeBounds: true)) + + var sinceDate = Date(timeIntervalSinceReferenceDate: 0) + var toDate = Date(timeIntervalSinceReferenceDate: 10000) + randomDate = Date.random(from: sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSince1970: -10000) + toDate = Date(timeIntervalSince1970: -10) + randomDate = Date.random(from: sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSinceReferenceDate: -1000) + toDate = Date(timeIntervalSinceReferenceDate: 10000) + randomDate = Date.random(from: sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + + sinceDate = Date(timeIntervalSinceReferenceDate: 0) + toDate = sinceDate + randomDate = Date.random(from: sinceDate, upTo: toDate) + XCTAssertTrue(randomDate.isBetween(sinceDate, toDate, includeBounds: true)) + } + } +// swiftlint:enable type_body_length diff --git a/Tests/FoundationTests/FileManagerExtensionsTests.swift b/Tests/FoundationTests/FileManagerExtensionsTests.swift index 692fae80d..3bf2a630e 100644 --- a/Tests/FoundationTests/FileManagerExtensionsTests.swift +++ b/Tests/FoundationTests/FileManagerExtensionsTests.swift @@ -10,66 +10,66 @@ import XCTest @testable import SwifterSwift final class FileManagerExtensionsTests: XCTestCase { - - func testJSONFromFileAtPath() { - do { - let bundle = Bundle(for: FileManagerExtensionsTests.self) - let filePath = bundle.path(forResource: "test", ofType: "json") - - guard let path = filePath else { - XCTFail("File path undefined.") - - return - } - - let json = try FileManager.default.jsonFromFile(atPath: path) - - XCTAssertNotNil(json) - - // Check contents - if let dict = json { - if let string = dict["title"] as? String, let id = dict["id"] as? Int { - XCTAssert(string == "Test") - XCTAssert(id == 1) - } else { - XCTFail("Does not contain the correct content.") - } - } else { - XCTFail("Opening of file returned nil.") - } - } catch { - XCTFail("Error encountered during opening of file.") - } - } - - func testJSONFromFileWithFilename() { - do { - var filename = "test.json" // With extension - var json = try FileManager.default.jsonFromFile(withFilename: filename, - at: FileManagerExtensionsTests.self) - - XCTAssertNotNil(json) - - filename = "test" // Without extension - json = try FileManager.default.jsonFromFile(withFilename: filename, - at: FileManagerExtensionsTests.self) - - XCTAssertNotNil(json) - - // Check contents - if let dict = json { - if let string = dict["title"] as? String, let id = dict["id"] as? Int { - XCTAssert(string == "Test") - XCTAssert(id == 1) - } else { - XCTFail("Does not contain the correct content.") - } - } else { - XCTFail("Opening of file returned nil.") - } - } catch { - XCTFail("Error encountered during opening of file.") - } - } - + + func testJSONFromFileAtPath() { + do { + let bundle = Bundle(for: FileManagerExtensionsTests.self) + let filePath = bundle.path(forResource: "test", ofType: "json") + + guard let path = filePath else { + XCTFail("File path undefined.") + + return + } + + let json = try FileManager.default.jsonFromFile(atPath: path) + + XCTAssertNotNil(json) + + // Check contents + if let dict = json { + if let string = dict["title"] as? String, let itemId = dict["id"] as? Int { + XCTAssert(string == "Test") + XCTAssert(itemId == 1) + } else { + XCTFail("Does not contain the correct content.") + } + } else { + XCTFail("Opening of file returned nil.") + } + } catch { + XCTFail("Error encountered during opening of file.") + } + } + + func testJSONFromFileWithFilename() { + do { + var filename = "test.json" // With extension + var json = try FileManager.default.jsonFromFile(withFilename: filename, + at: FileManagerExtensionsTests.self) + + XCTAssertNotNil(json) + + filename = "test" // Without extension + json = try FileManager.default.jsonFromFile(withFilename: filename, + at: FileManagerExtensionsTests.self) + + XCTAssertNotNil(json) + + // Check contents + if let dict = json { + if let string = dict["title"] as? String, let itemId = dict["id"] as? Int { + XCTAssert(string == "Test") + XCTAssert(itemId == 1) + } else { + XCTFail("Does not contain the correct content.") + } + } else { + XCTFail("Opening of file returned nil.") + } + } catch { + XCTFail("Error encountered during opening of file.") + } + } + } diff --git a/Tests/FoundationTests/LocaleExtensionsTests.swift b/Tests/FoundationTests/LocaleExtensionsTests.swift index 6b0787984..0cad9d6f6 100644 --- a/Tests/FoundationTests/LocaleExtensionsTests.swift +++ b/Tests/FoundationTests/LocaleExtensionsTests.swift @@ -10,9 +10,9 @@ import XCTest @testable import SwifterSwift final class LocaleExtensionsTests: XCTestCase { - - func testPosix() { - let test: Locale = .posix - XCTAssertEqual(test.identifier, "en_US_POSIX") - } + + func testPosix() { + let test: Locale = .posix + XCTAssertEqual(test.identifier, "en_US_POSIX") + } } diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index 50878cdba..c1af81553 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift final class NSAttributedStringExtensionsTests: XCTestCase { - + #if !os(macOS) && !os(tvOS) func testBolded() { let string = NSAttributedString(string: "Bolded") @@ -32,13 +32,14 @@ final class NSAttributedStringExtensionsTests: XCTestCase { let out = string.underlined let attributes = out.attributes(at: 0, effectiveRange: nil) let filteredAttributes = attributes.filter { (key, value) -> Bool in - return (key == NSAttributedStringKey.underlineStyle && (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) + return (key == NSAttributedStringKey.underlineStyle && + (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue) } XCTAssertEqual(filteredAttributes.count, 1) } #endif - + #if !os(macOS) && !os(tvOS) func testItalicized() { let string = NSAttributedString(string: "Italicized") @@ -82,92 +83,92 @@ final class NSAttributedStringExtensionsTests: XCTestCase { XCTAssertEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, UIColor.blue) XCTAssertNotEqual(attributes[NSAttributedStringKey.foregroundColor] as? UIColor, .red) } - + #endif - - #if !os(macOS) && !os(tvOS) - func testApplyingToRegex() { - let email = "steve.jobs@apple.com" - let testString = NSAttributedString(string: "Your email is \(email)!").bolded - let attributes: [NSAttributedStringKey: Any] = [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, .foregroundColor: UIColor.blue] - let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" - - let attrTestString = testString.applying(attributes: attributes, toRangesMatching: pattern) - - let attrAtBeginning = attrTestString.attributes(at: 0, effectiveRange: nil) - XCTAssert(attrAtBeginning.count == 1) - - var passed = false - // iterate through each range of attributes - attrTestString.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } - - // confirm that the string with the applied attributes is the email - XCTAssertEqual(emailFromRange, email) - - // the range contains the email, check to make sure the attributes are there and correct - for attr in attrs { - if attr.key == .underlineStyle { - XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) - passed = true - } else if attr.key == .foregroundColor { - XCTAssertEqual(attr.value as? UIColor, UIColor.blue) - passed = true - } else if attr.key == .font { - XCTAssertEqual((attr.value as? UIFont), .boldSystemFont(ofSize: UIFont.systemFontSize)) - } else { - passed = false - } - } - - XCTAssert(passed) - } - } - - func testApplyingToOccurrences() { - let name = "Steve Wozniak" - let greeting = "Hello, \(name)." - let attrGreeting = NSAttributedString(string: greeting).italicized.applying( - attributes: [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, - .foregroundColor: UIColor.red], toOccurrencesOf: name) - - let attrAtBeginning = attrGreeting.attributes(at: 0, effectiveRange: nil) - // assert that there is only one attribute at beginning from italics - XCTAssertEqual(attrAtBeginning.count, 1) - - var passed = false - // iterate through each range of attributes - attrGreeting.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } - - // confirm that the attributed string is the name - let stringAtRange = attrGreeting.attributedSubstring(from: range).string - XCTAssertEqual(stringAtRange, name) - - for attr in attrs { - if attr.key == .underlineStyle { - XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) - passed = true - } else if attr.key == .foregroundColor { - XCTAssertEqual(attr.value as? UIColor, UIColor.red) - passed = true - } else if attr.key == .font { - XCTAssertEqual((attr.value as? UIFont), .italicSystemFont(ofSize: UIFont.systemFontSize)) - } else { - passed = false - } - } - } - - XCTAssert(passed) - } - #endif - + + #if !os(macOS) && !os(tvOS) + func testApplyingToRegex() { + let email = "steve.jobs@apple.com" + let testString = NSAttributedString(string: "Your email is \(email)!").bolded + let attributes: [NSAttributedStringKey: Any] = [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, .foregroundColor: UIColor.blue] + let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" + + let attrTestString = testString.applying(attributes: attributes, toRangesMatching: pattern) + + let attrAtBeginning = attrTestString.attributes(at: 0, effectiveRange: nil) + XCTAssert(attrAtBeginning.count == 1) + + var passed = false + // iterate through each range of attributes + attrTestString.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } + + // confirm that the string with the applied attributes is the email + XCTAssertEqual(emailFromRange, email) + + // the range contains the email, check to make sure the attributes are there and correct + for attr in attrs { + if attr.key == .underlineStyle { + XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) + passed = true + } else if attr.key == .foregroundColor { + XCTAssertEqual(attr.value as? UIColor, UIColor.blue) + passed = true + } else if attr.key == .font { + XCTAssertEqual((attr.value as? UIFont), .boldSystemFont(ofSize: UIFont.systemFontSize)) + } else { + passed = false + } + } + + XCTAssert(passed) + } + } + + func testApplyingToOccurrences() { + let name = "Steve Wozniak" + let greeting = "Hello, \(name)." + let attrGreeting = NSAttributedString(string: greeting).italicized.applying( + attributes: [.underlineStyle: NSUnderlineStyle.styleSingle.rawValue, + .foregroundColor: UIColor.red], toOccurrencesOf: name) + + let attrAtBeginning = attrGreeting.attributes(at: 0, effectiveRange: nil) + // assert that there is only one attribute at beginning from italics + XCTAssertEqual(attrAtBeginning.count, 1) + + var passed = false + // iterate through each range of attributes + attrGreeting.enumerateAttributes(in: NSRange(0.. attrAtBeginning.count else { return } + + // confirm that the attributed string is the name + let stringAtRange = attrGreeting.attributedSubstring(from: range).string + XCTAssertEqual(stringAtRange, name) + + for attr in attrs { + if attr.key == .underlineStyle { + XCTAssertEqual(attr.value as? NSUnderlineStyle.RawValue, NSUnderlineStyle.styleSingle.rawValue) + passed = true + } else if attr.key == .foregroundColor { + XCTAssertEqual(attr.value as? UIColor, UIColor.red) + passed = true + } else if attr.key == .font { + XCTAssertEqual((attr.value as? UIFont), .italicSystemFont(ofSize: UIFont.systemFontSize)) + } else { + passed = false + } + } + } + + XCTAssert(passed) + } + #endif + #if !os(macOS) && !os(tvOS) // MARK: - Operators func testAppending() { @@ -202,31 +203,31 @@ final class NSAttributedStringExtensionsTests: XCTestCase { XCTAssertEqual(filteredAttributes.count, 1) } #endif - - #if !os(macOS) && !os(tvOS) - func testAttributes() { - let attrString = NSAttributedString(string: "Test String").bolded.struckthrough.underlined.colored(with: UIColor.blue) - let attributes = attrString.attributes - - XCTAssertEqual(attributes.count, 4) - - let filteredAttributes = attributes.filter { (key, value) -> Bool in - switch key { - case NSAttributedStringKey.underlineStyle: - return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue - case NSAttributedStringKey.strikethroughStyle: - return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue - case NSAttributedStringKey.font: - return (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize) - case NSAttributedStringKey.foregroundColor: - return (value as? UIColor) == .blue - default: - return false - } - } - - XCTAssertEqual(filteredAttributes.count, 4) - - } - #endif + + #if !os(macOS) && !os(tvOS) + func testAttributes() { + let attrString = NSAttributedString(string: "Test String").bolded.struckthrough.underlined.colored(with: UIColor.blue) + let attributes = attrString.attributes + + XCTAssertEqual(attributes.count, 4) + + let filteredAttributes = attributes.filter { (key, value) -> Bool in + switch key { + case NSAttributedStringKey.underlineStyle: + return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue + case NSAttributedStringKey.strikethroughStyle: + return (value as? NSUnderlineStyle.RawValue) == NSUnderlineStyle.styleSingle.rawValue + case NSAttributedStringKey.font: + return (value as? UIFont) == .boldSystemFont(ofSize: UIFont.systemFontSize) + case NSAttributedStringKey.foregroundColor: + return (value as? UIColor) == .blue + default: + return false + } + } + + XCTAssertEqual(filteredAttributes.count, 4) + + } + #endif } diff --git a/Tests/FoundationTests/NSPredicateExtensionsTests.swift b/Tests/FoundationTests/NSPredicateExtensionsTests.swift index 16ea01864..29706b5b5 100644 --- a/Tests/FoundationTests/NSPredicateExtensionsTests.swift +++ b/Tests/FoundationTests/NSPredicateExtensionsTests.swift @@ -10,70 +10,70 @@ import XCTest @testable import SwifterSwift final class NSPredicateExtensionsTests: XCTestCase { - - func testNot() { - let predicate = NSPredicate(format: "a < 7") - let notPredicate = predicate.not - XCTAssert(notPredicate.compoundPredicateType == .not) - if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate]) - } - } - - func testAndPredicate() { - let predicate1 = NSPredicate(format: "a < 7") - let predicate2 = NSPredicate(format: "a > 3") - let andPredicate = predicate1.and(predicate2) - XCTAssert(andPredicate.compoundPredicateType == .and) - if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate1, predicate2]) - } - } - - func testOrPredicate() { - let predicate1 = NSPredicate(format: "a < 7") - let predicate2 = NSPredicate(format: "a > 3") - let orPredicate = predicate1.or(predicate2) - XCTAssert(orPredicate.compoundPredicateType == .or) - if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate1, predicate2]) - } - } - - func testOperatorNot() { - let predicate = NSPredicate(format: "a < 7") - let notPredicate = !predicate - XCTAssert(notPredicate.compoundPredicateType == .not) - if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate]) - } - } - - func testOperatorAndPredicate() { - let predicate1 = NSPredicate(format: "a < 7") - let predicate2 = NSPredicate(format: "a > 3") - let andPredicate = predicate1 + predicate2 - XCTAssert(andPredicate.compoundPredicateType == .and) - if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate1, predicate2]) - } - } - - func testOperatorOrPredicate() { - let predicate1 = NSPredicate(format: "a < 7") - let predicate2 = NSPredicate(format: "a > 3") - let orPredicate = predicate1 | predicate2 - XCTAssert(orPredicate.compoundPredicateType == .or) - if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { - XCTAssertEqual(subpredicates, [predicate1, predicate2]) - } - } - - func testOperatorSubPredicate() { - let predicate1 = NSPredicate(format: "SELF BETWEEN{1,5}") - let predicate2 = NSPredicate(format: "SELF BETWEEN{3,6}") - let subPredicate = predicate1 - predicate2 - XCTAssert(subPredicate.evaluate(with: 2)) - XCTAssertFalse(subPredicate.evaluate(with: 4)) - } + + func testNot() { + let predicate = NSPredicate(format: "a < 7") + let notPredicate = predicate.not + XCTAssert(notPredicate.compoundPredicateType == .not) + if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate]) + } + } + + func testAndPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let andPredicate = predicate1.and(predicate2) + XCTAssert(andPredicate.compoundPredicateType == .and) + if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOrPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let orPredicate = predicate1.or(predicate2) + XCTAssert(orPredicate.compoundPredicateType == .or) + if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOperatorNot() { + let predicate = NSPredicate(format: "a < 7") + let notPredicate = !predicate + XCTAssert(notPredicate.compoundPredicateType == .not) + if let subpredicates = notPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate]) + } + } + + func testOperatorAndPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let andPredicate = predicate1 + predicate2 + XCTAssert(andPredicate.compoundPredicateType == .and) + if let subpredicates = andPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOperatorOrPredicate() { + let predicate1 = NSPredicate(format: "a < 7") + let predicate2 = NSPredicate(format: "a > 3") + let orPredicate = predicate1 | predicate2 + XCTAssert(orPredicate.compoundPredicateType == .or) + if let subpredicates = orPredicate.subpredicates as? [NSPredicate] { + XCTAssertEqual(subpredicates, [predicate1, predicate2]) + } + } + + func testOperatorSubPredicate() { + let predicate1 = NSPredicate(format: "SELF BETWEEN{1,5}") + let predicate2 = NSPredicate(format: "SELF BETWEEN{3,6}") + let subPredicate = predicate1 - predicate2 + XCTAssert(subPredicate.evaluate(with: 2)) + XCTAssertFalse(subPredicate.evaluate(with: 4)) + } } diff --git a/Tests/FoundationTests/URLExtensionsTests.swift b/Tests/FoundationTests/URLExtensionsTests.swift index 9d61a5d62..49898d825 100644 --- a/Tests/FoundationTests/URLExtensionsTests.swift +++ b/Tests/FoundationTests/URLExtensionsTests.swift @@ -10,40 +10,41 @@ import XCTest @testable import SwifterSwift final class URLExtensionsTests: XCTestCase { - + var url = URL(string: "https://www.google.com")! let params = ["q": "swifter swift"] let queryUrl = URL(string: "https://www.google.com?q=swifter%20swift")! - + func testAppendingQueryParameters() { XCTAssertEqual(url.appendingQueryParameters(params), queryUrl) } - + func testAppendQueryParameters() { url.appendQueryParameters(params) XCTAssertEqual(url, queryUrl) } - - func testQueryParameters() { - let url = URL(string: "https://www.google.com?q=swifter%20swift&steve=jobs&empty")! - guard let parameters = url.queryParameters else { - XCTAssert(false) - return - } - - XCTAssertEqual(parameters.count, 2) - XCTAssertEqual(parameters["q"], "swifter swift") - XCTAssertEqual(parameters["steve"], "jobs") - XCTAssertEqual(parameters["empty"], nil) - } - -#if os(iOS) || os(tvOS) - func testThumbnail() { - XCTAssertNil(url.thumbnail()) - - let videoUrl = Bundle(for: URLExtensionsTests.self).url(forResource: "big_buck_bunny_720p_1mb", withExtension: "mp4")! - XCTAssertNotNil(videoUrl.thumbnail()) - XCTAssertNotNil(videoUrl.thumbnail(fromTime: 1)) - } -#endif + + func testQueryParameters() { + let url = URL(string: "https://www.google.com?q=swifter%20swift&steve=jobs&empty")! + guard let parameters = url.queryParameters else { + XCTAssert(false) + return + } + + XCTAssertEqual(parameters.count, 2) + XCTAssertEqual(parameters["q"], "swifter swift") + XCTAssertEqual(parameters["steve"], "jobs") + XCTAssertEqual(parameters["empty"], nil) + } + + #if os(iOS) || os(tvOS) + func testThumbnail() { + XCTAssertNil(url.thumbnail()) + + let videoUrl = Bundle(for: URLExtensionsTests.self).url(forResource: "big_buck_bunny_720p_1mb", withExtension: "mp4")! + XCTAssertNotNil(videoUrl.thumbnail()) + XCTAssertNotNil(videoUrl.thumbnail(fromTime: 1)) + } + #endif + } diff --git a/Tests/FoundationTests/URLRequestExtensionsTests.swift b/Tests/FoundationTests/URLRequestExtensionsTests.swift index bde6daefa..828e02f06 100644 --- a/Tests/FoundationTests/URLRequestExtensionsTests.swift +++ b/Tests/FoundationTests/URLRequestExtensionsTests.swift @@ -5,20 +5,21 @@ // Created by Omar Albeik on 9/6/17. // Copyright © 2016 SwifterSwift // + import XCTest @testable import SwifterSwift final class URLRequestExtensionsTests: XCTestCase { - + func testInitFromURLString() { let urlString = "https://www.w3schools.com/" let request1 = URLRequest(url: URL(string: urlString)!) let request2 = URLRequest(urlString: urlString) XCTAssertNotNil(request2) XCTAssertEqual(request1.url, request2!.url) - + let invalidURLString = "invalid url" XCTAssertNil(URLRequest(urlString: invalidURLString)) } - + } diff --git a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift index 2ec14350a..2ecf240e5 100644 --- a/Tests/FoundationTests/UserDefaultsExtensionsTests.swift +++ b/Tests/FoundationTests/UserDefaultsExtensionsTests.swift @@ -9,23 +9,23 @@ import XCTest @testable import SwifterSwift final class UserDefaultsExtensionsTests: XCTestCase { - - private struct TestObject: Codable { - var id: Int - } - + + private struct TestObject: Codable { + var itemId: Int + } + func testSubscript() { let key = "testKey" UserDefaults.standard.set(true, forKey: key) XCTAssertNotNil(UserDefaults.standard[key]) XCTAssert(UserDefaults.standard[key] as? Bool ?? false) - + UserDefaults.standard.removeObject(forKey: key) UserDefaults.standard[key] = false XCTAssertNotNil(UserDefaults.standard[key]) XCTAssertFalse(UserDefaults.standard[key] as? Bool ?? false) } - + func testFloat() { let key = "floatTestKey" let number: Float = 10.0 @@ -33,7 +33,7 @@ final class UserDefaultsExtensionsTests: XCTestCase { XCTAssertNotNil(UserDefaults.standard.float(forKey: key)) XCTAssertEqual(UserDefaults.standard.float(forKey: key)!, number) } - + func testDate() { let key = "dateTestKey" let date: Date = Date() @@ -41,21 +41,21 @@ final class UserDefaultsExtensionsTests: XCTestCase { XCTAssertNotNil(UserDefaults.standard.date(forKey: key)) XCTAssertEqual(UserDefaults.standard.date(forKey: key)!, date) } - - func testGetCodableObject() { - let key = "codableTestKey" - let codable: TestObject = TestObject(id: 1) - UserDefaults.standard.set(object: codable, forKey: key) - let retrievedCodable = UserDefaults.standard.object(TestObject.self, with: key) - XCTAssertNotNil(retrievedCodable) - } - - func testSetCodableObject() { - let key = "codableTestKey" - let codable: TestObject = TestObject(id: 1) - UserDefaults.standard.set(object: codable, forKey: key) - let retrievedCodable = UserDefaults.standard.object(TestObject.self, with: key) - XCTAssertNotNil(retrievedCodable) - } - + + func testGetCodableObject() { + let key = "codableTestKey" + let codable: TestObject = TestObject(itemId: 1) + UserDefaults.standard.set(object: codable, forKey: key) + let retrievedCodable = UserDefaults.standard.object(TestObject.self, with: key) + XCTAssertNotNil(retrievedCodable) + } + + func testSetCodableObject() { + let key = "codableTestKey" + let codable: TestObject = TestObject(itemId: 1) + UserDefaults.standard.set(object: codable, forKey: key) + let retrievedCodable = UserDefaults.standard.object(TestObject.self, with: key) + XCTAssertNotNil(retrievedCodable) + } + } diff --git a/Tests/MapKitTests/MKPolylineTests.swift b/Tests/MapKitTests/MKPolylineTests.swift index f2d1f33b5..60e021b77 100644 --- a/Tests/MapKitTests/MKPolylineTests.swift +++ b/Tests/MapKitTests/MKPolylineTests.swift @@ -13,6 +13,7 @@ import MapKit import struct CoreLocation.CLLocationCoordinate2D final class MKPolylineTests: XCTestCase { + let coordinates = [(37.330514, -121.888863), (37.330832, -121.888337), (37.329599, -121.886859), @@ -41,4 +42,5 @@ final class MKPolylineTests: XCTestCase { XCTAssertEqual(coordinate1.longitude, coordinate2.longitude, accuracy: 0.000000001) } } + } diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index 6bc84586d..bbfaa3104 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -9,245 +9,245 @@ import XCTest @testable import SwifterSwift #if os(macOS) - import Cocoa - public typealias Color = NSColor +import Cocoa +public typealias Color = NSColor #else - import UIKit - public typealias Color = UIColor +import UIKit +public typealias Color = UIColor #endif #if !os(watchOS) - import CoreImage +import CoreImage #endif +// swiftlint:disable type_body_length final class ColorExtensionsTests: XCTestCase { - - // MARK: - Test properties - func testCGFloatComponents() { - XCTAssertEqual(Color.red.cgFloatComponents.red, 1.0) - XCTAssertEqual(Color.red.cgFloatComponents.green, 0.0) - XCTAssertEqual(Color.red.cgFloatComponents.blue, 0.0) - - XCTAssertEqual(Color.green.cgFloatComponents.red, 0.0) - XCTAssertEqual(Color.green.cgFloatComponents.green, 1.0) - XCTAssertEqual(Color.green.cgFloatComponents.blue, 0.0) - - XCTAssertEqual(Color.blue.cgFloatComponents.red, 0.0) - XCTAssertEqual(Color.blue.cgFloatComponents.green, 0.0) - XCTAssertEqual(Color.blue.cgFloatComponents.blue, 1.0) - - XCTAssertEqual(Color.black.cgFloatComponents.red, 0.0) - XCTAssertEqual(Color.black.cgFloatComponents.green, 0.0) - XCTAssertEqual(Color.black.cgFloatComponents.blue, 0.0) - - XCTAssertEqual(Color.white.cgFloatComponents.red, 1.0) - XCTAssertEqual(Color.white.cgFloatComponents.green, 1.0) - XCTAssertEqual(Color.white.cgFloatComponents.blue, 1.0) - - XCTAssertEqual(Int(Color(hex: 0x12FFFF)!.cgFloatComponents.red * 255.0), 0x12) - } - + + // MARK: - Test properties + func testCGFloatComponents() { + XCTAssertEqual(Color.red.cgFloatComponents.red, 1.0) + XCTAssertEqual(Color.red.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.red.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.green.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.green.cgFloatComponents.green, 1.0) + XCTAssertEqual(Color.green.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.blue.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.blue.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.blue.cgFloatComponents.blue, 1.0) + + XCTAssertEqual(Color.black.cgFloatComponents.red, 0.0) + XCTAssertEqual(Color.black.cgFloatComponents.green, 0.0) + XCTAssertEqual(Color.black.cgFloatComponents.blue, 0.0) + + XCTAssertEqual(Color.white.cgFloatComponents.red, 1.0) + XCTAssertEqual(Color.white.cgFloatComponents.green, 1.0) + XCTAssertEqual(Color.white.cgFloatComponents.blue, 1.0) + + XCTAssertEqual(Int(Color(hex: 0x12FFFF)!.cgFloatComponents.red * 255.0), 0x12) + } + // MARK: - Test properties func testRgbComponents() { XCTAssertEqual(Color.red.rgbComponents.red, 255) XCTAssertEqual(Color.red.rgbComponents.green, 0) XCTAssertEqual(Color.red.rgbComponents.blue, 0) - + XCTAssertEqual(Color.green.rgbComponents.red, 0) XCTAssertEqual(Color.green.rgbComponents.green, 255) XCTAssertEqual(Color.green.rgbComponents.blue, 0) - + XCTAssertEqual(Color.blue.rgbComponents.red, 0) XCTAssertEqual(Color.blue.rgbComponents.green, 0) XCTAssertEqual(Color.blue.rgbComponents.blue, 255) - + XCTAssertEqual(Color.black.rgbComponents.red, 0) XCTAssertEqual(Color.black.rgbComponents.green, 0) XCTAssertEqual(Color.black.rgbComponents.blue, 0) - + XCTAssertEqual(Color.white.rgbComponents.red, 255) XCTAssertEqual(Color.white.rgbComponents.green, 255) XCTAssertEqual(Color.white.rgbComponents.blue, 255) - + XCTAssertEqual(Color(hex: 0x12FFFF)?.rgbComponents.red, 0x12) } - + func testAlpha() { var color: Color = Color.red XCTAssertEqual(color.alpha, 1.0) - + color = Color.white.withAlphaComponent(0.5) XCTAssertEqual(color.alpha, 0.5) - + color = Color(red: 0, green: 0, blue: 0, transparency: 0.7)! XCTAssertEqual(color.alpha, 0.7) - + color = Color(red: 0, green: 0, blue: 0, transparency: 1.1)! XCTAssertEqual(color.alpha, 1.0) } - + // MARK: - Test properties func testHsbaComponents() { var color = Color(hex: 0x00FF00, transparency: 1.0)! XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (120/360)) / 1000)) XCTAssertEqual(color.hsbaComponents.saturation, 1.0) XCTAssertEqual(color.hsbaComponents.brightness, 1.0) - + color = Color(hex: 0x0000FF, transparency: 1.0)! XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (240/360)) / 1000)) XCTAssertEqual(color.hsbaComponents.saturation, 1.0) XCTAssertEqual(color.hsbaComponents.brightness, 1.0) - + color = Color(hex: 0x000000, transparency: 1.0)! XCTAssertEqual(color.hsbaComponents.hue, 0.0) XCTAssertEqual(color.hsbaComponents.saturation, 0.0) XCTAssertEqual(color.hsbaComponents.brightness, 0.0) - + color = Color(hex: 0xFFFFFF, transparency: 1.0)! XCTAssertEqual(color.hsbaComponents.hue, 0.0) XCTAssertEqual(color.hsbaComponents.saturation, 0.0) XCTAssertEqual(color.hsbaComponents.brightness, 1.0) - + color = Color(hex: 0x123456, transparency: 1.0)! XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (210/360)) / 1000)) XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 79) XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 34) - + color = Color(hex: 0xFCA864, transparency: 1.0)! XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (27/360)) / 1000)) XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 60) XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 99) - + color = Color(hex: 0x1F2D3C, transparency: 1.0)! XCTAssertEqual(CGFloat(round(1000 * color.hsbaComponents.hue) / 1000), CGFloat(round(1000 * (211/360)) / 1000)) XCTAssertEqual((color.hsbaComponents.saturation * 100).rounded(), 48) XCTAssertEqual((color.hsbaComponents.brightness * 100).rounded(), 24) } - + func testUInt() { var color = Color(hex: 0xFF0000, transparency: 1.0) XCTAssertEqual(color?.uInt, 0xFF0000) - + color = Color(hex: 0x00FF00, transparency: 1.0) XCTAssertEqual(color?.uInt, 0x00FF00) - + color = Color(hex: 0x0000FF, transparency: 1.0) XCTAssertEqual(color?.uInt, 0x0000FF) - + color = Color(hex: 0x000000, transparency: 1.0) XCTAssertEqual(color?.uInt, 0x000000) - + color = Color(hex: 0xFFFFFF, transparency: 1.0) XCTAssertEqual(color?.uInt, 0xFFFFFF) - + color = Color(hex: 0x123456, transparency: 1.0) XCTAssertEqual(color?.uInt, 0x123456) - + color = Color(hex: 0xFCA864, transparency: 1.0) XCTAssertEqual(color?.uInt, 0xFCA864) - + color = Color(hex: 0xFCA864, transparency: 1.0) XCTAssertEqual(color?.uInt, 0xFCA864) - + color = Color(hex: 0x1F2D3C, transparency: 1.0) XCTAssertEqual(color?.uInt, 0x1F2D3C) - } - + func testHexString() { var color = Color.red XCTAssertEqual(color.hexString, "#FF0000") - + color = Color.blue XCTAssertEqual(color.hexString, "#0000FF") - + color = Color(hex: 0xABCDEF)! XCTAssertEqual(color.hexString, "#ABCDEF") - + color = Color(hex: 0xABC)! XCTAssertEqual(color.hexString, "#000ABC") - + color = Color.black XCTAssertEqual(color.hexString, "#000000") } - + func testShortHexString() { var color: Color? = Color.red XCTAssertEqual(color?.shortHexString, "#F00") - + color = Color.blue XCTAssertEqual(color?.shortHexString, "#00F") - + color = Color(hexString: "#0F120F") XCTAssertNil(color?.shortHexString) - + color = Color(hexString: "#8FFFF") XCTAssertNil(color?.shortHexString) } - + func testShortHexOrHexString() { var color: Color? = Color.red XCTAssertEqual(color?.shortHexOrHexString, "#F00") - + color = Color(hexString: "#8FFFFF") XCTAssertEqual(color?.shortHexOrHexString, "#8FFFFF") - + color = Color(hexString: "#F") XCTAssertEqual(color?.shortHexOrHexString, "#00000F") - + color = Color(hexString: "#11") XCTAssertEqual(color?.shortHexOrHexString, "#001") } - + func testComplementary() { var color = Color.black - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + color.complementary?.getRed(&red, green: &green, blue: &blue, alpha: nil) + XCTAssertEqual(red, 1) + XCTAssertEqual(green, 1) + XCTAssertEqual(blue, 1) + color = Color.white - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 0) - XCTAssertEqual(b, 0) - + color.complementary?.getRed(&red, green: &green, blue: &blue, alpha: nil) + XCTAssertEqual(red, 0) + XCTAssertEqual(green, 0) + XCTAssertEqual(blue, 0) + color = Color.red - color.complementary?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) + color.complementary?.getRed(&red, green: &green, blue: &blue, alpha: nil) + XCTAssertEqual(red, 0) + XCTAssertEqual(green, 1) + XCTAssertEqual(blue, 1) } - + func testRandom() { let color1 = Color.random let color2 = Color.random - + XCTAssertNotEqual(color1, color2) } - + // MARK: - Test methods func testBlend() { var color1 = Color.white var color2 = Color.black - + var blendColor = Color.blend(color1, with: color2) XCTAssertEqual(blendColor.rgbComponents.red, 0xFF / 2) XCTAssertEqual(blendColor.rgbComponents.green, 0xFF / 2) XCTAssertEqual(blendColor.rgbComponents.blue, 0xFF / 2) - + color1 = Color(hex: 0x123456, transparency: 0.5)! color2 = Color(hex: 0x665544, transparency: 0.7)! - + blendColor = Color.blend(color1, with: color2) XCTAssertEqual(blendColor.rgbComponents.red, (0x12 + 0x66) / 2) XCTAssertEqual(blendColor.rgbComponents.green, (0x34 + 0x55) / 2) XCTAssertEqual(blendColor.rgbComponents.blue, (0x56 + 0x44) / 2) XCTAssertEqual(blendColor.alpha, (0.7 + 0.5) / 2) - + blendColor = Color.blend(color1, intensity1: 0.7, with: color2, intensity2: 0.3) var output: Double = 0x12 * 0.7 + 0x66 * 0.3 XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) @@ -257,7 +257,7 @@ final class ColorExtensionsTests: XCTestCase { XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = 0.5 * 0.7 + 0.7 * 0.3 XCTAssertEqual(blendColor.alpha, CGFloat(output)) - + blendColor = Color.blend(color1, intensity1: 0.0, with: color2, intensity2: 0.3) output = (0x12 * 0.0 + 0x66 * 0.3) / 0.3 XCTAssertEqual(blendColor.rgbComponents.red, Int(output)) @@ -267,39 +267,39 @@ final class ColorExtensionsTests: XCTestCase { XCTAssertEqual(blendColor.rgbComponents.blue, Int(output)) output = (0.5 * 0.0 + 0.7 * 0.3 / 0.3) XCTAssertEqual(blendColor.alpha, CGFloat(output)) - + blendColor = Color.blend(color1, intensity1: 1.0, with: color2, intensity2: 0.0) XCTAssertEqual(blendColor, color1) } - - func testLighten() { - let color = Color.blue - var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0 - color.getRed(&r, green: &g, blue: &b, alpha: nil) - - let lighterColor = color.lighten(by: 0.3) - var lightR: CGFloat = 0, lightG: CGFloat = 0, lightB: CGFloat = 0 - lighterColor.getRed(&lightR, green: &lightG, blue: &lightB, alpha: nil) - - XCTAssertEqual(lightR, min(r + 0.3, 1.0)) - XCTAssertEqual(lightG, min(g + 0.3, 1.0)) - XCTAssertEqual(lightB, min(b + 0.3, 1.0)) - } - - func testDarken() { - let color = Color.blue - var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0 - color.getRed(&r, green: &g, blue: &b, alpha: nil) - - let darkerColor = color.darken(by: 0.3) - var darkR: CGFloat = 0, darkG: CGFloat = 0, darkB: CGFloat = 0 - darkerColor.getRed(&darkR, green: &darkG, blue: &darkB, alpha: nil) - - XCTAssertEqual(darkR, max(r - 0.3, 0)) - XCTAssertEqual(darkG, max(g - 0.3, 0)) - XCTAssertEqual(darkB, max(b - 0.3, 0)) - } - + + func testLighten() { + let color = Color.blue + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: nil) + + let lighterColor = color.lighten(by: 0.3) + var lightR: CGFloat = 0, lightG: CGFloat = 0, lightB: CGFloat = 0 + lighterColor.getRed(&lightR, green: &lightG, blue: &lightB, alpha: nil) + + XCTAssertEqual(lightR, min(red + 0.3, 1.0)) + XCTAssertEqual(lightG, min(green + 0.3, 1.0)) + XCTAssertEqual(lightB, min(blue + 0.3, 1.0)) + } + + func testDarken() { + let color = Color.blue + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: nil) + + let darkerColor = color.darken(by: 0.3) + var darkR: CGFloat = 0, darkG: CGFloat = 0, darkB: CGFloat = 0 + darkerColor.getRed(&darkR, green: &darkG, blue: &darkB, alpha: nil) + + XCTAssertEqual(darkR, max(red - 0.3, 0)) + XCTAssertEqual(darkG, max(green - 0.3, 0)) + XCTAssertEqual(darkB, max(blue - 0.3, 0)) + } + // MARK: - Test initializers func testInit() { var color = Color(hex: 0xFFF) @@ -307,139 +307,138 @@ final class ColorExtensionsTests: XCTestCase { XCTAssertEqual(color?.rgbComponents.green, 0xf) XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) - + color = Color(hex: 0xFFFFFFF) XCTAssertEqual(color?.rgbComponents.red, 0xff) XCTAssertEqual(color?.rgbComponents.green, 0xff) XCTAssertEqual(color?.rgbComponents.blue, 0xff) XCTAssertEqual(color?.alpha, 1.0) - + color = Color(hex: 0x123456, transparency: 1.0) XCTAssertEqual(color?.rgbComponents.red, 0x12) XCTAssertEqual(color?.rgbComponents.green, 0x34) XCTAssertEqual(color?.rgbComponents.blue, 0x56) XCTAssertEqual(color?.alpha, 1.0) - + color = Color(hex: 0x999, transparency: 21.0) XCTAssertEqual(color?.rgbComponents.red, 0) XCTAssertEqual(color?.rgbComponents.green, 0x09) XCTAssertEqual(color?.rgbComponents.blue, 0x99) XCTAssertEqual(color?.alpha, 1.0) - + color = Color(hex: 0xaabbcc, transparency: 0.0) XCTAssertEqual(color?.rgbComponents.red, 0xaa) XCTAssertEqual(color?.rgbComponents.green, 0xbb) XCTAssertEqual(color?.rgbComponents.blue, 0xcc) XCTAssertEqual(color?.alpha, 0.0) - + color = Color(hex: 0x1, transparency: 0.5) XCTAssertEqual(color?.rgbComponents.red, 0) XCTAssertEqual(color?.rgbComponents.green, 0) XCTAssertEqual(color?.rgbComponents.blue, 1) XCTAssertEqual(color?.alpha, 0.5) - let color1 = Color(hex: 0xFFF, transparency: -0.4) let color2 = Color(hex: 0xFFF, transparency: 0) XCTAssertEqual(color1, color2) - + let color3 = Color(hex: 0xFFF, transparency: 1.5) let color4 = Color(hex: 0xFFF, transparency: 1) XCTAssertEqual(color3, color4) - } - + func testFailableInit() { var color = Color(hexString: "0xFFFFFF") XCTAssertNotNil(color) - + color = Color(hexString: "#FFFFFF") XCTAssertNotNil(color) - + color = Color(hexString: "FFFFFF") XCTAssertNotNil(color) - + color = Color(hexString: "#ABC") XCTAssertNotNil(color) - + color = Color(hexString: "#GGG") XCTAssertNil(color) - + color = Color(hexString: "4#fff") XCTAssertNil(color) - + color = Color(hexString: "FFFFFFF") XCTAssertNotNil(color) } - + func testInitWithComponents() { - var r1: CGFloat = 0 - var r2: CGFloat = 0 - var g1: CGFloat = 0 - var g2: CGFloat = 0 - var b1: CGFloat = 0 - var b2: CGFloat = 0 + var red1: CGFloat = 0 + var red2: CGFloat = 0 + var green1: CGFloat = 0 + var green2: CGFloat = 0 + var blue1: CGFloat = 0 + var blue2: CGFloat = 0 var alpha1: CGFloat = 0 var alpha2: CGFloat = 0 - + var color1 = Color(red: 255, green: 244, blue: 255, transparency: 2.0) var color2 = Color(red: 1.0, green: 244.0 / 255.0, blue: 1.0, alpha: 1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) + color1?.getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1) + color2.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2) + XCTAssertEqual(red1, red2) + XCTAssertEqual(green1, green2) + XCTAssertEqual(blue1, blue2) XCTAssertEqual(alpha1, alpha2) - + color1 = Color(red: 25, green: 244, blue: 55, transparency: -1.0) color2 = Color(red: 25.0 / 255.0, green: 244.0 / 255.0, blue: 55.0 / 255.0, alpha: 0.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) + color1?.getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1) + color2.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2) + XCTAssertEqual(red1, red2) + XCTAssertEqual(green1, green2) + XCTAssertEqual(blue1, blue2) XCTAssertEqual(alpha1, alpha2) - + color1 = Color(red: 2, green: 4, blue: 5) color2 = Color(red: 2.0 / 255.0, green: 4.0 / 255.0, blue: 5.0 / 255.0, alpha: 1.0) - color1?.getRed(&r1, green: &g1, blue: &b1, alpha: &alpha1) - color2.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) - XCTAssertEqual(r1, r2) - XCTAssertEqual(g1, g2) - XCTAssertEqual(b1, b2) + color1?.getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1) + color2.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2) + XCTAssertEqual(red1, red2) + XCTAssertEqual(green1, green2) + XCTAssertEqual(blue1, blue2) XCTAssertEqual(alpha1, alpha2) } - + func testFailableInitWithComponents() { let color1 = Color(red: 258, green: 0, blue: 0) XCTAssertNil(color1) - + let color2 = Color(red: 0, green: 258, blue: 0) XCTAssertNil(color2) - + let color3 = Color(red: 0, green: 0, blue: 258) XCTAssertNil(color3) - + let color4 = Color(red: 258, green: 258, blue: 258) XCTAssertNil(color4) - + } - + func testFailableInitWithComplementaryColor() { var color = Color(complementaryFor: Color.black) - var r: CGFloat = 0 - var g: CGFloat = 0 - var b: CGFloat = 0 - - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 1) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) - + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + + color?.getRed(&red, green: &green, blue: &blue, alpha: nil) + XCTAssertEqual(red, 1) + XCTAssertEqual(green, 1) + XCTAssertEqual(blue, 1) + color = Color(complementaryFor: Color.red) - color?.getRed(&r, green: &g, blue: &b, alpha: nil) - XCTAssertEqual(r, 0) - XCTAssertEqual(g, 1) - XCTAssertEqual(b, 1) + color?.getRed(&red, green: &green, blue: &blue, alpha: nil) + XCTAssertEqual(red, 0) + XCTAssertEqual(green, 1) + XCTAssertEqual(blue, 1) } - + } +// swiftlint:enable type_body_length diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index 7c5283329..04f2793fe 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -8,313 +8,172 @@ import XCTest @testable import SwifterSwift +private struct Person: Equatable { + var name: String + var age: Int? + + static func == (lhs: Person, rhs: Person) -> Bool { + return lhs.name == rhs.name && lhs.age == rhs.age + } + +} + +// swiftlint:disable type_body_length final class ArrayExtensionsTests: XCTestCase { - - func testAverage() { - XCTAssertEqual([1, 2, 3, 4, 5].average(), 3) - XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].average(), 3.4) - XCTAssertEqual([Int]().average(), 0) - XCTAssertEqual([Double]().average(), 0) - } - - func testFirstIndex() { - XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2)) - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2), 2) - XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 7)) - } - - func testIndexes() { - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indexes(of: 1), [0, 1, 5, 7]) - } - - func testIndices() { - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 1), [0, 1, 5, 7]) - XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) + + func testSum() { + XCTAssertEqual([1, 2, 3, 4, 5].sum(), 15) + XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].sum(), 17) } - - func testLastIndex() { - XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2)) - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2), 6) - XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 7)) - } - - func testPop() { - var arr = [1, 2, 3, 4, 5] - let item = arr.pop() - XCTAssertEqual(arr, [1, 2, 3, 4]) - XCTAssertNotNil(item) - XCTAssertEqual(item, 5) - arr.removeAll() - XCTAssertNil(arr.pop()) - } - - func testPrepend() { - var arr = [2, 3, 4, 5] - arr.prepend(1) - XCTAssertEqual(arr, [1, 2, 3, 4, 5]) - } - - func testPush() { - var arr = [1, 2, 3, 4] - arr.push(5) - XCTAssertEqual(arr, [1, 2, 3, 4, 5]) - } - - func testSwap() { - var array: [Int] = [1, 2, 3, 4, 5] - array.swap(from: 3, to: 0) - XCTAssertEqual(array[3], 1) - XCTAssertEqual(array[0], 4) + + func testAverage() { + XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].average(), 3.4) + XCTAssertEqual([Double]().average(), 0) + } + + func testPrepend() { + var arr = [2, 3, 4, 5] + arr.prepend(1) + XCTAssertEqual(arr, [1, 2, 3, 4, 5]) } - + func testSafeSwap() { var array: [Int] = [1, 2, 3, 4, 5] array.safeSwap(from: 3, to: 0) XCTAssertEqual(array[3], 1) XCTAssertEqual(array[0], 4) - - var newArray = array - newArray.safeSwap(from: 1, to: 1) - XCTAssertEqual(newArray, array) - - newArray = array - newArray.safeSwap(from: 1, to: 12) - XCTAssertEqual(newArray, array) - - let emptyArray: [Int] = [] - var swappedEmptyArray = emptyArray - swappedEmptyArray.safeSwap(from: 1, to: 3) - XCTAssertEqual(swappedEmptyArray, emptyArray) - - } - - func testRemoveAll() { - var arr = [0, 1, 2, 0, 3, 4, 5, 0, 0] - arr.removeAll(0) - XCTAssertEqual(arr, [1, 2, 3, 4, 5]) - arr = [] - arr.removeAll(0) - XCTAssertEqual(arr, []) - } - - func testRemoveAllItems() { - var arr = [0, 1, 2, 2, 0, 3, 4, 5, 0, 0] - arr.removeAll([0, 2]) - XCTAssertEqual(arr, [1, 3, 4, 5]) - arr.removeAll([]) - XCTAssertEqual(arr, [1, 3, 4, 5]) - arr = [] - arr.removeAll([]) - XCTAssertEqual(arr, []) - } - func testShuffle() { - var arr = ["a"] - arr.shuffle() - XCTAssertEqual(arr, arr) - - let original = [1, 2, 3, 4, 5] - var array = original - - while original == array { - array.shuffle() - } - XCTAssertEqual(array.count, 5) - XCTAssertNotEqual(original, array) - } - - func testShuffled() { - let original = [1, 2, 3, 4, 5] - var array = original - - while original == array { - array = array.shuffled() - } - XCTAssertEqual(array.count, 5) - XCTAssertNotEqual(original, array) - } - - func testSum() { - XCTAssertEqual([1, 2, 3, 4, 5].sum(), 15) - XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].sum(), 17) - } - - func testRemoveDuplicates() { - var array = [1, 1, 2, 2, 3, 3, 3, 4, 5] - array.removeDuplicates() - XCTAssertEqual(array, [1, 2, 3, 4, 5]) + var newArray = array + newArray.safeSwap(from: 1, to: 1) + XCTAssertEqual(newArray, array) + + newArray = array + newArray.safeSwap(from: 1, to: 12) + XCTAssertEqual(newArray, array) + + let emptyArray: [Int] = [] + var swappedEmptyArray = emptyArray + swappedEmptyArray.safeSwap(from: 1, to: 3) + XCTAssertEqual(swappedEmptyArray, emptyArray) } - - func testDuplicatesRemoved() { - XCTAssertEqual([1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved(), [1, 2, 3, 4, 5]) - XCTAssertEqual(["h", "e", "l", "l", "o"].duplicatesRemoved(), ["h", "e", "l", "o"]) - } - - func testItemAtIndex() { - XCTAssertEqual([1, 2, 3].item(at: 0), 1) - XCTAssertEqual([1, 2, 3].item(at: 1), 2) - XCTAssertEqual([1, 2, 3].item(at: 2), 3) - XCTAssertNil([1, 2, 3].item(at: 5)) - } - - func testContains() { - XCTAssert([Int]().contains([])) - XCTAssertFalse([Int]().contains([1, 2])) - XCTAssert([1, 2, 3].contains([1, 2])) - XCTAssert([1, 2, 3].contains([2, 3])) - XCTAssert([1, 2, 3].contains([1, 3])) - XCTAssertFalse([1, 2, 3].contains([4, 5])) - } - + func testFirstIndexWhere() { let array = [1, 7, 1, 2, 4, 1, 6] let index = array.firstIndex { $0 % 2 == 0 } XCTAssertEqual(index, 3) XCTAssertNil([Int]().firstIndex { $0 % 2 == 0 }) } - + func testLastIndexWhere() { let array = [1, 1, 1, 2, 2, 1, 1, 2, 1] let index = array.lastIndex { $0 % 2 == 0 } XCTAssertEqual(index, 7) + XCTAssertNil(array.lastIndex { $0 == 3 }) XCTAssertNil([Int]().lastIndex { $0 % 2 == 0 }) } - + func testIndicesWhere() { let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] let indices = array.indices { $0 % 2 == 0 } XCTAssertEqual(indices!, [0, 2, 4, 6, 8]) - let emptyArray: [Int] = [] - let emptyIndices = emptyArray.indices { $0 % 2 == 0 } - XCTAssertNil(emptyIndices) - } - - func testAllMatch() { - let array = [2, 4, 6, 8, 10, 12] - XCTAssert(array.all { $0 % 2 == 0 }) + let emptyArray: [Int] = [] + let emptyIndices = emptyArray.indices { $0 % 2 == 0 } + XCTAssertNil(emptyIndices) } - - func testNoneMatch() { - let array = [3, 5, 7, 9, 11, 13] - XCTAssert(array.none { $0 % 2 == 0 }) - } - + func testLastWhere() { let array = [1, 1, 2, 1, 1, 1, 2, 1, 4, 1] let element = array.last { $0 % 2 == 0 } XCTAssertEqual(element, 4) XCTAssertNil([Int]().last { $0 % 2 == 0 }) } - - func testReject() { + + func testRejectWhere() { let input = [1, 2, 3, 4, 5] let output = input.reject { $0 % 2 == 0 } XCTAssertEqual(output, [1, 3, 5]) } - + func testCountWhere() { let array = [1, 1, 1, 1, 4, 4, 1, 1, 1] let count = array.count { $0 % 2 == 0 } XCTAssertEqual(count, 2) } - + func testForEachReversed() { let input = [1, 2, 3, 4, 5] var output: [Int] = [] input.forEachReversed { output.append($0) } XCTAssertEqual(output.first, 5) } - + func testForEachWhere() { let input = [1, 2, 2, 2, 1, 4, 1] var output: [Int] = [] - input.forEach(where: {$0 % 2 == 0}, body: { output.append($0 * 2) }) + input.forEach(where: {$0 % 2 == 0}, body: { output.append($0 * 2) }) XCTAssertEqual(output, [4, 4, 4, 8]) } - + func testAccumulate() { let input = [1, 2, 3] let result = input.accumulate(initial: 0, next: +) XCTAssertEqual([1, 3, 6], result) } - + func testFilteredMap() { let input = [1, 2, 3, 4, 5] - let result = input.filtered({ $0 % 2 == 0 }, map: { $0.string }) + let result = input.filtered({ $0 % 2 == 0 }, map: { $0.string }) XCTAssertEqual(result.count, 2) XCTAssertEqual(["2", "4"], result) } - + func testKeepWhile() { var input = [2, 4, 6, 7, 8, 9, 10] input.keep(while: {$0 % 2 == 0 }) XCTAssertEqual(input, [2, 4, 6]) - + input = [7, 7, 8, 10] input.keep(while: {$0 % 2 == 0 }) XCTAssertEqual(input, [Int]()) } - + func testTakeWhile() { var input = [2, 4, 6, 7, 8, 9, 10] var output = input.take(while: {$0 % 2 == 0 }) XCTAssertEqual(output, [2, 4, 6]) - + input = [7, 7, 8, 10] output = input.take(while: {$0 % 2 == 0 }) XCTAssertEqual(output, [Int]()) - + XCTAssertEqual([].take(while: {$0 % 2 == 0 }), []) } - + func testSkipWhile() { var input = [2, 4, 6, 7, 8, 9, 10] var output = input.skip(while: {$0 % 2 == 0 }) XCTAssertEqual(output, [7, 8, 9, 10]) - + input = [7, 7, 8, 10] output = input.skip(while: {$0 % 2 == 0 }) XCTAssertEqual(output, [7, 7, 8, 10]) - - XCTAssertEqual([].skip(while: { $0 % 2 == 0}), []) - } - func testGroupBy() { - let array: [String] = ["james", "irving", "jordan", "jonshon", "iverson"] - let grouped = array.groupByKey { element -> String in - return String(element.first!) - } - XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) - XCTAssertEqual(grouped["i"] ?? [], [ "irving", "iverson" ]) + XCTAssertEqual([].skip(while: { $0 % 2 == 0}), []) } - - func testDivided() { - let input = [0, 1, 2, 3, 4, 5] - let (even, odd) = input.divided { $0 % 2 == 0 } - XCTAssertEqual(even, [0, 2, 4]) - XCTAssertEqual(odd, [1, 3, 5]) - - // Parameter names + indexes - let tuple = input.divided { $0 % 2 == 0 } - XCTAssertEqual(tuple.matching, [0, 2, 4]) - XCTAssertEqual(tuple.0, [0, 2, 4]) - XCTAssertEqual(tuple.nonMatching, [1, 3, 5]) - XCTAssertEqual(tuple.1, [1, 3, 5]) - } func testForEachSlice() { var iterations: Int = 0 - + // A slice with value zero var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] array.forEach(slice: 0) { _ in iterations += 1 } XCTAssertEqual(iterations, 0) - + // A slice that divide the total evenly array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] - + array.forEach(slice: 2) { (sliceArray) in switch iterations { case 0: @@ -330,9 +189,9 @@ final class ArrayExtensionsTests: XCTestCase { // A slice that does not divide the total evenly array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] - + iterations = 0 - + array.forEach(slice: 2) { (sliceArray) in switch iterations { case 0: @@ -346,44 +205,64 @@ final class ArrayExtensionsTests: XCTestCase { default: break } iterations += 1 - } - + // A slice greater than the array count array = [ "james", "irving", "jordan", "jonshon" ] array.forEach(slice: 6) { (sliceArray) in XCTAssertEqual(sliceArray, [ "james", "irving", "jordan", "jonshon"]) } - } - + func testGroupBySize() { - + // A slice with value zero var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] var slices = array.group(by: 0) XCTAssertNil(slices) - + // A slice that divide the total evenly array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] slices = array.group(by: 2) XCTAssertNotNil(slices) XCTAssertEqual(slices?.count, 3) - + // A slice that does not divide the total evenly array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] slices = array.group(by: 2) XCTAssertNotNil(slices) XCTAssertEqual(slices?.count, 4) - + // A slice greater than the array count array = [ "james", "irving", "jordan", "jonshon" ] slices = array.group(by: 6) XCTAssertNotNil(slices) XCTAssertEqual(slices?.count, 1) + } + + func testGroupBy() { + let array: [String] = ["james", "irving", "jordan", "jonshon", "iverson"] + let grouped = array.groupByKey { element -> String in + return String(element.first!) + } + XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) + XCTAssertEqual(grouped["i"] ?? [], [ "irving", "iverson" ]) + } + + func testDivided() { + let input = [0, 1, 2, 3, 4, 5] + let (even, odd) = input.divided { $0 % 2 == 0 } + XCTAssertEqual(even, [0, 2, 4]) + XCTAssertEqual(odd, [1, 3, 5]) + // Parameter names + indexes + let tuple = input.divided { $0 % 2 == 0 } + XCTAssertEqual(tuple.matching, [0, 2, 4]) + XCTAssertEqual(tuple.0, [0, 2, 4]) + XCTAssertEqual(tuple.nonMatching, [1, 3, 5]) + XCTAssertEqual(tuple.1, [1, 3, 5]) } - + func testRotated() { let array: [Int] = [1, 2, 3, 4] XCTAssertEqual(array.rotated(by: 0), [1, 2, 3, 4]) @@ -393,7 +272,7 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(array.rotated(by: -1), [2, 3, 4, 1]) XCTAssertEqual(array.rotated(by: -3), [4, 1, 2, 3]) } - + func testRotate() { var array: [Int] = [1, 2, 3, 4] array.rotate(by: 0) @@ -402,24 +281,39 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(array, [3, 4, 1, 2]) array.rotate(by: -1) XCTAssertEqual(array, [4, 1, 2, 3]) - } - struct Person: Equatable { - var name: String - var age: Int? - - static func == (lhs: Person, rhs: Person) -> Bool { - return lhs.name == rhs.name && lhs.age == rhs.age + func testShuffle() { + var arr = ["a"] + arr.shuffle() + XCTAssertEqual(arr, arr) + + let original = [1, 2, 3, 4, 5] + var array = original + + while original == array { + array.shuffle() } + XCTAssertEqual(array.count, 5) + XCTAssertNotEqual(original, array) } - + + func testShuffled() { + let original = [1, 2, 3, 4, 5] + var array = original + + while original == array { + array = array.shuffled() + } + XCTAssertEqual(array.count, 5) + XCTAssertNotEqual(original, array) + } + func testKeyPathSorted() { - let array = [Person(name: "James", age: 32), Person(name: "Wade", age: 36), Person(name: "Rose", age: 29)] - + XCTAssertEqual(array.sorted(by: \Person.name), [Person(name: "James", age: 32), Person(name: "Rose", age: 29), Person(name: "Wade", age: 36)]) @@ -433,27 +327,85 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(array.sorted(by: \Person.age, ascending: false), [Person(name: "Wade", age: 36), Person(name: "James", age: 32), Person(name: "Rose", age: 29)]) - + // Testing Mutating var mutableArray = [Person(name: "James", age: 32), Person(name: "Wade", age: 36), Person(name: "Rose", age: 29)] - + mutableArray.sort(by: \Person.name) XCTAssertEqual(mutableArray, [Person(name: "James", age: 32), Person(name: "Rose", age: 29), Person(name: "Wade", age: 36)]) - + // Testing Mutating Optional keyPath mutableArray.sort(by: \Person.age) XCTAssertEqual(mutableArray, [Person(name: "Rose", age: 29), Person(name: "James", age: 32), Person(name: "Wade", age: 36)]) - + // Testing nil path let nilArray = [Person(name: "James", age: nil), Person(name: "Wade", age: nil)] XCTAssertEqual(nilArray.sorted(by: \Person.age), [Person(name: "James", age: nil), - Person(name: "Wade", age: nil)]) + Person(name: "Wade", age: nil)]) + } + + func testContains() { + XCTAssert([Int]().contains([])) + XCTAssertFalse([Int]().contains([1, 2])) + XCTAssert([1, 2, 3].contains([1, 2])) + XCTAssert([1, 2, 3].contains([2, 3])) + XCTAssert([1, 2, 3].contains([1, 3])) + XCTAssertFalse([1, 2, 3].contains([4, 5])) + } + + func testIndices() { + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 1), [0, 1, 5, 7]) + XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) + } + + func testRemoveAll() { + var arr = [0, 1, 2, 0, 3, 4, 5, 0, 0] + arr.removeAll(0) + XCTAssertEqual(arr, [1, 2, 3, 4, 5]) + arr = [] + arr.removeAll(0) + XCTAssertEqual(arr, []) + } + + func testRemoveAllItems() { + var arr = [0, 1, 2, 2, 0, 3, 4, 5, 0, 0] + arr.removeAll([0, 2]) + XCTAssertEqual(arr, [1, 3, 4, 5]) + arr.removeAll([]) + XCTAssertEqual(arr, [1, 3, 4, 5]) + arr = [] + arr.removeAll([]) + XCTAssertEqual(arr, []) } - + + func testRemoveDuplicates() { + var array = [1, 1, 2, 2, 3, 3, 3, 4, 5] + array.removeDuplicates() + XCTAssertEqual(array, [1, 2, 3, 4, 5]) + } + + func testWithoutDuplicates() { + XCTAssertEqual([1, 1, 2, 2, 3, 3, 3, 4, 5].withoutDuplicates(), [1, 2, 3, 4, 5]) + XCTAssertEqual(["h", "e", "l", "l", "o"].withoutDuplicates(), ["h", "e", "l", "o"]) + } + + func testFirstIndex() { + XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2)) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2), 2) + XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 7)) + } + + func testLastIndex() { + XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2)) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2), 6) + XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 7)) + } + } +// swiftlint:enable type_body_length diff --git a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift index b2cf901b7..3210ccb51 100644 --- a/Tests/SwiftStdlibTests/BoolExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/BoolExtensionsTests.swift @@ -10,40 +10,27 @@ import XCTest @testable import SwifterSwift final class BoolExtensionsTests: XCTestCase { - + func testInt() { XCTAssertEqual(true.int, 1) XCTAssertEqual(false.int, 0) } - + func testString() { XCTAssertEqual(true.string, "true") XCTAssertEqual(false.string, "false") } - - func testToggled() { - XCTAssertFalse(true.toggled) - XCTAssert(false.toggled) - } - - func testRandom() { - var yes = 0, no = 0 - for _ in 1...10000 { - if Bool.random { - yes += 1 - } else { - no += 1 - } - } - XCTAssert(yes >= 10 && no >= 10) - } - - func testToggle() { - var t = true - t.toggle() - XCTAssertFalse(t) - t.toggle() - XCTAssert(t) + + func testRandom() { + var trueCount = 0, falseCount = 0 + for _ in 1...10000 { + if Bool.random { + trueCount += 1 + } else { + falseCount += 1 + } + } + XCTAssert(trueCount >= 10 && falseCount >= 10) } - + } diff --git a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift index dec9ae85d..b814b47a9 100644 --- a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift @@ -18,68 +18,67 @@ import XCTest @testable import SwifterSwift final class CharacterExtensionsTests: XCTestCase { - - func testOperators() { - let s = Character("s") - XCTAssertEqual(s * 5, "sssss") - XCTAssertEqual(5 * s, "sssss") - - XCTAssertEqual(s * 0, "") - XCTAssertEqual(0 * s, "") - - XCTAssertEqual(s * -5, "") - XCTAssertEqual(-5 * s, "") - } - - func testIsEmoji() { - XCTAssert(Character("😂").isEmoji) - XCTAssertFalse(Character("j").isEmoji) - } - - func testIsNumber() { - XCTAssert(Character("1").isNumber) - XCTAssertFalse(Character("s").isNumber) - } - + + func testIsEmoji() { + XCTAssert(Character("😂").isEmoji) + XCTAssertFalse(Character("j").isEmoji) + } + + func testIsNumber() { + XCTAssert(Character("1").isNumber) + XCTAssertFalse(Character("s").isNumber) + } + func testIsLetter() { XCTAssertTrue(Character("a").isLetter) XCTAssertTrue(Character("B").isLetter) XCTAssertFalse(Character("3").isLetter) XCTAssertFalse(Character("-").isLetter) } - + + func testIsLowercased() { + XCTAssert(Character("s").isLowercased) + XCTAssertFalse(Character("S").isLowercased) + } + + func testIsUpercased() { + XCTAssert(Character("S").isUppercased) + XCTAssertFalse(Character("s").isUppercased) + } + func testIsWhiteSpace() { XCTAssertTrue(Character(" ").isWhiteSpace) XCTAssertFalse(Character("-").isWhiteSpace) + } + func testInt() { + XCTAssertNotNil(Character("1").int) + XCTAssertEqual(Character("1").int, 1) + XCTAssertNil(Character("s").int) } - - func testInt() { - XCTAssertNotNil(Character("1").int) - XCTAssertEqual(Character("1").int, 1) - XCTAssertNil(Character("s").int) - } - - func testString() { - XCTAssertEqual(Character("s").string, String("s")) - } - - func testIsUpercased() { - XCTAssert(Character("S").isUppercased) - XCTAssertFalse(Character("s").isUppercased) - } - - func testIsLowercased() { - XCTAssert(Character("s").isLowercased) - XCTAssertFalse(Character("S").isLowercased) - } - + + func testString() { + XCTAssertEqual(Character("s").string, String("s")) + } + func testUppercased() { XCTAssertEqual(Character("s").uppercased, Character("S")) } - + func testLowercased() { XCTAssertEqual(Character("S").lowercased, Character("s")) - } + + func testOperators() { + let sLetter = Character("s") + XCTAssertEqual(sLetter * 5, "sssss") + XCTAssertEqual(5 * sLetter, "sssss") + + XCTAssertEqual(sLetter * 0, "") + XCTAssertEqual(0 * sLetter, "") + + XCTAssertEqual(sLetter * -5, "") + XCTAssertEqual(-5 * sLetter, "") + } + } diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index 46bd3e11c..55bc2cb36 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -10,24 +10,30 @@ import XCTest @testable import SwifterSwift final class CollectionExtensionsTests: XCTestCase { - + + let collection = [1, 2, 3, 4, 5] + func testForEachInParallel() { - let collection = [1, 2, 3, 4, 5] collection.forEachInParallel { item in XCTAssert(collection.contains(item)) } } - + func testSafeSubscript() { - let collection = [1, 2, 3, 4, 5] XCTAssertNotNil(collection[safe: 2]) XCTAssertEqual(collection[safe: 2], 3) XCTAssertNil(collection[safe: 10]) } - - func testRandomItem() { - XCTAssertNotNil([1, 2, 3].randomItem) - XCTAssert([1, 2, 3].contains([1, 2, 3].randomItem!)) - XCTAssertNil([].randomItem) + + func testRandomItem() { + XCTAssertNotNil([1, 2, 3].randomItem) + XCTAssert([1, 2, 3].contains([1, 2, 3].randomItem!)) + XCTAssertNil([].randomItem) + } + + func testAverage() { + XCTAssertEqual(collection.average(), 3) + XCTAssertEqual([Int]().average(), 0) } + } diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 4cbbc3d9c..67aa44dbc 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -10,73 +10,71 @@ import XCTest @testable import SwifterSwift final class DictionaryExtensionsTests: XCTestCase { - - var testDict: [String: Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] - - func testHasKey() { - XCTAssert(testDict.has(key: "testKey")) - XCTAssertFalse(testDict.has(key: "anotherKey")) - } - + + var testDict: [String: Any] = ["testKey": "testValue", "testArrayKey": [1, 2, 3, 4, 5]] + + func testHasKey() { + XCTAssert(testDict.has(key: "testKey")) + XCTAssertFalse(testDict.has(key: "anotherKey")) + } + func testRemoveAll() { var dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] - dict.removeAll(keys: ["key1", "key2"]) + dict.removeAll(keys: ["key1", "key2"]) XCTAssertTrue(dict.keys.contains("key3")) XCTAssertFalse(dict.keys.contains("key1")) XCTAssertFalse(dict.keys.contains("key2")) } - - func testJsonString() { - XCTAssertNotNil(testDict.jsonString()) - XCTAssertEqual(testDict.jsonString()?.contains("\"testArrayKey\":[1,2,3,4,5]"), true) - XCTAssertEqual(testDict.jsonString()?.contains("\"testKey\":\"testValue\""), true) - - XCTAssertEqual(testDict.jsonString(prettify: true)?.contains("[\n 1,\n 2,\n 3,\n 4,\n 5\n ]"), true) - - XCTAssertNil(["key": NSObject()].jsonString()) - XCTAssertNil([1: 2].jsonString()) - } - - func testJsonData() { - let dict = ["key": "value"] - - let jsonString = "{\"key\":\"value\"}" - let jsonData = jsonString.data(using: .utf8) - - let prettyJsonString = "{\n \"key\" : \"value\"\n}" - let prettyJsonData = prettyJsonString.data(using: .utf8) - - XCTAssertEqual(dict.jsonData(), jsonData) - XCTAssertEqual(dict.jsonData(prettify: true), prettyJsonData) - - XCTAssertNil(["key": NSObject()].jsonData()) - XCTAssertNil([1: 2].jsonData()) - } - - func testLowercaseAllKeys() { - var dict = ["tEstKeY": "value"] - dict.lowercaseAllKeys() - XCTAssertEqual(dict, ["testkey": "value"]) - } - - func testCountFiltered() { + + func testJsonData() { + let dict = ["key": "value"] + + let jsonString = "{\"key\":\"value\"}" + let jsonData = jsonString.data(using: .utf8) + + let prettyJsonString = "{\n \"key\" : \"value\"\n}" + let prettyJsonData = prettyJsonString.data(using: .utf8) + + XCTAssertEqual(dict.jsonData(), jsonData) + XCTAssertEqual(dict.jsonData(prettify: true), prettyJsonData) + + XCTAssertNil(["key": NSObject()].jsonData()) + XCTAssertNil([1: 2].jsonData()) + } + + func testJsonString() { + XCTAssertNotNil(testDict.jsonString()) + XCTAssertEqual(testDict.jsonString()?.contains("\"testArrayKey\":[1,2,3,4,5]"), true) + XCTAssertEqual(testDict.jsonString()?.contains("\"testKey\":\"testValue\""), true) + + XCTAssertEqual(testDict.jsonString(prettify: true)?.contains("[\n 1,\n 2,\n 3,\n 4,\n 5\n ]"), true) + + XCTAssertNil(["key": NSObject()].jsonString()) + XCTAssertNil([1: 2].jsonString()) + } + + func testCountWhere() { let dict: [String: String] = ["key1": "value", "key2": "value", "key3": "value3"] let count = dict.count { (tuple) -> Bool in return tuple.0 == "key1" || tuple.1 == "value" } XCTAssertEqual(count, 2) } - - // MARK: - Test Operators + + func testLowercaseAllKeys() { + var dict = ["tEstKeY": "value"] + dict.lowercaseAllKeys() + XCTAssertEqual(dict, ["testkey": "value"]) + } + func testOperatorPlus() { let dict: [String: String] = ["key1": "value1"] let dict2: [String: String] = ["key2": "value2"] let result = dict + dict2 XCTAssertTrue(result.keys.contains("key1")) XCTAssertTrue(result.keys.contains("key2")) - } - + func testOperatorMinus() { let dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] let result = dict-["key1", "key2"] @@ -84,7 +82,7 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertFalse(result.keys.contains("key1")) XCTAssertFalse(result.keys.contains("key2")) } - + func testOperatorPlusEqual() { var dict: [String: String] = ["key1": "value1"] let dict2: [String: String] = ["key2": "value2"] @@ -92,7 +90,7 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertTrue(dict.keys.contains("key1")) XCTAssertTrue(dict.keys.contains("key2")) } - + func testOperatorRemoveKeys() { var dict: [String: String] = ["key1": "value1", "key2": "value2", "key3": "value3"] dict-=["key1", "key2"] @@ -100,5 +98,5 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertFalse(dict.keys.contains("key1")) XCTAssertFalse(dict.keys.contains("key2")) } - + } diff --git a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift index c7de716d9..2ac857cba 100644 --- a/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DoubleExtensionsTests.swift @@ -10,86 +10,26 @@ import XCTest @testable import SwifterSwift final class DoubleExtensionsTests: XCTestCase { - - func testAbs() { - XCTAssertEqual(Double(-9.3).abs, Double(9.3)) - } - - func testCeil() { - XCTAssertEqual(Double(9.3).ceil, Double(10.0)) - } - - func testDegreesToRadians() { - XCTAssertEqual(Double(180).degreesToRadians, Double.pi) - } - - func testRandomBetween() { - XCTAssertGreaterThan(Double.random(between: 1, and: 5), 0) - XCTAssertLessThan(Double.random(between: 1, and: 5), 6) - - XCTAssertGreaterThan(Double(randomBetween: 1, and: 5), 0) - XCTAssertLessThan(Double(randomBetween: 1, and: 5), 6) - - XCTAssertGreaterThan(Double.random(inRange: 1...5), 0) - XCTAssertLessThan(Double.random(inRange: 1...5), 6) - - XCTAssertGreaterThan(Double(randomInRange: 1...5), 0) - XCTAssertLessThan(Double(randomInRange: 1...5), 6) - } - - func testFloor() { - XCTAssertEqual(Double(9.3).floor, Double(9.0)) - } - - func testIsPositive() { - XCTAssert(Double(1).isPositive) - XCTAssertFalse(Double(0).isPositive) - XCTAssertFalse(Double(-1).isPositive) - } - - func testIsNegative() { - XCTAssert(Double(-1).isNegative) - XCTAssertFalse(Double(0).isNegative) - XCTAssertFalse(Double(1).isNegative) - } - - func testInt() { - XCTAssertEqual(Double(-1).int, -1) - XCTAssertEqual(Double(2).int, 2) - XCTAssertEqual(Double(4.3).int, 4) - } - - func testFloat() { - XCTAssertEqual(Double(-1).float, Float(-1)) - XCTAssertEqual(Double(2).float, Float(2)) - XCTAssertEqual(Double(4.3).float, Float(4.3)) - } - - func testCGFloat() { - XCTAssertEqual(Double(4.3).cgFloat, CGFloat(4.3)) - } - - func testString() { - XCTAssertEqual(Double(2.3).string, "2.3") - } - - func testRadiansToDegrees() { - XCTAssertEqual(Double.pi.radiansToDegrees, Double(180)) - } - - func testOperators() { - XCTAssertEqual((Double(5.0) ** Double(2.0)), Double(25.0)) - XCTAssert((Double(5.0) ± Double(2.0)) == (Double(3.0), Double(7.0)) || (Double(5.0) ± Double(2.0)) == (Double(7.0), Double(3.0))) - XCTAssert((±Double(2.0)) == (Double(2.0), Double(-2.0)) || (±Double(2.0)) == (Double(-2.0), Double(2.0))) - XCTAssertEqual((√Double(25.0)), Double(5.0)) - } - - func testAsLocaleCurrency() { - let num = Double(10.23) - if let symbol = Locale.current.currencySymbol { - XCTAssert(num.asLocaleCurrency.contains(symbol)) - } - XCTAssert(num.asLocaleCurrency.contains("\(num)")) - } - + + func testInt() { + XCTAssertEqual(Double(-1).int, -1) + XCTAssertEqual(Double(2).int, 2) + XCTAssertEqual(Double(4.3).int, 4) + } + + func testFloat() { + XCTAssertEqual(Double(-1).float, Float(-1)) + XCTAssertEqual(Double(2).float, Float(2)) + XCTAssertEqual(Double(4.3).float, Float(4.3)) + } + + func testCGFloat() { + XCTAssertEqual(Double(4.3).cgFloat, CGFloat(4.3)) + } + + func testOperators() { + XCTAssertEqual((Double(5.0) ** Double(2.0)), Double(25.0)) + XCTAssertEqual((√Double(25.0)), Double(5.0)) + } + } diff --git a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift index 1b90dc27d..0efa1c849 100644 --- a/Tests/SwiftStdlibTests/FloatExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/FloatExtensionsTests.swift @@ -10,86 +10,26 @@ import XCTest @testable import SwifterSwift final class FloatExtensionsTests: XCTestCase { - - func testAbs() { - XCTAssertEqual(Float(-9.3).abs, Float(9.3)) - } - - func testCeil() { - XCTAssertEqual(Float(9.3).ceil, Float(10.0)) - } - - func testDegreesToRadians() { - XCTAssertEqual(Float(180).degreesToRadians, Float.pi) - } - - func testRandomBetween() { - XCTAssertGreaterThan(Float.random(between: 1, and: 5), 0) - XCTAssertLessThan(Float.random(between: 1, and: 5), 6) - - XCTAssertGreaterThan(Float(randomBetween: 1, and: 5), 0) - XCTAssertLessThan(Float(randomBetween: 1, and: 5), 6) - - XCTAssertGreaterThan(Float.random(inRange: 1...5), 0) - XCTAssertLessThan(Float.random(inRange: 1...5), 6) - - XCTAssertGreaterThan(Float(randomInRange: 1...5), 0) - XCTAssertLessThan(Float(randomInRange: 1...5), 6) - } - - func testFloor() { - XCTAssertEqual(Float(9.3).floor, Float(9.0)) - } - - func testIsPositive() { - XCTAssert(Float(1).isPositive) - XCTAssertFalse(Float(0).isPositive) - XCTAssertFalse(Float(-1).isPositive) - } - - func testIsNegative() { - XCTAssert(Float(-1).isNegative) - XCTAssertFalse(Float(0).isNegative) - XCTAssertFalse(Float(1).isNegative) - } - - func testInt() { - XCTAssertEqual(Float(-1).int, -1) - XCTAssertEqual(Float(2).int, 2) - XCTAssertEqual(Float(4.3).int, 4) - } - - func testDouble() { - XCTAssertEqual(Float(-1).double, Double(-1)) - XCTAssertEqual(Float(2).double, Double(2)) - XCTAssertEqual(Float(4.3).double, Double(4.3), accuracy: 0.00001) - } - - func testCGFloat() { - XCTAssertEqual(Float(4.3).cgFloat, CGFloat(4.3), accuracy: 0.00001) - } - - func testString() { - XCTAssertEqual(Float(2.3).string, "2.3") - } - - func testRadiansToDegrees() { - XCTAssertEqual(Float.pi.radiansToDegrees, Float(180)) - } - - func testOperators() { - XCTAssertEqual((Float(5.0) ** Float(2.0)), Float(25.0)) - XCTAssert((Float(5.0) ± Float(2.0)) == (Float(3.0), Float(7.0)) || (Float(5.0) ± Float(2.0)) == (Float(7.0), Float(3.0))) - XCTAssert((±Float(2.0)) == (Float(2.0), Float(-2.0)) || (±Float(2.0)) == (Float(-2.0), Float(2.0))) - XCTAssertEqual((√Float(25.0)), Float(5.0)) - } - - func testAsLocaleCurrency() { - let num = Float(10.23) - if let symbol = Locale.current.currencySymbol { - XCTAssert(num.asLocaleCurrency.contains(symbol)) - } - XCTAssert(num.asLocaleCurrency.contains("\(num)")) - } - + + func testInt() { + XCTAssertEqual(Float(-1).int, -1) + XCTAssertEqual(Float(2).int, 2) + XCTAssertEqual(Float(4.3).int, 4) + } + + func testDouble() { + XCTAssertEqual(Float(-1).double, Double(-1)) + XCTAssertEqual(Float(2).double, Double(2)) + XCTAssertEqual(Float(4.3).double, Double(4.3), accuracy: 0.00001) + } + + func testCGFloat() { + XCTAssertEqual(Float(4.3).cgFloat, CGFloat(4.3), accuracy: 0.00001) + } + + func testOperators() { + XCTAssertEqual((Float(5.0) ** Float(2.0)), Float(25.0)) + XCTAssertEqual((√Float(25.0)), Float(5.0)) + } + } diff --git a/Tests/SwiftStdlibTests/FloatingPointExtensionsTests.swift b/Tests/SwiftStdlibTests/FloatingPointExtensionsTests.swift new file mode 100644 index 000000000..a6b77c627 --- /dev/null +++ b/Tests/SwiftStdlibTests/FloatingPointExtensionsTests.swift @@ -0,0 +1,93 @@ +// +// FloatingPointExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 5.04.2018. +// Copyright © 2018 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +final class FloatingPointExtensionsTests: XCTestCase { + + func testAbs() { + XCTAssertEqual(Float(-9.3).abs, Float(9.3)) + XCTAssertEqual(Double(-9.3).abs, Double(9.3)) + } + + func testIsPositive() { + XCTAssert(Float(1).isPositive) + XCTAssertFalse(Float(0).isPositive) + XCTAssertFalse(Float(-1).isPositive) + + XCTAssert(Double(1).isPositive) + XCTAssertFalse(Double(0).isPositive) + XCTAssertFalse(Double(-1).isPositive) + } + + func testIsNegative() { + XCTAssert(Float(-1).isNegative) + XCTAssertFalse(Float(0).isNegative) + XCTAssertFalse(Float(1).isNegative) + + XCTAssert(Double(-1).isNegative) + XCTAssertFalse(Double(0).isNegative) + XCTAssertFalse(Double(1).isNegative) + } + + func testCeil() { + XCTAssertEqual(Float(9.3).ceil, Float(10.0)) + XCTAssertEqual(Double(9.3).ceil, Double(10.0)) + } + + func testDegreesToRadians() { + XCTAssertEqual(Float(180).degreesToRadians, Float.pi) + XCTAssertEqual(Double(180).degreesToRadians, Double.pi) + } + + func testFloor() { + XCTAssertEqual(Float(9.3).floor, Float(9.0)) + XCTAssertEqual(Double(9.3).floor, Double(9.0)) + } + + func testRadiansToDegrees() { + XCTAssertEqual(Float.pi.radiansToDegrees, Float(180)) + XCTAssertEqual(Double.pi.radiansToDegrees, Double(180)) + } + + func testRandom() { + XCTAssertGreaterThan(Float.random(between: 1, and: 5), 0) + XCTAssertLessThan(Float.random(between: 1, and: 5), 6) + + XCTAssertGreaterThan(Float(randomBetween: 1, and: 5), 0) + XCTAssertLessThan(Float(randomBetween: 1, and: 5), 6) + + XCTAssertGreaterThan(Float.random(inRange: 1...5), 0) + XCTAssertLessThan(Float.random(inRange: 1...5), 6) + + XCTAssertGreaterThan(Float(randomInRange: 1...5), 0) + XCTAssertLessThan(Float(randomInRange: 1...5), 6) + + XCTAssertGreaterThan(Double.random(between: 1, and: 5), 0) + XCTAssertLessThan(Double.random(between: 1, and: 5), 6) + + XCTAssertGreaterThan(Double(randomBetween: 1, and: 5), 0) + XCTAssertLessThan(Double(randomBetween: 1, and: 5), 6) + + XCTAssertGreaterThan(Double.random(inRange: 1...5), 0) + XCTAssertLessThan(Double.random(inRange: 1...5), 6) + + XCTAssertGreaterThan(Double(randomInRange: 1...5), 0) + XCTAssertLessThan(Double(randomInRange: 1...5), 6) + } + + func testOperators() { + XCTAssert((Float(5.0) ± Float(2.0)) == (Float(3.0), Float(7.0)) || (Float(5.0) ± Float(2.0)) == (Float(7.0), Float(3.0))) + XCTAssert((±Float(2.0)) == (Float(2.0), Float(-2.0)) || (±Float(2.0)) == (Float(-2.0), Float(2.0))) + + XCTAssert((Double(5.0) ± Double(2.0)) == (Double(3.0), Double(7.0)) || (Double(5.0) ± Double(2.0)) == (Double(7.0), Double(3.0))) + XCTAssert((±Double(2.0)) == (Double(2.0), Double(-2.0)) || (±Double(2.0)) == (Double(-2.0), Double(2.0))) + } + +} diff --git a/Tests/SwiftStdlibTests/IntExtensionsTests.swift b/Tests/SwiftStdlibTests/IntExtensionsTests.swift index 58fb865d5..3dbd1781e 100644 --- a/Tests/SwiftStdlibTests/IntExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/IntExtensionsTests.swift @@ -10,173 +10,119 @@ import XCTest @testable import SwifterSwift final class IntExtensionsTests: XCTestCase { - - func testAbs() { - XCTAssertEqual((-9).abs, 9) - } - - func testCountableRange() { - XCTAssertEqual(10.countableRange, 0..<10) - } - - func testIsPositive() { - XCTAssert(1.isPositive) - XCTAssertFalse(0.isPositive) - XCTAssertFalse((-1).isPositive) - } - - func testIsNegative() { - XCTAssert((-1).isNegative) - XCTAssertFalse(0.isNegative) - XCTAssertFalse(1.isNegative) - } - - func testDouble() { - XCTAssertEqual((-1).double, Double(-1)) - XCTAssertEqual(2.double, Double(2)) - } - - func testFloat() { - XCTAssertEqual((-1).float, Float(-1)) - XCTAssertEqual(2.float, Float(2)) - } - - func testString() { - XCTAssertEqual(2.string, "2") - } - - func testDegreesToRadians() { - XCTAssertEqual(180.degreesToRadians, Double.pi) - } - - func testDigits() { - let x = -123 - XCTAssertEqual(x.digits, [1, 2, 3]) + + func testCountableRange() { + XCTAssertEqual(10.countableRange, 0..<10) + } + + func testDegreesToRadians() { + XCTAssertEqual(180.degreesToRadians, Double.pi) + } + + func testRadiansToDegrees() { + XCTAssertEqual(Int(3.radiansToDegrees), 171) + } + + func testUInt() { + XCTAssertEqual(Int(10).uInt, UInt(10)) + } + + func testDouble() { + XCTAssertEqual((-1).double, Double(-1)) + XCTAssertEqual(2.double, Double(2)) + } + + func testFloat() { + XCTAssertEqual((-1).float, Float(-1)) + XCTAssertEqual(2.float, Float(2)) + } + + func testCGFloat() { + XCTAssertEqual(1.cgFloat, CGFloat(1)) + } + + func testKFormatted() { + XCTAssertEqual(10.kFormatted, "0k") + XCTAssertEqual((-10).kFormatted, "0k") + + XCTAssertEqual(0.kFormatted, "0k") + + XCTAssertEqual(1000.kFormatted, "1k") + XCTAssertEqual((-1000).kFormatted, "-1k") + + XCTAssertEqual(100000.kFormatted, "100k") + XCTAssertEqual((-100000).kFormatted, "-100k") + + XCTAssertEqual(1000000.kFormatted, "10kk") + } + + func testDigits() { + let number = -123 + XCTAssertEqual(number.digits, [1, 2, 3]) XCTAssertEqual(123.digits, [1, 2, 3]) XCTAssertEqual(0.digits, [0]) - } - - func testDigitsCount() { - let x = -123 - XCTAssertEqual(x.digitsCount, 3) - XCTAssertEqual(180.digitsCount, 3) + } + + func testDigitsCount() { + let number = -123 + XCTAssertEqual(number.digitsCount, 3) + XCTAssertEqual(180.digitsCount, 3) XCTAssertEqual(0.digitsCount, 1) XCTAssertEqual(1.digitsCount, 1) - } - - func testGcd() { - XCTAssertEqual(8.gcd(of: 20), 4) - } - - func testCGFloat() { - XCTAssertEqual(1.cgFloat, CGFloat(1)) - } - - func testIsEven() { - XCTAssert(2.isEven) - XCTAssertFalse(3.isEven) - } - - func testIsOdd() { - XCTAssert(3.isOdd) - XCTAssertFalse(2.isOdd) - } - - func testLcm() { - XCTAssertEqual(4.lcm(of: 3), 12) - } - - func testRadiansToDegrees() { - XCTAssertEqual(Int(3.radiansToDegrees), 171) - } - - func testRandomBetween() { - XCTAssertGreaterThan(Int.random(between: 1, and: 5), 0) - XCTAssertLessThan(Int.random(between: 1, and: 5), 6) - - XCTAssertGreaterThan(Int(randomBetween: 1, and: 5), 0) - XCTAssertLessThan(Int(randomBetween: 1, and: 5), 6) - - XCTAssertGreaterThan(Int.random(inRange: 1...5), 0) - XCTAssertLessThan(Int.random(inRange: 1...5), 6) - - XCTAssertGreaterThan(Int(randomInRange: 1...5), 0) - XCTAssertLessThan(Int(randomInRange: 1...5), 6) - } - - func testIsPrime() { - // Prime number - XCTAssertTrue(2.isPrime()) - XCTAssertTrue(3.isPrime()) - XCTAssertTrue(7.isPrime()) - XCTAssertTrue(19.isPrime()) - XCTAssertTrue(577.isPrime()) - XCTAssertTrue(1999.isPrime()) - - // Composite number - XCTAssertFalse(4.isPrime()) - XCTAssertFalse(21.isPrime()) - XCTAssertFalse(81.isPrime()) - XCTAssertFalse(121.isPrime()) - XCTAssertFalse(9409.isPrime()) - - // Others - XCTAssertFalse((-1).isPrime()) - XCTAssertFalse(0.isPrime()) - XCTAssertFalse(1.isPrime()) - } - - func testRomanNumeral() { - XCTAssertEqual(10.romanNumeral(), "X") - XCTAssertNil((-1).romanNumeral()) - } - - func testRoundToNearestN() { - XCTAssert(12.roundToNearest(5) == 10) - XCTAssert(63.roundToNearest(25) == 75) - XCTAssert(42.roundToNearest(0) == 42) - } - - func testTimeString() { - XCTAssertEqual((-1).timeString, "0 sec") - XCTAssertEqual(45.timeString, "45 sec") - XCTAssertEqual(120.timeString, "2 min") - XCTAssertEqual(3600.timeString, "1h") - XCTAssertEqual(3660.timeString, "1h 1m") - } - - func testUInt() { - XCTAssertEqual(Int(10).uInt, UInt(10)) - } - - func testKFormatted() { - XCTAssertEqual(10.kFormatted, "0k") - XCTAssertEqual((-10).kFormatted, "0k") - - XCTAssertEqual(0.kFormatted, "0k") - - XCTAssertEqual(1000.kFormatted, "1k") - XCTAssertEqual((-1000).kFormatted, "-1k") - - XCTAssertEqual(100000.kFormatted, "100k") - XCTAssertEqual((-100000).kFormatted, "-100k") - - XCTAssertEqual(1000000.kFormatted, "10kk") - } - - func testAsLocaleCurrency() { - let num = 10 - if let symbol = Locale.current.currencySymbol { - XCTAssert(num.asLocaleCurrency.contains(symbol)) - } - XCTAssert(num.asLocaleCurrency.contains("\(num)")) - } - - func testOperators() { - XCTAssertEqual(5 ** 2, 25) - XCTAssert((5 ± 2) == (3, 7) || (5 ± 2) == (7, 3)) - XCTAssert((±2) == (2, -2) || (±2) == (-2, 2)) - XCTAssertEqual(√25, 5.0) - } - + } + + func testRandom() { + XCTAssertGreaterThan(Int.random(between: 1, and: 5), 0) + XCTAssertLessThan(Int.random(between: 1, and: 5), 6) + + XCTAssertGreaterThan(Int(randomBetween: 1, and: 5), 0) + XCTAssertLessThan(Int(randomBetween: 1, and: 5), 6) + + XCTAssertGreaterThan(Int.random(inRange: 1...5), 0) + XCTAssertLessThan(Int.random(inRange: 1...5), 6) + + XCTAssertGreaterThan(Int(randomInRange: 1...5), 0) + XCTAssertLessThan(Int(randomInRange: 1...5), 6) + } + + func testIsPrime() { + // Prime number + XCTAssertTrue(2.isPrime()) + XCTAssertTrue(3.isPrime()) + XCTAssertTrue(7.isPrime()) + XCTAssertTrue(19.isPrime()) + XCTAssertTrue(577.isPrime()) + XCTAssertTrue(1999.isPrime()) + + // Composite number + XCTAssertFalse(4.isPrime()) + XCTAssertFalse(21.isPrime()) + XCTAssertFalse(81.isPrime()) + XCTAssertFalse(121.isPrime()) + XCTAssertFalse(9409.isPrime()) + + // Others + XCTAssertFalse((-1).isPrime()) + XCTAssertFalse(0.isPrime()) + XCTAssertFalse(1.isPrime()) + } + + func testRomanNumeral() { + XCTAssertEqual(10.romanNumeral(), "X") + XCTAssertNil((-1).romanNumeral()) + } + + func testRoundToNearest() { + XCTAssert(12.roundToNearest(5) == 10) + XCTAssert(63.roundToNearest(25) == 75) + XCTAssert(42.roundToNearest(0) == 42) + } + + func testOperators() { + XCTAssertEqual(5 ** 2, 25) + XCTAssert((5 ± 2) == (3, 7) || (5 ± 2) == (7, 3)) + XCTAssert((±2) == (2, -2) || (±2) == (-2, 2)) + XCTAssertEqual(√25, 5.0) + } + } diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index 0ce10e77f..cad9ddc4f 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -9,25 +9,28 @@ import XCTest @testable import SwifterSwift +private enum OptionalTestError: Error { + case optionalIsNil +} + final class OptionalExtensionsTests: XCTestCase { - + func testUnwrappedOrDefault() { var str: String? = nil - XCTAssertEqual(str.unwrapped(or: "swift"), "swift") - + str = "swifterswift" XCTAssertEqual(str.unwrapped(or: "swift"), "swifterswift") } - - func testUnwrappedOrError() { - let null: String? = nil - try XCTAssertThrowsError(null.unwrapped(or: OptionalTestError.optionalIsNil)) - - let some: String? = "I exist" - try XCTAssertNoThrow(some.unwrapped(or: OptionalTestError.optionalIsNil)) - } - + + func testUnwrappedOrError() { + let null: String? = nil + try XCTAssertThrowsError(null.unwrapped(or: OptionalTestError.optionalIsNil)) + + let some: String? = "I exist" + try XCTAssertNoThrow(some.unwrapped(or: OptionalTestError.optionalIsNil)) + } + func testRunBlock() { var str: String? = nil var didRun = false @@ -36,31 +39,28 @@ final class OptionalExtensionsTests: XCTestCase { } XCTAssertFalse(didRun) str = "swift" - str.run { s in + str.run { item in didRun = true XCTAssert(didRun) - XCTAssertEqual(s, "swift") + XCTAssertEqual(item, "swift") } } - - func testOptionalAssignment() { - let parameter1: String? = nil - let parameter2: String? = "foo" - - let key1: String = "key1" - let key2: String = "key2" - - var parameters = [String: String]() - - parameters[key1] ??= parameter1 - parameters[key2] ??= parameter2 - - XCTAssert(parameters[key1] == nil) - XCTAssertFalse(parameters[key1] != parameter1) - XCTAssert(parameters[key2] == parameter2) - } -} -enum OptionalTestError: Error { - case optionalIsNil + func testOptionalAssignment() { + let parameter1: String? = nil + let parameter2: String? = "foo" + + let key1: String = "key1" + let key2: String = "key2" + + var parameters = [String: String]() + + parameters[key1] ??= parameter1 + parameters[key2] ??= parameter2 + + XCTAssert(parameters[key1] == nil) + XCTAssertFalse(parameters[key1] != parameter1) + XCTAssert(parameters[key2] == parameter2) + } + } diff --git a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift new file mode 100644 index 000000000..9248b0c38 --- /dev/null +++ b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift @@ -0,0 +1,28 @@ +// +// SequenceExtensionsTests.swift +// SwifterSwift +// +// Created by Anton Novoselov on 04/04/2018. +// Copyright © 2018 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +final class SequenceExtensionsTests: XCTestCase { + + func testAllMatch() { + let collection = [2, 4, 6, 8, 10, 12] + XCTAssert(collection.all { $0 % 2 == 0 }) + } + + func testAnyMatch() { + let collection = [3, 5, 8, 9, 11, 13] + XCTAssert(collection.any { $0 % 2 == 0 }) + } + + func testNoneMatch() { + let collection = [3, 5, 7, 9, 11, 13] + XCTAssert(collection.none { $0 % 2 == 0 }) + } +} diff --git a/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift new file mode 100644 index 000000000..2effdc2ab --- /dev/null +++ b/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift @@ -0,0 +1,60 @@ +// +// SignedIntegerExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 5.04.2018. +// Copyright © 2018 ___ORGANIZATIONNAME___ +// + +import XCTest +@testable import SwifterSwift + +final class SignedIntegerExtensionsTests: XCTestCase { + + func testAbs() { + XCTAssertEqual((-9).abs, 9) + } + + func testIsPositive() { + XCTAssert(1.isPositive) + XCTAssertFalse(0.isPositive) + XCTAssertFalse((-1).isPositive) + } + + func testIsNegative() { + XCTAssert((-1).isNegative) + XCTAssertFalse(0.isNegative) + XCTAssertFalse(1.isNegative) + } + + func testIsEven() { + XCTAssert(2.isEven) + XCTAssertFalse(3.isEven) + } + + func testIsOdd() { + XCTAssert(3.isOdd) + XCTAssertFalse(2.isOdd) + } + + func testTimeString() { + XCTAssertEqual((-1).timeString, "0 sec") + XCTAssertEqual(45.timeString, "45 sec") + XCTAssertEqual(120.timeString, "2 min") + XCTAssertEqual(3600.timeString, "1h") + XCTAssertEqual(3660.timeString, "1h 1m") + } + + func testGcd() { + XCTAssertEqual(8.gcd(of: 20), 4) + } + + func testLcm() { + XCTAssertEqual(4.lcm(of: 3), 12) + } + + func testString() { + XCTAssertEqual(2.string, "2") + } + +} diff --git a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift index 5df5426c6..31b28c290 100644 --- a/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SignedNumericExtensionsTests.swift @@ -10,15 +10,34 @@ import XCTest @testable import SwifterSwift class SignedNumericExtensionsTests: XCTestCase { - - func testString() { - let number: Double = -1.2 - XCTAssertEqual(number.string, "-1.2") - } - - func testAsLocaleCurrency() { - let number: Double = 3.2 - XCTAssertEqual(number.asLocaleCurrency, "$3.20") - } - + + func testString() { + let number1: Double = -1.2 + XCTAssertEqual(number1.string, "-1.2") + + let number2: Float = 2.3 + XCTAssertEqual(number2.string, "2.3") + } + + func testAsLocaleCurrency() { + let number1: Double = 3.2 + XCTAssertEqual(number1.asLocaleCurrency, "$3.20") + + let number2 = Double(10.23) + if let symbol = Locale.current.currencySymbol { + XCTAssertNotNil(number2.asLocaleCurrency!) + XCTAssert(number2.asLocaleCurrency!.contains(symbol)) + } + XCTAssertNotNil(number2.asLocaleCurrency!) + XCTAssert(number2.asLocaleCurrency!.contains("\(number2)")) + + let number3 = 10 + if let symbol = Locale.current.currencySymbol { + XCTAssertNotNil(number3.asLocaleCurrency) + XCTAssert(number3.asLocaleCurrency!.contains(symbol)) + } + XCTAssertNotNil(number3.asLocaleCurrency) + XCTAssert(number3.asLocaleCurrency!.contains("\(number3)")) + } + } diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 9a3e28e04..e08a7b5a1 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -9,141 +9,120 @@ import XCTest @testable import SwifterSwift +// swiftlint:disable type_body_length final class StringExtensionsTests: XCTestCase { - + + var helloWorld = "Hello World!" + override func setUp() { super.setUp() NSTimeZone.default = NSTimeZone.system } - + func testBase64Decoded() { - XCTAssertEqual("SGVsbG8gV29ybGQh".base64Decoded, "Hello World!") - XCTAssertNil("hello".base64Decoded) + XCTAssertEqual("SGVsbG8gV29ybGQh".base64Decoded, helloWorld) + XCTAssertNil(helloWorld.base64Decoded) } - + func testBase64Encoded() { - XCTAssertEqual("Hello World!".base64Encoded, "SGVsbG8gV29ybGQh") + XCTAssertEqual(helloWorld.base64Encoded, "SGVsbG8gV29ybGQh") } - + func testCharactersArray() { let str = "Swift" let chars = [Character("S"), Character("w"), Character("i"), Character("f"), Character("t")] XCTAssertEqual(str.charactersArray, chars) } - + func testCamelCased() { XCTAssertEqual("Hello test".camelCased, "helloTest") XCTAssertEqual("Hellotest".camelCased, "hellotest") } - - func testCamelize() { - var str = "Hello test" - str.camelize() - XCTAssertEqual(str, "helloTest") - } - - func testContain() { - XCTAssert("Hello Tests".contains("Hello", caseSensitive: true)) - XCTAssert("Hello Tests".contains("hello", caseSensitive: false)) - } - - func testContainEmoji() { - XCTAssert("Hello 😂".containEmoji) - XCTAssertFalse("Hello ;)".containEmoji) - } - - func testCount() { - XCTAssertEqual("Hello This Tests".count(of: "T"), 2) - XCTAssertEqual("Hello This Tests".count(of: "t"), 1) - XCTAssertEqual("Hello This Tests".count(of: "T", caseSensitive: false), 3) - XCTAssertEqual("Hello This Tests".count(of: "t", caseSensitive: false), 3) - - } - - func testEnd() { - XCTAssert("Hello Test".ends(with: "test", caseSensitive: false)) - XCTAssert("Hello Tests".ends(with: "sts")) - } - - func testFirstCharacter() { - XCTAssertNil("".firstCharacterAsString) - XCTAssertNotNil("Hello".firstCharacterAsString) - XCTAssertEqual("Hello".firstCharacterAsString, "H") - } - func testHasLetters() { - XCTAssert("hsj 1 wq3".hasLetters) - XCTAssertFalse("123".hasLetters) - XCTAssert("Hello test".hasLetters) - } - - func testHasNumbers() { - XCTAssert("hsj 1 wq3".hasNumbers) - XCTAssert("123".hasNumbers) - XCTAssertFalse("Hello test".hasNumbers) - } - - func testIsAlphabetic() { - XCTAssert("abc".isAlphabetic) - XCTAssertFalse("123abc".isAlphabetic) - XCTAssertFalse("123".isAlphabetic) - } - - func testIsAlphaNumeric() { - XCTAssert("123abc".isAlphaNumeric) - XCTAssertFalse("123".isAlphaNumeric) - XCTAssertFalse("abc".isAlphaNumeric) - } - - func testIsEmail() { - XCTAssert("omaralbeik@gmail.com".isEmail) - XCTAssertFalse("omaralbeik@gmailcom".isEmail) - XCTAssertFalse("omaralbeikgmail.com".isEmail) - } - - func testIsValidUrl() { - XCTAssert("https://google.com".isValidUrl) - XCTAssert("http://google.com".isValidUrl) - XCTAssert("ftp://google.com".isValidUrl) - } - - func testIsValidSchemedUrl() { - XCTAssertFalse("Hello world!".isValidSchemedUrl) - XCTAssert("https://google.com".isValidSchemedUrl) - XCTAssert("ftp://google.com".isValidSchemedUrl) - XCTAssertFalse("google.com".isValidSchemedUrl) - } - - func testIsValidHttpsUrl() { - XCTAssertFalse("Hello world!".isValidHttpsUrl) - XCTAssert("https://google.com".isValidHttpsUrl) - XCTAssertFalse("http://google.com".isValidHttpsUrl) - XCTAssertFalse("google.com".isValidHttpsUrl) - } - - func testIsValidHttpUrl() { - XCTAssertFalse("Hello world!".isValidHttpUrl) - XCTAssert("http://google.com".isValidHttpUrl) - XCTAssertFalse("google.com".isValidHttpUrl) - } - + func testContainEmoji() { + XCTAssert("Hello 😂".containEmoji) + XCTAssertFalse("Hello ;)".containEmoji) + } + + func testFirstCharacter() { + XCTAssertNil("".firstCharacterAsString) + XCTAssertNotNil("Hello".firstCharacterAsString) + XCTAssertEqual("Hello".firstCharacterAsString, "H") + } + + func testHasLetters() { + XCTAssert("hsj 1 wq3".hasLetters) + XCTAssertFalse("123".hasLetters) + XCTAssert("Hello test".hasLetters) + } + + func testHasNumbers() { + XCTAssert("hsj 1 wq3".hasNumbers) + XCTAssert("123".hasNumbers) + XCTAssertFalse("Hello test".hasNumbers) + } + + func testIsAlphabetic() { + XCTAssert("abc".isAlphabetic) + XCTAssertFalse("123abc".isAlphabetic) + XCTAssertFalse("123".isAlphabetic) + } + + func testIsAlphaNumeric() { + XCTAssert("123abc".isAlphaNumeric) + XCTAssertFalse("123".isAlphaNumeric) + XCTAssertFalse("abc".isAlphaNumeric) + } + + func testIsEmail() { + XCTAssert("john@appleseed.com".isEmail) + XCTAssertFalse("john@appleseedcom".isEmail) + XCTAssertFalse("johnappleseed.com".isEmail) + } + + func testIsValidUrl() { + XCTAssert("https://google.com".isValidUrl) + XCTAssert("http://google.com".isValidUrl) + XCTAssert("ftp://google.com".isValidUrl) + } + + func testIsValidSchemedUrl() { + XCTAssertFalse("Hello world!".isValidSchemedUrl) + XCTAssert("https://google.com".isValidSchemedUrl) + XCTAssert("ftp://google.com".isValidSchemedUrl) + XCTAssertFalse("google.com".isValidSchemedUrl) + } + + func testIsValidHttpsUrl() { + XCTAssertFalse("Hello world!".isValidHttpsUrl) + XCTAssert("https://google.com".isValidHttpsUrl) + XCTAssertFalse("http://google.com".isValidHttpsUrl) + XCTAssertFalse("google.com".isValidHttpsUrl) + } + + func testIsValidHttpUrl() { + XCTAssertFalse("Hello world!".isValidHttpUrl) + XCTAssert("http://google.com".isValidHttpUrl) + XCTAssertFalse("google.com".isValidHttpUrl) + } + func testIsValidFileURL() { XCTAssertFalse("Hello world!".isValidFileUrl) XCTAssert("file://var/folder/file.txt".isValidFileUrl) XCTAssertFalse("google.com".isValidFileUrl) } - - func testIsNumeric() { - XCTAssert("123".isNumeric) + + func testIsNumeric() { + XCTAssert("123".isNumeric) XCTAssert("123.4".isNumeric) XCTAssert("1.25e2".isNumeric) XCTAssert("1.25e-2".isNumeric) XCTAssert("000123.456".isNumeric) - XCTAssertFalse("123abc".isNumeric) - XCTAssertFalse("abc".isNumeric) + XCTAssertFalse("123abc".isNumeric) + XCTAssertFalse("abc".isNumeric) XCTAssertFalse("123.@.".isNumeric) - } - + } + func testIsDigits() { XCTAssert("123".isDigits) XCTAssert("987654321".isDigits) @@ -152,472 +131,344 @@ final class StringExtensionsTests: XCTestCase { XCTAssertFalse("123abc".isDigits) } - func testHasUniqueCharacters() { - XCTAssert("swift".hasUniqueCharacters()) - XCTAssertFalse("language".hasUniqueCharacters()) - XCTAssertFalse("".hasUniqueCharacters()) + func testLastCharacter() { + XCTAssertNotNil("Hello".lastCharacterAsString) + XCTAssertEqual("Hello".lastCharacterAsString, "o") + XCTAssertNil("".lastCharacterAsString) } - - func testLastCharacter() { - XCTAssertNotNil("Hello".lastCharacterAsString) - XCTAssertEqual("Hello".lastCharacterAsString, "o") - XCTAssertNil("".lastCharacterAsString) - } - - func testLatinize() { - var str = "Hëllô Teśt" - str.latinize() - XCTAssertEqual(str, "Hello Test") - } - - func testLatinized() { - XCTAssertEqual("Hëllô Teśt".latinized, "Hello Test") - } - - func testLines() { - XCTAssertEqual("Hello\ntest".lines(), ["Hello", "test"]) - } - - func testMostCommonCharacter() { - let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter - XCTAssertEqual(mostCommonCharacter(), "e") - XCTAssertNil("".mostCommonCharacter()) - } - - func testRandom() { - let str1 = String.random(ofLength: 10) - XCTAssertEqual(str1.count, 10) - - let str2 = String.random(ofLength: 10) - XCTAssertEqual(str2.count, 10) - - XCTAssertNotEqual(str1, str2) - - XCTAssertEqual(String.random(ofLength: 0), "") - } - - func testReverse() { - var str = "Hello" - str.reverse() - XCTAssertEqual(str, "olleH") - } - - func testSlice() { - XCTAssertEqual("12345678".slicing(from: 2, length: 3), "345") - XCTAssertEqual("12345678".slicing(from: 2, length: 0), "") - XCTAssertNil("12345678".slicing(from: 12, length: 0)) - XCTAssertEqual("12345678".slicing(from: 2, length: 100), "345678") - - var str = "12345678" - str.slice(from: 2, length: 3) - XCTAssertEqual(str, "345") - - str = "12345678" - str.slice(from: 2, length: 0) - print(str) - XCTAssertEqual(str, "") - - str = "12345678" - str.slice(from: 12, length: 0) - XCTAssertEqual(str, "12345678") - - str = "12345678" - str.slice(from: 2, length: 100) - XCTAssertEqual(str, "345678") - - str = "12345678" - str.slice(from: 2, to: 5) - XCTAssertEqual(str, "345") - - str = "12345678" - str.slice(from: 2, to: 1) - XCTAssertEqual(str, "12345678") - - str = "12345678" - str.slice(at: 2) - XCTAssertEqual(str, "345678") - } - - func testStart() { - XCTAssert("Hello Test".starts(with: "hello", caseSensitive: false)) - XCTAssert("Hello Tests".starts(with: "He")) - } - - func testDateWithFormat() { - let dateString = "2012-12-08 17:00:00.0" - let date = dateString.date(withFormat: "yyyy-dd-MM HH:mm:ss.S") - XCTAssertNotNil(date) - XCTAssertNil(dateString.date(withFormat: "Hello world!")) - } - - func testOperators() { - let sa = "sa" - - XCTAssertEqual(sa * 5, "sasasasasa") - XCTAssertEqual(5 * sa, "sasasasasa") - - XCTAssertEqual(sa * 0, "") - XCTAssertEqual(0 * sa, "") - - XCTAssertEqual(sa * -5, "") - XCTAssertEqual(-5 * sa, "") - } - - func testToBool() { - XCTAssertNotNil("1".bool) - XCTAssert("1".bool!) - - XCTAssertNotNil("false".bool) - XCTAssertFalse("false".bool!) - XCTAssertNil("8s".bool) - } - - func testDate() { - let dateFromStr = "2015-06-01".date - XCTAssertNotNil(dateFromStr) - XCTAssertEqual(dateFromStr?.year, 2015) - XCTAssertEqual(dateFromStr?.month, 6) - XCTAssertEqual(dateFromStr?.day, 1) - } - - func testDateTime() { - let dateFromStr = "2015-06-01 14:23:09".dateTime - XCTAssertNotNil(dateFromStr) - XCTAssertEqual(dateFromStr?.year, 2015) - XCTAssertEqual(dateFromStr?.month, 6) - XCTAssertEqual(dateFromStr?.day, 1) - XCTAssertEqual(dateFromStr?.hour, 14) - XCTAssertEqual(dateFromStr?.minute, 23) - XCTAssertEqual(dateFromStr?.second, 9) - } - - func testDouble() { - XCTAssertNotNil("8".double()) - XCTAssertEqual("8".double(), 8) - - XCTAssertNotNil("8.23".double(locale: Locale(identifier: "en_US_POSIX"))) - XCTAssertEqual("8.23".double(locale: Locale(identifier: "en_US_POSIX")), 8.23) - - XCTAssertNil("8s".double()) - } - - func testFloat() { - XCTAssertNotNil("8".float()) - XCTAssertEqual("8".float(), 8) - XCTAssertNotNil("8.23".float(locale: Locale(identifier: "en_US_POSIX"))) - XCTAssertEqual("8.23".float(locale: Locale(identifier: "en_US_POSIX")), Float(8.23)) - - XCTAssertNil("8s".float()) - } - - func testCgFloat() { - XCTAssertNotNil("8".cgFloat()) - XCTAssertEqual("8".cgFloat(), 8) - - XCTAssertNotNil("8.23".cgFloat(locale: Locale(identifier: "en_US_POSIX"))) - XCTAssertEqual("8.23".cgFloat(locale: Locale(identifier: "en_US_POSIX")), CGFloat(8.23)) - - XCTAssertNil("8s".cgFloat()) - } - - func testInt() { - XCTAssertNotNil("8".int) - XCTAssertEqual("8".int, 8) - - XCTAssertNil("8s".int) - } - - func testLoremIpsum() { - // https://www.lipsum.com/ - let completeLoremIpsum = """ - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - """ - - XCTAssertEqual(String.loremIpsum(), completeLoremIpsum) - XCTAssertEqual(String.loremIpsum(ofLength: 0), "") - XCTAssertEqual(String.loremIpsum(ofLength: 26), "Lorem ipsum dolor sit amet") - } - - func testUrl() { - XCTAssertNil("hello world".url) - - let google = "https://www.google.com" - XCTAssertEqual(google.url, URL(string: google)) - } - - func testTrim() { - var str = "\n Hello \n " - str.trim() - XCTAssertEqual(str, "Hello") - } - - func testTrimmed() { - XCTAssertEqual("\n Hello \n ".trimmed, "Hello") - } - - func testTruncate() { - var str = "This is a very long sentence" - str.truncate(toLength: 14) - XCTAssertEqual(str, "This is a very...") - - str = "This is a very long sentence" - str.truncate(toLength: 14, trailing: nil) - XCTAssertEqual(str, "This is a very") - - str = "This is a short sentence" - str.truncate(toLength: 100) - XCTAssertEqual(str, "This is a short sentence") - - str.truncate(toLength: -1) - XCTAssertEqual(str, "This is a short sentence") - } - - func testTruncated() { - XCTAssertEqual("This is a very long sentence".truncated(toLength: 14), "This is a very...") - - XCTAssertEqual("This is a very long sentence".truncated(toLength: 14, trailing: nil), "This is a very") - XCTAssertEqual("This is a short sentence".truncated(toLength: 100), "This is a short sentence") - } - - func testUnicodeArray() { - XCTAssertEqual("Hello".unicodeArray(), [72, 101, 108, 108, 111]) - } - - func testUrlDecode() { - var url = "it's%20easy%20to%20encode%20strings" - url.urlDecode() - XCTAssertEqual(url, "it's easy to encode strings") - } - - func testUrlDecoded() { - XCTAssertEqual("it's%20easy%20to%20encode%20strings".urlDecoded, "it's easy to encode strings") - XCTAssertEqual("%%".urlDecoded, "%%") - } - - func testUrlEncode() { - var url = "it's easy to encode strings" - url.urlEncode() - XCTAssertEqual(url, "it's%20easy%20to%20encode%20strings") - } - - func testUrlEncoded() { - XCTAssertEqual("it's easy to encode strings".urlEncoded, "it's%20easy%20to%20encode%20strings") - } - - func testMatches() { - XCTAssertTrue("123".matches(pattern: "\\d{3}")) - XCTAssertFalse("dasda".matches(pattern: "\\d{3}")) - XCTAssertFalse("notanemail.com".matches(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}")) - XCTAssertTrue("email@mail.com".matches(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}")) + func testLatinized() { + XCTAssertEqual("Hëllô Teśt".latinized, "Hello Test") + } + + func testBool() { + XCTAssertNotNil("1".bool) + XCTAssert("1".bool!) + + XCTAssertNotNil("false".bool) + XCTAssertFalse("false".bool!) + XCTAssertNil("8s".bool) + } + + func testDate() { + let dateFromStr = "2015-06-01".date + XCTAssertNotNil(dateFromStr) + XCTAssertEqual(dateFromStr?.year, 2015) + XCTAssertEqual(dateFromStr?.month, 6) + XCTAssertEqual(dateFromStr?.day, 1) + } + + func testDateTime() { + let dateFromStr = "2015-06-01 14:23:09".dateTime + XCTAssertNotNil(dateFromStr) + XCTAssertEqual(dateFromStr?.year, 2015) + XCTAssertEqual(dateFromStr?.month, 6) + XCTAssertEqual(dateFromStr?.day, 1) + XCTAssertEqual(dateFromStr?.hour, 14) + XCTAssertEqual(dateFromStr?.minute, 23) + XCTAssertEqual(dateFromStr?.second, 9) + } + + func testInt() { + XCTAssertNotNil("8".int) + XCTAssertEqual("8".int, 8) + + XCTAssertNil("8s".int) + } + + func testLoremIpsum() { + // https://www.lipsum.com/ + let completeLoremIpsum = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + """ + + XCTAssertEqual(String.loremIpsum(), completeLoremIpsum) + XCTAssertEqual(String.loremIpsum(ofLength: 0), "") + XCTAssertEqual(String.loremIpsum(ofLength: 26), "Lorem ipsum dolor sit amet") + } + + func testUrl() { + XCTAssertNil("hello world".url) + + let google = "https://www.google.com" + XCTAssertEqual(google.url, URL(string: google)) + } + + func testTrimmed() { + XCTAssertEqual("\n Hello \n ".trimmed, "Hello") + } + + func testUrlDecoded() { + XCTAssertEqual("it's%20easy%20to%20encode%20strings".urlDecoded, "it's easy to encode strings") + XCTAssertEqual("%%".urlDecoded, "%%") + } + + func testUrlEncoded() { + XCTAssertEqual("it's easy to encode strings".urlEncoded, "it's%20easy%20to%20encode%20strings") + } + + func testWithoutSpacesAndNewLines() { + XCTAssertEqual("Hello \n Test".withoutSpacesAndNewLines, "HelloTest") + } + + func testIsWhiteSpaces() { + var str = "test string" + XCTAssertEqual(str.isWhitespace, false) + + str = " " + XCTAssertEqual(str.isWhitespace, true) + + str = " \n \n " + XCTAssertEqual(str.isWhitespace, true) + } + + func testFloat() { + XCTAssertNotNil("8".float()) + XCTAssertEqual("8".float(), 8) + + XCTAssertNotNil("8.23".float(locale: Locale(identifier: "en_US_POSIX"))) + XCTAssertEqual("8.23".float(locale: Locale(identifier: "en_US_POSIX")), Float(8.23)) + + XCTAssertNil("8s".float()) + } + + func testDouble() { + XCTAssertNotNil("8".double()) + XCTAssertEqual("8".double(), 8) + + XCTAssertNotNil("8.23".double(locale: Locale(identifier: "en_US_POSIX"))) + XCTAssertEqual("8.23".double(locale: Locale(identifier: "en_US_POSIX")), 8.23) + + XCTAssertNil("8s".double()) + } + + func testCgFloat() { + XCTAssertNotNil("8".cgFloat()) + XCTAssertEqual("8".cgFloat(), 8) + + XCTAssertNotNil("8.23".cgFloat(locale: Locale(identifier: "en_US_POSIX"))) + XCTAssertEqual("8.23".cgFloat(locale: Locale(identifier: "en_US_POSIX")), CGFloat(8.23)) + + XCTAssertNil("8s".cgFloat()) + } + + func testLines() { + XCTAssertEqual("Hello\ntest".lines(), ["Hello", "test"]) + } + + func testLocalized() { + XCTAssertEqual(helloWorld.localized(), NSLocalizedString(helloWorld, comment: "")) + XCTAssertEqual(helloWorld.localized(comment: "comment"), NSLocalizedString(helloWorld, comment: "comment")) + } + + func testMostCommonCharacter() { + let mostCommonCharacter = "This is a test, since e is appearing every where e should be the common character".mostCommonCharacter + XCTAssertEqual(mostCommonCharacter(), "e") + XCTAssertNil("".mostCommonCharacter()) + } + + func testUnicodeArray() { + XCTAssertEqual("Hello".unicodeArray(), [72, 101, 108, 108, 111]) + } + + func testWords() { + XCTAssertEqual("Swift is amazing".words(), ["Swift", "is", "amazing"]) + } + + func testWordsCount() { + XCTAssertEqual("Swift is amazing".wordCount(), 3) } - - func testWithoutSpacesAndNewLines() { - XCTAssertEqual("Hello \n Test".withoutSpacesAndNewLines, "HelloTest") - } - - func testSubscript() { - let str = "Hello world!" - XCTAssertEqual(str[safe: 1], "e") - XCTAssertNil(str[safe: 18]) - - XCTAssertEqual(str[safe: 1..<5], "ello") - XCTAssertNil(str[safe: 10..<18]) - XCTAssertNil(""[safe: 1..<2]) - - XCTAssertEqual(str[safe: 0...4], "Hello") - XCTAssertNil(str[safe: 10...18]) - XCTAssertNil(""[safe: 1...2]) - } - - func testCopyToPasteboard() { - let str = "Hello world!" - #if os(iOS) - str.copyToPasteboard() - let strFromPasteboard = UIPasteboard.general.string - XCTAssertEqual(strFromPasteboard, str) - - #elseif os(macOS) - str.copyToPasteboard() - let strFromPasteboard = NSPasteboard.general.string(forType: .string) - XCTAssertEqual(strFromPasteboard, str) - #endif - } - - func testInitRandomOfLength() { - let str1 = String(randomOfLength: 10) - XCTAssertEqual(str1.count, 10) - - let str2 = String(randomOfLength: 10) - XCTAssertEqual(str2.count, 10) - - XCTAssertNotEqual(str1, str2) - - XCTAssertEqual(String(randomOfLength: 0), "") - - } - - func testInitFromBase64() { - XCTAssertNotNil(String(base64: "SGVsbG8gV29ybGQh")) - XCTAssertEqual(String(base64: "SGVsbG8gV29ybGQh"), "Hello World!") - XCTAssertNil(String(base64: "hello")) - } - - func testNSString() { - XCTAssertEqual("Hello".nsString, NSString(string: "Hello")) - } - - func testLastPathComponent() { - let string = "hello" - let nsString = NSString(string: "hello") - XCTAssertEqual(string.lastPathComponent, nsString.lastPathComponent) - - } - - func testLastPathExtension() { - let string = "hello" - let nsString = NSString(string: "hello") - XCTAssertEqual(string.pathExtension, nsString.pathExtension) - } - - func testLastDeletingLastPathComponent() { - let string = "hello" - let nsString = NSString(string: "hello") - XCTAssertEqual(string.deletingLastPathComponent, nsString.deletingLastPathComponent) - } - - func testLastDeletingPathExtension() { - let string = "hello" - let nsString = NSString(string: "hello") - XCTAssertEqual(string.deletingPathExtension, nsString.deletingPathExtension) - } - - func testLastPathComponents() { - let string = "hello" - let nsString = NSString(string: "hello") - XCTAssertEqual(string.pathComponents, nsString.pathComponents) - } - - func testAppendingPathComponent() { - let string = "hello".appendingPathComponent("world") - let nsString = NSString(string: "hello").appendingPathComponent("world") - XCTAssertEqual(string, nsString) - } - - func testAppendingPathExtension() { - let string = "hello".appendingPathExtension("world") - let nsString = NSString(string: "hello").appendingPathExtension("world") - XCTAssertEqual(string, nsString) - } - - #if !os(tvOS) && !os(watchOS) - func testBold() { - let boldString = "hello".bold - let attrs = boldString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, boldString.length)) - XCTAssertNotNil(attrs[NSAttributedStringKey.font]) - - #if os(macOS) - guard let font = attrs[.font] as? NSFont else { - XCTFail() - return - } - XCTAssertEqual(font, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)) - #elseif os(iOS) - guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { - XCTFail() - return - } - XCTAssertEqual(font, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) - #endif - } - #endif - - func testUnderline() { - let underlinedString = "hello".underline - let attrs = underlinedString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, underlinedString.length)) - XCTAssertNotNil(attrs[NSAttributedStringKey.underlineStyle]) - guard let style = attrs[NSAttributedStringKey.underlineStyle] as? Int else { - XCTFail() - return - } - XCTAssertEqual(style, NSUnderlineStyle.styleSingle.rawValue) - } - - func testStrikethrough() { - let strikedthroughString = "hello".strikethrough - let attrs = strikedthroughString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, strikedthroughString.length)) - XCTAssertNotNil(attrs[NSAttributedStringKey.strikethroughStyle]) - guard let style = attrs[NSAttributedStringKey.strikethroughStyle] as? NSNumber else { - XCTFail() - return - } - XCTAssertEqual(style, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) - } - - #if os(iOS) - func testItalic() { - let italicString = "hello".italic - let attrs = italicString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, italicString.length)) - XCTAssertNotNil(attrs[NSAttributedStringKey.font]) - guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { - XCTFail() - return - } - XCTAssertEqual(font, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) - } - #endif - - func testColored() { - let coloredString = "hello".colored(with: .orange) - let attrs = coloredString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, coloredString.length)) - XCTAssertNotNil(attrs[NSAttributedStringKey.foregroundColor]) - - #if os(macOS) - guard let color = attrs[.foregroundColor] as? NSColor else { - XCTFail() - return - } - XCTAssertEqual(color, NSColor.orange) - #else - guard let color = attrs[NSAttributedStringKey.foregroundColor] as? UIColor else { - XCTFail() - return - } - XCTAssertEqual(color, UIColor.orange) - #endif - } - - func testWords() { - XCTAssertEqual("Swift is amazing".words(), ["Swift", "is", "amazing"]) - } - - func testWordsCount() { - XCTAssertEqual("Swift is amazing".wordCount(), 3) - } func testToSlug() { let str = " A nice & hög _ Str " XCTAssertEqual(str.toSlug(), "a-nice-&-hog-str") XCTAssertEqual("Swift is amazing".toSlug(), "swift-is-amazing") } - - func testPaddingStart() { - XCTAssertEqual("str".paddingStart(10), " str") - XCTAssertEqual("str".paddingStart(10, with: "br"), "brbrbrbstr") - XCTAssertEqual("str".paddingStart(5, with: "brazil"), "brstr") - XCTAssertEqual("str".paddingStart(6, with: "a"), "aaastr") - XCTAssertEqual("str".paddingStart(6, with: "abc"), "abcstr") - XCTAssertEqual("str".paddingStart(2), "str") + func testSubscript() { + let str = "Hello world!" + XCTAssertEqual(str[safe: 1], "e") + XCTAssertNil(str[safe: 18]) + + XCTAssertEqual(str[safe: 1..<5], "ello") + XCTAssertNil(str[safe: 10..<18]) + XCTAssertNil(""[safe: 1..<2]) + + XCTAssertEqual(str[safe: 0...4], "Hello") + XCTAssertNil(str[safe: 10...18]) + XCTAssertNil(""[safe: 1...2]) } - - func testPaddingEnd() { - XCTAssertEqual("str".paddingEnd(10), "str ") - XCTAssertEqual("str".paddingEnd(10, with: "br"), "strbrbrbrb") - XCTAssertEqual("str".paddingEnd(5, with: "brazil"), "strbr") - XCTAssertEqual("str".paddingEnd(6, with: "a"), "straaa") - XCTAssertEqual("str".paddingEnd(6, with: "abc"), "strabc") - XCTAssertEqual("str".paddingEnd(2), "str") + + func testCopyToPasteboard() { + let str = "Hello world!" + #if os(iOS) + str.copyToPasteboard() + let strFromPasteboard = UIPasteboard.general.string + XCTAssertEqual(strFromPasteboard, str) + + #elseif os(macOS) + str.copyToPasteboard() + let strFromPasteboard = NSPasteboard.general.string(forType: .string) + XCTAssertEqual(strFromPasteboard, str) + #endif + } + + func testCamelize() { + var str = "Hello test" + str.camelize() + XCTAssertEqual(str, "helloTest") + + str = "helloWorld" + str.camelize() + XCTAssertEqual(str, "helloworld") + } + + func testHasUniqueCharacters() { + XCTAssert("swift".hasUniqueCharacters()) + XCTAssertFalse("language".hasUniqueCharacters()) + XCTAssertFalse("".hasUniqueCharacters()) + } + + func testContain() { + XCTAssert("Hello Tests".contains("Hello", caseSensitive: true)) + XCTAssert("Hello Tests".contains("hello", caseSensitive: false)) + } + + func testCount() { + XCTAssertEqual("Hello This Tests".count(of: "T"), 2) + XCTAssertEqual("Hello This Tests".count(of: "t"), 1) + XCTAssertEqual("Hello This Tests".count(of: "T", caseSensitive: false), 3) + XCTAssertEqual("Hello This Tests".count(of: "t", caseSensitive: false), 3) + } + + func testEnd() { + XCTAssert("Hello Test".ends(with: "test", caseSensitive: false)) + XCTAssert("Hello Tests".ends(with: "sts")) + } + + func testLatinize() { + var str = "Hëllô Teśt" + str.latinize() + XCTAssertEqual(str, "Hello Test") + } + + func testRandom() { + let str1 = String.random(ofLength: 10) + XCTAssertEqual(str1.count, 10) + + let str2 = String.random(ofLength: 10) + XCTAssertEqual(str2.count, 10) + + XCTAssertNotEqual(str1, str2) + + XCTAssertEqual(String.random(ofLength: 0), "") + } + + func testReverse() { + var str = "Hello" + str.reverse() + XCTAssertEqual(str, "olleH") + } + + func testSlice() { + XCTAssertEqual("12345678".slicing(from: 2, length: 3), "345") + XCTAssertEqual("12345678".slicing(from: 2, length: 0), "") + XCTAssertNil("12345678".slicing(from: 12, length: 0)) + XCTAssertEqual("12345678".slicing(from: 2, length: 100), "345678") + + var str = "12345678" + str.slice(from: 2, length: 3) + XCTAssertEqual(str, "345") + + str = "12345678" + str.slice(from: 2, length: 0) + print(str) + XCTAssertEqual(str, "") + + str = "12345678" + str.slice(from: 12, length: 0) + XCTAssertEqual(str, "12345678") + + str = "12345678" + str.slice(from: 2, length: 100) + XCTAssertEqual(str, "345678") + + str = "12345678" + str.slice(from: 2, to: 5) + XCTAssertEqual(str, "345") + + str = "12345678" + str.slice(from: 2, to: 1) + XCTAssertEqual(str, "12345678") + + str = "12345678" + str.slice(at: 2) + XCTAssertEqual(str, "345678") + + str = "12345678" + str.slice(at: 20) + XCTAssertEqual(str, "12345678") + } + + func testStart() { + XCTAssert("Hello Test".starts(with: "hello", caseSensitive: false)) + XCTAssert("Hello Tests".starts(with: "He")) + } + + func testDateWithFormat() { + let dateString = "2012-12-08 17:00:00.0" + let date = dateString.date(withFormat: "yyyy-dd-MM HH:mm:ss.S") + XCTAssertNotNil(date) + XCTAssertNil(dateString.date(withFormat: "Hello world!")) + } + + func testTrim() { + var str = "\n Hello \n " + str.trim() + XCTAssertEqual(str, "Hello") + } + + func testTruncate() { + var str = "This is a very long sentence" + str.truncate(toLength: 14) + XCTAssertEqual(str, "This is a very...") + + str = "This is a very long sentence" + str.truncate(toLength: 14, trailing: nil) + XCTAssertEqual(str, "This is a very") + + str = "This is a short sentence" + str.truncate(toLength: 100) + XCTAssertEqual(str, "This is a short sentence") + + str.truncate(toLength: -1) + XCTAssertEqual(str, "This is a short sentence") + } + + func testTruncated() { + XCTAssertEqual("This is a very long sentence".truncated(toLength: 14), "This is a very...") + + XCTAssertEqual("This is a very long sentence".truncated(toLength: 14, trailing: nil), "This is a very") + XCTAssertEqual("This is a short sentence".truncated(toLength: 100), "This is a short sentence") + } + + func testUrlDecode() { + var url = "it's%20easy%20to%20encode%20strings" + url.urlDecode() + XCTAssertEqual(url, "it's easy to encode strings") + } + + func testUrlEncode() { + var url = "it's easy to encode strings" + url.urlEncode() + XCTAssertEqual(url, "it's%20easy%20to%20encode%20strings") + } + + func testMatches() { + XCTAssertTrue("123".matches(pattern: "\\d{3}")) + XCTAssertFalse("dasda".matches(pattern: "\\d{3}")) + XCTAssertFalse("notanemail.com".matches(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}")) + XCTAssertTrue("email@mail.com".matches(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}")) } func testPadStart() { @@ -636,7 +487,7 @@ final class StringExtensionsTests: XCTestCase { str = "str" str.padStart(6, with: "a") XCTAssertEqual(str, "aaastr") - + str = "str" str.padStart(6, with: "abc") XCTAssertEqual(str, "abcstr") @@ -645,62 +496,225 @@ final class StringExtensionsTests: XCTestCase { str.padStart(2) XCTAssertEqual(str, "str") } - + + func testPaddingStart() { + XCTAssertEqual("str".paddingStart(10), " str") + XCTAssertEqual("str".paddingStart(10, with: "br"), "brbrbrbstr") + XCTAssertEqual("str".paddingStart(5, with: "brazil"), "brstr") + XCTAssertEqual("str".paddingStart(6, with: "a"), "aaastr") + XCTAssertEqual("str".paddingStart(6, with: "abc"), "abcstr") + XCTAssertEqual("str".paddingStart(2), "str") + } + func testPadEnd() { var str: String = "str" str.padEnd(10) XCTAssertEqual(str, "str ") - + str = "str" str.padEnd(10, with: "br") XCTAssertEqual(str, "strbrbrbrb") - + str = "str" str.padEnd(5, with: "brazil") XCTAssertEqual(str, "strbr") - + str = "str" str.padEnd(6, with: "a") XCTAssertEqual(str, "straaa") - + str = "str" str.padEnd(6, with: "abc") XCTAssertEqual(str, "strabc") - + str = "str" str.padEnd(2) XCTAssertEqual(str, "str") } - - func testWhiteSpaces() { - var str = "test string" - XCTAssertEqual(str.isWhitespace, false) - - str = " " - XCTAssertEqual(str.isWhitespace, true) - - str = " \n \n " - XCTAssertEqual(str.isWhitespace, true) + + func testPaddingEnd() { + XCTAssertEqual("str".paddingEnd(10), "str ") + XCTAssertEqual("str".paddingEnd(10, with: "br"), "strbrbrbrb") + XCTAssertEqual("str".paddingEnd(5, with: "brazil"), "strbr") + XCTAssertEqual("str".paddingEnd(6, with: "a"), "straaa") + XCTAssertEqual("str".paddingEnd(6, with: "abc"), "strabc") + XCTAssertEqual("str".paddingEnd(2), "str") } - + #if os(iOS) || os(tvOS) func testIsSpelledCorrectly() { let strCorrect = "Hello, World!" - + XCTAssertTrue(strCorrect.isSpelledCorrectly) - + let strNonCorrect = "Helol, Wrold!" XCTAssertFalse(strNonCorrect.isSpelledCorrectly) } #endif - + func testRemovingPrefix() { let inputStr = "Hello, World!" XCTAssertEqual(inputStr.removingPrefix("Hello, "), "World!") } - + func testRemovingSuffix() { let inputStr = "Hello, World!" XCTAssertEqual(inputStr.removingSuffix(", World!"), "Hello") } + + func testInitFromBase64() { + XCTAssertNotNil(String(base64: "SGVsbG8gV29ybGQh")) + XCTAssertEqual(String(base64: "SGVsbG8gV29ybGQh"), "Hello World!") + XCTAssertNil(String(base64: "hello")) + } + + func testInitRandomOfLength() { + let str1 = String(randomOfLength: 10) + XCTAssertEqual(str1.count, 10) + + let str2 = String(randomOfLength: 10) + XCTAssertEqual(str2.count, 10) + + XCTAssertNotEqual(str1, str2) + + XCTAssertEqual(String(randomOfLength: 0), "") + } + + #if !os(tvOS) && !os(watchOS) + func testBold() { + let boldString = "hello".bold + let attrs = boldString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, boldString.length)) + XCTAssertNotNil(attrs[NSAttributedStringKey.font]) + + #if os(macOS) + guard let font = attrs[.font] as? NSFont else { + XCTFail() + return + } + XCTAssertEqual(font, NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)) + #elseif os(iOS) + guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { + XCTFail() + return + } + XCTAssertEqual(font, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) + #endif + } + #endif + + func testUnderline() { + let underlinedString = "hello".underline + let attrs = underlinedString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, underlinedString.length)) + XCTAssertNotNil(attrs[NSAttributedStringKey.underlineStyle]) + guard let style = attrs[NSAttributedStringKey.underlineStyle] as? Int else { + XCTFail() + return + } + XCTAssertEqual(style, NSUnderlineStyle.styleSingle.rawValue) + } + + func testStrikethrough() { + let strikedthroughString = "hello".strikethrough + let attrs = strikedthroughString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, strikedthroughString.length)) + XCTAssertNotNil(attrs[NSAttributedStringKey.strikethroughStyle]) + guard let style = attrs[NSAttributedStringKey.strikethroughStyle] as? NSNumber else { + XCTFail() + return + } + XCTAssertEqual(style, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) + } + + #if os(iOS) + func testItalic() { + let italicString = "hello".italic + let attrs = italicString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, italicString.length)) + XCTAssertNotNil(attrs[NSAttributedStringKey.font]) + guard let font = attrs[NSAttributedStringKey.font] as? UIFont else { + XCTFail() + return + } + XCTAssertEqual(font, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) + } + #endif + + func testColored() { + let coloredString = "hello".colored(with: .orange) + let attrs = coloredString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, coloredString.length)) + XCTAssertNotNil(attrs[NSAttributedStringKey.foregroundColor]) + + #if os(macOS) + guard let color = attrs[.foregroundColor] as? NSColor else { + XCTFail() + return + } + XCTAssertEqual(color, NSColor.orange) + #else + guard let color = attrs[NSAttributedStringKey.foregroundColor] as? UIColor else { + XCTFail() + return + } + XCTAssertEqual(color, UIColor.orange) + #endif + } + + func testNSString() { + XCTAssertEqual("Hello".nsString, NSString(string: "Hello")) + } + + func testLastPathComponent() { + let string = "hello" + let nsString = NSString(string: "hello") + XCTAssertEqual(string.lastPathComponent, nsString.lastPathComponent) + } + + func testLastPathExtension() { + let string = "hello" + let nsString = NSString(string: "hello") + XCTAssertEqual(string.pathExtension, nsString.pathExtension) + } + + func testLastDeletingLastPathComponent() { + let string = "hello" + let nsString = NSString(string: "hello") + XCTAssertEqual(string.deletingLastPathComponent, nsString.deletingLastPathComponent) + } + + func testLastDeletingPathExtension() { + let string = "hello" + let nsString = NSString(string: "hello") + XCTAssertEqual(string.deletingPathExtension, nsString.deletingPathExtension) + } + + func testLastPathComponents() { + let string = "hello" + let nsString = NSString(string: "hello") + XCTAssertEqual(string.pathComponents, nsString.pathComponents) + } + + func testAppendingPathComponent() { + let string = "hello".appendingPathComponent("world") + let nsString = NSString(string: "hello").appendingPathComponent("world") + XCTAssertEqual(string, nsString) + } + + func testAppendingPathExtension() { + let string = "hello".appendingPathExtension("world") + let nsString = NSString(string: "hello").appendingPathExtension("world") + XCTAssertEqual(string, nsString) + } + + func testOperators() { + let testString = "sa" + + XCTAssertEqual(testString * 5, "sasasasasa") + XCTAssertEqual(5 * testString, "sasasasasa") + + XCTAssertEqual(testString * 0, "") + XCTAssertEqual(0 * testString, "") + + XCTAssertEqual(testString * -5, "") + XCTAssertEqual(-5 * testString, "") + } + } +// swiftlint:enable type_body_length diff --git a/Tests/SwiftStdlibTests/StringProtocolExtensionsTests.swift b/Tests/SwiftStdlibTests/StringProtocolExtensionsTests.swift index a7a2f9309..59fc9fcff 100644 --- a/Tests/SwiftStdlibTests/StringProtocolExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringProtocolExtensionsTests.swift @@ -10,14 +10,14 @@ import XCTest @testable import SwifterSwift final class StringProtocolExtensionsTests: XCTestCase { - + func testCommonSuffix() { let string1 = "Hello world!" let string2 = "It's cold!" XCTAssert(string1.commonSuffix(with: string2) == "ld!") - + let string3 = "你好世界" XCTAssert(string1.commonSuffix(with: string3).isEmpty) } - + } diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 3fe99fa57..59c8ccaa9 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -9,7 +9,7 @@ import XCTest @testable import SwifterSwift final class SwifterSwiftTests: XCTestCase { - + func testTypeName() { let number = 8 XCTAssertEqual(SwifterSwift.typeName(for: number), "Int") @@ -43,9 +43,9 @@ final class SwifterSwiftTests: XCTestCase { incrementor() }) - for i in 1...10 { + for index in 1...10 { debouncedIncrementor() - if i == 10 { + if index == 10 { SwifterSwift.delay(milliseconds: 30, completion: { done.fulfill() }) @@ -58,5 +58,5 @@ final class SwifterSwiftTests: XCTestCase { XCTAssertEqual(value, 1, "Value was incremented only once") }) } - + } diff --git a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift index 3d6a4253b..d369b8e6a 100644 --- a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift @@ -11,82 +11,85 @@ import XCTest @testable import SwifterSwift final class UIAlertControllerExtensionsTests: XCTestCase { - + func testAddAction() { let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert) - let discardedResult = alertController.addAction(title: "ActionTitle", style: .destructive, isEnabled: false, handler: nil) - + let discardedResult = alertController.addAction(title: "ActionTitle", + style: .destructive, isEnabled: false, handler: nil) + XCTAssertNotNil(discardedResult) - + XCTAssert(alertController.actions.count == 1) - + let action = alertController.actions.first - + XCTAssertEqual(action?.title, "ActionTitle") XCTAssertEqual(action?.style, .destructive) XCTAssertEqual(action?.isEnabled, false) } - + func testSelector() {} - + func testAddTextField() { - + let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert) - + let selector = #selector(testSelector) - - alertController.addTextField(text: "TextField", placeholder: "PlaceHolder", editingChangedTarget: self, editingChangedSelector: selector) - + + alertController.addTextField(text: "TextField", placeholder: "PlaceHolder", + editingChangedTarget: self, editingChangedSelector: selector) + XCTAssert(alertController.textFields?.count == 1) - + let textField = alertController.textFields?.first - + XCTAssertEqual(textField?.text, "TextField") XCTAssertEqual(textField?.placeholder, "PlaceHolder") XCTAssertNotNil(textField?.allTargets) XCTAssertNotNil(textField?.actions(forTarget: self, forControlEvent: .editingChanged)) - + } - + func testMessageInit() { - - let alertController = UIAlertController(title: "Title", message: "Message", defaultActionButtonTitle: "Ok", tintColor: .blue) - + let alertController = UIAlertController(title: "Title", message: "Message", + defaultActionButtonTitle: "Ok", tintColor: .blue) + XCTAssertNotNil(alertController) - + XCTAssertEqual(alertController.title, "Title") XCTAssertEqual(alertController.message, "Message") XCTAssertEqual(alertController.view.tintColor, .blue) - + XCTAssert(alertController.actions.count == 1) - + let defaultAction = alertController.actions.first - + XCTAssertEqual(defaultAction?.title, "Ok") XCTAssertEqual(defaultAction?.style, .default) } - + enum TestError: Error { case error } - + func testErrorInit() { let error = TestError.error - - let alertController = UIAlertController(title: "Title", error: error, defaultActionButtonTitle: "Ok", tintColor: .red) - + + let alertController = UIAlertController(title: "Title", error: error, + defaultActionButtonTitle: "Ok", tintColor: .red) + XCTAssertNotNil(alertController) - + XCTAssertEqual(alertController.title, "Title") XCTAssertEqual(alertController.message, error.localizedDescription) XCTAssertEqual(alertController.view.tintColor, .red) - + XCTAssert(alertController.actions.count == 1) - + let defaultAction = alertController.actions.first - + XCTAssertEqual(defaultAction?.title, "Ok") XCTAssertEqual(defaultAction?.style, .default) } - + } #endif diff --git a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift index 57d9560d0..a6dc7c055 100644 --- a/Tests/UIKitTests/UIBarButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIBarButtonExtensionsTests.swift @@ -7,26 +7,26 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UIBarButtonExtensionsTests: XCTestCase { - + func testSelector() {} - + func testAddTargetForAction() { - + let barButton = UIBarButtonItem() let selector = #selector(testSelector) - + barButton.addTargetForAction(self, action: selector) - + let target = barButton.target as? UIBarButtonExtensionsTests - + XCTAssertEqual(target, self) XCTAssertEqual(barButton.action, selector) } - + } #endif diff --git a/Tests/UIKitTests/UIButtonExtensionsTests.swift b/Tests/UIKitTests/UIButtonExtensionsTests.swift index ff1946eca..dedcc97fb 100644 --- a/Tests/UIKitTests/UIButtonExtensionsTests.swift +++ b/Tests/UIKitTests/UIButtonExtensionsTests.swift @@ -7,170 +7,155 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UIButtonExtensionsTests: XCTestCase { - + func testImageForDisabled() { - let button = UIButton() XCTAssertEqual(button.imageForDisabled, button.image(for: .disabled)) - + let newImage = UIImage() button.imageForDisabled = newImage XCTAssertEqual(button.imageForDisabled, newImage) } - + func testImageForHighlighted() { - let button = UIButton() XCTAssertEqual(button.imageForHighlighted, button.image(for: .highlighted)) - + let newImage = UIImage() button.imageForHighlighted = newImage XCTAssertEqual(button.imageForHighlighted, newImage) } - + func testImageForNormal() { - let button = UIButton() XCTAssertEqual(button.imageForNormal, button.image(for: .normal)) - + let newImage = UIImage() button.imageForNormal = newImage XCTAssertEqual(button.imageForNormal, newImage) } - + func testImageForSelected() { - let button = UIButton() XCTAssertEqual(button.imageForSelected, button.image(for: .selected)) - + let newImage = UIImage() button.imageForSelected = newImage XCTAssertEqual(button.imageForSelected, newImage) } - + func testTitleColorForDisabled() { - let button = UIButton() XCTAssertEqual(button.titleColorForDisabled, button.titleColor(for: .disabled)) - + button.titleColorForDisabled = .green XCTAssertEqual(button.titleColorForDisabled, .green) } - + func testTitleColorForHighlighted() { - let button = UIButton() XCTAssertEqual(button.titleColorForHighlighted, button.titleColor(for: .highlighted)) - + button.titleColorForHighlighted = .green XCTAssertEqual(button.titleColorForHighlighted, .green) } - + func testTitleColorForNormal() { - let button = UIButton() XCTAssertEqual(button.titleColorForNormal, button.titleColor(for: .normal)) - + button.titleColorForNormal = .green XCTAssertEqual(button.titleColorForNormal, .green) } - + func testTitleColorForSelected() { - let button = UIButton() XCTAssertEqual(button.titleColorForSelected, button.titleColor(for: .selected)) - + button.titleColorForSelected = .green XCTAssertEqual(button.titleColorForSelected, .green) } - + func testTitleForDisabled() { - let button = UIButton() XCTAssertEqual(button.titleForDisabled, button.title(for: .disabled)) - + let title = "Disabled" button.titleForDisabled = title XCTAssertEqual(button.titleForDisabled, title) } - + func testTitleForHighlighted() { - let button = UIButton() XCTAssertEqual(button.titleForHighlighted, button.title(for: .highlighted)) - + let title = "Highlighted" button.titleForHighlighted = title XCTAssertEqual(button.titleForHighlighted, title) } - + func testTitleForNormal() { - let button = UIButton() XCTAssertEqual(button.titleForNormal, button.title(for: .normal)) - + let title = "Normal" button.titleForNormal = title XCTAssertEqual(button.titleForNormal, title) } - + func testTitleForSelected() { - let button = UIButton() XCTAssertEqual(button.titleForSelected, button.title(for: .selected)) - + let title = "Selected" button.titleForSelected = title XCTAssertEqual(button.titleForSelected, title) } - + func testSetImageForAllStates() { - let button = UIButton() let image = UIImage() button.setImageForAllStates(image) - + XCTAssertEqual(button.imageForDisabled, image) XCTAssertEqual(button.imageForHighlighted, image) XCTAssertEqual(button.imageForNormal, image) XCTAssertEqual(button.imageForSelected, image) } - + func testSetTitleColorForAllStates() { - let button = UIButton() let color = UIColor.green button.setTitleColorForAllStates(color) - + XCTAssertEqual(button.titleColorForDisabled, color) XCTAssertEqual(button.titleColorForHighlighted, color) XCTAssertEqual(button.titleColorForNormal, color) XCTAssertEqual(button.titleColorForSelected, color) } - + func testSetTitleForAllStates() { - let button = UIButton() let title = "Title" button.setTitleForAllStates(title) - + XCTAssertEqual(button.titleForDisabled, title) XCTAssertEqual(button.titleForHighlighted, title) XCTAssertEqual(button.titleForNormal, title) XCTAssertEqual(button.titleForSelected, title) } - - func testCenterTextAndImage() { - let button: UIButton = UIButton() - button.centerTextAndImage(spacing: 20) - XCTAssertEqual(button.imageEdgeInsets, UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 10)) - XCTAssertEqual(button.titleEdgeInsets, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: -10)) - } - + + func testCenterTextAndImage() { + let button: UIButton = UIButton() + button.centerTextAndImage(spacing: 20) + XCTAssertEqual(button.imageEdgeInsets, UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 10)) + XCTAssertEqual(button.titleEdgeInsets, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: -10)) + } + } #endif diff --git a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift index 80b1a254f..22ebd623e 100644 --- a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift +++ b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift @@ -7,45 +7,45 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UICollectionViewExtensionsTests: XCTestCase { - + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) let emptyCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) - + override func setUp() { super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. + collectionView.dataSource = self collectionView.reloadData() - + emptyCollectionView.dataSource = self emptyCollectionView.reloadData() } - + func testIndexPathForLastRow() { XCTAssertEqual(collectionView.indexPathForLastItem, IndexPath(item: 0, section: 1)) } - + func testLastSection() { XCTAssertEqual(collectionView.lastSection, 1) XCTAssertEqual(emptyCollectionView.lastSection, 0) } - + func testNumberOfRows() { XCTAssertEqual(collectionView.numberOfItems(), 5) XCTAssertEqual(emptyCollectionView.numberOfItems(), 0) } - + func testIndexPathForLastRowInSection() { XCTAssertNil(collectionView.indexPathForLastItem(inSection: -1)) XCTAssertNil(collectionView.indexPathForLastItem(inSection: 2)) XCTAssertEqual(collectionView.indexPathForLastItem(inSection: 0), IndexPath(item: 4, section: 0)) } - + func testReloadData() { var completionCalled = false collectionView.reloadData { @@ -53,32 +53,32 @@ final class UICollectionViewExtensionsTests: XCTestCase { XCTAssert(completionCalled) } } - - #if os(iOS) - func testRegisterCellWithNibUsingClass() { - let indexPath = IndexPath(row: 0, section: 0) - collectionView.register(nibWithCellClass: UICollectionViewCell.self, at: UICollectionViewExtensionsTests.self) - let cell = collectionView.dequeueReusableCell(withClass: UICollectionViewCell.self, for: indexPath) - XCTAssertNotNil(cell) - } - #endif - + + #if os(iOS) + func testRegisterCellWithNibUsingClass() { + let indexPath = IndexPath(row: 0, section: 0) + collectionView.register(nibWithCellClass: UICollectionViewCell.self, at: UICollectionViewExtensionsTests.self) + let cell = collectionView.dequeueReusableCell(withClass: UICollectionViewCell.self, for: indexPath) + XCTAssertNotNil(cell) + } + #endif + } extension UICollectionViewExtensionsTests: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { - + func numberOfSections(in collectionView: UICollectionView) -> Int { return (collectionView == self.collectionView) ? 2 : 0 } - + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return (collectionView == self.collectionView) ? (section == 0 ? 5 : 0) : 0 } - + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return UICollectionViewCell() } - + } - + #endif diff --git a/Tests/UIKitTests/UIDatePickerExtensionsTests.swift b/Tests/UIKitTests/UIDatePickerExtensionsTests.swift index 6786020b9..8d6ecc44e 100644 --- a/Tests/UIKitTests/UIDatePickerExtensionsTests.swift +++ b/Tests/UIKitTests/UIDatePickerExtensionsTests.swift @@ -12,20 +12,20 @@ import XCTest @testable import SwifterSwift final class UIDatePickerExtensionsTests: XCTestCase { - + func testTextColor() { let datePicker = UIDatePicker() XCTAssertNil(datePicker.textColor) - + datePicker.textColor = .red XCTAssertEqual(datePicker.textColor, .red) - + datePicker.textColor = .green XCTAssertEqual(datePicker.textColor, .green) - + datePicker.textColor = nil XCTAssertNil(datePicker.textColor) } - + } #endif diff --git a/Tests/UIKitTests/UIFontExtensionsTest.swift b/Tests/UIKitTests/UIFontExtensionsTest.swift index ce6faf014..876257576 100644 --- a/Tests/UIKitTests/UIFontExtensionsTest.swift +++ b/Tests/UIKitTests/UIFontExtensionsTest.swift @@ -11,45 +11,46 @@ import XCTest @testable import SwifterSwift final class UIFontExtension: XCTestCase { - - func testBold() { - let font = UIFont.preferredFont(forTextStyle: .body) - let boldFont = font.bold - XCTAssert(boldFont.fontDescriptor.symbolicTraits.contains(.traitBold)) - } - - func testItalic() { - let font = UIFont.preferredFont(forTextStyle: .body) - let italicFont = font.italic - XCTAssert(italicFont.fontDescriptor.symbolicTraits.contains(.traitItalic)) - } - + + func testBold() { + let font = UIFont.preferredFont(forTextStyle: .body) + let boldFont = font.bold + XCTAssert(boldFont.fontDescriptor.symbolicTraits.contains(.traitBold)) + } + + func testItalic() { + let font = UIFont.preferredFont(forTextStyle: .body) + let italicFont = font.italic + XCTAssert(italicFont.fontDescriptor.symbolicTraits.contains(.traitItalic)) + } + func testMonospacedDigitFont() { let font = UIFont.preferredFont(forTextStyle: .body) let monoFont = font.monospaced - + let attributes = monoFont.fontDescriptor.fontAttributes - guard let settings = attributes[UIFontDescriptor.AttributeName.featureSettings] as? [[UIFontDescriptor.AttributeName: Int]] else { + let fontKey: UIFontDescriptor.AttributeName = UIFontDescriptor.AttributeName.featureSettings + guard let settings = attributes[fontKey] as? [[UIFontDescriptor.AttributeName: Int]] else { XCTFail("Unable to get settings from font") return } - + guard let selector = settings.first?[.init("CTFeatureSelectorIdentifier")] else { XCTFail("Unable to get selector from font") return } - + guard let space = settings.first?[.init("CTFeatureTypeIdentifier")] else { XCTFail("Unable to get space from font") return } - + XCTAssertEqual(selector, kMonospacedNumbersSelector) XCTAssertEqual(space, kNumberSpacingType) XCTAssertEqual(font.fontName, monoFont.fontName) XCTAssertEqual(font.familyName, monoFont.familyName) XCTAssertEqual(font.lineHeight, monoFont.lineHeight) } - + } #endif diff --git a/Tests/UIKitTests/UIImageExtensionsTests.swift b/Tests/UIKitTests/UIImageExtensionsTests.swift index 9e033aea4..6b40c652d 100644 --- a/Tests/UIKitTests/UIImageExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageExtensionsTests.swift @@ -7,36 +7,35 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UIImageExtensionsTests: XCTestCase { - + func testBytesSize() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! XCTAssertEqual(image.bytesSize, 68665) XCTAssertEqual(UIImage().bytesSize, 0) - } - + func testKilobytesSize() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! XCTAssertEqual(image.kilobytesSize, 67) } - + func testOriginal() { let image = UIImage(color: .blue, size: CGSize(width: 20, height: 20)) XCTAssertEqual(image.original, image.withRenderingMode(.alwaysOriginal)) } - + func testTemplate() { let image = UIImage(color: .blue, size: CGSize(width: 20, height: 20)) XCTAssertEqual(image.template, image.withRenderingMode(.alwaysTemplate)) } - + func testCompressed() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! @@ -45,7 +44,7 @@ final class UIImageExtensionsTests: XCTestCase { XCTAssertEqual(compressedImage!.kilobytesSize, 54) XCTAssertNil(UIImage().compressed()) } - + func testCropped() { let image = UIImage(color: .black, size: CGSize(width: 20, height: 20)) var cropped = image.cropped(to: CGRect(x: 0, y: 0, width: 40, height: 40)) @@ -54,53 +53,53 @@ final class UIImageExtensionsTests: XCTestCase { let small = UIImage(color: .black, size: CGSize(width: 10, height: 10)) XCTAssertEqual(cropped.bytesSize, small.bytesSize) } - + func testScaledToHeight() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! - + let scaledImage = image.scaled(toHeight: 300) XCTAssertNotNil(scaledImage) XCTAssertEqual(scaledImage!.size.height, 300) } - + func testScaledToWidth() { let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! - + let scaledImage = image.scaled(toWidth: 300) XCTAssertNotNil(scaledImage) XCTAssertEqual(scaledImage!.size.width, 300) } - + func testFilled() { let image = UIImage(color: .black, size: CGSize(width: 20, height: 20)) let image2 = UIImage(color: .yellow, size: CGSize(width: 20, height: 20)) XCTAssertEqual(image.filled(withColor: .yellow).bytesSize, image2.bytesSize) - + var emptyImage = UIImage() var filledImage = emptyImage.filled(withColor: .red) XCTAssertEqual(emptyImage, filledImage) - + emptyImage = UIImage(color: .yellow, size: CGSize.zero) filledImage = emptyImage.filled(withColor: .red) XCTAssertEqual(emptyImage, filledImage) } - - func testTinted() { - let baseImage = UIImage(color: .white, size: CGSize(width: 20, height: 20)) - let tintedImage = baseImage.tint(.black, blendMode: .overlay) - let testImage = UIImage(color: .black, size: CGSize(width: 20, height: 20)) - XCTAssertEqual(testImage.bytesSize, tintedImage.bytesSize) - } - - func testWithCornerRadius() { - let image = UIImage(color: .black, size: CGSize(width: 20, height: 20)) - XCTAssertNotNil(image.withRoundedCorners()) - XCTAssertNotNil(image.withRoundedCorners(radius: 5)) - XCTAssertNotNil(image.withRoundedCorners(radius: -10)) - XCTAssertNotNil(image.withRoundedCorners(radius: 30)) - } - + + func testTinted() { + let baseImage = UIImage(color: .white, size: CGSize(width: 20, height: 20)) + let tintedImage = baseImage.tint(.black, blendMode: .overlay) + let testImage = UIImage(color: .black, size: CGSize(width: 20, height: 20)) + XCTAssertEqual(testImage.bytesSize, tintedImage.bytesSize) + } + + func testWithCornerRadius() { + let image = UIImage(color: .black, size: CGSize(width: 20, height: 20)) + XCTAssertNotNil(image.withRoundedCorners()) + XCTAssertNotNil(image.withRoundedCorners(radius: 5)) + XCTAssertNotNil(image.withRoundedCorners(radius: -10)) + XCTAssertNotNil(image.withRoundedCorners(radius: 30)) + } + } #endif diff --git a/Tests/UIKitTests/UIImageViewExtensionsTests.swift b/Tests/UIKitTests/UIImageViewExtensionsTests.swift index 87128a952..d8bf30b2b 100644 --- a/Tests/UIKitTests/UIImageViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageViewExtensionsTests.swift @@ -7,46 +7,46 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UIImageViewExtensionsTests: XCTestCase { - + func testDownload() { - // Success + // Success let imageView = UIImageView() let url = URL(string: "https://developer.apple.com/swift/images/swift-og.png")! let placeHolder = UIImage() - let downloadExpectation = expectation(description: "Download success") + let downloadExpectation = expectation(description: "Download success") imageView.download(from: url, contentMode: .scaleAspectFill, placeholder: placeHolder) { image in XCTAssertEqual(imageView.image, image) - downloadExpectation.fulfill() + downloadExpectation.fulfill() } XCTAssertEqual(imageView.image, placeHolder) XCTAssertEqual(imageView.contentMode, .scaleAspectFill) - - // Failure - let failImageView = UIImageView() + + // Failure + let failImageView = UIImageView() let failingURL = URL(string: "https://developer.apple.com/")! - let failExpectation = expectation(description: "Download failure") + let failExpectation = expectation(description: "Download failure") failImageView.image = nil failImageView.download(from: failingURL, contentMode: .center, placeholder: nil) { image in XCTAssertNil(image) DispatchQueue.main.async { XCTAssertNil(failImageView.image) } - failExpectation.fulfill() + failExpectation.fulfill() } XCTAssertEqual(failImageView.contentMode, .center) XCTAssertNil(failImageView.image) - waitForExpectations(timeout: 15, handler: nil) + waitForExpectations(timeout: 15, handler: nil) } - + func testBlur() { let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 100)) imageView.blur(withStyle: .dark) - + let blurView = imageView.subviews.first as? UIVisualEffectView XCTAssertNotNil(blurView) XCTAssertNotNil(blurView?.effect) @@ -54,12 +54,12 @@ final class UIImageViewExtensionsTests: XCTestCase { XCTAssertEqual(blurView?.autoresizingMask, [.flexibleWidth, .flexibleHeight]) XCTAssert(imageView.clipsToBounds) } - + func testBlurred() { let imageView = UIImageView() let blurredImageView = imageView.blurred(withStyle: .extraLight) XCTAssertEqual(blurredImageView, imageView) } - + } #endif diff --git a/Tests/UIKitTests/UILabelExtensionsTests.swift b/Tests/UIKitTests/UILabelExtensionsTests.swift index a74ecb667..0369d94e2 100644 --- a/Tests/UIKitTests/UILabelExtensionsTests.swift +++ b/Tests/UIKitTests/UILabelExtensionsTests.swift @@ -10,26 +10,26 @@ import XCTest @testable import SwifterSwift #if os(iOS) || os(tvOS) - final class UILabelExtensionsTests: XCTestCase { - - func testInitWithText() { - let label = UILabel(text: "Hello world") - XCTAssertEqual(label.text, "Hello world") - } - - func testrequiredHeight() { - let frame = CGRect(x: 0, y: 0, width: 100, height: 100) - let label = UILabel(frame: frame) - label.text = "Hello world" - - #if os(iOS) - XCTAssert(label.requiredHeight > 20) - XCTAssert(label.requiredHeight < 25) - #else - XCTAssert(label.requiredHeight > 0) - XCTAssert(label.requiredHeight < 100) - #endif - } - +final class UILabelExtensionsTests: XCTestCase { + + func testInitWithText() { + let label = UILabel(text: "Hello world") + XCTAssertEqual(label.text, "Hello world") } + + func testrequiredHeight() { + let frame = CGRect(x: 0, y: 0, width: 100, height: 100) + let label = UILabel(frame: frame) + label.text = "Hello world" + + #if os(iOS) + XCTAssert(label.requiredHeight > 20) + XCTAssert(label.requiredHeight < 25) + #else + XCTAssert(label.requiredHeight > 0) + XCTAssert(label.requiredHeight < 100) + #endif + } + +} #endif diff --git a/Tests/UIKitTests/UINavigationBarExtensionTests.swift b/Tests/UIKitTests/UINavigationBarExtensionTests.swift index 8aec86a1c..8b16dca1e 100644 --- a/Tests/UIKitTests/UINavigationBarExtensionTests.swift +++ b/Tests/UIKitTests/UINavigationBarExtensionTests.swift @@ -7,51 +7,52 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift - + final class UINavigationBarExtensionsTests: XCTestCase { - - func testSetTitleFont() { - let navigationBar = UINavigationBar() - let helveticaFont = UIFont(name: "HelveticaNeue", size: 14)! - navigationBar.setTitleFont(helveticaFont, color: .green) + + func testSetTitleFont() { + let navigationBar = UINavigationBar() + let helveticaFont = UIFont(name: "HelveticaNeue", size: 14)! + navigationBar.setTitleFont(helveticaFont, color: .green) let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor - XCTAssertEqual(color, .green) + XCTAssertEqual(color, .green) let font = navigationBar.titleTextAttributes?[NSAttributedStringKey.font] as? UIFont - XCTAssertEqual(font, helveticaFont) - - navigationBar.setTitleFont(helveticaFont) + XCTAssertEqual(font, helveticaFont) + + navigationBar.setTitleFont(helveticaFont) let defaultColor = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor - XCTAssertEqual(defaultColor, .black) - } - - func testMakeTransparent() { - let navigationBar = UINavigationBar() - navigationBar.makeTransparent(withTint: .red) - XCTAssertNotNil(navigationBar.backgroundImage(for: .default)) - XCTAssertNotNil(navigationBar.shadowImage) - XCTAssert(navigationBar.isTranslucent) - XCTAssertEqual(navigationBar.tintColor, .red) + XCTAssertEqual(defaultColor, .black) + } + + func testMakeTransparent() { + let navigationBar = UINavigationBar() + navigationBar.makeTransparent(withTint: .red) + XCTAssertNotNil(navigationBar.backgroundImage(for: .default)) + XCTAssertNotNil(navigationBar.shadowImage) + XCTAssert(navigationBar.isTranslucent) + XCTAssertEqual(navigationBar.tintColor, .red) let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor - XCTAssertEqual(color, .red) - - navigationBar.makeTransparent() + XCTAssertEqual(color, .red) + + navigationBar.makeTransparent() let defaultColor = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor - XCTAssertEqual(defaultColor, .white) - } - - func testSetColors() { - let navigationBar = UINavigationBar() - navigationBar.setColors(background: .blue, text: .green) - XCTAssertFalse(navigationBar.isTranslucent) - XCTAssertEqual(navigationBar.backgroundColor, .blue) - XCTAssertEqual(navigationBar.barTintColor, .blue) - XCTAssertNotNil(navigationBar.backgroundImage(for: .default)) - XCTAssertEqual(navigationBar.tintColor, .green) + XCTAssertEqual(defaultColor, .white) + } + + func testSetColors() { + let navigationBar = UINavigationBar() + navigationBar.setColors(background: .blue, text: .green) + XCTAssertFalse(navigationBar.isTranslucent) + XCTAssertEqual(navigationBar.backgroundColor, .blue) + XCTAssertEqual(navigationBar.barTintColor, .blue) + XCTAssertNotNil(navigationBar.backgroundImage(for: .default)) + XCTAssertEqual(navigationBar.tintColor, .green) let color = navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor - XCTAssertEqual(color, .green) - } + XCTAssertEqual(color, .green) + } + } #endif diff --git a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift index b25df7af7..cd71f27df 100644 --- a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift @@ -7,52 +7,27 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift - + final class UINavigationControllerExtensionsTests: XCTestCase { -// This test is commented because we not sure if after the animation it already removed the viewcontroller from the array, it's something internal of UIKit that require a deeper looking. -// func testPopViewController() { -// let navigationController = UINavigationController() -// let vcToPop = UIViewController() -// let exp = expectation(description: "popCallback") -// -// navigationController.pushViewController(vcToPop, animated: false) -// -// navigationController.popViewController() { -// XCTAssert(navigationController.viewControllers.isEmpty) -// exp.fulfill() -// } -// waitForExpectations(timeout: 5, handler: nil) -// } - - func testPushViewController() { - let navigationController = UINavigationController() - let vcToPush = UIViewController() - - navigationController.pushViewController(vcToPush, animated: false) - - let exp = expectation(description: "pushCallback") - - navigationController.pushViewController(vcToPush) { - XCTAssert(navigationController.viewControllers.count == 1) - XCTAssertEqual(navigationController.topViewController, vcToPush) - exp.fulfill() - } - waitForExpectations(timeout: 5, handler: nil) - - } - -// func testMakeTransparent() { -// let navigationController = UINavigationController() -// navigationController.makeTransparent(withTint: .red) -// XCTAssertNotNil(navigationController.navigationBar.backgroundImage(for: .default)) -// XCTAssertNotNil(navigationController.navigationBar.shadowImage) -// XCTAssert(navigationController.navigationBar.isTranslucent) -// XCTAssertEqual(navigationController.navigationBar.tintColor, .red) -// let titleColor = navigationController.navigationBar.titleTextAttributes?[NSAttributedStringKey.foregroundColor] as? UIColor -// XCTAssertEqual(titleColor, .red) -// } + + func testPushViewController() { + let navigationController = UINavigationController() + let vcToPush = UIViewController() + + navigationController.pushViewController(vcToPush, animated: false) + + let exp = expectation(description: "pushCallback") + + navigationController.pushViewController(vcToPush) { + XCTAssert(navigationController.viewControllers.count == 1) + XCTAssertEqual(navigationController.topViewController, vcToPush) + exp.fulfill() + } + waitForExpectations(timeout: 5, handler: nil) + } + } #endif diff --git a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift index 76fc20760..cf5979caa 100644 --- a/Tests/UIKitTests/UINavigationItemExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationItemExtensionsTests.swift @@ -7,25 +7,26 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift - + final class UINavigationItemExtensionsTests: XCTestCase { - - func testReplaceTitle() { - let navigationItem = UINavigationItem() - let image = UIImage() - navigationItem.replaceTitle(with: image) - - let imageView = navigationItem.titleView as? UIImageView - XCTAssertNotNil(imageView) - - let frame = CGRect(x: 0, y: 0, width: 100, height: 30) - XCTAssertEqual(imageView?.frame, frame) - - XCTAssertEqual(imageView?.contentMode, .scaleAspectFit) - XCTAssertEqual(imageView?.image, image) - } + + func testReplaceTitle() { + let navigationItem = UINavigationItem() + let image = UIImage() + navigationItem.replaceTitle(with: image) + + let imageView = navigationItem.titleView as? UIImageView + XCTAssertNotNil(imageView) + + let frame = CGRect(x: 0, y: 0, width: 100, height: 30) + XCTAssertEqual(imageView?.frame, frame) + + XCTAssertEqual(imageView?.contentMode, .scaleAspectFit) + XCTAssertEqual(imageView?.image, image) + } + } #endif diff --git a/Tests/UIKitTests/UISearchBarExtensionsTests.swift b/Tests/UIKitTests/UISearchBarExtensionsTests.swift index 42ef97764..1e18b30cc 100644 --- a/Tests/UIKitTests/UISearchBarExtensionsTests.swift +++ b/Tests/UIKitTests/UISearchBarExtensionsTests.swift @@ -11,17 +11,17 @@ import XCTest #if os(iOS) final class UISearchBarExtensionsTests: XCTestCase { - + func testSearchBar() { let searchBar = UISearchBar() XCTAssertNil(searchBar.textField) - + let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let aSearchBar = UISearchBar(frame: frame) aSearchBar.text = "Hello" XCTAssertNotNil(aSearchBar.textField) } - + func testTrimmedText() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let aSearchBar = UISearchBar(frame: frame) @@ -29,7 +29,7 @@ final class UISearchBarExtensionsTests: XCTestCase { XCTAssertNotNil(aSearchBar.trimmedText) XCTAssertEqual(aSearchBar.trimmedText!, "Hello") } - + func testClear() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let aSearchBar = UISearchBar(frame: frame) @@ -37,6 +37,6 @@ final class UISearchBarExtensionsTests: XCTestCase { aSearchBar.clear() XCTAssertEqual(aSearchBar.text!, "") } - + } #endif diff --git a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift index e076066f5..aa11b7134 100644 --- a/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift +++ b/Tests/UIKitTests/UISegmentedControlExtensionsTests.swift @@ -13,20 +13,21 @@ import XCTest final class UISegmentedControlExtensionsTests: XCTestCase { - func testSegmentTitles() { - let segmentControl = UISegmentedControl() - XCTAssert(segmentControl.segmentTitles.isEmpty) - let titles = ["Title1", "Title2"] - segmentControl.segmentTitles = titles - XCTAssertEqual(segmentControl.segmentTitles, titles) - } - - func testSegmentImages() { - let segmentControl = UISegmentedControl() - XCTAssert(segmentControl.segmentImages.isEmpty) - let images = [UIImage(), UIImage()] - segmentControl.segmentImages = images - XCTAssertEqual(segmentControl.segmentImages, images) - } + func testSegmentTitles() { + let segmentControl = UISegmentedControl() + XCTAssert(segmentControl.segmentTitles.isEmpty) + let titles = ["Title1", "Title2"] + segmentControl.segmentTitles = titles + XCTAssertEqual(segmentControl.segmentTitles, titles) + } + + func testSegmentImages() { + let segmentControl = UISegmentedControl() + XCTAssert(segmentControl.segmentImages.isEmpty) + let images = [UIImage(), UIImage()] + segmentControl.segmentImages = images + XCTAssertEqual(segmentControl.segmentImages, images) + } + } #endif diff --git a/Tests/UIKitTests/UISliderExtensionsTests.swift b/Tests/UIKitTests/UISliderExtensionsTests.swift index d0f581948..5c8a1abf2 100644 --- a/Tests/UIKitTests/UISliderExtensionsTests.swift +++ b/Tests/UIKitTests/UISliderExtensionsTests.swift @@ -7,52 +7,50 @@ // #if os(iOS) - + import XCTest @testable import SwifterSwift final class UISliderExtensionsTests: XCTestCase { - func testCompletionCalledAnimated() { - let slider = UISlider() - slider.minimumValue = 0 - slider.maximumValue = 100 - let exp = expectation(description: "calledCompletion") - slider.setValue(90, animated: true, duration: 0.5) { - XCTAssertEqual(slider.value, 90.0) - exp.fulfill() - } - waitForExpectations(timeout: 5, handler: nil) - } - - func testSetValue() { - let slider = UISlider() - slider.minimumValue = 0 - slider.maximumValue = 100 - var completionCalled = false - - slider.setValue(99) { - completionCalled = true - XCTAssert(completionCalled) - } - XCTAssertFalse(completionCalled) - XCTAssertEqual(slider.value, 99) - - } - - func testCompletionCalled() { - let slider = UISlider() - slider.minimumValue = 0 - slider.maximumValue = 100 - let exp = expectation(description: "calledCompletion") - slider.setValue(50, animated: false, duration: 2) { - XCTAssert(true) - exp.fulfill() - } - XCTAssertEqual(slider.value, 50.0) - waitForExpectations(timeout: 3, handler: nil) - - } - + func testCompletionCalledAnimated() { + let slider = UISlider() + slider.minimumValue = 0 + slider.maximumValue = 100 + let exp = expectation(description: "calledCompletion") + slider.setValue(90, animated: true, duration: 0.5) { + XCTAssertEqual(slider.value, 90.0) + exp.fulfill() + } + waitForExpectations(timeout: 5, handler: nil) + } + + func testSetValue() { + let slider = UISlider() + slider.minimumValue = 0 + slider.maximumValue = 100 + var completionCalled = false + + slider.setValue(99) { + completionCalled = true + XCTAssert(completionCalled) + } + XCTAssertFalse(completionCalled) + XCTAssertEqual(slider.value, 99) + } + + func testCompletionCalled() { + let slider = UISlider() + slider.minimumValue = 0 + slider.maximumValue = 100 + let exp = expectation(description: "calledCompletion") + slider.setValue(50, animated: false, duration: 2) { + XCTAssert(true) + exp.fulfill() + } + XCTAssertEqual(slider.value, 50.0) + waitForExpectations(timeout: 3, handler: nil) + } + } #endif diff --git a/Tests/UIKitTests/UIStackViewExtensionsTest.swift b/Tests/UIKitTests/UIStackViewExtensionsTest.swift index 21936e9b8..2033e23ea 100644 --- a/Tests/UIKitTests/UIStackViewExtensionsTest.swift +++ b/Tests/UIKitTests/UIStackViewExtensionsTest.swift @@ -7,39 +7,44 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift class UIStackViewExtensionsTest: XCTestCase { - - // MARK: - Initializers - func testInitWithViews() { - let view1 = UIView() - let view2 = UIView() - var stack = UIStackView(arrangedSubviews: [view1, view2], axis: .horizontal) - - XCTAssertEqual(stack.arrangedSubviews.count, 2) - XCTAssertTrue(stack.arrangedSubviews[0] === view1) - XCTAssertTrue(stack.arrangedSubviews[1] === view2) - //defaults - XCTAssertEqual(stack.axis, .horizontal) - XCTAssertEqual(stack.alignment, .fill) - XCTAssertEqual(stack.distribution, .fill) - XCTAssertEqual(stack.spacing, 0.0) - - XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical).axis, .vertical) - XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, alignment: .center).alignment, .center) - XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, distribution: .fillEqually).distribution, .fillEqually) - XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, spacing: 16.0).spacing, 16.0) - - stack = UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, spacing: 16.0, - alignment: .center, distribution: .fillEqually) - - XCTAssertEqual(stack.axis, .vertical) - XCTAssertEqual(stack.alignment, .center) - XCTAssertEqual(stack.distribution, .fillEqually) - XCTAssertEqual(stack.spacing, 16.0) - } + + // MARK: - Initializers + func testInitWithViews() { + let view1 = UIView() + let view2 = UIView() + var stack = UIStackView(arrangedSubviews: [view1, view2], axis: .horizontal) + + XCTAssertEqual(stack.arrangedSubviews.count, 2) + XCTAssertTrue(stack.arrangedSubviews[0] === view1) + XCTAssertTrue(stack.arrangedSubviews[1] === view2) + + XCTAssertEqual(stack.axis, .horizontal) + XCTAssertEqual(stack.alignment, .fill) + XCTAssertEqual(stack.distribution, .fill) + XCTAssertEqual(stack.spacing, 0.0) + + XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical).axis, .vertical) + XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, alignment: .center).alignment, + .center) + + XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, + distribution: .fillEqually).distribution, .fillEqually) + + XCTAssertEqual(UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, spacing: 16.0).spacing, 16.0) + + stack = UIStackView(arrangedSubviews: [view1, view2], axis: .vertical, spacing: 16.0, + alignment: .center, distribution: .fillEqually) + + XCTAssertEqual(stack.axis, .vertical) + XCTAssertEqual(stack.alignment, .center) + XCTAssertEqual(stack.distribution, .fillEqually) + XCTAssertEqual(stack.spacing, 16.0) + } + } #endif diff --git a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift index dc007b669..ca941c99c 100644 --- a/Tests/UIKitTests/UIStoryboardExtensionsTests.swift +++ b/Tests/UIKitTests/UIStoryboardExtensionsTests.swift @@ -10,13 +10,18 @@ import XCTest @testable import SwifterSwift - + final class UIStoryboardExtensionsTests: XCTestCase { - - func testInstantiateViewController() { - let storyboard = UIStoryboard(name: "TestStoryboard", bundle: Bundle(for: UIStoryboardExtensionsTests.self)) - let viewController = storyboard.instantiateViewController(withClass: UIViewController.self) - XCTAssertNotNil(viewController) + + func testMainStoryboard() { + XCTAssertNil(UIStoryboard.main) } + + func testInstantiateViewController() { + let storyboard = UIStoryboard(name: "TestStoryboard", bundle: Bundle(for: UIStoryboardExtensionsTests.self)) + let viewController = storyboard.instantiateViewController(withClass: UIViewController.self) + XCTAssertNotNil(viewController) + } + } #endif diff --git a/Tests/UIKitTests/UISwitchExtensionsTests.swift b/Tests/UIKitTests/UISwitchExtensionsTests.swift index 47d75cc47..4135705c9 100644 --- a/Tests/UIKitTests/UISwitchExtensionsTests.swift +++ b/Tests/UIKitTests/UISwitchExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest #if os(iOS) final class UISwitchExtensionsTests: XCTestCase { - + func testToggle() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let aSwitch = UISwitch(frame: frame) @@ -19,6 +19,6 @@ final class UISwitchExtensionsTests: XCTestCase { aSwitch.toggle(animated: false) XCTAssert(aSwitch.isOn) } - + } #endif diff --git a/Tests/UIKitTests/UITabBarExtensionsTests.swift b/Tests/UIKitTests/UITabBarExtensionsTests.swift index 65ab6c65c..c4ff1c13c 100644 --- a/Tests/UIKitTests/UITabBarExtensionsTests.swift +++ b/Tests/UIKitTests/UITabBarExtensionsTests.swift @@ -7,35 +7,34 @@ // #if os(iOS) || os(tvOS) - + import XCTest @testable import SwifterSwift final class UITabBarExtensionsTests: XCTestCase { - + func testSetColors() { let frame = CGRect(x: 0, y: 0, width: 300, height: 44) var tabBar = UITabBar(frame: frame) tabBar.setColors(background: .red, selectedBackground: .orange, item: .white, selectedItem: .black) - + XCTAssertEqual(tabBar.barTintColor, .red) - + tabBar = UITabBar(frame: frame) tabBar.setColors() XCTAssertNotEqual(tabBar.barTintColor, .red) - + let bundle = Bundle.init(for: UIImageExtensionsTests.self) let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! - + let item1 = UITabBarItem(title: "First", image: image, selectedImage: image) let item2 = UITabBarItem(title: "Second", image: nil, selectedImage: nil) tabBar.items = [item1, item2] tabBar.selectedItem = item1 XCTAssertNotNil(tabBar.selectedItem) - + tabBar.setColors(selectedBackground: .orange, item: .white, selectedItem: .black) - } - + } #endif diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 3c1c7d2be..69357fb83 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -11,10 +11,10 @@ import XCTest @testable import SwifterSwift final class UITableViewExtensionsTests: XCTestCase { - + let tableView = UITableView() let emptyTableView = UITableView() - + override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. @@ -22,80 +22,81 @@ final class UITableViewExtensionsTests: XCTestCase { emptyTableView.dataSource = self tableView.reloadData() } - + func testIndexPathForLastRow() { XCTAssertEqual(tableView.indexPathForLastRow, IndexPath(row: 7, section: 1)) } - + func testLastSection() { XCTAssertEqual(tableView.lastSection, 1) XCTAssertEqual(emptyTableView.lastSection, 0) } - + func testNumberOfRows() { XCTAssertEqual(tableView.numberOfRows(), 13) XCTAssertEqual(emptyTableView.numberOfRows(), 0) } - + func testIndexPathForLastRowInSection() { XCTAssertNil(tableView.indexPathForLastRow(inSection: -1)) XCTAssertEqual(tableView.indexPathForLastRow(inSection: 0), IndexPath(row: 4, section: 0)) XCTAssertEqual(UITableView().indexPathForLastRow(inSection: 0), IndexPath(row: 0, section: 0)) } - + func testReloadData() { - let exp = expectation(description: "reloadCallback") + let exp = expectation(description: "reloadCallback") tableView.reloadData { XCTAssert(true) - exp.fulfill() + exp.fulfill() } - waitForExpectations(timeout: 5, handler: nil) + waitForExpectations(timeout: 5, handler: nil) } - + func testRemoveTableFooterView() { tableView.tableFooterView = UIView() XCTAssertNotNil(tableView.tableFooterView) tableView.removeTableFooterView() XCTAssertNil(tableView.tableFooterView) } - + func testRemoveTableHeaderView() { tableView.tableHeaderView = UIView() XCTAssertNotNil(tableView.tableHeaderView) tableView.removeTableHeaderView() XCTAssertNil(tableView.tableHeaderView) } - + func testScrollToBottom() { let bottomOffset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.bounds.size.height) tableView.scrollToBottom() XCTAssertEqual(bottomOffset, tableView.contentOffset) } - + func testScrollToTop() { tableView.scrollToTop() XCTAssertEqual(CGPoint.zero, tableView.contentOffset) } - + func testDequeueReusableCellWithClass() { tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell") let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) XCTAssertNotNil(cell) } - + func testDequeueReusableCellWithClassForIndexPath() { tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell") let indexPath = tableView.indexPathForLastRow! let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self, for: indexPath) XCTAssertNotNil(cell) } - + func testDequeueReusableHeaderFooterView() { - tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "UITableViewHeaderFooterView") + tableView.register(UITableViewHeaderFooterView.self, + forHeaderFooterViewReuseIdentifier: "UITableViewHeaderFooterView") let headerFooterView = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) XCTAssertNotNil(headerFooterView) } - + #if os(iOS) func testRegisterReusableViewWithClassAndNib() { let nilView = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) @@ -106,7 +107,7 @@ final class UITableViewExtensionsTests: XCTestCase { XCTAssertNotNil(view) } #endif - + func testRegisterReusableViewWithClass() { let nilView = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) XCTAssertNil(nilView) @@ -114,7 +115,7 @@ final class UITableViewExtensionsTests: XCTestCase { let view = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) XCTAssertNotNil(view) } - + func testRegisterCellWithClass() { let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) XCTAssertNil(nilCell) @@ -122,7 +123,7 @@ final class UITableViewExtensionsTests: XCTestCase { let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) XCTAssertNotNil(cell) } - + #if os(iOS) func testRegisterCellWithClassAndNib() { let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) @@ -133,25 +134,25 @@ final class UITableViewExtensionsTests: XCTestCase { XCTAssertNotNil(cell) } #endif - - #if os(iOS) - func testRegisterCellWithNibUsingClass() { - let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) - XCTAssertNil(nilCell) - tableView.register(nibWithCellClass: UITableViewCell.self, at: UITableViewExtensionsTests.self) - let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) - XCTAssertNotNil(cell) - } - #endif + + #if os(iOS) + func testRegisterCellWithNibUsingClass() { + let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) + XCTAssertNil(nilCell) + tableView.register(nibWithCellClass: UITableViewCell.self, at: UITableViewExtensionsTests.self) + let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) + XCTAssertNotNil(cell) + } + #endif } extension UITableViewExtensionsTests: UITableViewDataSource { - + func numberOfSections(in tableView: UITableView) -> Int { return tableView == self.emptyTableView ? 0 : 2 } - + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if tableView == self.emptyTableView { return 0 @@ -159,11 +160,11 @@ extension UITableViewExtensionsTests: UITableViewDataSource { return section == 0 ? 5 : 8 } } - + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return UITableViewCell() } - + } #endif diff --git a/Tests/UIKitTests/UITextFieldExtensionsTests.swift b/Tests/UIKitTests/UITextFieldExtensionsTests.swift index 8f6caef67..e6711520b 100644 --- a/Tests/UIKitTests/UITextFieldExtensionsTests.swift +++ b/Tests/UIKitTests/UITextFieldExtensionsTests.swift @@ -11,7 +11,7 @@ import XCTest #if os(iOS) || os(tvOS) final class UITextFieldExtensionsTests: XCTestCase { - + func testIsEmpty() { let textField = UITextField() XCTAssert(textField.isEmpty) @@ -20,7 +20,7 @@ final class UITextFieldExtensionsTests: XCTestCase { textField.text = nil XCTAssert(textField.isEmpty) } - + func testTrimmedText() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let textField = UITextField(frame: frame) @@ -28,7 +28,7 @@ final class UITextFieldExtensionsTests: XCTestCase { XCTAssertNotNil(textField.trimmedText) XCTAssertEqual(textField.trimmedText!, "Hello") } - + func testTextType() { let tf1 = UITextField(frame: .zero) tf1.textType = .emailAddress @@ -38,7 +38,7 @@ final class UITextFieldExtensionsTests: XCTestCase { XCTAssertEqual(tf1.autocapitalizationType, .none) XCTAssertFalse(tf1.isSecureTextEntry) XCTAssertEqual(tf1.placeholder, "Email Address") - + let tf2 = UITextField(frame: .zero) tf2.textType = .password XCTAssertEqual(tf2.textType, .password) @@ -54,7 +54,7 @@ final class UITextFieldExtensionsTests: XCTestCase { XCTAssertFalse(tf3.isSecureTextEntry) } - + func testHasValidEmail() { let textField = UITextField(frame: .zero) textField.text = "john@doe.com" @@ -64,49 +64,47 @@ final class UITextFieldExtensionsTests: XCTestCase { textField.text = nil XCTAssertFalse(textField.hasValidEmail) } - + func testLeftViewTintColor() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let textField = UITextField(frame: frame) - + let imageView = UIImageView() imageView.tintColor = .red - + textField.leftView = imageView XCTAssertEqual(textField.leftViewTintColor, .red) - + textField.leftViewTintColor = .blue XCTAssertEqual(textField.leftViewTintColor, .blue) - + textField.leftView = nil XCTAssertNil(textField.leftViewTintColor) - + textField.leftViewTintColor = .yellow XCTAssertNil(textField.leftViewTintColor) - } - + func testRightViewTintColor() { - let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let textField = UITextField(frame: frame) - + let imageView = UIImageView() imageView.tintColor = .red - + textField.rightView = imageView XCTAssertEqual(textField.rightViewTintColor, .red) - + textField.rightViewTintColor = .blue XCTAssertEqual(textField.rightViewTintColor, .blue) - + textField.rightView = nil XCTAssertNil(textField.rightViewTintColor) - + textField.rightViewTintColor = .yellow XCTAssertNil(textField.rightViewTintColor) } - + func testClear() { let frame = CGRect(x: 0, y: 0, width: 100, height: 30) let textField = UITextField(frame: frame) @@ -114,35 +112,36 @@ final class UITextFieldExtensionsTests: XCTestCase { textField.clear() XCTAssertEqual(textField.text!, "") } - + func testSetPlaceHolderTextColor() { let textField = UITextField() textField.attributedPlaceholder = NSAttributedString(string: "Attributed Placeholder") textField.setPlaceHolderTextColor(.blue) let color = textField.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor XCTAssertEqual(color, .blue) - + textField.placeholder = nil textField.setPlaceHolderTextColor(.yellow) let emptyColor = textField.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor XCTAssertNil(emptyColor) } - - func testAddPaddingLeft() { - let textfield = UITextField() - textfield.frame = CGRect(x: 0, y: 0, width: 100, height: 30) - textfield.addPaddingLeft(40) - XCTAssertEqual(textfield.leftView?.frame.width, 40) - } - - func testAddPaddingImageIcon() { - let textfield = UITextField() - textfield.frame = CGRect(x: 0, y: 0, width: 100, height: 44) - - let bundle = Bundle.init(for: UIImageExtensionsTests.self) - let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! - textfield.addPaddingLeftIcon(image, padding: 5) - XCTAssertEqual(textfield.leftView?.frame.width, image.size.width + 5) - } + + func testAddPaddingLeft() { + let textfield = UITextField() + textfield.frame = CGRect(x: 0, y: 0, width: 100, height: 30) + textfield.addPaddingLeft(40) + XCTAssertEqual(textfield.leftView?.frame.width, 40) + } + + func testAddPaddingImageIcon() { + let textfield = UITextField() + textfield.frame = CGRect(x: 0, y: 0, width: 100, height: 44) + + let bundle = Bundle.init(for: UIImageExtensionsTests.self) + let image = UIImage(named: "TestImage", in: bundle, compatibleWith: nil)! + textfield.addPaddingLeftIcon(image, padding: 5) + XCTAssertEqual(textfield.leftView?.frame.width, image.size.width + 5) + } + } #endif diff --git a/Tests/UIKitTests/UITextViewExtensionsTests.swift b/Tests/UIKitTests/UITextViewExtensionsTests.swift index 25ede2f68..1ead9b9e7 100644 --- a/Tests/UIKitTests/UITextViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITextViewExtensionsTests.swift @@ -11,35 +11,34 @@ import XCTest #if os(iOS) || os(tvOS) final class UITextViewExtensionsTests: XCTestCase { - + var textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) - + override func setUp() { super.setUp() } - + func testClear() { textView.text = "Hello" textView.clear() XCTAssertEqual(textView.text, "") XCTAssertEqual(textView.attributedText?.string, "") } - + func testScroll() { let text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation." textView.text = text textView.scrollToBottom() XCTAssertNotEqual(textView.contentOffset.y, 0.0) #if os(iOS) - XCTAssertEqual(textView.contentOffset.y, 87.0) + XCTAssertEqual(textView.contentOffset.y, 87.0) #elseif os(tvOS) - XCTAssertEqual(textView.contentOffset.y, 3370.0) + XCTAssertEqual(textView.contentOffset.y, 3370.0) #endif - + textView.scrollToTop() XCTAssertNotEqual(textView.contentOffset.y, 0.0) - } - + } #endif diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index 1e7b4d90a..06e6f2dc3 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -10,67 +10,73 @@ import XCTest @testable import SwifterSwift - + final class UIViewControllerExtensionsTests: XCTestCase { - - class MockNotificationViewController: UIViewController { - var notificationFired = false - + + class MockNotificationViewController: UIViewController { + var notificationFired = false + @objc func testSelector() { - notificationFired = true - } - } - - let notificationIdentifier = Notification.Name("MockNotification") - - func testAddNotificationObserver() { - let viewController = MockNotificationViewController() - let selector = #selector(MockNotificationViewController.testSelector) - viewController.addNotificationObserver(name: notificationIdentifier, selector: selector) - NotificationCenter.default.post(name: notificationIdentifier, object: nil) - XCTAssert(viewController.notificationFired) - } - + notificationFired = true + } + } + + let notificationIdentifier = Notification.Name("MockNotification") + + func testAddNotificationObserver() { + let viewController = MockNotificationViewController() + let selector = #selector(MockNotificationViewController.testSelector) + viewController.addNotificationObserver(name: notificationIdentifier, selector: selector) + NotificationCenter.default.post(name: notificationIdentifier, object: nil) + XCTAssert(viewController.notificationFired) + } + func testIsVisible() { let viewController = UIViewController() XCTAssertFalse(viewController.isVisible) } - - func testRemoveNotificationObserver() { - let viewController = MockNotificationViewController() - let selector = #selector(MockNotificationViewController.testSelector) - viewController.addNotificationObserver(name: notificationIdentifier, selector: selector) - viewController.removeNotificationObserver(name: notificationIdentifier) - NotificationCenter.default.post(name: notificationIdentifier, object: nil) - XCTAssertFalse(viewController.notificationFired) - } - - func testRemoveNotificationsObserver() { - let viewController = MockNotificationViewController() - let selector = #selector(MockNotificationViewController.testSelector) - viewController.addNotificationObserver(name: notificationIdentifier, selector: selector) - viewController.removeNotificationsObserver() - NotificationCenter.default.post(name: notificationIdentifier, object: nil) - XCTAssertFalse(viewController.notificationFired) - } - - func testShowAlert() { - let viewController = UIViewController() - UIApplication.shared.keyWindow?.rootViewController = viewController - let title = "test title" - let message = "test message" - let actionButtons = ["OK", "Cancel"] - let preferredButtonIndex = 1 - let alertController = viewController.showAlert(title: title, message: message, buttonTitles: actionButtons, highlightedButtonIndex: preferredButtonIndex, completion: nil) - XCTAssertEqual(alertController.preferredStyle, .alert) - XCTAssertEqual(alertController.title, title) - XCTAssertEqual(alertController.message, message) - //check whether the buttons are added in the same order - for i in 0.. Date: Sun, 8 Apr 2018 17:43:12 +0300 Subject: [PATCH 134/201] Add SwiftLint to test targets (#433) --- CHANGELOG.md | 3 +- .../Deprecated/SwiftStdlibDeprecated.swift | 4 --- .../SwiftStdlib/SequenceExtensions.swift | 6 ++-- SwifterSwift.xcodeproj/project.pbxproj | 30 ++++++++++++++++++- .../SequenceExtensionsTests.swift | 7 +++-- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a86ba3430..b56749cce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - added `removingSuffix(_ suffix:)` method to remove given suffix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). - **SwiftLint**: - reduced the number of disabled rules in _.swiftlint.yml_, please add `disable` and `enable` statements from now on when needed in code. - + - added SwiftLint to test targets to insure code style consistency across the project. + ### Changed - **SignedNumeric**: - `asLocaleCurrency` now returns an optional string. diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index d183cd606..dec402bc4 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -5,7 +5,6 @@ // Copyright © 2016 SwifterSwift // -// MARK: - Properties public extension Bool { /// SwifterSwift: Return inversed value of bool. @@ -20,7 +19,6 @@ public extension Bool { } -// MARK: - Methods public extension Bool { @discardableResult @@ -39,7 +37,6 @@ public extension Bool { } - extension String { /// SwifterSwift: Number of characters in string. @@ -128,7 +125,6 @@ public extension Array { } -// MARK: - Methods (Equatable) public extension Array where Element: Equatable { /// SwifterSwift: Return array with all duplicate elements removed. diff --git a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift index 5b6f3746a..aa4a5da2d 100644 --- a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift @@ -9,6 +9,7 @@ import Foundation public extension Sequence { + /// SwifterSwift: Check if all elements in collection match a conditon. /// /// [2, 2, 4].all(matching: {$0 % 2 == 0}) -> true @@ -19,7 +20,7 @@ public extension Sequence { public func all(matching condition: (Element) throws -> Bool) rethrows -> Bool { return try !contains { try !condition($0) } } - + /// SwifterSwift: Check if no elements in collection match a conditon. /// /// [2, 2, 4].none(matching: {$0 % 2 == 0}) -> false @@ -30,7 +31,7 @@ public extension Sequence { public func none(matching condition: (Element) throws -> Bool) rethrows -> Bool { return try !contains { try condition($0) } } - + /// SwifterSwift: Check if any element in collection match a conditon. /// /// [2, 2, 4].any(matching: {$0 % 2 == 0}) -> false @@ -41,4 +42,5 @@ public extension Sequence { public func any(matching condition: (Element) throws -> Bool) rethrows -> Bool { return try contains { try condition($0) } } + } diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 1394d756f..33b69cded 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -1077,6 +1077,7 @@ 07C50CC51F5EAF2700F46E5A /* Sources */, 07C50CC61F5EAF2700F46E5A /* Frameworks */, 07C50CC71F5EAF2700F46E5A /* Resources */, + 0763D8C5207A1931000029F3 /* ShellScript */, ); buildRules = ( ); @@ -1114,6 +1115,7 @@ 07C50CE31F5EAF6300F46E5A /* Sources */, 07C50CE41F5EAF6300F46E5A /* Frameworks */, 07C50CE51F5EAF6300F46E5A /* Resources */, + 0763D8C6207A193D000029F3 /* ShellScript */, ); buildRules = ( ); @@ -1267,7 +1269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = ""; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; 074EAF161F7B859500C74636 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -1321,6 +1323,32 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; + 0763D8C5207A1931000029F3 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; + 0763D8C6207A193D000029F3 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift index 9248b0c38..c99267eb0 100644 --- a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift @@ -10,19 +10,20 @@ import XCTest @testable import SwifterSwift final class SequenceExtensionsTests: XCTestCase { - + func testAllMatch() { let collection = [2, 4, 6, 8, 10, 12] XCTAssert(collection.all { $0 % 2 == 0 }) } - + func testAnyMatch() { let collection = [3, 5, 8, 9, 11, 13] XCTAssert(collection.any { $0 % 2 == 0 }) } - + func testNoneMatch() { let collection = [3, 5, 7, 9, 11, 13] XCTAssert(collection.none { $0 % 2 == 0 }) } + } From ead1c8bb7a77e8b7337555f365a9b6d479737991 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 8 Apr 2018 21:35:18 +0300 Subject: [PATCH 135/201] v4.3 (#435) --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .gitignore | 11 +++-- CHANGELOG.md | 8 +--- CONTRIBUTING.md | 73 ++++++++++++++++++-------------- README.md | 17 +++++--- 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index fcc0a732f..24e5e5874 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,4 +9,4 @@ - [ ] I have added tests for new extensions, and they passed. - [ ] All extensions have a **clear** comments explaining their functionality, all parameters and return type in English. - [ ] All extensions are declared as **public**. -- [ ] I have added a changelog entry describing my changes. +- [ ] I have added a [changelog](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG_GUIDELINES.md) entry describing my changes. diff --git a/.gitignore b/.gitignore index b2670c6ad..4226d70f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Xcode +## Xcode .DS_Store ## Build generated @@ -31,15 +31,14 @@ xcuserdata/ timeline.xctimeline playground.xcworkspace -# Swift Package Manager +## Swift Package Manager .build/ -# CocoaPods +## CocoaPods Pods/ -# Carthage +## Carthage Carthage/Build -# Jazzy docs -############ +## Jazzy docs docs/ diff --git a/CHANGELOG.md b/CHANGELOG.md index b56749cce..a7de23148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,9 @@ # CHANGELOG The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. -# Upcoming release - - > # Upcoming release > -> ### Added > ### Added +> ### Added > ### Changed > ### Deprecated > ### Removed @@ -56,13 +53,10 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - deprecated `toggled` property, use `!self` instead. - deprecated `toggle` method, use `self = !self` instead. -### Removed - ### Fixed - **String** - Fixed UIView extension `addShadow` was not showing the shadow on view bug. [#420](https://github.com/SwifterSwift/SwifterSwift/pull/420) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -### Security --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0dafacccc..d42394ce5 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,6 +11,7 @@ This document contains information and guidelines about contributing to this pro - [Adding changelog entries](#adding-changelog-entries) - [Reporting Issues](#reporting-issues) + --- @@ -21,33 +22,9 @@ For any usage questions that are not specific to the project itself, please ask By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows us to focus on improving the project for others. ---- - -## Reporting Issues -A great way to contribute to the project is to send a detailed issue when you encounter an problem. -We always appreciate a well-written, thorough bug report. - -Check that the project issues database doesn't already include that problem or suggestion before submitting an issue. -If you find a match, add a quick "**+1**" or "**I have this problem too**". -Doing this helps prioritize the most common problems and requests. --- -**When reporting issues, please include the following:** - -- What did you do? -- What did you expect to happen? -- What happened instead? -- SwifterSwift version -- Xcode version -- macOS version running Xcode -- Swift version -- Platform(s) running SwifterSwift -- Demo Project (if available) - -This information will help us review and fix your issue faster. - - ## Ways to Contribute @@ -58,10 +35,11 @@ You can contribute to the project in a variety of ways: - Add missing unit tests 😅 - Fixing or reporting bugs 😱 -If you're new to Open Source or Swift the SwifterSwift community is a great place to get involved +If you're new to Open Source or Swift the SwifterSwift community is a great place to get involved. **Your contribution is always welcomed, no contribution is too small.** + --- @@ -69,16 +47,19 @@ If you're new to Open Source or Swift the SwifterSwift community is a great plac Please refer to the following rules before submitting a pull request with your new extensions: -- Add your contributions to [**master branch** ](https://github.com/SwifterSwift/SwifterSwift/tree/master): +- Make sure no similar extension already exist in SwifterSwift. +- Add your contributions to [**master branch**](https://github.com/SwifterSwift/SwifterSwift/tree/master): - by doing this we can merge new pull-requests into **master** branch as soon as they are accepted, and add them to the next releases once they are fully tested. - Mention the original source of extension source (if possible) as a comment inside extension: ```swift public extension SomeType { + public name: SomeType { // https://stackoverflow.com/somepage // .. code } + } ``` @@ -87,21 +68,22 @@ public extension SomeType { - Always declare extensions as **public**. - All extensions names should be as clear as possible. - All extensions should be well documented. see [Adding documentation](#adding-documentation) -- Avoid using custom classes and objects the goal for this library is to extend the standards types available natively in Swift, iOS, macOS, watchOS and tvOS. +- Avoid using custom classes and objects the goal for this library is to extend the standards types available natively in Swift, iOS, macOS, watchOS, tvOS and Linux. - Extensions could be: - Enums - Instance properties & type properties - Instance methods & type methods - Initializers + - Structs - All extensions should be tested. -- Files are named based on the type that the contained extensions extend. +- Files are named based on the type that the contained extensions extend. - (example: all String extensions are found in "**StringExtensions.swift**" file) - All extensions files and test files have a one to one relation. - (example: all tests for "**StringExtensions.swift**" are found in the "**StringExtensionsTests.swift**" file) - There should be a one to one relationship between extensions and their backing tests. - Tests should be named using the same API of the extension it backs. - (example: `DateExtensions` method `isBetween` is named `testIsBetween`) -- All test files are named based on the extensions which it tests. +- All test files are named based on the extensions which it tests. - (example: all String extensions tests are found in "**StringExtensionsTests.swift**" file) - Extensions and tests are ordered inside files in the following order: @@ -121,8 +103,6 @@ public extension SomeType {} public extension SomeType {} ``` - - --- ## Adding documentation @@ -203,14 +183,43 @@ In Xcode select a method and press `command` + `alt` + `/` to create a documenta --- + ## Adding changelog entries -The [Changelog](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md) is a file which contains a curated, chronologically ordered list of notable changes for each version of a project. Please make sure to add a changelog entry describing your contribution to it everyting there is a notable change. +The [Changelog](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md) is a file which contains a curated, chronologically ordered list of notable changes for each version of a project. Please make sure to add a changelog entry describing your contribution to it every time there is a notable change. The [Changelog Guidelines](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG_GUIDELINES.md) contains instructions for maintaining (or adding new entries) to the Changelog. + --- + +## Reporting Issues +A great way to contribute to the project is to send a detailed issue when you encounter a problem. +We always appreciate a well-written, thorough bug report. + +Check that the project [issues page](https://github.com/SwifterSwift/SwifterSwift/issues) doesn't already include that problem or suggestion before submitting an issue. +If you find a match, add a quick "**+1**" or "**I have this problem too**". +Doing this helps prioritize the most common problems and requests. + +**When reporting issues, please include the following:** + +- What did you do? +- What did you expect to happen? +- What happened instead? +- SwifterSwift version +- Xcode version +- macOS version running Xcode +- Swift version +- Platform(s) running SwifterSwift +- Demo Project (if available) + +This information will help us review and fix your issue faster. + + +--- + + ## [No Brown M&M's](http://en.wikipedia.org/wiki/Van_Halen#Contract_riders) If you made it all the way to the end, bravo dear user, we love you. You can include the 🚀 emoji in the top of your ticket to signal to us that you did in fact read this file and are trying to conform to it as best as possible: `:rocket:`. diff --git a/README.md b/README.md index 14f4f979d..83c6ed4c8 100755 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ [![docs](http://swifterswift.com/docs/badge.svg)](http://swifterswift.com/docs) [![CocoaPods](https://img.shields.io/cocoapods/dt/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) [![CocoaPods](https://img.shields.io/cocoapods/dm/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) -[![Swift](https://img.shields.io/badge/Swift-4.0-orange.svg)](https://swift.org) -[![Xcode](https://img.shields.io/badge/Xcode-9.0-blue.svg)](https://developer.apple.com/xcode) +[![Swift](https://img.shields.io/badge/Swift-4.1-orange.svg)](https://swift.org) +[![Xcode](https://img.shields.io/badge/Xcode-9.3-blue.svg)](https://developer.apple.com/xcode) [![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) [![Slack Channel](https://slackin-ppvrggbpgn.now.sh/badge.svg)](https://slackin-ppvrggbpgn.now.sh/) -SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. +SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS, watchOS and Linux. ### [Whats New in v4.3.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v430) @@ -114,9 +114,11 @@ let package = Package(
  • FloatingPoint extensions
  • Int extensions
  • Optional extensions
  • +
  • Sequence extensions
  • SignedInteger extensions
  • SignedNumeric extensions
  • String extensions
  • +
  • StringProtocol extensions
  • @@ -128,6 +130,7 @@ let package = Package(
  • Calendar extensions
  • Data extensions
  • Date extensions
  • +
  • FileManager extensions
  • Locale extensions
  • NSAttributedString extensions
  • NSPredicate extensions
  • @@ -158,6 +161,7 @@ let package = Package(
  • UISearchBar extensions
  • UISegmentedControl extensions
  • UISlider extensions
  • +
  • UIStackView extensions
  • UIStoryboard extensions
  • UISwitch extensions
  • UITabBar extensions
  • @@ -251,13 +255,12 @@ Special thanks to: - [Steven Deutsch](https://github.com/SD10) and [Luciano Almeida](https://github.com/LucianoPAlmeida) for their latest contributions to extensions, docs and tests. - [Paweł Urbanek](https://github.com/pawurb) for adding tvOS, watchOS, and macOS initial support and helping with extensions. -- [Mert Akengin](https://github.com/PvtMert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swifterswift.com) and logo. -- [Abdul Rahman Dabbour](https://github.com/thedabbour) for helping document the project. +- [Mert Akengin](https://github.com/pvtmert) and [Bashar Ghadanfar](https://www.behance.net/lionbytes) for designing [project website](http://swifterswift.com) and logo. +- [Abdul Rahman Dabbour](https://github.com/ardabbour) for helping document the project. - Many thanks to all other [contributors](https://github.com/SwifterSwift/SwifterSwift/graphs/contributors) of this project. - ## License -SwifterSwift is released under an MIT license. See [LICENSE](LICENSE) for more information. +SwifterSwift is released under the MIT license. See [LICENSE](https://github.com/SwifterSwift/SwifterSwift/blob/master/LICENSE) for more information. From f5c4b7575d5daee8c1fd329338c927586a0dedc6 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 9 Apr 2018 20:39:31 +0300 Subject: [PATCH 136/201] Signed numeric (#434) --- CHANGELOG.md | 4 ++++ .../SwiftStdlib/SignedIntegerExtensions.swift | 18 +++++++++++++++- .../SwiftStdlib/SignedNumericExtensions.swift | 21 +++++++++++++++++++ .../StringExtensionsTests.swift | 12 +++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7de23148..0ffe830b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `all()` method moved from ArrayExtensions to SequenceExtensions. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). - `none()` method moved from ArrayExtensions to SequenceExtensions. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). - Added `any()` method to return if any element of sequence elements conforms to given condition. [#424](https://github.com/SwifterSwift/SwifterSwift/pull/424) by [n0an](https://github.com/n0an). +- **SignedInteger** + - added `ordinalString(locale:)` method to return string ordinal representation of number in specified locale language. [#434](https://github.com/SwifterSwift/SwifterSwift/pull/434) by [n0an](https://github.com/n0an). +- **SignedNumeric** + - added `spelledOutString(locale:)` method to return string representation of number spelled in specified locale language. [#434](https://github.com/SwifterSwift/SwifterSwift/pull/434) by [n0an](https://github.com/n0an). - **String** - added computed property `isSpelledCorrectly` to check if the given string has typos or not. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). - added `removingPrefix(_ prefix:)` method to remove given prefix from the string. [#430](https://github.com/SwifterSwift/SwifterSwift/pull/430) by [n0an](https://github.com/n0an). diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index e6e149eca..d93b6ec47 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -78,5 +78,21 @@ public extension SignedInteger { return (self * n).abs / gcd(of: n) } // swiftlint:enable identifier_name - + + #if canImport(Foundation) + @available(iOS 9.0, macOS 10.11, *) + /// SwifterSwift: Ordinal representation of an integer. + /// + /// print((12).ordinalString()) // prints "12th" + /// + /// - Parameter locale: Locale, default is .current. + /// - Returns: String ordinal representation of number in specified locale language. E.g. input 92, output in "en": "92nd" + public func ordinalString(locale: Locale = .current) -> String? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.numberStyle = .ordinal + guard let number = self as? NSNumber else { return nil } + return formatter.string(from: number) + } + #endif } diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index 9238f21fe..766bea2e4 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -25,3 +25,24 @@ public extension SignedNumeric { } } + +// MARK: - Methods +public extension SignedNumeric { + + /// SwifterSwift: Spelled out representation of a number. + /// + /// print((12.32).spelledOutString()) // prints "twelve point three two" + /// + /// - Parameter locale: Locale, default is .current. + /// - Returns: String representation of number spelled in specified locale language. E.g. input 92, output in "en": "ninety-two" + #if canImport(Foundation) + public func spelledOutString(locale: Locale = .current) -> String? { + let formatter = NumberFormatter() + formatter.locale = locale + formatter.numberStyle = .spellOut + + guard let number = self as? NSNumber else { return nil } + return formatter.string(from: number) + } + #endif +} diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index e08a7b5a1..6b3ed3ba7 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -715,6 +715,18 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(testString * -5, "") XCTAssertEqual(-5 * testString, "") } + + func testIntSpellOut() { + let num = 12.32 + XCTAssertNotNil(num.spelledOutString(locale: Locale(identifier: "en_US"))) + XCTAssertEqual(num.spelledOutString(locale: Locale(identifier: "en_US")), "twelve point three two") + } + + func testIntOrdinal() { + let num = 12 + XCTAssertNotNil(num.ordinalString()) + XCTAssertEqual(num.ordinalString(), "12th") + } } // swiftlint:enable type_body_length From d5e470c4a12cb59ce4848fcfdf358cca242008b1 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 10 Apr 2018 13:34:57 -0300 Subject: [PATCH 137/201] updating travis osximage (#436) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1fcd4c2ba..64ef308a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.3beta +osx_image: xcode9.3 env: global: From 627595520806b8acb521a346f73f7bda2ad34f49 Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Tue, 10 Apr 2018 20:03:58 +0200 Subject: [PATCH 138/201] Remove warnings and dead references (#440) --- .../SwiftStdlib/SignedIntegerExtensions.swift | 2 +- .../SwiftStdlib/SignedNumericExtensions.swift | 4 ++-- SwifterSwift.xcodeproj/project.pbxproj | 10 ---------- Tests/SwiftStdlibTests/StringExtensionsTests.swift | 4 ++-- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index d93b6ec47..cfa760fb1 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -78,7 +78,7 @@ public extension SignedInteger { return (self * n).abs / gcd(of: n) } // swiftlint:enable identifier_name - + #if canImport(Foundation) @available(iOS 9.0, macOS 10.11, *) /// SwifterSwift: Ordinal representation of an integer. diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index 766bea2e4..b3b3e6d7a 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -28,7 +28,7 @@ public extension SignedNumeric { // MARK: - Methods public extension SignedNumeric { - + /// SwifterSwift: Spelled out representation of a number. /// /// print((12.32).spelledOutString()) // prints "twelve point three two" @@ -40,7 +40,7 @@ public extension SignedNumeric { let formatter = NumberFormatter() formatter.locale = locale formatter.numberStyle = .spellOut - + guard let number = self as? NSNumber else { return nil } return formatter.string(from: number) } diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 33b69cded..4ea9f8ad8 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -415,7 +415,6 @@ /* Begin PBXFileReference section */ 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; - 07263D5C1FB3175F003CE515 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensions.swift; sourceTree = ""; }; 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; @@ -611,14 +610,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 071306651FB596600023A9D8 /* Recovered References */ = { - isa = PBXGroup; - children = ( - 07263D5C1FB3175F003CE515 /* FoundationDeprecated.swift */, - ); - name = "Recovered References"; - sourceTree = ""; - }; 0713066D1FB5977F0023A9D8 /* Deprecated */ = { isa = PBXGroup; children = ( @@ -686,7 +677,6 @@ 07898B8D1F278E6300558C97 /* Sources */, 07C50CF21F5EAF7B00F46E5A /* Tests */, 07898B5E1F278D7600558C97 /* Products */, - 071306651FB596600023A9D8 /* Recovered References */, ); sourceTree = ""; }; diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 6b3ed3ba7..79f3b8865 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -715,13 +715,13 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(testString * -5, "") XCTAssertEqual(-5 * testString, "") } - + func testIntSpellOut() { let num = 12.32 XCTAssertNotNil(num.spelledOutString(locale: Locale(identifier: "en_US"))) XCTAssertEqual(num.spelledOutString(locale: Locale(identifier: "en_US")), "twelve point three two") } - + func testIntOrdinal() { let num = 12 XCTAssertNotNil(num.ordinalString()) From 686c6178ea64e7e1aea6772f40ebc35a6f3b890a Mon Sep 17 00:00:00 2001 From: Joan Disho Date: Wed, 11 Apr 2018 01:25:34 +0200 Subject: [PATCH 139/201] Update UITableView and UICollectionView Extensions (#439) * return not an optional value in "dequeueReusable..." in UICollectionView and UITableView Extentions. * pass tests for UITableViewExtentionsTests * remove the unnecessary "?" * refactor fatalError messages in UICollection and UITableView Extensions. * added a changelog about UITableView and UICollectionView Extensions --- CHANGELOG.md | 6 ++++ .../UIKit/UICollectionViewExtensions.swift | 16 +++++++--- .../UIKit/UITableViewExtensions.swift | 31 ++++++++++++------- .../UITableViewExtensionsTests.swift | 10 ------ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ffe830b3..516b31f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > > ### Added > ### Changed +- **UITableViewExtentions**: + - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) + - `dequeueReusableHeaderFooterView(withClass)`now returns `UITableViewHeaderFooterView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) +- **UICollectionView**: + - `dequeueReusableCell(withClass:for)` now return `UICollectionViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) + - `dequeueReusableSupplementaryView(ofKind:withClass:for)`now returns `UICollectionReusableView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) > ### Deprecated > ### Removed > ### Fixed diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index ea7c33418..562cc16b0 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -75,9 +75,12 @@ public extension UICollectionView { /// - name: UICollectionViewCell type. /// - indexPath: location of cell in collectionView. /// - Returns: UICollectionViewCell object with associated class name. - public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { - return dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as? T - } + public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T { + guard let cell = dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as? T else { + fatalError("Couldn't find UICollectionViewCell for \(String(describing: name))") + } + return cell + } /// SwifterSwift: Dequeue reusable UICollectionReusableView using class name. /// @@ -86,8 +89,11 @@ public extension UICollectionView { /// - name: UICollectionReusableView type. /// - indexPath: location of cell in collectionView. /// - Returns: UICollectionReusableView object with associated class name. - public func dequeueReusableSupplementaryView(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T? { - return dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as? T + public func dequeueReusableSupplementaryView(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T { + guard let cell = dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as? T else { + fatalError("Couldn't find UICollectionReusableView for \(String(describing: name))") + } + return cell } /// SwifterSwift: Register UICollectionReusableView using class name. diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index c17bd9559..9ad2f9433 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -92,10 +92,13 @@ public extension UITableView { /// SwifterSwift: Dequeue reusable UITableViewCell using class name /// /// - Parameter name: UITableViewCell type - /// - Returns: UITableViewCell object with associated class name (optional value) - public func dequeueReusableCell(withClass name: T.Type) -> T? { - return dequeueReusableCell(withIdentifier: String(describing: name)) as? T - } + /// - Returns: UITableViewCell object with associated class name. + public func dequeueReusableCell(withClass name: T.Type) -> T { + guard let cell = dequeueReusableCell(withIdentifier: String(describing: name)) as? T else { + fatalError("Couldn't find UITableViewCell for \(String(describing: name))") + } + return cell + } /// SwiferSwift: Dequeue reusable UITableViewCell using class name for indexPath /// @@ -103,17 +106,23 @@ public extension UITableView { /// - name: UITableViewCell type. /// - indexPath: location of cell in tableView. /// - Returns: UITableViewCell object with associated class name. - public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T? { - return dequeueReusableCell(withIdentifier: String(describing: name), for: indexPath) as? T - } + public func dequeueReusableCell(withClass name: T.Type, for indexPath: IndexPath) -> T { + guard let cell = dequeueReusableCell(withIdentifier: String(describing: name), for: indexPath) as? T else { + fatalError("Couldn't find UITableViewCell for \(String(describing: name))") + } + return cell + } /// SwiferSwift: Dequeue reusable UITableViewHeaderFooterView using class name /// /// - Parameter name: UITableViewHeaderFooterView type - /// - Returns: UITableViewHeaderFooterView object with associated class name (optional value) - public func dequeueReusableHeaderFooterView(withClass name: T.Type) -> T? { - return dequeueReusableHeaderFooterView(withIdentifier: String(describing: name)) as? T - } + /// - Returns: UITableViewHeaderFooterView object with associated class name. + public func dequeueReusableHeaderFooterView(withClass name: T.Type) -> T { + guard let headerFooterView = dequeueReusableHeaderFooterView(withIdentifier: String(describing: name)) as? T else { + fatalError("Couldn't find UITableViewHeaderFooterView for \(String(describing: name))") + } + return headerFooterView + } /// SwifterSwift: Register UITableViewHeaderFooterView using class name /// diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 69357fb83..96e3a1991 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -99,8 +99,6 @@ final class UITableViewExtensionsTests: XCTestCase { #if os(iOS) func testRegisterReusableViewWithClassAndNib() { - let nilView = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) - XCTAssertNil(nilView) let nib = UINib(nibName: "UITableViewHeaderFooterView", bundle: Bundle(for: UITableViewExtensionsTests.self)) tableView.register(nib: nib, withHeaderFooterViewClass: UITableViewHeaderFooterView.self) let view = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) @@ -109,16 +107,12 @@ final class UITableViewExtensionsTests: XCTestCase { #endif func testRegisterReusableViewWithClass() { - let nilView = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) - XCTAssertNil(nilView) tableView.register(headerFooterViewClassWith: UITableViewHeaderFooterView.self) let view = tableView.dequeueReusableHeaderFooterView(withClass: UITableViewHeaderFooterView.self) XCTAssertNotNil(view) } func testRegisterCellWithClass() { - let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) - XCTAssertNil(nilCell) tableView.register(cellWithClass: UITableViewCell.self) let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) XCTAssertNotNil(cell) @@ -126,8 +120,6 @@ final class UITableViewExtensionsTests: XCTestCase { #if os(iOS) func testRegisterCellWithClassAndNib() { - let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) - XCTAssertNil(nilCell) let nib = UINib(nibName: "UITableViewCell", bundle: Bundle(for: UITableViewExtensionsTests.self)) tableView.register(nib: nib, withCellClass: UITableViewCell.self) let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) @@ -137,8 +129,6 @@ final class UITableViewExtensionsTests: XCTestCase { #if os(iOS) func testRegisterCellWithNibUsingClass() { - let nilCell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) - XCTAssertNil(nilCell) tableView.register(nibWithCellClass: UITableViewCell.self, at: UITableViewExtensionsTests.self) let cell = tableView.dequeueReusableCell(withClass: UITableViewCell.self) XCTAssertNotNil(cell) From 8e6a8ace0865b801abe011ca7db19a3844241d54 Mon Sep 17 00:00:00 2001 From: Seto Elkahfi Date: Wed, 11 Apr 2018 17:52:40 +0700 Subject: [PATCH 140/201] Add isValidIndexPath to UITableViewExtensions (#441) --- CHANGELOG.md | 2 ++ Sources/Extensions/UIKit/UITableViewExtensions.swift | 8 ++++++++ Tests/UIKitTests/UITableViewExtensionsTests.swift | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 516b31f92..d789a3451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > # Upcoming release > > ### Added +- **UITableViewExtentions**: + - Added `isValidIndexPath(_ indexPath:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). > ### Changed - **UITableViewExtentions**: - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index 9ad2f9433..42efa0f53 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -173,6 +173,14 @@ public extension UITableView { register(UINib(nibName: identifier, bundle: bundle), forCellReuseIdentifier: identifier) } + /// SwifterSwift: Check whether IndexPath is valid within the tableView + /// + /// - Parameter indexPath: An IndexPath to check + /// - Returns: Boolean value for valid or invalid IndexPath + public func isValidIndexPath(_ indexPath: IndexPath) -> Bool { + return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section) + } + } #endif diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 96e3a1991..523d86d7e 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -97,6 +97,13 @@ final class UITableViewExtensionsTests: XCTestCase { XCTAssertNotNil(headerFooterView) } + func testIsValidIndexPath() { + let validIndexPath = IndexPath(row: 0, section: 0) + XCTAssertTrue(tableView.isValidIndexPath(validIndexPath)) + let invalidIndexPath = IndexPath(row: 10, section: 0) + XCTAssertFalse(tableView.isValidIndexPath(invalidIndexPath)) + } + #if os(iOS) func testRegisterReusableViewWithClassAndNib() { let nib = UINib(nibName: "UITableViewHeaderFooterView", bundle: Bundle(for: UITableViewExtensionsTests.self)) From 0bb4f03b1f59ff6b2cb058903a594d6f53678b1a Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Fri, 13 Apr 2018 09:20:51 +0300 Subject: [PATCH 141/201] Optional extensions (#442) --- .swiftlint.yml | 2 - CHANGELOG.md | 23 ++-- .../CoreGraphics/CGPointExtensions.swift | 9 +- .../Extensions/Shared/ColorExtensions.swift | 12 +- .../Deprecated/SwiftStdlibDeprecated.swift | 3 +- .../SwiftStdlib/DoubleExtensions.swift | 3 +- .../SwiftStdlib/FloatExtensions.swift | 3 +- .../SwiftStdlib/FloatingPointExtensions.swift | 6 +- .../SwiftStdlib/IntExtensions.swift | 12 +- .../SwiftStdlib/OptionalExtensions.swift | 105 ++++++++++-------- .../SwiftStdlib/SignedIntegerExtensions.swift | 6 +- .../SwiftStdlib/SignedNumericExtensions.swift | 3 +- .../SwiftStdlib/StringExtensions.swift | 12 +- .../UIKit/UITextViewExtensions.swift | 4 +- .../Extensions/UIKit/UIViewExtensions.swift | 6 +- .../FoundationTests/DateExtensionsTests.swift | 9 +- Tests/SharedTests/ColorExtensionsTests.swift | 3 +- .../ArrayExtensionsTests.swift | 3 +- .../OptionalExtensionsTests.swift | 24 ++++ .../StringExtensionsTests.swift | 23 ++-- 20 files changed, 144 insertions(+), 127 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 965d20a52..6ca479806 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,5 +1,3 @@ disabled_rules: - line_length - file_length -- legacy_constructor -- xctfail_message diff --git a/CHANGELOG.md b/CHANGELOG.md index d789a3451..203bcfe43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,29 @@ # CHANGELOG The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. -> # Upcoming release -> -> ### Added +# Upcoming release + +### Added - **UITableViewExtentions**: - Added `isValidIndexPath(_ indexPath:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). -> ### Changed +**Optional**: + - Added `isNilOrEmpty` property to check whether an optional is nil or empty collection. + +### Changed - **UITableViewExtentions**: - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableHeaderFooterView(withClass)`now returns `UITableViewHeaderFooterView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - **UICollectionView**: - `dequeueReusableCell(withClass:for)` now return `UICollectionViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableSupplementaryView(ofKind:withClass:for)`now returns `UICollectionReusableView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) -> ### Deprecated -> ### Removed -> ### Fixed -> ### Security + +### Deprecated + +### Removed + +### Fixed + +### Security --- diff --git a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift index d5784504d..7dceb5c63 100644 --- a/Sources/Extensions/CoreGraphics/CGPointExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGPointExtensions.swift @@ -80,9 +80,8 @@ public extension CGPoint { /// - lhs: self /// - rhs: CGPoint to add. public static func += (lhs: inout CGPoint, rhs: CGPoint) { - // swiftlint:disable shorthand_operator + // swiftlint:disable next shorthand_operator lhs = lhs + rhs - // swiftlint:enable shorthand_operator } /// SwifterSwift: Subtract two CGPoints. @@ -111,9 +110,8 @@ public extension CGPoint { /// - lhs: self /// - rhs: CGPoint to subtract. public static func -= (lhs: inout CGPoint, rhs: CGPoint) { - // swiftlint:disable shorthand_operator + // swiftlint:disable next shorthand_operator lhs = lhs - rhs - // swiftlint:enable shorthand_operator } /// SwifterSwift: Multiply a CGPoint with a scalar @@ -141,9 +139,8 @@ public extension CGPoint { /// - scalar: scalar value. /// - Returns: result of multiplication of the given CGPoint with the scalar. public static func *= (point: inout CGPoint, scalar: CGFloat) { - // swiftlint:disable shorthand_operator + // swiftlint:disable next shorthand_operator point = point * scalar - // swiftlint:enable shorthand_operator } /// SwifterSwift: Multiply a CGPoint with a scalar diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index c91c6be66..99b805a9d 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -32,7 +32,7 @@ public extension Color { return Color(red: red, green: green, blue: blue)! } - // swiftlint:disable large_tuple + // swiftlint:disable next large_tuple /// SwifterSwift: RGB components for a Color (between 0 and 255). /// /// UIColor.red.rgbComponents.red -> 255 @@ -50,9 +50,8 @@ public extension Color { let blue = components[2] return (red: Int(red * 255.0), green: Int(green * 255.0), blue: Int(blue * 255.0)) } - // swiftlint:enable large_tuple - // swiftlint:disable large_tuple + // swiftlint:disable next large_tuple /// SwifterSwift: RGB components for a Color represented as CGFloat numbers (between 0 and 1) /// /// UIColor.red.rgbComponents.red -> 1.0 @@ -70,9 +69,8 @@ public extension Color { let blue = components[2] return (red: red, green: green, blue: blue) } - // swiftlint:enable large_tuple - // swiftlint:disable large_tuple + // swiftlint:disable next large_tuple /// SwifterSwift: Get components of hue, saturation, and brightness, and alpha (read-only). public var hsbaComponents: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) { var hue: CGFloat = 0.0 @@ -83,7 +81,6 @@ public extension Color { getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) return (hue: hue, saturation: saturation, brightness: brightness, alpha: alpha) } - // swiftlint:enable large_tuple /// SwifterSwift: Hexadecimal value string (read-only). public var hexString: String { @@ -357,7 +354,7 @@ public extension Color { } -// swiftlint:disable type_body_length +// swiftlint:disable next type_body_length // MARK: - Social public extension Color { @@ -1805,4 +1802,3 @@ public extension Color { } #endif -// swiftlint:enable type_body_length diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index dec402bc4..86cd98d8e 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -48,7 +48,7 @@ extension String { return count } - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Sliced string from a start index. /// /// "Hello World".slicing(at: 6) -> "World" @@ -62,7 +62,6 @@ extension String { } return self[safe: i.. Double { return pow(lhs, rhs) } -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name prefix operator √ /// SwifterSwift: Square root of double. /// @@ -57,4 +57,3 @@ public prefix func √ (double: Double) -> Double { // http://nshipster.com/swift-operators/ return sqrt(double) } -// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift index e72f1ee99..6f6ccef0d 100755 --- a/Sources/Extensions/SwiftStdlib/FloatExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatExtensions.swift @@ -47,7 +47,7 @@ public func ** (lhs: Float, rhs: Float) -> Float { return pow(lhs, rhs) } -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name prefix operator √ /// SwifterSwift: Square root of float. /// @@ -57,4 +57,3 @@ public prefix func √ (float: Float) -> Float { // http://nshipster.com/swift-operators/ return sqrt(float) } -// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift index 7ce0807bd..833ddc870 100644 --- a/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/FloatingPointExtensions.swift @@ -100,7 +100,7 @@ public extension FloatingPoint { // MARK: - Operators -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name infix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -112,9 +112,8 @@ public func ± (lhs: T, rhs: T) -> (T, T) { // http://nshipster.com/swift-operators/ return (lhs + rhs, lhs - rhs) } -// swiftlint:enable identifier_name -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name prefix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -124,4 +123,3 @@ public prefix func ± (number: T) -> (T, T) { // http://nshipster.com/swift-operators/ return 0 ± number } -// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index b41bcf249..89e44e38c 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -165,12 +165,11 @@ public extension Int { return romanValue } - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Rounds to the closest multiple of n public func roundToNearest(_ n: Int) -> Int { return n == 0 ? self : Int(round(Double(self) / Double(n))) * n } - // swiftlint:enable identifier_name } @@ -210,7 +209,7 @@ public func ** (lhs: Int, rhs: Int) -> Double { return pow(Double(lhs), Double(rhs)) } -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name prefix operator √ /// SwifterSwift: Square root of integer. /// @@ -220,9 +219,8 @@ public prefix func √ (int: Int) -> Double { // http://nshipster.com/swift-operators/ return sqrt(Double(int)) } -// swiftlint:enable identifier_name -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name infix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -234,9 +232,8 @@ public func ± (lhs: Int, rhs: Int) -> (Int, Int) { // http://nshipster.com/swift-operators/ return (lhs + rhs, lhs - rhs) } -// swiftlint:enable identifier_name -// swiftlint:disable identifier_name +// swiftlint:disable next identifier_name prefix operator ± /// SwifterSwift: Tuple of plus-minus operation. /// @@ -246,4 +243,3 @@ public prefix func ± (int: Int) -> (Int, Int) { // http://nshipster.com/swift-operators/ return 0 ± int } -// swiftlint:enable identifier_name diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index f396229b9..3ed386197 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -9,22 +9,22 @@ // MARK: - Methods public extension Optional { - /// SwifterSwift: Get self of default value (if self is nil). - /// - /// let foo: String? = nil - /// print(foo.unwrapped(or: "bar")) -> "bar" - /// - /// let bar: String? = "bar" - /// print(bar.unwrapped(or: "foo")) -> "bar" - /// - /// - Parameter defaultValue: default value to return if self is nil. - /// - Returns: self if not nil or default value if nil. - public func unwrapped(or defaultValue: Wrapped) -> Wrapped { - // http://www.russbishop.net/improving-optionals - return self ?? defaultValue - } + /// SwifterSwift: Get self of default value (if self is nil). + /// + /// let foo: String? = nil + /// print(foo.unwrapped(or: "bar")) -> "bar" + /// + /// let bar: String? = "bar" + /// print(bar.unwrapped(or: "foo")) -> "bar" + /// + /// - Parameter defaultValue: default value to return if self is nil. + /// - Returns: self if not nil or default value if nil. + public func unwrapped(or defaultValue: Wrapped) -> Wrapped { + // http://www.russbishop.net/improving-optionals + return self ?? defaultValue + } - /// SwifterSwift: Gets the wrapped value of an optional. If the optional is `nil`, throw a custom error. + /// SwifterSwift: Gets the wrapped value of an optional. If the optional is `nil`, throw a custom error. /// /// let foo: String? = nil /// try print(foo.unwrapped(or: MyError.notFound)) -> error: MyError.notFound @@ -40,39 +40,50 @@ public extension Optional { return wrapped } - /// SwifterSwift: Runs a block to Wrapped if not nil - /// - /// let foo: String? = nil - /// foo.run { unwrappedFoo in - /// // block will never run sice foo is nill - /// print(unwrappedFoo) - /// } - /// - /// let bar: String? = "bar" - /// bar.run { unwrappedBar in - /// // block will run sice bar is not nill - /// print(unwrappedBar) -> "bar" - /// } - /// - /// - Parameter block: a block to run if self is not nil. - public func run(_ block: (Wrapped) -> Void) { - // http://www.russbishop.net/improving-optionals - _ = self.map(block) - } + /// SwifterSwift: Runs a block to Wrapped if not nil + /// + /// let foo: String? = nil + /// foo.run { unwrappedFoo in + /// // block will never run sice foo is nill + /// print(unwrappedFoo) + /// } + /// + /// let bar: String? = "bar" + /// bar.run { unwrappedBar in + /// // block will run sice bar is not nill + /// print(unwrappedBar) -> "bar" + /// } + /// + /// - Parameter block: a block to run if self is not nil. + public func run(_ block: (Wrapped) -> Void) { + // http://www.russbishop.net/improving-optionals + _ = self.map(block) + } + + /// SwifterSwift: Assign an optional value to a variable only if the value is not nil. + /// + /// let someParameter: String? = nil + /// let parameters = [String:Any]() //Some parameters to be attached to a GET request + /// parameters[someKey] ??= someParameter //It won't be added to the parameters dict + /// + /// - Parameters: + /// - lhs: Any? + /// - rhs: Any? + public static func ??= (lhs: inout Optional, rhs: Optional) { + guard let rhs = rhs else { return } + lhs = rhs + } + +} + +// MARK: - Methods (Collection) +public extension Optional where Wrapped: Collection { - /// SwifterSwift: Assign an optional value to a variable only if the value is not nil. - /// - /// let someParameter: String? = nil - /// let parameters = [String:Any]() //Some parameters to be attached to a GET request - /// parameters[someKey] ??= someParameter //It won't be added to the parameters dict - /// - /// - Parameters: - /// - lhs: Any? - /// - rhs: Any? - public static func ??= (lhs: inout Optional, rhs: Optional) { - guard let rhs = rhs else { return } - lhs = rhs - } + /// Check if optional is nil or empty collection. + public var isNilOrEmpty: Bool { + guard let collection = self else { return true } + return collection.isEmpty + } } diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index cfa760fb1..eff9bfe8d 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -59,7 +59,7 @@ public extension SignedInteger { // MARK: - Methods public extension SignedInteger { - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Greatest common divisor of integer value and n. /// /// - Parameter n: integer value to find gcd with. @@ -67,9 +67,8 @@ public extension SignedInteger { public func gcd(of n: Self) -> Self { return n == 0 ? self : n.gcd(of: self % n) } - // swiftlint:enable identifier_name - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Least common multiple of integer and n. /// /// - Parameter n: integer value to find lcm with. @@ -77,7 +76,6 @@ public extension SignedInteger { public func lcm(of n: Self) -> Self { return (self * n).abs / gcd(of: n) } - // swiftlint:enable identifier_name #if canImport(Foundation) @available(iOS 9.0, macOS 10.11, *) diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index b3b3e6d7a..a9b1c1e6b 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -19,9 +19,8 @@ public extension SignedNumeric { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current - // swiftlint:disable force_cast + // swiftlint:disable next force_cast return formatter.string(from: self as! NSNumber) - // swiftlint:enable force_cast } } diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 520ab8111..787d351d1 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -563,7 +563,7 @@ public extension String { } #endif - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Safely subscript string with index. /// /// "Hello World!"[3] -> "l" @@ -574,7 +574,6 @@ public extension String { guard i >= 0 && i < count else { return nil } return self[index(startIndex, offsetBy: i)] } - // swiftlint:enable identifier_name /// SwifterSwift: Safely subscript string within a half-open range. /// @@ -736,7 +735,7 @@ public extension String { self = String(chars) } - // swiftlint:disable identifier_name + // swiftlint:disable next identifier_name /// SwifterSwift: Sliced string from a start index with length. /// /// "Hello World".slicing(from: 6, length: 5) -> "World" @@ -753,9 +752,8 @@ public extension String { guard length > 0 else { return "" } return self[safe: i.. Date: Sat, 14 Apr 2018 19:01:52 -0500 Subject: [PATCH 142/201] Update CONTRIBUTING.md (#450) --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d42394ce5..2ce7088d1 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,6 +64,7 @@ public extension SomeType { ``` - A pull request should only add one extension at a time. +- Do not use an existing SwifterSwift extension inside another SwifterSwift extension. All extensions should be able to be copied and pasted and work immediately without having to copy another extension. - All extensions should follow [Swift API Design Guidelines](https://developer.apple.com/videos/play/wwdc2016/403/) - Always declare extensions as **public**. - All extensions names should be as clear as possible. From ed2c65b7bb63392393d9e6ecccd2418f7a5ba7c8 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 17 Apr 2018 21:14:13 -0300 Subject: [PATCH 143/201] Adding organization name to the project settings (#451) --- Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift | 2 +- SwifterSwift.xcodeproj/project.pbxproj | 1 + Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift index 76d8b8ed8..47f5ba8e1 100644 --- a/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift +++ b/Sources/Extensions/UIKit/Deprecated/UIKitDeprecated.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 5.04.2018. -// Copyright © 2018 ___ORGANIZATIONNAME___ +// Copyright © 2018 SwifterSwift // #if canImport(UIKit) diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 4ea9f8ad8..b30e0a069 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -1125,6 +1125,7 @@ attributes = { LastSwiftUpdateCheck = 0900; LastUpgradeCheck = 0930; + ORGANIZATIONNAME = SwifterSwift; TargetAttributes = { 07898B5C1F278D7600558C97 = { CreatedOnToolsVersion = 9.0; diff --git a/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift b/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift index 2effdc2ab..8fdce170c 100644 --- a/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SignedIntegerExtensionsTests.swift @@ -3,7 +3,7 @@ // SwifterSwift // // Created by Omar Albeik on 5.04.2018. -// Copyright © 2018 ___ORGANIZATIONNAME___ +// Copyright © 2018 SwifterSwift // import XCTest From c1a5d92ce11732b6310009ff771160fee221838e Mon Sep 17 00:00:00 2001 From: Seto Elkahfi Date: Wed, 18 Apr 2018 15:45:23 +0700 Subject: [PATCH 144/201] Add safeScrollToRow(at:at:animated:) to safely scroll table view (#445) --- CHANGELOG.md | 9 +++--- .../UIKit/UITableViewExtensions.swift | 12 ++++++++ .../UITableViewExtensionsTests.swift | 29 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 203bcfe43..54b7d7479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,14 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added -- **UITableViewExtentions**: - - Added `isValidIndexPath(_ indexPath:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). -**Optional**: +- **UITableView**: + - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). + - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). +- **Optional**: - Added `isNilOrEmpty` property to check whether an optional is nil or empty collection. ### Changed -- **UITableViewExtentions**: +- **UITableView**: - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableHeaderFooterView(withClass)`now returns `UITableViewHeaderFooterView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - **UICollectionView**: diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index 42efa0f53..bff1d6d1f 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -181,6 +181,18 @@ public extension UITableView { return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section) } + /// SwifterSwift: Safely scroll to possibly invalid IndexPath + /// + /// - Parameters: + /// - indexPath: Target IndexPath to scroll to + /// - scrollPosition: Scroll position + /// - animated: Whether to animate or not + public func safeScrollToRow(at indexPath: IndexPath, at scrollPosition: UITableViewScrollPosition, animated: Bool) { + guard indexPath.section < numberOfSections else { return } + guard indexPath.row < numberOfRows(inSection: indexPath.section) else { return } + scrollToRow(at: indexPath, at: scrollPosition, animated: animated) + } + } #endif diff --git a/Tests/UIKitTests/UITableViewExtensionsTests.swift b/Tests/UIKitTests/UITableViewExtensionsTests.swift index 523d86d7e..a4a5b659d 100644 --- a/Tests/UIKitTests/UITableViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITableViewExtensionsTests.swift @@ -104,6 +104,35 @@ final class UITableViewExtensionsTests: XCTestCase { XCTAssertFalse(tableView.isValidIndexPath(invalidIndexPath)) } + func testSafeScrollToIndexPath() { + let validIndexPathTop = IndexPath(row: 0, section: 0) + + tableView.contentOffset = .init(x: 0, y: 100) + XCTAssertNotEqual(tableView.contentOffset, .zero) + + tableView.safeScrollToRow(at: validIndexPathTop, at: .top, animated: false) + XCTAssertEqual(tableView.contentOffset, .zero) + + let validIndexPathBottom = IndexPath(row: 7, section: 1) + let bottomOffset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.bounds.size.height) + + tableView.contentOffset = .init(x: 0, y: 200) + XCTAssertNotEqual(tableView.contentOffset, bottomOffset) + + tableView.safeScrollToRow(at: validIndexPathBottom, at: .bottom, animated: false) + #if os(tvOS) + XCTAssertEqual(bottomOffset.y, tableView.contentOffset.y, accuracy: 15.0) + #else + XCTAssertEqual(bottomOffset.y, tableView.contentOffset.y, accuracy: 2.0) + #endif + + let invalidIndexPath = IndexPath(row: 213, section: 21) + tableView.contentOffset = .zero + + tableView.safeScrollToRow(at: invalidIndexPath, at: .bottom, animated: false) + XCTAssertEqual(tableView.contentOffset, .zero) + } + #if os(iOS) func testRegisterReusableViewWithClassAndNib() { let nib = UINib(nibName: "UITableViewHeaderFooterView", bundle: Bundle(for: UITableViewExtensionsTests.self)) From 71161cfacff2de0a37887d6673dff0ec244a35fa Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 19 Apr 2018 18:15:31 -0300 Subject: [PATCH 145/201] Adding recursive find on firstResponder UIView extension. (#447) * Fixing UIView.addShadow() extension not adding shadow. * Adding changelog. * Add PR info on changelog. * Adding recursive find on firstResponder UIView extension. * Adding changelog entry. * Updating documentation. * Making UIView first responder a function. * Updating changelog. * Merge conflicts resolved * Change implementation to BFS algorithm. --- CHANGELOG.md | 14 ++++------ .../Extensions/UIKit/UIViewExtensions.swift | 28 +++++++++++-------- Tests/UIKitTests/UIViewExtensionsTests.swift | 24 ++++++++++++++-- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b7d7479..dcffc3207 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,14 +17,12 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **UICollectionView**: - `dequeueReusableCell(withClass:for)` now return `UICollectionViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableSupplementaryView(ofKind:withClass:for)`now returns `UICollectionReusableView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - -### Deprecated - -### Removed - -### Fixed - -### Security +- **UIView**: + - **Breaking Change** `firstResponder` UIView extension is now a function and suport recursive find in the view hierarchy. [#447](https://github.com/SwifterSwift/SwifterSwift/pull/447) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +> ### Deprecated +> ### Removed +> ### Fixed +> ### Security --- diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index fa78e5949..f112b7593 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -82,16 +82,7 @@ public extension UIView { layer.masksToBounds = true layer.cornerRadius = abs(CGFloat(Int(newValue * 100)) / 100) } - } - - /// SwifterSwift: First responder. - public var firstResponder: UIView? { - guard !isFirstResponder else { return self } - for subView in subviews where subView.isFirstResponder { - return subView - } - return nil - } + } // SwifterSwift: Height of view. public var height: CGFloat { @@ -224,7 +215,22 @@ public extension UIView { // MARK: - Methods public extension UIView { - /// SwifterSwift: Set some or all corners radiuses of view. + /// SwifterSwift: Recursively find the first responder. + public func firstResponder() -> UIView? { + var views = [UIView](arrayLiteral: self) + var i = 0 + repeat { + let view = views[i] + if view.isFirstResponder { + return view + } + views.append(contentsOf: view.subviews) + i += 1 + } while i < views.count + return nil + } + + /// SwifterSwift: Set some or all corners radiuses of view. /// /// - Parameters: /// - corners: array of corners to change (example: [.bottomLeft, .topRight]). diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 5ce032a88..476155535 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -42,8 +42,28 @@ final class UIViewExtensionsTests: XCTestCase { } func testFirstResponder() { - let view = UIView() - XCTAssertNil(view.firstResponder) + // When there's no firstResponder + XCTAssertNil(UIView().firstResponder()) + + let window = UIWindow() + + // When self is firstResponder + let txtView = UITextField(frame: CGRect.zero) + window.addSubview(txtView) + txtView.becomeFirstResponder() + XCTAssertTrue(txtView.firstResponder() === txtView) + + // When a subview is firstResponder + let superView = UIView() + window.addSubview(superView) + let subView = UITextField(frame: CGRect.zero) + superView.addSubview(subView) + subView.becomeFirstResponder() + XCTAssertTrue(superView.firstResponder() === subView) + + // When you have to find recursively + XCTAssertTrue(window.firstResponder() === subView) + } func testHeight() { From 00e23084d736c98f9742111a9b9224536584639b Mon Sep 17 00:00:00 2001 From: Caleb Kleveter Date: Thu, 19 Apr 2018 18:31:59 -0500 Subject: [PATCH 146/201] Added deprecation warning to Array.groupByKey(keyForValue:) method (#454) * Added deprecation warning to Array.groupByKey(keyForValue:) method * Removed call to Array.groupByKey method in Collection tests * Updated CHANGELOG for deprecated Array.groupByKey(keyForValue:) method * Moved deprecated groupByKey(keyForValue:) method to SwiftStdlibDeprecated.swift * Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- .../Extensions/SwiftStdlib/ArrayExtensions.swift | 15 --------------- .../Deprecated/SwiftStdlibDeprecated.swift | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcffc3207..f2e53909e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,11 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `dequeueReusableSupplementaryView(ofKind:withClass:for)`now returns `UICollectionReusableView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - **UIView**: - **Breaking Change** `firstResponder` UIView extension is now a function and suport recursive find in the view hierarchy. [#447](https://github.com/SwifterSwift/SwifterSwift/pull/447) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -> ### Deprecated + +### Deprecated +- **Array** + - `groupByKey(keyForValue:)`. [#454](https://github.com/SwifterSwift/SwifterSwift/pull/454) by [@calebkleveter](https://github.com/calebkleveter) + > ### Removed > ### Fixed > ### Security diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index e2080a02b..19f47af73 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -280,21 +280,6 @@ public extension Array { return slices } - /// SwifterSwift: Group the elements of the array in a dictionary. - /// - /// [0, 2, 5, 4, 7].groupByKey { $0%2 ? "evens" : "odds" } -> [ "evens" : [0, 2, 4], "odds" : [5, 7] ] - /// - /// - Parameter getKey: Clousure to define the key for each element. - /// - Returns: A dictionary with values grouped with keys. - public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { - var group = [K: [Element]]() - for value in self { - let key = try keyForValue(value) - group[key] = (group[key] ?? []) + [value] - } - return group - } - /// SwifterSwift: Separates an array into 2 arrays based on a predicate. /// /// [0, 1, 2, 3, 4, 5].divided { $0 % 2 == 0 } -> ( [0, 2, 4], [1, 3, 5] ) diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index 86cd98d8e..95757d3e8 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -122,6 +122,21 @@ public extension Array { return self[index] } + /// SwifterSwift: Group the elements of the array in a dictionary. + /// + /// [0, 2, 5, 4, 7].groupByKey { $0%2 ? "evens" : "odds" } -> [ "evens" : [0, 2, 4], "odds" : [5, 7] ] + /// + /// - Parameter getKey: Clousure to define the key for each element. + /// - Returns: A dictionary with values grouped with keys. + @available(*, deprecated, message: "Use 'Dictionary.init(grouping:by:)' instead.") + public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { + var group = [K: [Element]]() + for value in self { + let key = try keyForValue(value) + group[key] = (group[key] ?? []) + [value] + } + return group + } } public extension Array where Element: Equatable { From 07c725ea52dddd8e3598d1eb3184ae7df4553299 Mon Sep 17 00:00:00 2001 From: Morgan Dock Date: Mon, 23 Apr 2018 00:11:27 -0700 Subject: [PATCH 147/201] Add UIGestureRecognizer extension to remove itself from associated view (#456) --- CHANGELOG.md | 2 + .../UIKit/UIGestureRecognizerExtensions.swift | 23 +++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 8 ++++ .../UIGestureRecognizerExtensionsTests.swift | 41 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 Sources/Extensions/UIKit/UIGestureRecognizerExtensions.swift create mode 100644 Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index f2e53909e..c50b3035c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **UIGestureRecognizer**: + - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). diff --git a/Sources/Extensions/UIKit/UIGestureRecognizerExtensions.swift b/Sources/Extensions/UIKit/UIGestureRecognizerExtensions.swift new file mode 100644 index 000000000..6c58fe804 --- /dev/null +++ b/Sources/Extensions/UIKit/UIGestureRecognizerExtensions.swift @@ -0,0 +1,23 @@ +// +// UIGestureRecognizerExtensions.swift +// SwifterSwift +// +// Created by Morgan Dock on 4/21/18. +// Copyright © 2018 SwifterSwift +// + +#if canImport(UIKit) +import UIKit + +#if !os(watchOS) +// MARK: - Methods +public extension UIGestureRecognizer { + + /// SwifterSwift: Remove Gesture Recognizer from its view. + public func removeFromView() { + self.view?.removeGestureRecognizer(self) + } +} +#endif + +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index b30e0a069..91b03ea96 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -358,6 +358,8 @@ 784C75372051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75382051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75392051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; + 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */; }; + 90693555208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -543,6 +545,8 @@ 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineExtensions.swift; sourceTree = ""; }; 784C75362051BE1D001C48DD /* MKPolylineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineTests.swift; sourceTree = ""; }; + 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensions.swift; sourceTree = ""; }; + 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensions.swift; sourceTree = ""; }; @@ -764,6 +768,7 @@ 07B7F17E1F5EB41600E6F910 /* UIButtonExtensions.swift */, 07B7F17F1F5EB41600E6F910 /* UICollectionViewExtensions.swift */, 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */, + 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */, 07B7F1811F5EB41600E6F910 /* UIImageExtensions.swift */, 07B7F1821F5EB41600E6F910 /* UIImageViewExtensions.swift */, 07B7F1831F5EB41600E6F910 /* UILabelExtensions.swift */, @@ -863,6 +868,7 @@ 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */, 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */, 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */, + 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */, ); path = UIKitTests; sourceTree = ""; @@ -1349,6 +1355,7 @@ files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, A94AA78720280F9100E229A5 /* FileManagerExtensions.swift in Sources */, + 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */, B23678EC1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2181F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, @@ -1602,6 +1609,7 @@ 07C50D2F1F5EB04600F46E5A /* ColorExtensionsTests.swift in Sources */, 07C50D331F5EB04700F46E5A /* UINavigationBarExtensionTests.swift in Sources */, 07C50D401F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, + 90693555208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift in Sources */, 07C50D311F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, 07C50D2C1F5EB04600F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, 077BA0B91F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift b/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift new file mode 100644 index 000000000..a7a5d7d7e --- /dev/null +++ b/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift @@ -0,0 +1,41 @@ +// +// UIGestureRecognizerExtensionsTests.swift +// SwifterSwift +// +// Created by Morgan Dock on 4/21/18. +// Copyright © 2018 SwifterSwift +// + +#if os(iOS) +import XCTest +@testable import SwifterSwift + +class UIGestureRecognizerExtensionsTests: XCTestCase { + + func testRemoveFromView() { + let view = UIImageView() + let tap = UITapGestureRecognizer() + + //First Baseline Assertion + XCTAssert(view.gestureRecognizers == nil) + XCTAssert(tap.view == nil) + + view.addGestureRecognizer(tap) + + //Verify change + XCTAssertFalse(view.gestureRecognizers == nil) + XCTAssertFalse(tap.view == nil) + + //Second Baseline Assertion + XCTAssertFalse((view.gestureRecognizers?.count ?? 0) == 0) + XCTAssertFalse(view.gestureRecognizers?.isEmpty ?? true) + + tap.removeFromView() + + //Verify change + XCTAssert((view.gestureRecognizers?.count ?? 1) == 0) + XCTAssert(view.gestureRecognizers?.isEmpty ?? false) + XCTAssert(tap.view == nil) + } +} +#endif From 8c6deaef0418982260d8bc2f4a1932c52e4e0896 Mon Sep 17 00:00:00 2001 From: Camila Oliveira Date: Tue, 24 Apr 2018 13:45:25 -0300 Subject: [PATCH 148/201] Add UIScrollView extension to snapshot entire scrollview (#457) * Add UIScrollView extension to snapshot entire scrollview * Remove unnecessary whitespaces (bot request) * Duplicate render fix * Update CHANGELOG.md * Swiftlint autocorrect --- CHANGELOG.md | 2 + .../UIKit/UIScrollViewExtensions.swift | 38 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 8 ++++ .../UIScrollViewExtensionsTest.swift | 24 ++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 Sources/Extensions/UIKit/UIScrollViewExtensions.swift create mode 100644 Tests/UIKitTests/UIScrollViewExtensionsTest.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index c50b3035c..715d5c525 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **UIScrollView**: + - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). - **UIGestureRecognizer**: - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) - **UITableView**: diff --git a/Sources/Extensions/UIKit/UIScrollViewExtensions.swift b/Sources/Extensions/UIKit/UIScrollViewExtensions.swift new file mode 100644 index 000000000..b5f255a4f --- /dev/null +++ b/Sources/Extensions/UIKit/UIScrollViewExtensions.swift @@ -0,0 +1,38 @@ +// +// UIScrollViewExtensions.swift +// SwifterSwift +// +// Created by camila oliveira on 22/04/18. +// Copyright © 2018 SwifterSwift +// + +#if canImport(UIKit) + import UIKit +#if !os(watchOS) + +// MARK: - Methods +public extension UIScrollView { + //Original Source: https://gist.github.com/thestoics/1204051 + /// SwifterSwift: Takes a snapshot of an entire ScrollView + /// + /// AnySubclassOfUIScroolView().snapshot + /// UITableView().snapshot + /// + /// - Returns: Snapshot as UIimage for rendered ScrollView + public var snapshot: UIImage? { + UIGraphicsBeginImageContextWithOptions(contentSize, false, 0) + defer { + UIGraphicsEndImageContext() + } + guard let context = UIGraphicsGetCurrentContext() else { return nil } + let previousFrame = frame + frame = CGRect(origin: frame.origin, size: contentSize) + layer.render(in: context) + frame = previousFrame + return UIGraphicsGetImageFromCurrentImageContext() + } +} + +#endif + +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 91b03ea96..b48afec7b 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -358,6 +358,8 @@ 784C75372051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75382051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; 784C75392051BE1D001C48DD /* MKPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C75362051BE1D001C48DD /* MKPolylineTests.swift */; }; + 86B3F7AC208D3D5C00BC297B /* UIScrollViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */; }; + 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */; }; 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */; }; 90693555208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -545,6 +547,8 @@ 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineExtensions.swift; sourceTree = ""; }; 784C75362051BE1D001C48DD /* MKPolylineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineTests.swift; sourceTree = ""; }; + 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewExtensions.swift; sourceTree = ""; }; + 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewExtensionsTest.swift; sourceTree = ""; }; 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensions.swift; sourceTree = ""; }; 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; @@ -788,6 +792,7 @@ 07B7F1911F5EB41600E6F910 /* UIViewExtensions.swift */, 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */, 42F53FEB2039C5AC0070DC11 /* UIStackViewExtensions.swift */, + 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */, ); path = UIKit; sourceTree = ""; @@ -868,6 +873,7 @@ 07C50D221F5EB03200F46E5A /* UIViewControllerExtensionsTests.swift */, 07C50D231F5EB03200F46E5A /* UIViewExtensionsTests.swift */, 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */, + 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */, 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */, ); path = UIKitTests; @@ -1409,6 +1415,7 @@ 70269A2B1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F2161F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, 07B7F2101F5EB43C00E6F910 /* DateExtensions.swift in Sources */, + 86B3F7AC208D3D5C00BC297B /* UIScrollViewExtensions.swift in Sources */, 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F19E1F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, 07B7F20F1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, @@ -1647,6 +1654,7 @@ 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, + 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */, 18C8E5E32074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */, 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIScrollViewExtensionsTest.swift b/Tests/UIKitTests/UIScrollViewExtensionsTest.swift new file mode 100644 index 000000000..cdf8fa2fa --- /dev/null +++ b/Tests/UIKitTests/UIScrollViewExtensionsTest.swift @@ -0,0 +1,24 @@ +// +// UIScrollViewExtensionsTest.swift +// SwifterSwift +// +// Created by camila oliveira on 22/04/18. +// Copyright © 2018 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +#if os(iOS) || os(tvOS) +final class UIScrollViewExtensionsTest: XCTestCase { + func testSnapshot() { + let frame = CGRect(x: 0, y: 0, width: 100, height: 100) + let scroll = UIScrollView(frame: frame) + scroll.contentSize = frame.size + let snapshot = scroll.snapshot + XCTAssertNotNil(snapshot) + let view = UIScrollView() + XCTAssertNil(view.snapshot) + } +} +#endif From ce0532053fde0f421bf71ae24a25f767b4c4a262 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 24 Apr 2018 19:07:00 -0300 Subject: [PATCH 149/201] Adding delete all path components URL extensions. (#452) * Adding delete all path components URL extensions. * Changelog entries. * Changelog fix * changelog changes. * adding empty line on comments. * Resolving conflicts . --- CHANGELOG.md | 3 +++ .../Extensions/Foundation/URLExtensions.swift | 25 +++++++++++++++++++ .../FoundationTests/URLExtensionsTests.swift | 12 +++++++++ 3 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 715d5c525..3c3692d3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). - **UIGestureRecognizer**: - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) + +- **URL** + - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 79b57fc72..8c1ed9895 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -63,6 +63,31 @@ public extension URL { self = appendingQueryParameters(parameters) } + /// SwifterSwift: Returns a new URL by removing all the path components. + /// + /// let url = URL(string: "https://domain.com/path/other")! + /// print(url.deletingAllPathComponents()) // prints "https://domain.com/" + /// + /// - Returns: URL with all path components removed. + public func deletingAllPathComponents() -> URL { + var url: URL = self + for _ in 0.. Date: Wed, 25 Apr 2018 00:20:58 +0200 Subject: [PATCH 150/201] Use UIImage's scale when scaling (#446) --- CHANGELOG.md | 18 ++++++++++++------ .../Extensions/UIKit/UIImageExtensions.swift | 10 ++++++---- Tests/UIKitTests/UIImageExtensionsTests.swift | 4 ++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c3692d3d..3881d556c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,18 +22,24 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableHeaderFooterView(withClass)`now returns `UITableViewHeaderFooterView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - **UICollectionView**: - - `dequeueReusableCell(withClass:for)` now return `UICollectionViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) + - `dequeueReusableCell(withClass:for)` now returns `UICollectionViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - `dequeueReusableSupplementaryView(ofKind:withClass:for)`now returns `UICollectionReusableView` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) - **UIView**: - - **Breaking Change** `firstResponder` UIView extension is now a function and suport recursive find in the view hierarchy. [#447](https://github.com/SwifterSwift/SwifterSwift/pull/447) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - + - **Breaking Change** `firstResponder` UIView extension is now a function and supports recursive find in the view hierarchy. [#447](https://github.com/SwifterSwift/SwifterSwift/pull/447) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **UIImage**: + - `scaled(toWidth:, opaque:, with orientation:)` and `scaled(toHeight:, opaque:, with orientation:)` now have an optional parameter for opaqueness. [#446](https://github.com/SwifterSwift/SwifterSwift/pull/446) by [vyax](https://github.com/vyax) + ### Deprecated - **Array** - `groupByKey(keyForValue:)`. [#454](https://github.com/SwifterSwift/SwifterSwift/pull/454) by [@calebkleveter](https://github.com/calebkleveter) -> ### Removed -> ### Fixed -> ### Security +>### Removed + +### Fixed +- **UIImage**: + - `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were ignoring an image's scale. [#446](https://github.com/SwifterSwift/SwifterSwift/pull/446) by [vyax](https://github.com/vyax) + +>### Security --- diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index c9018d852..2a43cb460 100644 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -68,12 +68,13 @@ public extension UIImage { /// /// - Parameters: /// - toHeight: new height. + /// - opaque: flag indicating whether the bitmap is opaque. /// - orientation: optional UIImage orientation (default is nil). /// - Returns: optional scaled UIImage (if applicable). - public func scaled(toHeight: CGFloat, with orientation: UIImageOrientation? = nil) -> UIImage? { + public func scaled(toHeight: CGFloat, opaque: Bool = false, with orientation: UIImageOrientation? = nil) -> UIImage? { let scale = toHeight / size.height let newWidth = size.width * scale - UIGraphicsBeginImageContext(CGSize(width: newWidth, height: toHeight)) + UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: toHeight), opaque, scale) draw(in: CGRect(x: 0, y: 0, width: newWidth, height: toHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() @@ -84,12 +85,13 @@ public extension UIImage { /// /// - Parameters: /// - toWidth: new width. + /// - opaque: flag indicating whether the bitmap is opaque. /// - orientation: optional UIImage orientation (default is nil). /// - Returns: optional scaled UIImage (if applicable). - public func scaled(toWidth: CGFloat, with orientation: UIImageOrientation? = nil) -> UIImage? { + public func scaled(toWidth: CGFloat, opaque: Bool = false, with orientation: UIImageOrientation? = nil) -> UIImage? { let scale = toWidth / size.width let newHeight = size.height * scale - UIGraphicsBeginImageContext(CGSize(width: toWidth, height: newHeight)) + UIGraphicsBeginImageContextWithOptions(CGSize(width: toWidth, height: newHeight), opaque, scale) draw(in: CGRect(x: 0, y: 0, width: toWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() diff --git a/Tests/UIKitTests/UIImageExtensionsTests.swift b/Tests/UIKitTests/UIImageExtensionsTests.swift index 6b40c652d..cf46a8348 100644 --- a/Tests/UIKitTests/UIImageExtensionsTests.swift +++ b/Tests/UIKitTests/UIImageExtensionsTests.swift @@ -60,7 +60,7 @@ final class UIImageExtensionsTests: XCTestCase { let scaledImage = image.scaled(toHeight: 300) XCTAssertNotNil(scaledImage) - XCTAssertEqual(scaledImage!.size.height, 300) + XCTAssertEqual(scaledImage!.size.height, 300, accuracy: 0.1) } func testScaledToWidth() { @@ -69,7 +69,7 @@ final class UIImageExtensionsTests: XCTestCase { let scaledImage = image.scaled(toWidth: 300) XCTAssertNotNil(scaledImage) - XCTAssertEqual(scaledImage!.size.width, 300) + XCTAssertEqual(scaledImage!.size.width, 300, accuracy: 0.1) } func testFilled() { From 17ac3b80078f86987da2a3e0ba76f2ebbb9d5436 Mon Sep 17 00:00:00 2001 From: Morgan Dock Date: Tue, 1 May 2018 05:59:56 -0700 Subject: [PATCH 151/201] =?UTF-8?q?=F0=9F=9A=80=20add=20`applyShadow(color?= =?UTF-8?q?:alpha:xOffset:yOffset:blur:spread)`=20method=20to=20...=20(#46?= =?UTF-8?q?0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add `applyShadow(color:alpha:xOffset:yOffset:blur:spread)` method to apply a shadow to a CALayer with the same describing parameters as Sketch, Zeplin, etc. (#459) * Update changelog to use the correct reference for this pull request * Update parameters to use CGSize and CGColor. Remove BezierPath for CGPath * update extension to be excluded from watchOS, make color non-default to support macOS --- CHANGELOG.md | 2 ++ .../CoreAnimation/CALayerExtensions.swift | 36 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 12 +++++++ 3 files changed, 50 insertions(+) create mode 100644 Sources/Extensions/CoreAnimation/CALayerExtensions.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 3881d556c..fd5fadbbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **CALayer**: + - Added `applyShadow(color:alpha:xOffset:yOffset:blur:spread)` method to apply a shadow to a CALayer with the same describing paramaters as Sketch, Zeplin, etc. [#460](https://github.com/SwifterSwift/SwifterSwift/pull/460) by [mmdock](https://github.com/mmdock) - **UIScrollView**: - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). - **UIGestureRecognizer**: diff --git a/Sources/Extensions/CoreAnimation/CALayerExtensions.swift b/Sources/Extensions/CoreAnimation/CALayerExtensions.swift new file mode 100644 index 000000000..572cac20f --- /dev/null +++ b/Sources/Extensions/CoreAnimation/CALayerExtensions.swift @@ -0,0 +1,36 @@ +// +// CALayerExtension.swift +// SwifterSwift +// +// Created by Morgan Dock on 4/26/18. +// Copyright © 2018 SwifterSwift +// + +#if !os(watchOS) + +public extension CALayer { + + /// SwifterSwift: Create a shadow affect, using the same parameters used in design software such as Sketch, Zeplin, and others. + /// This Extension originates from here: https://stackoverflow.com/questions/34269399/how-to-control-shadow-spread-and-blur/34270362 + /// + /// - Parameters: + /// - color: the tint of the shadow effect. No Default is provided + /// - alpha: opacity of the color applied to the shaddow effect. Default is 0.08 + /// - offset: the x and y offsets represented as a CGSize. Default is (0, 3) + /// - blur: if set to 0 the shadow will be sharp, the higher the number, the more blurred it will be. Default is 5. + /// - spread: positive values increase the size of the shadow, negative values decrease the size. Default is 0. + public func applyShadow(withColor color: CGColor, alpha: Float = 0.08, offset: CGSize = CGSize(width: 0, height: 3), blur: CGFloat = 5, spread: CGFloat = 0) { + shadowColor = color + shadowOpacity = alpha + shadowOffset = offset + shadowRadius = blur / 2.0 + if spread == 0 { + shadowPath = nil + } else { + let dirX = -spread + shadowPath = CGPath(rect: bounds.insetBy(dx: dirX, dy: dirX), transform: nil) + } + } + +} +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index b48afec7b..4d5660bb8 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -362,6 +362,7 @@ 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */; }; 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */; }; 90693555208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */; }; + 90B1983A2091CCEE0038A08E /* CALayerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B198392091CCEE0038A08E /* CALayerExtensions.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -551,6 +552,7 @@ 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewExtensionsTest.swift; sourceTree = ""; }; 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensions.swift; sourceTree = ""; }; 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; + 90B198392091CCEE0038A08E /* CALayerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CALayerExtensions.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensions.swift; sourceTree = ""; }; @@ -715,6 +717,7 @@ 07898B941F27904200558C97 /* Extensions */ = { isa = PBXGroup; children = ( + 90B198382091CCD50038A08E /* CoreAnimation */, 784C752D2051BD01001C48DD /* MapKit */, 0726D7751F7C19880028CAB5 /* Shared */, 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, @@ -942,6 +945,14 @@ path = MapKitTests; sourceTree = ""; }; + 90B198382091CCD50038A08E /* CoreAnimation */ = { + isa = PBXGroup; + children = ( + 90B198392091CCEE0038A08E /* CALayerExtensions.swift */, + ); + path = CoreAnimation; + sourceTree = ""; + }; B23678EA1FB116680027C931 /* Deprecated */ = { isa = PBXGroup; children = ( @@ -1360,6 +1371,7 @@ buildActionMask = 2147483647; files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 90B1983A2091CCEE0038A08E /* CALayerExtensions.swift in Sources */, A94AA78720280F9100E229A5 /* FileManagerExtensions.swift in Sources */, 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */, B23678EC1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, From 9a109092a7693840eff52f4ed637a4b9e6b8298c Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Tue, 1 May 2018 08:01:21 -0500 Subject: [PATCH 152/201] =?UTF-8?q?Revert=20"=F0=9F=9A=80=20add=20`applySh?= =?UTF-8?q?adow(color:alpha:xOffset:yOffset:blur:spread)`=20method=20to=20?= =?UTF-8?q?...=20(#460)"=20(#461)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 17ac3b80078f86987da2a3e0ba76f2ebbb9d5436. --- CHANGELOG.md | 2 -- .../CoreAnimation/CALayerExtensions.swift | 36 ------------------- SwifterSwift.xcodeproj/project.pbxproj | 12 ------- 3 files changed, 50 deletions(-) delete mode 100644 Sources/Extensions/CoreAnimation/CALayerExtensions.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5fadbbc..3881d556c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,6 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added -- **CALayer**: - - Added `applyShadow(color:alpha:xOffset:yOffset:blur:spread)` method to apply a shadow to a CALayer with the same describing paramaters as Sketch, Zeplin, etc. [#460](https://github.com/SwifterSwift/SwifterSwift/pull/460) by [mmdock](https://github.com/mmdock) - **UIScrollView**: - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). - **UIGestureRecognizer**: diff --git a/Sources/Extensions/CoreAnimation/CALayerExtensions.swift b/Sources/Extensions/CoreAnimation/CALayerExtensions.swift deleted file mode 100644 index 572cac20f..000000000 --- a/Sources/Extensions/CoreAnimation/CALayerExtensions.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// CALayerExtension.swift -// SwifterSwift -// -// Created by Morgan Dock on 4/26/18. -// Copyright © 2018 SwifterSwift -// - -#if !os(watchOS) - -public extension CALayer { - - /// SwifterSwift: Create a shadow affect, using the same parameters used in design software such as Sketch, Zeplin, and others. - /// This Extension originates from here: https://stackoverflow.com/questions/34269399/how-to-control-shadow-spread-and-blur/34270362 - /// - /// - Parameters: - /// - color: the tint of the shadow effect. No Default is provided - /// - alpha: opacity of the color applied to the shaddow effect. Default is 0.08 - /// - offset: the x and y offsets represented as a CGSize. Default is (0, 3) - /// - blur: if set to 0 the shadow will be sharp, the higher the number, the more blurred it will be. Default is 5. - /// - spread: positive values increase the size of the shadow, negative values decrease the size. Default is 0. - public func applyShadow(withColor color: CGColor, alpha: Float = 0.08, offset: CGSize = CGSize(width: 0, height: 3), blur: CGFloat = 5, spread: CGFloat = 0) { - shadowColor = color - shadowOpacity = alpha - shadowOffset = offset - shadowRadius = blur / 2.0 - if spread == 0 { - shadowPath = nil - } else { - let dirX = -spread - shadowPath = CGPath(rect: bounds.insetBy(dx: dirX, dy: dirX), transform: nil) - } - } - -} -#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 4d5660bb8..b48afec7b 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -362,7 +362,6 @@ 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */; }; 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */; }; 90693555208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */; }; - 90B1983A2091CCEE0038A08E /* CALayerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B198392091CCEE0038A08E /* CALayerExtensions.swift */; }; 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; 9D4914851F85138E00F3868F /* NSPredicateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */; }; @@ -552,7 +551,6 @@ 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewExtensionsTest.swift; sourceTree = ""; }; 90693550208B4F9400407C4D /* UIGestureRecognizerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensions.swift; sourceTree = ""; }; 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; - 90B198392091CCEE0038A08E /* CALayerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CALayerExtensions.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensions.swift; sourceTree = ""; }; @@ -717,7 +715,6 @@ 07898B941F27904200558C97 /* Extensions */ = { isa = PBXGroup; children = ( - 90B198382091CCD50038A08E /* CoreAnimation */, 784C752D2051BD01001C48DD /* MapKit */, 0726D7751F7C19880028CAB5 /* Shared */, 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, @@ -945,14 +942,6 @@ path = MapKitTests; sourceTree = ""; }; - 90B198382091CCD50038A08E /* CoreAnimation */ = { - isa = PBXGroup; - children = ( - 90B198392091CCEE0038A08E /* CALayerExtensions.swift */, - ); - path = CoreAnimation; - sourceTree = ""; - }; B23678EA1FB116680027C931 /* Deprecated */ = { isa = PBXGroup; children = ( @@ -1371,7 +1360,6 @@ buildActionMask = 2147483647; files = ( 07B7F2191F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, - 90B1983A2091CCEE0038A08E /* CALayerExtensions.swift in Sources */, A94AA78720280F9100E229A5 /* FileManagerExtensions.swift in Sources */, 90693551208B4F9400407C4D /* UIGestureRecognizerExtensions.swift in Sources */, B23678EC1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, From 0ba61d67deb60d10a2ed97f27aa7e9112bfd0cf9 Mon Sep 17 00:00:00 2001 From: Ratul sharker Date: Tue, 1 May 2018 19:03:51 +0600 Subject: [PATCH 153/201] =?UTF-8?q?=20=F0=9F=9A=80=20Wrap=20to=20the=20con?= =?UTF-8?q?tent=20(String=20/=20AttributedText)=20UITextView=20#New-Extens?= =?UTF-8?q?ion=20(#458)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WrapToContent extension method is added with unit test. * Test case failure resolved for tvOS. * extension made public * Swift lint warning resovled and changelog added * one empty line spacing removed for swift lint. * self keyword removed. * unnecessary `init` is removed from the test case. --- CHANGELOG.md | 3 ++ .../UIKit/UITextViewExtensions.swift | 10 ++++++ .../UITextViewExtensionsTests.swift | 33 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3881d556c..de291a910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. # Upcoming release +### Added +- **UITextView**: +- Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) ### Added - **UIScrollView**: diff --git a/Sources/Extensions/UIKit/UITextViewExtensions.swift b/Sources/Extensions/UIKit/UITextViewExtensions.swift index 8a25b52d7..ccba43dad 100644 --- a/Sources/Extensions/UIKit/UITextViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITextViewExtensions.swift @@ -33,6 +33,16 @@ public extension UITextView { scrollRangeToVisible(range) } + /// SwifterSwift: Wrap to the content (Text / Attributed Text). + public func wrapToContent() { + contentInset = UIEdgeInsets.zero + scrollIndicatorInsets = UIEdgeInsets.zero + contentOffset = CGPoint.zero + textContainerInset = UIEdgeInsets.zero + textContainer.lineFragmentPadding = 0 + sizeToFit() + } + } #endif diff --git a/Tests/UIKitTests/UITextViewExtensionsTests.swift b/Tests/UIKitTests/UITextViewExtensionsTests.swift index 1ead9b9e7..79c6a05bd 100644 --- a/Tests/UIKitTests/UITextViewExtensionsTests.swift +++ b/Tests/UIKitTests/UITextViewExtensionsTests.swift @@ -40,5 +40,38 @@ final class UITextViewExtensionsTests: XCTestCase { XCTAssertNotEqual(textView.contentOffset.y, 0.0) } + func testWrapToContent() { + let text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + + // initial setting + textView.frame = CGRect(x: 0, y: 0, width: 100, height: 20) + textView.font = UIFont.systemFont(ofSize: 20.0) + textView.text = text + + // determining the text size + let constraintRect = CGSize(width: 100, height: CGFloat.greatestFiniteMagnitude) + let boundingBox = text.boundingRect(with: constraintRect, + options: NSStringDrawingOptions.usesLineFragmentOrigin, + attributes: [.font: textView.font!], + context: nil) + let textHeight = ceil(boundingBox.height) + let textSize = CGSize(width: 100, height: textHeight) + + // before setting wrap, content won't be equal to bounds + XCTAssertNotEqual(textView.bounds.size, textView.contentSize) + + // calling the wrap extension method + textView.wrapToContent() + + // setting the frame + // + // This is important to set the frame after calling the wrapToContent, otherwise + // boundingRect can give you fractional value, and method call `sizeToFit` inside the + // wrapToContent would change to the fractional value instead of the ceil value. + textView.bounds = CGRect(x: 0, y: 0, width: textSize.width, height: textSize.height) + + // after setting wrap, content size will be equal to bounds + XCTAssertEqual(textView.bounds.size, textView.contentSize) + } } #endif From 56508657da446de9e8e63735ff50c7eea012b96a Mon Sep 17 00:00:00 2001 From: Olivia Date: Tue, 1 May 2018 14:54:16 -0700 Subject: [PATCH 154/201] =?UTF-8?q?=F0=9F=9A=80=20Add=20random=20method=20?= =?UTF-8?q?to=20Character=20(#462)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add random method to Character * Added random Character test * Updated changelog * Compare strings made of random characters * Remove blank lines * Rename to randomAlphanumeric * Add verbose to pod lib lint * Remove verbose flag --- CHANGELOG.md | 2 ++ .../SwiftStdlib/CharacterExtensions.swift | 15 ++++++++++++++- .../CharacterExtensionsTests.swift | 9 +++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de291a910..d562d4105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **Character**: +- Added `random()` method to generate a random Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) - **UITextView**: - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) diff --git a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift index 017d3417e..a57e13be9 100755 --- a/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CharacterExtensions.swift @@ -105,7 +105,21 @@ public extension Character { public var uppercased: Character { return String(self).uppercased().first! } +} +// MARK: - Methods +public extension Character { + /// SwifterSwift: Random character. + /// + /// Character.random() -> k + /// + /// - Returns: A random character. + public static func randomAlphanumeric() -> Character { + let allCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + let randomNumber = Int(arc4random_uniform(UInt32(allCharacters.count))) + let randomIndex = allCharacters.index(allCharacters.startIndex, offsetBy: randomNumber) + return allCharacters[randomIndex] + } } // MARK: - Operators @@ -136,5 +150,4 @@ public extension Character { guard lhs > 0 else { return "" } return String(repeating: String(rhs), count: lhs) } - } diff --git a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift index b814b47a9..203d5e227 100644 --- a/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CharacterExtensionsTests.swift @@ -68,6 +68,15 @@ final class CharacterExtensionsTests: XCTestCase { func testLowercased() { XCTAssertEqual(Character("S").lowercased, Character("s")) } + func testRandom() { + var string1 = String() + var string2 = String() + for _ in 0..<10 { + string1.append(Character.randomAlphanumeric()) + string2.append(Character.randomAlphanumeric()) + } + XCTAssertNotEqual(string1, string2) + } func testOperators() { let sLetter = Character("s") From 17cea0ca62fb9aab12b72674e3d166d09aeddf29 Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Tue, 1 May 2018 16:56:58 -0500 Subject: [PATCH 155/201] Fix log entry method name --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d562d4105..43747479d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added - **Character**: -- Added `random()` method to generate a random Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) +- Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) - **UITextView**: - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) From 8ff197531199522bee44303f42444bd321931466 Mon Sep 17 00:00:00 2001 From: Shai Mishali Date: Fri, 4 May 2018 01:04:39 +0300 Subject: [PATCH 156/201] Add `isBetween(min:max:)` and `clamped(min:max:)` Comparable extensions (#466) * Added `ComparableExtensions` with `isBetween` and `clamped` * Added `clamped` and `isBetween` tests. Also fixed a deprecation warning in `ArrayExtensionsTests` * Updated CHANGELOG --- CHANGELOG.md | 15 ++++--- .../SwiftStdlib/ComparableExtensions.swift | 43 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 ++++++++ .../ArrayExtensionsTests.swift | 4 +- .../ComparableExtensionsTests.swift | 31 +++++++++++++ 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 Sources/Extensions/SwiftStdlib/ComparableExtensions.swift create mode 100644 Tests/SwiftStdlibTests/ComparableExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 43747479d..31eaaa907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,23 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. # Upcoming release -### Added -- **Character**: -- Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) -- **UITextView**: -- Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) ### Added +- **Comparable**: + - Added `isBetween(min:max:)` and `clamped(min:max:)` to confirm a value is between bounds or limit it between bounds. [#466](https://github.com/SwifterSwift/SwifterSwift/pull/466) by [freak4pc](https://github.com/freak4pc). + - **UIScrollView**: - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). + - **UIGestureRecognizer**: - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) +- **Character**: + - Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) + +- **UITextView**: + - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) + - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - **UITableView**: diff --git a/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift b/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift new file mode 100644 index 000000000..338822098 --- /dev/null +++ b/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift @@ -0,0 +1,43 @@ +// +// ComparableExtensions.swift +// SwifterSwift +// +// Created by Shai Mishali on 5/4/18. +// Copyright © 2018 SwifterSwift +// + +// MARK: - Methods +public extension Comparable { + /// SwifterSwift: Returns true if value is between provided `min` + /// and `max`. + /// + /// 1.isBetween(min: 5, max: 7) // false + /// 7.isBetween(min: 6, max: 12) // true + /// date.isBetween(min: date1, max: date2) + /// "c".isBetween(min: "a", max: "d") // true + /// 0.32.isBetween(min: 0.31, max: 0.33) // true + /// + /// - parameter min: Minimum comparable value. + /// - parameter max: Maximum comparable value. + /// + /// - returns: `true` if value is between `min` and `max`, `false` otherwise. + public func isBetween(min: Self, max: Self) -> Bool { + return self >= min && self <= max + } + + /// SwifterSwift: Returns value limited within the provided range + /// between `min` and `max`. + /// + /// 1.clamped(min: 3, max: 8) // 3 + /// 4.clamped(min: 3, max: 7) // 4 + /// "c".clamped(min: "e", max: "g") // "e" + /// 0.32.clamped(min: 0.1, max: 0.29) // 0.29 + /// + /// - parameter min: Lower bound to limit the value to. + /// - parameter max: Upper bound to limit the value to. + /// + /// - returns: A value limited to the range between `min` and `max`. + public func clamped(min minNum: Self, max maxNum: Self) -> Self { + return max(minNum, min(self, maxNum)) + } +} diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index b48afec7b..2ec9e976b 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -352,6 +352,13 @@ 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; + 7832C2AF209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; + 7832C2B0209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; + 7832C2B1209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; + 7832C2B2209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; + 7832C2B4209BB32500224EED /* ComparableExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */; }; + 7832C2B5209BB32500224EED /* ComparableExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */; }; + 7832C2B6209BB32500224EED /* ComparableExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */; }; 784C752F2051BD26001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 784C75302051BD4A001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; 784C75312051BD4B001C48DD /* MKPolylineExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */; }; @@ -545,6 +552,8 @@ 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensionsTest.swift; sourceTree = ""; }; 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensions.swift; sourceTree = ""; }; 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; + 7832C2AE209BB19300224EED /* ComparableExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensions.swift; sourceTree = ""; }; + 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensionsTests.swift; sourceTree = ""; }; 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineExtensions.swift; sourceTree = ""; }; 784C75362051BE1D001C48DD /* MKPolylineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineTests.swift; sourceTree = ""; }; 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollViewExtensions.swift; sourceTree = ""; }; @@ -641,6 +650,7 @@ 07B7F1671F5EB41600E6F910 /* BoolExtensions.swift */, 07B7F1681F5EB41600E6F910 /* CharacterExtensions.swift */, 07B7F1691F5EB41600E6F910 /* CollectionExtensions.swift */, + 7832C2AE209BB19300224EED /* ComparableExtensions.swift */, 07B7F16E1F5EB41600E6F910 /* DictionaryExtensions.swift */, 07B7F16F1F5EB41600E6F910 /* DoubleExtensions.swift */, 07B7F1701F5EB41600E6F910 /* FloatExtensions.swift */, @@ -664,6 +674,7 @@ 07C50CFB1F5EB03200F46E5A /* BoolExtensionsTests.swift */, 07C50CFC1F5EB03200F46E5A /* CharacterExtensionsTests.swift */, 07C50CFD1F5EB03200F46E5A /* CollectionExtensionsTests.swift */, + 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */, 07C50D001F5EB03200F46E5A /* DictionaryExtensionsTests.swift */, 07C50D011F5EB03200F46E5A /* DoubleExtensionsTests.swift */, 07C50D021F5EB03200F46E5A /* FloatExtensionsTests.swift */, @@ -1373,6 +1384,7 @@ 07B7F22F1F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */, 07B7F1981F5EB42000E6F910 /* UIImageViewExtensions.swift in Sources */, 42F53FEC2039C5AC0070DC11 /* UIStackViewExtensions.swift in Sources */, + 7832C2AF209BB19300224EED /* ComparableExtensions.swift in Sources */, 07B7F2321F5EB45100E6F910 /* CLLocationExtensions.swift in Sources */, 07B7F20E1F5EB43C00E6F910 /* CollectionExtensions.swift in Sources */, 07B7F2151F5EB43C00E6F910 /* IntExtensions.swift in Sources */, @@ -1448,6 +1460,7 @@ 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */, 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, + 7832C2B0209BB19300224EED /* ComparableExtensions.swift in Sources */, 077BA0901F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1B71F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, 07B7F1BA1F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */, @@ -1513,6 +1526,7 @@ 07B7F1C11F5EB42200E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1CF1F5EB42200E6F910 /* UITableViewExtensions.swift in Sources */, 077BA0911F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, + 7832C2B1209BB19300224EED /* ComparableExtensions.swift in Sources */, 07B7F1CD1F5EB42200E6F910 /* UISwitchExtensions.swift in Sources */, 07B7F1D01F5EB42200E6F910 /* UITextFieldExtensions.swift in Sources */, 07B7F1E71F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, @@ -1587,6 +1601,7 @@ 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, + 7832C2B2209BB19300224EED /* ComparableExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, 078CE2A2207643F8001720DF /* UIKitDeprecated.swift in Sources */, B23678EF1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, @@ -1646,6 +1661,7 @@ 07C50D2D1F5EB04600F46E5A /* UIButtonExtensionsTests.swift in Sources */, 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */, A94AA78A202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, + 7832C2B4209BB32500224EED /* ComparableExtensionsTests.swift in Sources */, 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, @@ -1672,6 +1688,7 @@ 07C50D481F5EB04700F46E5A /* UILabelExtensionsTests.swift in Sources */, 07C50D701F5EB05100F46E5A /* OptionalExtensionsTests.swift in Sources */, 07C50D6E1F5EB05100F46E5A /* IntExtensionsTests.swift in Sources */, + 7832C2B5209BB32500224EED /* ComparableExtensionsTests.swift in Sources */, 07C50D711F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, 07C50D6A1F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 077BA09F1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, @@ -1762,6 +1779,7 @@ 07C50D7D1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */, + 7832C2B6209BB32500224EED /* ComparableExtensionsTests.swift in Sources */, 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, A94AA78C202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index 3a6667111..c3a635e21 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -242,9 +242,11 @@ final class ArrayExtensionsTests: XCTestCase { func testGroupBy() { let array: [String] = ["james", "irving", "jordan", "jonshon", "iverson"] - let grouped = array.groupByKey { element -> String in + + let grouped = Dictionary(grouping: array) { element -> String in return String(element.first!) } + XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) XCTAssertEqual(grouped["i"] ?? [], [ "irving", "iverson" ]) } diff --git a/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift b/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift new file mode 100644 index 000000000..2a9a5eeef --- /dev/null +++ b/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift @@ -0,0 +1,31 @@ +// +// ComparableExtensionsTests.swift +// SwifterSwift +// +// Created by Shai Mishali on 5/4/18. +// Copyright © 2018 SwifterSwift +// + +import XCTest + +@testable import SwifterSwift + +final class ComparableExtensionsTests: XCTestCase { + + func testIsBetween() { + XCTAssertFalse(1.isBetween(min: 5, max: 7), "number range") + XCTAssertTrue(7.isBetween(min: 6, max: 12), "number range") + XCTAssertTrue(0.32.isBetween(min: 0.31, max: 0.33), "float range") + XCTAssertTrue("c".isBetween(min: "a", max: "d"), "string range") + + let date = Date() + XCTAssertTrue(date.isBetween(min: date, max: date.addingTimeInterval(1000)), "date range") + } + + func testClamped() { + XCTAssertEqual(1.clamped(min: 3, max: 8), 3) + XCTAssertEqual(4.clamped(min: 3, max: 7), 4) + XCTAssertEqual("c".clamped(min: "e", max: "g"), "e") + XCTAssertEqual(0.32.clamped(min: 0.37, max: 0.42), 0.37) + } +} From 2e78957cc3d2448ae3cd300854e0247b1ed7a1ff Mon Sep 17 00:00:00 2001 From: Shai Mishali Date: Fri, 4 May 2018 20:26:09 +0300 Subject: [PATCH 157/201] Fix Comparable extensions to used `ClosedRange` vs `min/max`. (#468) --- .../SwiftStdlib/ComparableExtensions.swift | 32 +++++++++---------- .../ComparableExtensionsTests.swift | 18 +++++------ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift b/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift index 338822098..18486f2d7 100644 --- a/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ComparableExtensions.swift @@ -8,36 +8,34 @@ // MARK: - Methods public extension Comparable { - /// SwifterSwift: Returns true if value is between provided `min` - /// and `max`. + /// SwifterSwift: Returns true if value is in the provided range. /// - /// 1.isBetween(min: 5, max: 7) // false - /// 7.isBetween(min: 6, max: 12) // true - /// date.isBetween(min: date1, max: date2) - /// "c".isBetween(min: "a", max: "d") // true - /// 0.32.isBetween(min: 0.31, max: 0.33) // true + /// 1.isBetween(5...7) // false + /// 7.isBetween(6...12) // true + /// date.isBetween(date1...date2) + /// "c".isBetween(a...d) // true + /// 0.32.isBetween(0.31...0.33) // true /// /// - parameter min: Minimum comparable value. /// - parameter max: Maximum comparable value. /// /// - returns: `true` if value is between `min` and `max`, `false` otherwise. - public func isBetween(min: Self, max: Self) -> Bool { - return self >= min && self <= max + public func isBetween(_ range: ClosedRange) -> Bool { + return range ~= self } - /// SwifterSwift: Returns value limited within the provided range - /// between `min` and `max`. + /// SwifterSwift: Returns value limited within the provided range. /// - /// 1.clamped(min: 3, max: 8) // 3 - /// 4.clamped(min: 3, max: 7) // 4 - /// "c".clamped(min: "e", max: "g") // "e" - /// 0.32.clamped(min: 0.1, max: 0.29) // 0.29 + /// 1.clamped(to: 3...8) // 3 + /// 4.clamped(to: 3...7) // 4 + /// "c".clamped(to: "e"..."g") // "e" + /// 0.32.clamped(to: 0.1...0.29) // 0.29 /// /// - parameter min: Lower bound to limit the value to. /// - parameter max: Upper bound to limit the value to. /// /// - returns: A value limited to the range between `min` and `max`. - public func clamped(min minNum: Self, max maxNum: Self) -> Self { - return max(minNum, min(self, maxNum)) + public func clamped(to range: ClosedRange) -> Self { + return max(range.lowerBound, min(self, range.upperBound)) } } diff --git a/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift b/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift index 2a9a5eeef..20aac01c0 100644 --- a/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ComparableExtensionsTests.swift @@ -13,19 +13,19 @@ import XCTest final class ComparableExtensionsTests: XCTestCase { func testIsBetween() { - XCTAssertFalse(1.isBetween(min: 5, max: 7), "number range") - XCTAssertTrue(7.isBetween(min: 6, max: 12), "number range") - XCTAssertTrue(0.32.isBetween(min: 0.31, max: 0.33), "float range") - XCTAssertTrue("c".isBetween(min: "a", max: "d"), "string range") + XCTAssertFalse(1.isBetween(5...7), "number range") + XCTAssertTrue(7.isBetween(6...12), "number range") + XCTAssertTrue(0.32.isBetween(0.31...0.33), "float range") + XCTAssertTrue("c".isBetween("a"..."d"), "string range") let date = Date() - XCTAssertTrue(date.isBetween(min: date, max: date.addingTimeInterval(1000)), "date range") + XCTAssertTrue(date.isBetween(date...date.addingTimeInterval(1000)), "date range") } func testClamped() { - XCTAssertEqual(1.clamped(min: 3, max: 8), 3) - XCTAssertEqual(4.clamped(min: 3, max: 7), 4) - XCTAssertEqual("c".clamped(min: "e", max: "g"), "e") - XCTAssertEqual(0.32.clamped(min: 0.37, max: 0.42), 0.37) + XCTAssertEqual(1.clamped(to: 3...8), 3) + XCTAssertEqual(4.clamped(to: 3...7), 4) + XCTAssertEqual("c".clamped(to: "e"..."g"), "e") + XCTAssertEqual(0.32.clamped(to: 0.37...0.42), 0.37) } } From 046af2b5e392f3da91f662b57ec05694ceff5c52 Mon Sep 17 00:00:00 2001 From: Joan Disho Date: Fri, 4 May 2018 23:03:29 +0200 Subject: [PATCH 158/201] Value for query key (#467) * return not an optional value in "dequeueReusable..." in UICollectionView and UITableView Extentions. * pass tests for UITableViewExtentionsTests * remove the unnecessary "?" * refactor fatalError messages in UICollection and UITableView Extensions. * added a changelog about UITableView and UICollectionView Extensions * add function to get the value of a query key * add tests * change from `value(for:)` to `queryValue(for:)` and add a test case for a non-existing key * update CHANGELOG * refactor comment --- CHANGELOG.md | 2 ++ Sources/Extensions/Foundation/URLExtensions.swift | 14 ++++++++++++++ Tests/FoundationTests/URLExtensionsTests.swift | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31eaaa907..b5c8d36f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). +   + - Added `queryValue(for:)` to get the value of a query key from a URL. [#467](https://github.com/SwifterSwift/SwifterSwift/pull/467) by [jdisho](https://github.com/jdisho). - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 8c1ed9895..497340181 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -63,6 +63,20 @@ public extension URL { self = appendingQueryParameters(parameters) } + /// SwifterSwift: Get value of a query key. + /// + /// var url = URL(string: "https://google.com?code=12345")! + /// queryValue(for: "code") -> "12345" + /// + /// - Parameter key: The key of a query value. + public func queryValue(for key: String) -> String? { + let stringURL = self.absoluteString + guard let items = URLComponents(string: stringURL)?.queryItems else { return nil } + for item in items where item.name == key { + return item.value + } + return nil + } /// SwifterSwift: Returns a new URL by removing all the path components. /// /// let url = URL(string: "https://domain.com/path/other")! diff --git a/Tests/FoundationTests/URLExtensionsTests.swift b/Tests/FoundationTests/URLExtensionsTests.swift index 9798dbce7..eab900393 100644 --- a/Tests/FoundationTests/URLExtensionsTests.swift +++ b/Tests/FoundationTests/URLExtensionsTests.swift @@ -37,6 +37,18 @@ final class URLExtensionsTests: XCTestCase { XCTAssertEqual(parameters["empty"], nil) } + func testValueForQueryKey() { + let url = URL(string: "https://google.com?code=12345&empty")! + + let codeResult = url.queryValue(for: "code") + let emtpyResult = url.queryValue(for: "empty") + let otherResult = url.queryValue(for: "other") + + XCTAssertEqual(codeResult, "12345") + XCTAssertEqual(emtpyResult, nil) + XCTAssertEqual(otherResult, nil) + } + func testDeletingAllPathComponents() { let url = URL(string: "https://domain.com/path/other/")! let result = url.deletingAllPathComponents() From e72ddbc6ffc35b41d5d22840feffe25fa59a3335 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 6 May 2018 14:11:15 -0300 Subject: [PATCH 159/201] Fixing foreach(slice: ) docs. (#469) --- .../SwiftStdlib/ArrayExtensions.swift | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 19f47af73..a90190c64 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -71,7 +71,7 @@ public extension Array { swapAt(index, otherIndex) } - /// SwifterSwift: Get first index where condition is met. + /// SwifterSwift: Get the first index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 6].firstIndex { $0 % 2 == 0 } -> 3 /// @@ -84,7 +84,7 @@ public extension Array { return nil } - /// SwifterSwift: Get last index where condition is met. + /// SwifterSwift: Get the last index where condition is met. /// /// [1, 7, 1, 2, 4, 1, 8].lastIndex { $0 % 2 == 0 } -> 6 /// @@ -142,8 +142,8 @@ public extension Array { /// - Returns: number of times the condition evaluated to true. public func count(where condition: (Element) throws -> Bool) rethrows -> Int { var count = 0 - for element in self { - if try condition(element) { count += 1 } + for element in self where try condition(element) { + count += 1 } return count } @@ -154,7 +154,7 @@ public extension Array { /// /// - Parameter body: a closure that takes an element of the array as a parameter. public func forEachReversed(_ body: (Element) throws -> Void) rethrows { - try reversed().forEach { try body($0) } + try reversed().forEach(body) } /// SwifterSwift: Calls given closure with each element where condition is true. @@ -243,7 +243,7 @@ public extension Array { return [Element]() } - /// SwifterSwift: Calls given closure with an array of size of the parameter slice where condition is true. + /// SwifterSwift: Calls the given closure with an array of size of the parameter slice. /// /// [0, 2, 4, 7].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7] /// [0, 2, 4, 7, 6].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7], [6] @@ -261,7 +261,7 @@ public extension Array { } } - /// SwifterSwift: Returns an array of slices of length "size" from the array. If array can't be split evenly, the final slice will be the remaining elements. + /// SwifterSwift: Returns an array of slices of length "size" from the array. If array can't be split evenly, the last slice will be the remaining elements. /// /// [0, 2, 4, 7].group(by: 2) -> [[0, 2], [4, 7]] /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] @@ -333,7 +333,7 @@ public extension Array { /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: Number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Parameter places: The number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start become the end. /// /// - Returns: self after rotating public mutating func rotate(by places: Int) -> [Element] { @@ -367,7 +367,7 @@ public extension Array { return array.shuffle() } - /// SwifterSwift: Return a sorted array based on an optional keypath. + /// SwifterSwift: Returns a sorted array based on an optional keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. /// - Parameter ascending: If order must be ascending. @@ -382,7 +382,7 @@ public extension Array { }) } - /// SwifterSwift: Return a sorted array based on a keypath. + /// SwifterSwift: Returns a sorted array based on a keypath. /// /// - Parameter path: Key path to sort. The key path type must be Comparable. /// - Parameter ascending: If order must be ascending. From 14eea2f4ddd0af0c0c21f04cffb5a6253850ba7d Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 6 May 2018 22:28:55 +0300 Subject: [PATCH 160/201] Update SPM instructions (#471) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83c6ed4c8..973bb8067 100755 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ let package = Package( name: "YOUR_PROJECT_NAME", targets: [], dependencies: [ - .Package(url: "https://github.com/SwifterSwift/SwifterSwift.git", majorVersion: 4), + .package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "4.0.0") ] ) From 06961e74878c22f256cc55bfef7a22999699119b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=A4rtwig?= Date: Mon, 7 May 2018 01:01:18 +0200 Subject: [PATCH 161/201] Refactor array extensions (#470) * Change conformance of sum() from Array to Sequence * Change conformance of average() from Array to Collection * Change conformance of firstIndex(where:), lastIndex(where:) and indices(where:) from Array to Collection * Change conformance of last(where:), reject(where:), count(where:), forEachReversed() and forEach(where:, body:) from Array to Sequence * Change conformance of accumulate(initial:, next:) and filtered(_:, map:) from Array to Sequence * Change conformance of forEach(slice:, body:) and group(by:) from Array to Collection * Return early in contains(_:) when the condition is false * Change conformance of contains(_:) from Array to Sequence * Change conformance of firstIndex(of:) and lastIndex(of:) from Array to Collection * Add changelog entry for the array extensions refactoring --- CHANGELOG.md | 3 + .../SwiftStdlib/ArrayExtensions.swift | 255 ------------------ .../SwiftStdlib/CollectionExtensions.swift | 132 ++++++++- .../SwiftStdlib/SequenceExtensions.swift | 128 +++++++++ .../ArrayExtensionsTests.swift | 192 ------------- .../CollectionExtensionsTests.swift | 119 +++++++- .../SequenceExtensionsTests.swift | 60 +++++ 7 files changed, 437 insertions(+), 452 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5c8d36f3..8d9adb0ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **Breaking Change** `firstResponder` UIView extension is now a function and supports recursive find in the view hierarchy. [#447](https://github.com/SwifterSwift/SwifterSwift/pull/447) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **UIImage**: - `scaled(toWidth:, opaque:, with orientation:)` and `scaled(toHeight:, opaque:, with orientation:)` now have an optional parameter for opaqueness. [#446](https://github.com/SwifterSwift/SwifterSwift/pull/446) by [vyax](https://github.com/vyax) +- **Array/Collection/Sequence** + - The conformance of `sum()`, `last(where:)`, `reject(where:)`, `count(where:)`, `forEachReversed()`, `forEach(where:, body:)`, `accumulate(initial:, next:)`, `filtered(_:, map:)` and `contains(_:)` has been changed from Array to Sequence [#470](https://github.com/SwifterSwift/SwifterSwift/pull/470) by [vyax](https://github.com/vyax) + - The conformance of `average()`, `firstIndex(where:)`, `lastIndex(where:)`, `indices(where:)`, `forEach(slice:, body:)`, `group(by:)`, `firstIndex(of:)` and `lastIndex(of:)` has been changed from Array to Collection [#470](https://github.com/SwifterSwift/SwifterSwift/pull/470) by [vyax](https://github.com/vyax) ### Deprecated - **Array** diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index a90190c64..fbf44ef91 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -6,43 +6,6 @@ // Copyright © 2016 SwifterSwift // -// MARK: - Methods (Numeric) -public extension Array where Element: Numeric { - - /// SwifterSwift: Sum of all elements in array. - /// - /// [1, 2, 3, 4, 5].sum() -> 15 - /// - /// - Returns: sum of the array's elements. - public func sum() -> Element { - var total: Element = 0 - for index in 0.. Element { - guard !isEmpty else { return 0 } - var total: Element = 0 - for index in 0.. 3 - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: first index where the specified condition evaluates to true. (optional) - public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { - for (index, value) in lazy.enumerated() where try condition(value) { - return index - } - return nil - } - - /// SwifterSwift: Get the last index where condition is met. - /// - /// [1, 7, 1, 2, 4, 1, 8].lastIndex { $0 % 2 == 0 } -> 6 - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: last index where the specified condition evaluates to true. (optional) - public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { - for (index, value) in lazy.enumerated().reversed() where try condition(value) { - return index - } - return nil - } - - /// SwifterSwift: Get all indices where condition is met. - /// - /// [1, 7, 1, 2, 4, 1, 8].indices(where: { $0 == 1 }) -> [0, 2, 5] - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: all indices where the specified condition evaluates to true. (optional) - public func indices(where condition: (Element) throws -> Bool) rethrows -> [Index]? { - var indicies: [Index] = [] - for (index, value) in lazy.enumerated() where try condition(value) { - indicies.append(index) - } - return indicies.isEmpty ? nil : indicies - } - - /// SwifterSwift: Get last element that satisfies a conditon. - /// - /// [2, 2, 4, 7].last(where: {$0 % 2 == 0}) -> 4 - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: the last element in the array matching the specified condition. (optional) - public func last(where condition: (Element) throws -> Bool) rethrows -> Element? { - for element in reversed() { - if try condition(element) { return element } - } - return nil - } - - /// SwifterSwift: Filter elements based on a rejection condition. - /// - /// [2, 2, 4, 7].reject(where: {$0 % 2 == 0}) -> [7] - /// - /// - Parameter condition: to evaluate the exclusion of an element from the array. - /// - Returns: the array with rejected values filtered from it. - public func reject(where condition: (Element) throws -> Bool) rethrows -> [Element] { - return try filter { return try !condition($0) } - } - - /// SwifterSwift: Get element count based on condition. - /// - /// [2, 2, 4, 7].count(where: {$0 % 2 == 0}) -> 3 - /// - /// - Parameter condition: condition to evaluate each element against. - /// - Returns: number of times the condition evaluated to true. - public func count(where condition: (Element) throws -> Bool) rethrows -> Int { - var count = 0 - for element in self where try condition(element) { - count += 1 - } - return count - } - - /// SwifterSwift: Iterate over a collection in reverse order. (right to left) - /// - /// [0, 2, 4, 7].forEachReversed({ print($0)}) -> //Order of print: 7,4,2,0 - /// - /// - Parameter body: a closure that takes an element of the array as a parameter. - public func forEachReversed(_ body: (Element) throws -> Void) rethrows { - try reversed().forEach(body) - } - - /// SwifterSwift: Calls given closure with each element where condition is true. - /// - /// [0, 2, 4, 7].forEach(where: {$0 % 2 == 0}, body: { print($0)}) -> //print: 0, 2, 4 - /// - /// - Parameters: - /// - condition: condition to evaluate each element against. - /// - body: a closure that takes an element of the array as a parameter. - public func forEach(where condition: (Element) throws -> Bool, body: (Element) throws -> Void) rethrows { - for element in self where try condition(element) { - try body(element) - } - } - - /// SwifterSwift: Reduces an array while returning each interim combination. - /// - /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] - /// - /// - Parameters: - /// - initial: initial value. - /// - next: closure that combines the accumulating value and next element of the array. - /// - Returns: an array of the final accumulated value and each interim combination. - public func accumulate(initial: U, next: (U, Element) throws -> U) rethrows -> [U] { - var runningTotal = initial - return try map { element in - runningTotal = try next(runningTotal, element) - return runningTotal - } - } - - /// SwifterSwift: Filtered and map in a single operation. - /// - /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] - /// - /// - Parameters: - /// - isIncluded: condition of inclusion to evaluate each element against. - /// - transform: transform element function to evaluate every element. - /// - Returns: Return an filtered and mapped array. - public func filtered(_ isIncluded: (Element) throws -> Bool, map transform: (Element) throws -> T) rethrows -> [T] { - return try compactMap({ - if try isIncluded($0) { - return try transform($0) - } - return nil - }) - } - @discardableResult /// SwifterSwift: Keep elements of Array while condition is true. /// @@ -243,43 +74,6 @@ public extension Array { return [Element]() } - /// SwifterSwift: Calls the given closure with an array of size of the parameter slice. - /// - /// [0, 2, 4, 7].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7] - /// [0, 2, 4, 7, 6].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7], [6] - /// - /// - Parameters: - /// - slice: size of array in each interation. - /// - body: a closure that takes an array of slice size as a parameter. - public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { - guard slice > 0, !isEmpty else { return } - - var value: Int = 0 - while value < count { - try body(Array(self[Swift.max(value, startIndex).. [[0, 2], [4, 7]] - /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] - /// - /// - Parameter size: The size of the slices to be returned. - /// - Returns: grouped self. - public func group(by size: Int) -> [[Element]]? { - //Inspired by: https://lodash.com/docs/4.17.4#chunk - guard size > 0, !isEmpty else { return nil } - var value: Int = 0 - var slices: [[Element]] = [] - while value < count { - slices.append(Array(self[Swift.max(value, startIndex).. ( [0, 2, 4], [1, 3, 5] ) @@ -421,25 +215,6 @@ public extension Array { // MARK: - Methods (Equatable) public extension Array where Element: Equatable { - /// SwifterSwift: Check if array contains an array of elements. - /// - /// [1, 2, 3, 4, 5].contains([1, 2]) -> true - /// [1.2, 2.3, 4.5, 3.4, 4.5].contains([2, 6]) -> false - /// ["h", "e", "l", "l", "o"].contains(["l", "o"]) -> true - /// - /// - Parameter elements: array of elements to check. - /// - Returns: true if array contains all given items. - public func contains(_ elements: [Element]) -> Bool { - guard !elements.isEmpty else { return true } - var found = true - for element in elements { - if !contains(element) { - found = false - } - } - return found - } - /// SwifterSwift: All indices of specified item. /// /// [1, 2, 2, 3, 4, 2, 5].indices(of 2) -> [1, 2, 5] @@ -513,34 +288,4 @@ public extension Array where Element: Equatable { } } - /// SwifterSwift: First index of a given item in an array. - /// - /// [1, 2, 2, 3, 4, 2, 5].firstIndex(of: 2) -> 1 - /// [1.2, 2.3, 4.5, 3.4, 4.5].firstIndex(of: 6.5) -> nil - /// ["h", "e", "l", "l", "o"].firstIndex(of: "l") -> 2 - /// - /// - Parameter item: item to check. - /// - Returns: first index of item in array (if exists). - public func firstIndex(of item: Element) -> Index? { - for (index, value) in lazy.enumerated() where value == item { - return index - } - return nil - } - - /// SwifterSwift: Last index of element in array. - /// - /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of: 2) -> 5 - /// [1.2, 2.3, 4.5, 3.4, 4.5].lastIndex(of: 6.5) -> nil - /// ["h", "e", "l", "l", "o"].lastIndex(of: "l") -> 3 - /// - /// - Parameter item: item to check. - /// - Returns: last index of item in array (if exists). - public func lastIndex(of item: Element) -> Index? { - for (index, value) in lazy.enumerated().reversed() where value == item { - return index - } - return nil - } - } diff --git a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift index b724b34f9..70e3d31e1 100644 --- a/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/CollectionExtensions.swift @@ -16,7 +16,7 @@ public extension Collection { /// } /// /// - Parameter each: closure to run for each element. - public func forEachInParallel(_ each: (Self.Iterator.Element) -> Void) { + public func forEachInParallel(_ each: (Self.Element) -> Void) { let indicesArray = Array(indices) DispatchQueue.concurrentPerform(iterations: indicesArray.count) { (index) in @@ -32,7 +32,7 @@ public extension Collection { /// arr[safe: 10] -> nil /// /// - Parameter index: index of element to access element. - public subscript(safe index: Index) -> Iterator.Element? { + public subscript(safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } @@ -48,10 +48,121 @@ public extension Collection where Index == Int { return self[index] } + /// SwifterSwift: Get the first index where condition is met. + /// + /// [1, 7, 1, 2, 4, 1, 6].firstIndex { $0 % 2 == 0 } -> 3 + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: first index where the specified condition evaluates to true. (optional) + public func firstIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { + for (index, value) in lazy.enumerated() where try condition(value) { + return index + } + return nil + } + + /// SwifterSwift: Get the last index where condition is met. + /// + /// [1, 7, 1, 2, 4, 1, 8].lastIndex { $0 % 2 == 0 } -> 6 + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: last index where the specified condition evaluates to true. (optional) + public func lastIndex(where condition: (Element) throws -> Bool) rethrows -> Index? { + for (index, value) in lazy.enumerated().reversed() where try condition(value) { + return index + } + return nil + } + + /// SwifterSwift: Get all indices where condition is met. + /// + /// [1, 7, 1, 2, 4, 1, 8].indices(where: { $0 == 1 }) -> [0, 2, 5] + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: all indices where the specified condition evaluates to true. (optional) + public func indices(where condition: (Element) throws -> Bool) rethrows -> [Index]? { + var indicies: [Index] = [] + for (index, value) in lazy.enumerated() where try condition(value) { + indicies.append(index) + } + return indicies.isEmpty ? nil : indicies + } + + /// SwifterSwift: Calls the given closure with an array of size of the parameter slice. + /// + /// [0, 2, 4, 7].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7] + /// [0, 2, 4, 7, 6].forEach(slice: 2) { print($0) } -> //print: [0, 2], [4, 7], [6] + /// + /// - Parameters: + /// - slice: size of array in each interation. + /// - body: a closure that takes an array of slice size as a parameter. + public func forEach(slice: Int, body: ([Element]) throws -> Void) rethrows { + guard slice > 0, !isEmpty else { return } + + var value: Int = 0 + while value < count { + try body(Array(self[Swift.max(value, startIndex).. [[0, 2], [4, 7]] + /// [0, 2, 4, 7, 6].group(by: 2) -> [[0, 2], [4, 7], [6]] + /// + /// - Parameter size: The size of the slices to be returned. + /// - Returns: grouped self. + public func group(by size: Int) -> [[Element]]? { + //Inspired by: https://lodash.com/docs/4.17.4#chunk + guard size > 0, !isEmpty else { return nil } + var value: Int = 0 + var slices: [[Element]] = [] + while value < count { + slices.append(Array(self[Swift.max(value, startIndex).. 1 + /// [1.2, 2.3, 4.5, 3.4, 4.5].firstIndex(of: 6.5) -> nil + /// ["h", "e", "l", "l", "o"].firstIndex(of: "l") -> 2 + /// + /// - Parameter item: item to check. + /// - Returns: first index of item in array (if exists). + public func firstIndex(of item: Element) -> Index? { + for (index, value) in lazy.enumerated() where value == item { + return index + } + return nil + } + + /// SwifterSwift: Last index of element in array. + /// + /// [1, 2, 2, 3, 4, 2, 5].lastIndex(of: 2) -> 5 + /// [1.2, 2.3, 4.5, 3.4, 4.5].lastIndex(of: 6.5) -> nil + /// ["h", "e", "l", "l", "o"].lastIndex(of: "l") -> 3 + /// + /// - Parameter item: item to check. + /// - Returns: last index of item in array (if exists). + public func lastIndex(of item: Element) -> Index? { + for (index, value) in lazy.enumerated().reversed() where value == item { + return index + } + return nil + } + } // MARK: - Methods (Integer) -public extension Collection where Iterator.Element == IntegerLiteralType, Index == Int { +public extension Collection where Element == IntegerLiteralType, Index == Int { /// SwifterSwift: Average of all elements in array. /// @@ -62,3 +173,18 @@ public extension Collection where Iterator.Element == IntegerLiteralType, Index } } + +// MARK: - Methods (FloatingPoint) +public extension Collection where Element: FloatingPoint { + + /// SwifterSwift: Average of all elements in array. + /// + /// [1.2, 2.3, 4.5, 3.4, 4.5].average() = 3.18 + /// + /// - Returns: average of the array's elements. + public func average() -> Element { + guard !isEmpty else { return 0 } + return reduce(0, {$0 + $1}) / Element(count) + } + +} diff --git a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift index aa4a5da2d..69c5405a9 100644 --- a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift @@ -43,4 +43,132 @@ public extension Sequence { return try contains { try condition($0) } } + /// SwifterSwift: Get last element that satisfies a conditon. + /// + /// [2, 2, 4, 7].last(where: {$0 % 2 == 0}) -> 4 + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: the last element in the array matching the specified condition. (optional) + public func last(where condition: (Element) throws -> Bool) rethrows -> Element? { + for element in reversed() { + if try condition(element) { return element } + } + return nil + } + + /// SwifterSwift: Filter elements based on a rejection condition. + /// + /// [2, 2, 4, 7].reject(where: {$0 % 2 == 0}) -> [7] + /// + /// - Parameter condition: to evaluate the exclusion of an element from the array. + /// - Returns: the array with rejected values filtered from it. + public func reject(where condition: (Element) throws -> Bool) rethrows -> [Element] { + return try filter { return try !condition($0) } + } + + /// SwifterSwift: Get element count based on condition. + /// + /// [2, 2, 4, 7].count(where: {$0 % 2 == 0}) -> 3 + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: number of times the condition evaluated to true. + public func count(where condition: (Element) throws -> Bool) rethrows -> Int { + var count = 0 + for element in self where try condition(element) { + count += 1 + } + return count + } + + /// SwifterSwift: Iterate over a collection in reverse order. (right to left) + /// + /// [0, 2, 4, 7].forEachReversed({ print($0)}) -> //Order of print: 7,4,2,0 + /// + /// - Parameter body: a closure that takes an element of the array as a parameter. + public func forEachReversed(_ body: (Element) throws -> Void) rethrows { + try reversed().forEach(body) + } + + /// SwifterSwift: Calls the given closure with each element where condition is true. + /// + /// [0, 2, 4, 7].forEach(where: {$0 % 2 == 0}, body: { print($0)}) -> //print: 0, 2, 4 + /// + /// - Parameters: + /// - condition: condition to evaluate each element against. + /// - body: a closure that takes an element of the array as a parameter. + public func forEach(where condition: (Element) throws -> Bool, body: (Element) throws -> Void) rethrows { + for element in self where try condition(element) { + try body(element) + } + } + + /// SwifterSwift: Reduces an array while returning each interim combination. + /// + /// [1, 2, 3].accumulate(initial: 0, next: +) -> [1, 3, 6] + /// + /// - Parameters: + /// - initial: initial value. + /// - next: closure that combines the accumulating value and next element of the array. + /// - Returns: an array of the final accumulated value and each interim combination. + public func accumulate(initial: U, next: (U, Element) throws -> U) rethrows -> [U] { + var runningTotal = initial + return try map { element in + runningTotal = try next(runningTotal, element) + return runningTotal + } + } + + /// SwifterSwift: Filtered and map in a single operation. + /// + /// [1,2,3,4,5].filtered({ $0 % 2 == 0 }, map: { $0.string }) -> ["2", "4"] + /// + /// - Parameters: + /// - isIncluded: condition of inclusion to evaluate each element against. + /// - transform: transform element function to evaluate every element. + /// - Returns: Return an filtered and mapped array. + public func filtered(_ isIncluded: (Element) throws -> Bool, map transform: (Element) throws -> T) rethrows -> [T] { + return try compactMap({ + if try isIncluded($0) { + return try transform($0) + } + return nil + }) + } + +} + +public extension Sequence where Element: Equatable { + + /// SwifterSwift: Check if array contains an array of elements. + /// + /// [1, 2, 3, 4, 5].contains([1, 2]) -> true + /// [1.2, 2.3, 4.5, 3.4, 4.5].contains([2, 6]) -> false + /// ["h", "e", "l", "l", "o"].contains(["l", "o"]) -> true + /// + /// - Parameter elements: array of elements to check. + /// - Returns: true if array contains all given items. + public func contains(_ elements: [Element]) -> Bool { + guard !elements.isEmpty else { return true } + for element in elements { + if !contains(element) { + return false + } + } + return true + } + +} + +// MARK: - Methods (Numeric) +public extension Sequence where Element: Numeric { + + /// SwifterSwift: Sum of all elements in array. + /// + /// [1, 2, 3, 4, 5].sum() -> 15 + /// + /// - Returns: sum of the array's elements. + public func sum() -> Element { + return reduce(0, {$0 + $1}) + } + } diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index c3a635e21..ed7e417f0 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -18,19 +18,8 @@ private struct Person: Equatable { } -// swiftlint:disable next type_body_length final class ArrayExtensionsTests: XCTestCase { - func testSum() { - XCTAssertEqual([1, 2, 3, 4, 5].sum(), 15) - XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].sum(), 17) - } - - func testAverage() { - XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].average(), 3.4) - XCTAssertEqual([Double]().average(), 0) - } - func testPrepend() { var arr = [2, 3, 4, 5] arr.prepend(1) @@ -57,76 +46,6 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(swappedEmptyArray, emptyArray) } - func testFirstIndexWhere() { - let array = [1, 7, 1, 2, 4, 1, 6] - let index = array.firstIndex { $0 % 2 == 0 } - XCTAssertEqual(index, 3) - XCTAssertNil([Int]().firstIndex { $0 % 2 == 0 }) - } - - func testLastIndexWhere() { - let array = [1, 1, 1, 2, 2, 1, 1, 2, 1] - let index = array.lastIndex { $0 % 2 == 0 } - XCTAssertEqual(index, 7) - XCTAssertNil(array.lastIndex { $0 == 3 }) - XCTAssertNil([Int]().lastIndex { $0 % 2 == 0 }) - } - - func testIndicesWhere() { - let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - let indices = array.indices { $0 % 2 == 0 } - XCTAssertEqual(indices!, [0, 2, 4, 6, 8]) - let emptyArray: [Int] = [] - let emptyIndices = emptyArray.indices { $0 % 2 == 0 } - XCTAssertNil(emptyIndices) - } - - func testLastWhere() { - let array = [1, 1, 2, 1, 1, 1, 2, 1, 4, 1] - let element = array.last { $0 % 2 == 0 } - XCTAssertEqual(element, 4) - XCTAssertNil([Int]().last { $0 % 2 == 0 }) - } - - func testRejectWhere() { - let input = [1, 2, 3, 4, 5] - let output = input.reject { $0 % 2 == 0 } - XCTAssertEqual(output, [1, 3, 5]) - } - - func testCountWhere() { - let array = [1, 1, 1, 1, 4, 4, 1, 1, 1] - let count = array.count { $0 % 2 == 0 } - XCTAssertEqual(count, 2) - } - - func testForEachReversed() { - let input = [1, 2, 3, 4, 5] - var output: [Int] = [] - input.forEachReversed { output.append($0) } - XCTAssertEqual(output.first, 5) - } - - func testForEachWhere() { - let input = [1, 2, 2, 2, 1, 4, 1] - var output: [Int] = [] - input.forEach(where: {$0 % 2 == 0}, body: { output.append($0 * 2) }) - XCTAssertEqual(output, [4, 4, 4, 8]) - } - - func testAccumulate() { - let input = [1, 2, 3] - let result = input.accumulate(initial: 0, next: +) - XCTAssertEqual([1, 3, 6], result) - } - - func testFilteredMap() { - let input = [1, 2, 3, 4, 5] - let result = input.filtered({ $0 % 2 == 0 }, map: { $0.string }) - XCTAssertEqual(result.count, 2) - XCTAssertEqual(["2", "4"], result) - } - func testKeepWhile() { var input = [2, 4, 6, 7, 8, 9, 10] input.keep(while: {$0 % 2 == 0 }) @@ -161,96 +80,6 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual([].skip(while: { $0 % 2 == 0}), []) } - func testForEachSlice() { - var iterations: Int = 0 - - // A slice with value zero - var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] - array.forEach(slice: 0) { _ in - iterations += 1 - } - XCTAssertEqual(iterations, 0) - - // A slice that divide the total evenly - array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] - - array.forEach(slice: 2) { (sliceArray) in - switch iterations { - case 0: - XCTAssertEqual(sliceArray, [ "james", "irving" ]) - case 1: - XCTAssertEqual(sliceArray, [ "jordan", "jonshon" ]) - case 2: - XCTAssertEqual(sliceArray, [ "iverson", "shaq" ]) - default: break - } - iterations += 1 - } - - // A slice that does not divide the total evenly - array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] - - iterations = 0 - - array.forEach(slice: 2) { (sliceArray) in - switch iterations { - case 0: - XCTAssertEqual(sliceArray, [ "james", "irving" ]) - case 1: - XCTAssertEqual(sliceArray, [ "jordan", "jonshon" ]) - case 2: - XCTAssertEqual(sliceArray, [ "iverson", "shaq" ]) - case 3: - XCTAssertEqual(sliceArray, [ "bird" ]) - default: break - } - iterations += 1 - } - - // A slice greater than the array count - array = [ "james", "irving", "jordan", "jonshon" ] - array.forEach(slice: 6) { (sliceArray) in - XCTAssertEqual(sliceArray, [ "james", "irving", "jordan", "jonshon"]) - } - } - - func testGroupBySize() { - - // A slice with value zero - var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] - var slices = array.group(by: 0) - XCTAssertNil(slices) - - // A slice that divide the total evenly - array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] - slices = array.group(by: 2) - XCTAssertNotNil(slices) - XCTAssertEqual(slices?.count, 3) - - // A slice that does not divide the total evenly - array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] - slices = array.group(by: 2) - XCTAssertNotNil(slices) - XCTAssertEqual(slices?.count, 4) - - // A slice greater than the array count - array = [ "james", "irving", "jordan", "jonshon" ] - slices = array.group(by: 6) - XCTAssertNotNil(slices) - XCTAssertEqual(slices?.count, 1) - } - - func testGroupBy() { - let array: [String] = ["james", "irving", "jordan", "jonshon", "iverson"] - - let grouped = Dictionary(grouping: array) { element -> String in - return String(element.first!) - } - - XCTAssertEqual(grouped["j"] ?? [], [ "james", "jordan", "jonshon" ]) - XCTAssertEqual(grouped["i"] ?? [], [ "irving", "iverson" ]) - } - func testDivided() { let input = [0, 1, 2, 3, 4, 5] let (even, odd) = input.divided { $0 % 2 == 0 } @@ -352,15 +181,6 @@ final class ArrayExtensionsTests: XCTestCase { Person(name: "Wade", age: nil)]) } - func testContains() { - XCTAssert([Int]().contains([])) - XCTAssertFalse([Int]().contains([1, 2])) - XCTAssert([1, 2, 3].contains([1, 2])) - XCTAssert([1, 2, 3].contains([2, 3])) - XCTAssert([1, 2, 3].contains([1, 3])) - XCTAssertFalse([1, 2, 3].contains([4, 5])) - } - func testIndices() { XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 1), [0, 1, 5, 7]) XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) @@ -397,16 +217,4 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(["h", "e", "l", "l", "o"].withoutDuplicates(), ["h", "e", "l", "o"]) } - func testFirstIndex() { - XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2)) - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2), 2) - XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 7)) - } - - func testLastIndex() { - XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2)) - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2), 6) - XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 7)) - } - } diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index 55bc2cb36..f66eb0b1b 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -31,9 +31,124 @@ final class CollectionExtensionsTests: XCTestCase { XCTAssertNil([].randomItem) } + func testFirstIndexWhere() { + let array = [1, 7, 1, 2, 4, 1, 6] + let index = array.firstIndex { $0 % 2 == 0 } + XCTAssertEqual(index, 3) + XCTAssertNil([Int]().firstIndex { $0 % 2 == 0 }) + } + + func testLastIndexWhere() { + let array = [1, 1, 1, 2, 2, 1, 1, 2, 1] + let index = array.lastIndex { $0 % 2 == 0 } + XCTAssertEqual(index, 7) + XCTAssertNil(array.lastIndex { $0 == 3 }) + XCTAssertNil([Int]().lastIndex { $0 % 2 == 0 }) + } + + func testIndicesWhere() { + let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + let indices = array.indices { $0 % 2 == 0 } + XCTAssertEqual(indices!, [0, 2, 4, 6, 8]) + let emptyArray: [Int] = [] + let emptyIndices = emptyArray.indices { $0 % 2 == 0 } + XCTAssertNil(emptyIndices) + } + + func testForEachSlice() { + var iterations: Int = 0 + + // A slice with value zero + var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] + array.forEach(slice: 0) { _ in + iterations += 1 + } + XCTAssertEqual(iterations, 0) + + // A slice that divide the total evenly + array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] + + array.forEach(slice: 2) { (sliceArray) in + switch iterations { + case 0: + XCTAssertEqual(sliceArray, [ "james", "irving" ]) + case 1: + XCTAssertEqual(sliceArray, [ "jordan", "jonshon" ]) + case 2: + XCTAssertEqual(sliceArray, [ "iverson", "shaq" ]) + default: break + } + iterations += 1 + } + + // A slice that does not divide the total evenly + array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] + + iterations = 0 + + array.forEach(slice: 2) { (sliceArray) in + switch iterations { + case 0: + XCTAssertEqual(sliceArray, [ "james", "irving" ]) + case 1: + XCTAssertEqual(sliceArray, [ "jordan", "jonshon" ]) + case 2: + XCTAssertEqual(sliceArray, [ "iverson", "shaq" ]) + case 3: + XCTAssertEqual(sliceArray, [ "bird" ]) + default: break + } + iterations += 1 + } + + // A slice greater than the array count + array = [ "james", "irving", "jordan", "jonshon" ] + array.forEach(slice: 6) { (sliceArray) in + XCTAssertEqual(sliceArray, [ "james", "irving", "jordan", "jonshon"]) + } + } + + func testGroupBySize() { + + // A slice with value zero + var array: [String] = ["james", "irving", "jordan", "jonshon", "iverson", "shaq"] + var slices = array.group(by: 0) + XCTAssertNil(slices) + + // A slice that divide the total evenly + array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq"] + slices = array.group(by: 2) + XCTAssertNotNil(slices) + XCTAssertEqual(slices?.count, 3) + + // A slice that does not divide the total evenly + array = [ "james", "irving", "jordan", "jonshon", "iverson", "shaq", "bird"] + slices = array.group(by: 2) + XCTAssertNotNil(slices) + XCTAssertEqual(slices?.count, 4) + + // A slice greater than the array count + array = [ "james", "irving", "jordan", "jonshon" ] + slices = array.group(by: 6) + XCTAssertNotNil(slices) + XCTAssertEqual(slices?.count, 1) + } + + func testFirstIndex() { + XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2)) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 2), 2) + XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].firstIndex(of: 7)) + } + + func testLastIndex() { + XCTAssertNotNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2)) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 2), 6) + XCTAssertNil([1, 1, 2, 3, 4, 1, 2, 1].lastIndex(of: 7)) + } + func testAverage() { - XCTAssertEqual(collection.average(), 3) - XCTAssertEqual([Int]().average(), 0) + XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].average(), 3.4) + XCTAssertEqual([Double]().average(), 0) } } diff --git a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift index c99267eb0..c950a9673 100644 --- a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift @@ -26,4 +26,64 @@ final class SequenceExtensionsTests: XCTestCase { XCTAssert(collection.none { $0 % 2 == 0 }) } + func testLastWhere() { + let array = [1, 1, 2, 1, 1, 1, 2, 1, 4, 1] + let element = array.last { $0 % 2 == 0 } + XCTAssertEqual(element, 4) + XCTAssertNil([Int]().last { $0 % 2 == 0 }) + } + + func testRejectWhere() { + let input = [1, 2, 3, 4, 5] + let output = input.reject { $0 % 2 == 0 } + XCTAssertEqual(output, [1, 3, 5]) + } + + func testCountWhere() { + let array = [1, 1, 1, 1, 4, 4, 1, 1, 1] + let count = array.count { $0 % 2 == 0 } + XCTAssertEqual(count, 2) + } + + func testForEachReversed() { + let input = [1, 2, 3, 4, 5] + var output: [Int] = [] + input.forEachReversed { output.append($0) } + XCTAssertEqual(output.first, 5) + } + + func testForEachWhere() { + let input = [1, 2, 2, 2, 1, 4, 1] + var output: [Int] = [] + input.forEach(where: {$0 % 2 == 0}, body: { output.append($0 * 2) }) + XCTAssertEqual(output, [4, 4, 4, 8]) + } + + func testAccumulate() { + let input = [1, 2, 3] + let result = input.accumulate(initial: 0, next: +) + XCTAssertEqual([1, 3, 6], result) + } + + func testFilteredMap() { + let input = [1, 2, 3, 4, 5] + let result = input.filtered({ $0 % 2 == 0 }, map: { $0.string }) + XCTAssertEqual(result.count, 2) + XCTAssertEqual(["2", "4"], result) + } + + func testContains() { + XCTAssert([Int]().contains([])) + XCTAssertFalse([Int]().contains([1, 2])) + XCTAssert([1, 2, 3].contains([1, 2])) + XCTAssert([1, 2, 3].contains([2, 3])) + XCTAssert([1, 2, 3].contains([1, 3])) + XCTAssertFalse([1, 2, 3].contains([4, 5])) + } + + func testSum() { + XCTAssertEqual([1, 2, 3, 4, 5].sum(), 15) + XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].sum(), 17) + } + } From b9a1854b20e90cb1e23ce3db8ef5513a9a2dd24e Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Mon, 14 May 2018 20:23:23 -0300 Subject: [PATCH 162/201] Removing Dictionary specialised version of count(where:) (#473) --- .../SwiftStdlib/DictionaryExtensions.swift | 14 -------------- .../DictionaryExtensionsTests.swift | 8 -------- 2 files changed, 22 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index d710eb72f..e507da6a5 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -76,20 +76,6 @@ public extension Dictionary { return String(data: jsonData, encoding: .utf8) } - /// SwifterSwift: Count dictionary entries that where function returns true. - /// - /// - Parameter where: condition to evaluate each tuple entry against. - /// - Returns: Count of entries that matches the where clousure. - public func count(where condition: @escaping ((key: Key, value: Value)) throws -> Bool) rethrows -> Int { - var count: Int = 0 - try self.forEach { - if try condition($0) { - count += 1 - } - } - return count - } - } // MARK: - Methods (ExpressibleByStringLiteral) diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 67aa44dbc..09cb2eec8 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -53,14 +53,6 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertNil([1: 2].jsonString()) } - func testCountWhere() { - let dict: [String: String] = ["key1": "value", "key2": "value", "key3": "value3"] - let count = dict.count { (tuple) -> Bool in - return tuple.0 == "key1" || tuple.1 == "value" - } - XCTAssertEqual(count, 2) - } - func testLowercaseAllKeys() { var dict = ["tEstKeY": "value"] dict.lowercaseAllKeys() From afd673fab9d870bfba2dfcb2847c7a0f477e65dd Mon Sep 17 00:00:00 2001 From: Rafael Lellys Date: Thu, 17 May 2018 19:57:49 -0700 Subject: [PATCH 163/201] Update README.md (#481) Add SwifterSwift/MapKit subspec to install using Cocoapods --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 973bb8067..cb590b6e8 100755 --- a/README.md +++ b/README.md @@ -52,6 +52,9 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy

    - Integrate AppKit extensions only:

    pod 'SwifterSwift/AppKit'
    +

    - Integrate MapKit extensions only:

    +
    pod 'SwifterSwift/MapKit'
    +

    - Integrate CoreGraphics extensions only:

    pod 'SwifterSwift/CoreGraphics'
    From 3d317236103a2a7a0f0e1755a72324ad6e4bfc67 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 22 May 2018 10:00:14 -0300 Subject: [PATCH 164/201] Just making removeAllkeys more generic (#482) * Just making removeAll Dictionary extension more generic. * Fix * Changelog entry :) * Docs. * remove set. * Minor change. --- CHANGELOG.md | 4 +++- .../SwiftStdlib/DictionaryExtensions.swift | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d9adb0ca..de1e1a0b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). -   + - Added `queryValue(for:)` to get the value of a query key from a URL. [#467](https://github.com/SwifterSwift/SwifterSwift/pull/467) by [jdisho](https://github.com/jdisho). - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). @@ -43,6 +43,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **Array/Collection/Sequence** - The conformance of `sum()`, `last(where:)`, `reject(where:)`, `count(where:)`, `forEachReversed()`, `forEach(where:, body:)`, `accumulate(initial:, next:)`, `filtered(_:, map:)` and `contains(_:)` has been changed from Array to Sequence [#470](https://github.com/SwifterSwift/SwifterSwift/pull/470) by [vyax](https://github.com/vyax) - The conformance of `average()`, `firstIndex(where:)`, `lastIndex(where:)`, `indices(where:)`, `forEach(slice:, body:)`, `group(by:)`, `firstIndex(of:)` and `lastIndex(of:)` has been changed from Array to Collection [#470](https://github.com/SwifterSwift/SwifterSwift/pull/470) by [vyax](https://github.com/vyax) +- **Dictionary** + - The `removeAll(keys:)` changed its paramenter keys to a generic `Sequence` instead of an `Array`. [#482](https://github.com/SwifterSwift/SwifterSwift/pull/482) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). ### Deprecated - **Array** diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index e507da6a5..99b8d0620 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -21,7 +21,7 @@ public extension Dictionary { return index(forKey: key) != nil } - /// SwifterSwift: Remove all keys of the dictionary. + /// SwifterSwift: Remove all keys contained in the keys parameter from the dictionary. /// /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] /// dict.removeAll(keys: ["key1", "key2"]) @@ -30,8 +30,8 @@ public extension Dictionary { /// dict.keys.contains("key2") -> false /// /// - Parameter keys: keys to be removed - public mutating func removeAll(keys: [Key]) { - keys.forEach({ removeValue(forKey: $0)}) + public mutating func removeAll(keys: S) where S.Element == Key { + keys.forEach { removeValue(forKey: $0) } } /// SwifterSwift: JSON Data from dictionary. @@ -79,7 +79,7 @@ public extension Dictionary { } // MARK: - Methods (ExpressibleByStringLiteral) -public extension Dictionary where Key: ExpressibleByStringLiteral { +public extension Dictionary where Key: StringProtocol { /// SwifterSwift: Lowercase all keys in dictionary. /// @@ -136,7 +136,7 @@ public extension Dictionary { rhs.forEach { lhs[$0] = $1} } - /// SwifterSwift: Remove contained in the array from the dictionary + /// SwifterSwift: Remove keys contained in the sequence from the dictionary /// /// let dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] /// let result = dict-["key1", "key2"] @@ -148,13 +148,13 @@ public extension Dictionary { /// - lhs: dictionary /// - rhs: array with the keys to be removed. /// - Returns: a new dictionary with keys removed. - public static func - (lhs: [Key: Value], keys: [Key]) -> [Key: Value] { + public static func - (lhs: [Key: Value], keys: S) -> [Key: Value] where S.Element == Key { var result = lhs result.removeAll(keys: keys) return result } - /// SwifterSwift: Remove contained in the array from the dictionary + /// SwifterSwift: Remove keys contained in the sequence from the dictionary /// /// var dict : [String : String] = ["key1" : "value1", "key2" : "value2", "key3" : "value3"] /// dict-=["key1", "key2"] @@ -165,7 +165,7 @@ public extension Dictionary { /// - Parameters: /// - lhs: dictionary /// - rhs: array with the keys to be removed. - public static func -= (lhs: inout [Key: Value], keys: [Key]) { + public static func -= (lhs: inout [Key: Value], keys: S) where S.Element == Key { lhs.removeAll(keys: keys) } From 4903b2394ae8f673c83e0cd0f6a1765df2f58a9f Mon Sep 17 00:00:00 2001 From: Olivia Date: Thu, 31 May 2018 09:44:09 -0700 Subject: [PATCH 165/201] Add SKNode Descendants (#490) * Project structure * SKNode specification * Added descendants to SKNode * SKNode documentation * Add test for SKNode descendants * Reduce into * Changelog * Podspec * Add PR number to changelog * Use SKNode over SpriteKitNode * Remove trailing whitespace * Import SwifterSwift to SKNodeTests * Import SpriteKit in SpriteKitTests * Add SpriteKit to all targets * Condense descendants function * Use canImport * Uniform file naming --- CHANGELOG.md | 5 ++- .../SpriteKit/SKNodeExtensions.swift | 22 ++++++++++++ SwifterSwift.podspec | 6 ++++ SwifterSwift.xcodeproj/project.pbxproj | 34 +++++++++++++++++++ Tests/SpriteKitTests/SpriteKitTests.swift | 25 ++++++++++++++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 Sources/Extensions/SpriteKit/SKNodeExtensions.swift create mode 100644 Tests/SpriteKitTests/SpriteKitTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index de1e1a0b9..9bde06f27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **SKNode**: +- Added `descendants` method to get an array of all descendants of an SKNode. [#490](https://github.com/SwifterSwift/SwifterSwift/pull/490) by [oliviabrown9](https://github.com/oliviabrown9). + - **Comparable**: - Added `isBetween(min:max:)` and `clamped(min:max:)` to confirm a value is between bounds or limit it between bounds. [#466](https://github.com/SwifterSwift/SwifterSwift/pull/466) by [freak4pc](https://github.com/freak4pc). @@ -14,7 +17,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) - **Character**: - - Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [oliviabrown9](https://github.com/oliviabrown9) + - Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/462) by [oliviabrown9](https://github.com/oliviabrown9) - **UITextView**: - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) diff --git a/Sources/Extensions/SpriteKit/SKNodeExtensions.swift b/Sources/Extensions/SpriteKit/SKNodeExtensions.swift new file mode 100644 index 000000000..fc21fdab5 --- /dev/null +++ b/Sources/Extensions/SpriteKit/SKNodeExtensions.swift @@ -0,0 +1,22 @@ +// +// SKNodeExtensions.swift +// SwifterSwift +// +// Created by Olivia Brown on 5/28/18. +// Copyright © 2018 SwifterSwift +// + +#if canImport(SpriteKit) +import SpriteKit + +// MARK: - Methods +public extension SKNode { + /// SwifterSwift: Return an array of all SKNode descendants + /// + /// mySKNode.descendants() -> [childNodeOne, childNodeTwo] + /// + public func descendants() -> [SKNode] { + return children + children.reduce(into: [SKNode]()) { $0 += $1.descendants() } + } +} +#endif diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index c188f4fe2..843625114 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -59,4 +59,10 @@ Pod::Spec.new do |s| s.subspec 'MapKit' do |sp| sp.source_files = 'Sources/Extensions/MapKit/*.swift' end + + # SpriteKit Extensions + s.subspec 'SpriteKit' do |sp| + sp.source_files = 'Sources/Extensions/SpriteKit/*.swift' + end + end diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 2ec9e976b..c41677d8b 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -332,6 +332,9 @@ 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AD1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; 182698AE1F8AB46F0052F21E /* CGColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */; }; + 1875A8F820BDE50A00A6D258 /* SKNodeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */; }; + 1875A8FA20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */; }; + 1875A8FB20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */; }; 18C8E5DE2074C58100F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; 18C8E5DF2074C60C00F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; 18C8E5E02074C60C00F8AF51 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */; }; @@ -352,6 +355,10 @@ 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; + 752AC7A020BC975E00659E76 /* SKNodeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */; }; + 752AC7A520BC9FF500659E76 /* SpriteKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */; }; + 752AC7A620BCA04100659E76 /* SpriteKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */; }; + 752AC7A720BCA04200659E76 /* SpriteKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */; }; 7832C2AF209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; 7832C2B0209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; 7832C2B1209BB19300224EED /* ComparableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7832C2AE209BB19300224EED /* ComparableExtensions.swift */; }; @@ -552,6 +559,8 @@ 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensionsTest.swift; sourceTree = ""; }; 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensions.swift; sourceTree = ""; }; 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; + 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKNodeExtensions.swift; sourceTree = ""; }; + 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteKitTests.swift; sourceTree = ""; }; 7832C2AE209BB19300224EED /* ComparableExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensions.swift; sourceTree = ""; }; 7832C2B3209BB32500224EED /* ComparableExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensionsTests.swift; sourceTree = ""; }; 784C752E2051BD26001C48DD /* MKPolylineExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MKPolylineExtensions.swift; sourceTree = ""; }; @@ -726,6 +735,7 @@ 07898B941F27904200558C97 /* Extensions */ = { isa = PBXGroup; children = ( + 752AC79E20BC974700659E76 /* SpriteKit */, 784C752D2051BD01001C48DD /* MapKit */, 0726D7751F7C19880028CAB5 /* Shared */, 077BA0871F6BE73000D9C4AC /* SwiftStdlib */, @@ -811,6 +821,7 @@ 07C50CF21F5EAF7B00F46E5A /* Tests */ = { isa = PBXGroup; children = ( + 752AC7A120BC977700659E76 /* SpriteKitTests */, 784C75322051BDCA001C48DD /* MapKitTests */, 077BA0931F6BE93000D9C4AC /* SwiftStdlibTests */, 07C50CF91F5EB03200F46E5A /* FoundationTests */, @@ -937,6 +948,22 @@ path = CoreLocationTests; sourceTree = ""; }; + 752AC79E20BC974700659E76 /* SpriteKit */ = { + isa = PBXGroup; + children = ( + 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */, + ); + path = SpriteKit; + sourceTree = ""; + }; + 752AC7A120BC977700659E76 /* SpriteKitTests */ = { + isa = PBXGroup; + children = ( + 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */, + ); + path = SpriteKitTests; + sourceTree = ""; + }; 784C752D2051BD01001C48DD /* MapKit */ = { isa = PBXGroup; children = ( @@ -1379,6 +1406,7 @@ 784C752F2051BD26001C48DD /* MKPolylineExtensions.swift in Sources */, 07B7F1A71F5EB42000E6F910 /* UIViewExtensions.swift in Sources */, 07B7F1991F5EB42000E6F910 /* UILabelExtensions.swift in Sources */, + 752AC7A020BC975E00659E76 /* SKNodeExtensions.swift in Sources */, 9D9784DB1FCAE3D200D988E7 /* StringProtocolExtensions.swift in Sources */, 07B7F20C1F5EB43C00E6F910 /* BoolExtensions.swift in Sources */, 07B7F22F1F5EB45100E6F910 /* CGFloatExtensions.swift in Sources */, @@ -1441,6 +1469,7 @@ buildActionMask = 2147483647; files = ( 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + 1875A8F820BDE50A00A6D258 /* SKNodeExtensions.swift in Sources */, B23678ED1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */, 07B7F2061F5EB43C00E6F910 /* SignedIntegerExtensions.swift in Sources */, @@ -1507,6 +1536,7 @@ buildActionMask = 2147483647; files = ( 07B7F1F51F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, + 1875A8FB20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */, B23678EE1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, 07B7F1F41F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, @@ -1593,6 +1623,7 @@ 784C75302051BD4A001C48DD /* MKPolylineExtensions.swift in Sources */, 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, + 1875A8FA20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */, 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */, 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */, @@ -1655,6 +1686,7 @@ 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, + 752AC7A520BC9FF500659E76 /* SpriteKitTests.swift in Sources */, 07C50D5A1F5EB05000F46E5A /* CollectionExtensionsTests.swift in Sources */, 076AEC8D1FDB49480077D153 /* UIDatePickerExtensionsTests.swift in Sources */, 07C50D351F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, @@ -1692,6 +1724,7 @@ 07C50D711F5EB05100F46E5A /* StringExtensionsTests.swift in Sources */, 07C50D6A1F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 077BA09F1F6BEA4900D9C4AC /* URLRequestExtensionsTests.swift in Sources */, + 752AC7A620BCA04100659E76 /* SpriteKitTests.swift in Sources */, 07C50D441F5EB04700F46E5A /* UICollectionViewExtensionsTests.swift in Sources */, 07C50D521F5EB04700F46E5A /* UITableViewExtensionsTests.swift in Sources */, 078916DB2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */, @@ -1777,6 +1810,7 @@ 07C50D751F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, 07FE50431F891B40000766AA /* ColorExtensionsTests.swift in Sources */, 07C50D7D1F5EB05100F46E5A /* LocaleExtensionsTests.swift in Sources */, + 752AC7A720BCA04200659E76 /* SpriteKitTests.swift in Sources */, 07C50D781F5EB05100F46E5A /* DateExtensionsTests.swift in Sources */, 07C50D821F5EB05800F46E5A /* CGPointExtensionsTests.swift in Sources */, 7832C2B6209BB32500224EED /* ComparableExtensionsTests.swift in Sources */, diff --git a/Tests/SpriteKitTests/SpriteKitTests.swift b/Tests/SpriteKitTests/SpriteKitTests.swift new file mode 100644 index 000000000..522f98286 --- /dev/null +++ b/Tests/SpriteKitTests/SpriteKitTests.swift @@ -0,0 +1,25 @@ +// +// SpriteKitTests.swift +// SwifterSwift +// +// Created by Olivia Brown on 5/28/18. +// Copyright © 2018 SwifterSwift +// + +import XCTest +import SpriteKit + +@testable import SwifterSwift + +final class SpriteKitTests: XCTestCase { + func testDescendants() { + let scene = SKScene() + let childOne = SKNode() + scene.addChild(childOne) + let childTwo = SKNode() + childOne.addChild(childTwo) + XCTAssertEqual(scene.descendants(), [childOne, childTwo]) + XCTAssertEqual(childOne.descendants(), [childTwo]) + XCTAssertEqual(childTwo.descendants(), []) + } +} From 5c3ba31c9718ed70dc67e33cef9780923c98e62f Mon Sep 17 00:00:00 2001 From: Olivia Date: Thu, 31 May 2018 17:51:33 -0700 Subject: [PATCH 166/201] Add SpriteKit to README (#493) * Add SpriteKit to README * Add PR number * Revert CHANGELOG --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index cb590b6e8..85db16305 100755 --- a/README.md +++ b/README.md @@ -60,6 +60,9 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy

    - Integrate CoreLocation extensions only:

    pod 'SwifterSwift/CoreLocation'
    + +

    - Integrate SpriteKit extensions only:

    +
    pod 'SwifterSwift/SpriteKit'
    @@ -214,6 +217,14 @@ let package = Package( +
    +SpriteKit Extensions +
    + +
    +
    Misc. Extensions From faf7e4e954be7ca098913e02a3ae923dc985ad9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=A4rtwig?= Date: Tue, 5 Jun 2018 16:34:18 +0200 Subject: [PATCH 167/201] Add containsDuplicates to check whether a collection contains duplicates (#496) --- CHANGELOG.md | 6 +++++- .../SwiftStdlib/SequenceExtensions.swift | 16 ++++++++++++++++ .../SequenceExtensionsTests.swift | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bde06f27..8b2502546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,14 +24,18 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - - Added `queryValue(for:)` to get the value of a query key from a URL. [#467](https://github.com/SwifterSwift/SwifterSwift/pull/467) by [jdisho](https://github.com/jdisho). + - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). + - **Optional**: - Added `isNilOrEmpty` property to check whether an optional is nil or empty collection. +- **Sequence** + - added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). + ### Changed - **UITableView**: - `dequeueReusableCell(withClass:for)`, `dequeueReusableCell(withClass)` now return `UITableViewCell` object, `fatalError(...)` if not found. [#439](https://github.com/SwifterSwift/SwifterSwift/pull/439) by [jdisho](https://github.com/jdisho) diff --git a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift index 69c5405a9..342432172 100644 --- a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift @@ -159,6 +159,22 @@ public extension Sequence where Element: Equatable { } +public extension Sequence where Element: Hashable { + + /// SwifterSwift: Check whether a sequence contains duplicates. + /// + /// - Returns: true if the receiver contains duplicates. + public func containsDuplicates() -> Bool { + var set = Set() + for element in self { + if !set.insert(element).inserted { + return true + } + } + return false + } +} + // MARK: - Methods (Numeric) public extension Sequence where Element: Numeric { diff --git a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift index c950a9673..68dfa49a1 100644 --- a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift @@ -81,6 +81,12 @@ final class SequenceExtensionsTests: XCTestCase { XCTAssertFalse([1, 2, 3].contains([4, 5])) } + func testContainsDuplicates() { + XCTAssertFalse([String]().containsDuplicates()) + XCTAssert(["a", "b", "b", "c"].containsDuplicates()) + XCTAssertFalse(["a", "b", "c", "d"].containsDuplicates()) + } + func testSum() { XCTAssertEqual([1, 2, 3, 4, 5].sum(), 15) XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].sum(), 17) From 20ca06c0f81860f84827e199f6adc1552f04645c Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Tue, 5 Jun 2018 07:35:14 -0700 Subject: [PATCH 168/201] Add UIWindow extensions closes #477 (#494) * #closes #477 * Fix tests --- CHANGELOG.md | 8 +--- README.md | 1 + .../Extensions/UIKit/UIWindowExtensions.swift | 48 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 8 ++++ .../UIKitTests/UIWindowExtensionsTests.swift | 41 ++++++++++++++++ 5 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 Sources/Extensions/UIKit/UIWindowExtensions.swift create mode 100644 Tests/UIKitTests/UIWindowExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b2502546..1dc78782f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,22 +6,16 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S ### Added - **SKNode**: - Added `descendants` method to get an array of all descendants of an SKNode. [#490](https://github.com/SwifterSwift/SwifterSwift/pull/490) by [oliviabrown9](https://github.com/oliviabrown9). - - **Comparable**: - Added `isBetween(min:max:)` and `clamped(min:max:)` to confirm a value is between bounds or limit it between bounds. [#466](https://github.com/SwifterSwift/SwifterSwift/pull/466) by [freak4pc](https://github.com/freak4pc). - - **UIScrollView**: - Added `snapshot` method to get a full snapshot of a rendered scroll view. [#457](https://github.com/SwifterSwift/SwifterSwift/pull/457) by [aliamcami](https://github.com/aliamcami). - - **UIGestureRecognizer**: - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) - - **Character**: - Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/462) by [oliviabrown9](https://github.com/oliviabrown9) - - **UITextView**: - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) - - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `queryValue(for:)` to get the value of a query key from a URL. [#467](https://github.com/SwifterSwift/SwifterSwift/pull/467) by [jdisho](https://github.com/jdisho). @@ -32,6 +26,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **Optional**: - Added `isNilOrEmpty` property to check whether an optional is nil or empty collection. +- **UIWindow**: + - Added `switchRootViewController` method to switch root view controller with animation. [#494](https://github.com/SwifterSwift/SwifterSwift/pull/494) by [omaralbeik](https://github.com/omaralbeik). - **Sequence** - added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). diff --git a/README.md b/README.md index 85db16305..7fcb8184d 100755 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ let package = Package(
  • UITextView extensions
  • UIViewController extensions
  • UIView extensions
  • +
  • UIWindow extensions
  • diff --git a/Sources/Extensions/UIKit/UIWindowExtensions.swift b/Sources/Extensions/UIKit/UIWindowExtensions.swift new file mode 100644 index 000000000..a158b992c --- /dev/null +++ b/Sources/Extensions/UIKit/UIWindowExtensions.swift @@ -0,0 +1,48 @@ +// +// UIWindowExtensions.swift +// SwifterSwift +// +// Created by Omar Albeik on 6/2/18. +// Copyright © 2018 SwifterSwift +// + +#if canImport(UIKit) +import UIKit + +#if os(iOS) +public extension UIWindow { + + /// SwifterSwift: Switch current root view controller with a new view controller. + /// + /// - Parameters: + /// - viewController: new view controller. + /// - animated: set to true to animate view controller change (default is true). + /// - duration: animation duration in seconds (default is 0.5). + /// - options: animataion options (default is .transitionFlipFromRight). + /// - completion: optional completion handler called after view controller is changed. + public func switchRootViewController( + to viewController: UIViewController, + animated: Bool = true, + duration: TimeInterval = 0.5, + options: UIViewAnimationOptions = .transitionFlipFromRight, + _ completion: (() -> Void)? = nil) { + + guard animated else { + rootViewController = viewController + completion?() + return + } + + UIView.transition(with: self, duration: duration, options: options, animations: { + let oldState = UIView.areAnimationsEnabled + UIView.setAnimationsEnabled(false) + self.rootViewController = viewController + UIView.setAnimationsEnabled(oldState) + }, completion: { _ in + completion?() + }) + } + +} +#endif +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index c41677d8b..8f88b51c9 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 071306701FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; 071306711FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; 071306721FB597920023A9D8 /* FoundationDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */; }; + 0722CB3820C2E46C00C6C1B6 /* UIWindowExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0722CB3720C2E46B00C6C1B6 /* UIWindowExtensions.swift */; }; + 0722CB3A20C2E49A00C6C1B6 /* UIWindowExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0722CB3920C2E49900C6C1B6 /* UIWindowExtensionsTests.swift */; }; 0726D7771F7C199E0028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; 0726D77B1F7C24840028CAB5 /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */; }; @@ -433,6 +435,8 @@ /* Begin PBXFileReference section */ 0713066E1FB597920023A9D8 /* FoundationDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationDeprecated.swift; sourceTree = ""; }; + 0722CB3720C2E46B00C6C1B6 /* UIWindowExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWindowExtensions.swift; sourceTree = ""; }; + 0722CB3920C2E49900C6C1B6 /* UIWindowExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIWindowExtensionsTests.swift; sourceTree = ""; }; 0726D7761F7C199E0028CAB5 /* ColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtensions.swift; sourceTree = ""; }; 074EAF1A1F7BA68B00C74636 /* UIFontExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensions.swift; sourceTree = ""; }; 074EAF1E1F7BA74600C74636 /* UIFontExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontExtensionsTest.swift; sourceTree = ""; }; @@ -814,6 +818,7 @@ 076AEC881FDB48580077D153 /* UIDatePickerExtensions.swift */, 42F53FEB2039C5AC0070DC11 /* UIStackViewExtensions.swift */, 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */, + 0722CB3720C2E46B00C6C1B6 /* UIWindowExtensions.swift */, ); path = UIKit; sourceTree = ""; @@ -897,6 +902,7 @@ 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */, 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */, 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */, + 0722CB3920C2E49900C6C1B6 /* UIWindowExtensionsTests.swift */, ); path = UIKitTests; sourceTree = ""; @@ -1424,6 +1430,7 @@ 077BA08F1F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1A11F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, 078CE29F207643F8001720DF /* UIKitDeprecated.swift in Sources */, + 0722CB3820C2E46C00C6C1B6 /* UIWindowExtensions.swift in Sources */, 07B7F1A41F5EB42000E6F910 /* UITextFieldExtensions.swift in Sources */, 07B7F20B1F5EB43C00E6F910 /* ArrayExtensions.swift in Sources */, 07B7F1A01F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */, @@ -1676,6 +1683,7 @@ 07FE50451F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, 07C50D391F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, 784C75372051BE1D001C48DD /* MKPolylineTests.swift in Sources */, + 0722CB3A20C2E49A00C6C1B6 /* UIWindowExtensionsTests.swift in Sources */, 9D9784E41FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift in Sources */, 07C50D361F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, 07C50D8C1F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIWindowExtensionsTests.swift b/Tests/UIKitTests/UIWindowExtensionsTests.swift new file mode 100644 index 000000000..9c939083c --- /dev/null +++ b/Tests/UIKitTests/UIWindowExtensionsTests.swift @@ -0,0 +1,41 @@ +// +// UIWindowExtensionsTests.swift +// SwifterSwift +// +// Created by Omar Albeik on 6/2/18. +// Copyright © 2018 SwifterSwift +// + +#if os(iOS) +import XCTest +@testable import SwifterSwift + +final class UIWindowExtensionsTests: XCTestCase { + + func testSwitchRootViewController() { + let viewController = UIViewController() + let tableViewController = UITableViewController() + + let window = UIWindow() + window.rootViewController = viewController + + XCTAssertNotNil(window.rootViewController) + XCTAssertEqual(window.rootViewController!, viewController) + + window.switchRootViewController(to: tableViewController, animated: false) + XCTAssertNotNil(window.rootViewController) + XCTAssertEqual(window.rootViewController!, tableViewController) + + let completionExpectation = expectation(description: "Completed") + + window.switchRootViewController(to: viewController, animated: true, duration: 0.75) { + completionExpectation.fulfill() + XCTAssertNotNil(window.rootViewController) + XCTAssertEqual(window.rootViewController!, viewController) + } + + waitForExpectations(timeout: 1, handler: nil) + } + +} +#endif From 7511a0220c07ef2e2a6c99efae6bbcf538170562 Mon Sep 17 00:00:00 2001 From: andlang <8532438+andlang@users.noreply.github.com> Date: Tue, 5 Jun 2018 20:30:59 +0200 Subject: [PATCH 169/201] Add `single(where)` SequenceExtension (#483) * Add `single(where)` SequenceExtension --- CHANGELOG.md | 1 + .../SwiftStdlib/SequenceExtensions.swift | 20 +++++++++++++++++++ .../SequenceExtensionsTests.swift | 13 ++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dc78782f..453b4d098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **Sequence** - added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). + - Added `single(where:)` to get the only element of a sequence that matches a given condition. [#483](https://github.com/SwifterSwift/SwifterSwift/pull/483) by [andlang](https://github.com/andlang). ### Changed - **UITableView**: diff --git a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift index 342432172..246d8a3b7 100644 --- a/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SequenceExtensions.swift @@ -135,6 +135,26 @@ public extension Sequence { }) } + /// SwifterSwift: Get the only element based on a condition. + /// + /// [].single(where: {_ in true}) -> nil + /// [4].single(where: {_ in true}) -> 4 + /// [1, 4, 7].single(where: {$0 % 2 == 0}) -> 4 + /// [2, 2, 4, 7].single(where: {$0 % 2 == 0}) -> nil + /// + /// - Parameter condition: condition to evaluate each element against. + /// - Returns: The only element in the array matching the specified condition. If there are more matching elements, nil is returned. (optional) + public func single(where condition: ((Element) throws -> Bool)) rethrows -> Element? { + var singleElement: Element? + for element in self where try condition(element) { + guard singleElement == nil else { + singleElement = nil + break + } + singleElement = element + } + return singleElement + } } public extension Sequence where Element: Equatable { diff --git a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift index 68dfa49a1..1c897c69b 100644 --- a/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/SequenceExtensionsTests.swift @@ -9,6 +9,10 @@ import XCTest @testable import SwifterSwift +private enum SequenceTestError: Error { + case closureThrows +} + final class SequenceExtensionsTests: XCTestCase { func testAllMatch() { @@ -72,6 +76,15 @@ final class SequenceExtensionsTests: XCTestCase { XCTAssertEqual(["2", "4"], result) } + func testSingle() { + XCTAssertNil([].single(where: { _ in true })) + XCTAssertEqual([4].single(where: { _ in true }), 4) + XCTAssertNil([2, 4].single(where: { _ in true })) + XCTAssertEqual([1, 4, 7].single(where: { $0 % 2 == 0 }), 4) + XCTAssertNil([2, 2, 4, 7].single(where: { $0 % 2 == 0 })) + XCTAssertThrowsError(try [2].single(where: { _ in throw SequenceTestError.closureThrows })) + } + func testContains() { XCTAssert([Int]().contains([])) XCTAssertFalse([Int]().contains([1, 2])) From 41b53663a9777a4090cec5993156a4d1c27a0e3a Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 7 Jun 2018 22:06:11 -0300 Subject: [PATCH 170/201] Adding Danger xcode-sumary (#498) * testing danger xcode-sumary * xcpretty with json * multiple targets on the report * smart quotes * put xcpretty-json-formatter on bundler * minor adjustments * Quotes * Danger verbose * Quotes? * Installing xcpretty without bundle * removing report to see if its error * Running danger after the build * Adding warning to see if theres going to have the expected output. * Remove random variable * Minor adjustments --- .travis.yml | 15 ++++++--------- Dangerfile | 13 +++++++++---- Gemfile | 3 +++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 64ef308a9..ba8db8059 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: - TVOS_SCHEME='SwifterSwift-tvOS' - WATCHOS_SCHEME='SwifterSwift-watchOS' - MACOS_SCHEME='SwifterSwift-macOS' - - IOS_DESTINATION='platform=iOS Simulator,name=iPhone 6S' + - IOS_DESTINATION='platform=iOS Simulator,name=iPhone X' - TVOS_DESTINATION='platform=tvOS Simulator,name=Apple TV 4K (at 1080p)' - WATCHOS_DESTINATION='name=Apple Watch - 42mm' - MACOS_DESTINATION='platform=OS X' @@ -18,19 +18,16 @@ before_install: - bundle install - brew update - brew outdated xctool || brew upgrade xctool - -before_script: - - bundle exec danger - script: - set -o pipefail - swift --version - - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | xcpretty + - xcodebuild clean build test -project "$PROJECT" -scheme "$IOS_SCHEME" -destination "$IOS_DESTINATION" | XCPRETTY_JSON_FILE_OUTPUT="xcodebuild-ios.json" xcpretty -f `xcpretty-json-formatter` - bash <(curl -s https://codecov.io/bash) -cF ios -J 'SwifterSwift' - - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | xcpretty + - xcodebuild clean build test -project "$PROJECT" -scheme "$TVOS_SCHEME" -destination "$TVOS_DESTINATION" | XCPRETTY_JSON_FILE_OUTPUT="xcodebuild-tvos.json" xcpretty -f `xcpretty-json-formatter` - bash <(curl -s https://codecov.io/bash) -cF tvos -J 'SwifterSwift' - - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | xcpretty + - xcodebuild clean build test -project "$PROJECT" -scheme "$MACOS_SCHEME" -destination "$MACOS_DESTINATION" | XCPRETTY_JSON_FILE_OUTPUT="xcodebuild-macos.json" xcpretty -f `xcpretty-json-formatter` - bash <(curl -s https://codecov.io/bash) -cF osx -J 'SwifterSwift' - - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | xcpretty + - xcodebuild clean build -project "$PROJECT" -scheme "$WATCHOS_SCHEME" -destination "$WATCHOS_DESTINATION" | XCPRETTY_JSON_FILE_OUTPUT="xcodebuild-watchos.json" xcpretty -f `xcpretty-json-formatter` - swiftlint lint + - bundle exec danger --verbose - pod lib lint diff --git a/Dangerfile b/Dangerfile index c93e654a7..ed7c46bb9 100644 --- a/Dangerfile +++ b/Dangerfile @@ -1,4 +1,4 @@ -message(“Thank you for submitting a pull request to SwifterSwift. The team will review your submission as soon as possible.“) +message('Thank you for submitting a pull request to SwifterSwift. The team will review your submission as soon as possible.') # Checks for modified source files source_changes_exist = !git.modified_files.grep(/Sources/).empty? @@ -10,15 +10,20 @@ no_changelog_entry = !git.modified_files.include?("CHANGELOG.md") no_test_changes = git.modified_files.grep(/Tests/).empty? if source_changes_exist && no_test_changes - warn(“Consider adding tests for new extensions or updating existing tests for a modified SwifterSwift extension”) + warn('Consider adding tests for new extensions or updating existing tests for a modified SwifterSwift extension') end if source_changes_exist && no_changelog_entry - warn(“The source files have been modified. Please consider adding a CHANGELOG entry if necessary.“) + warn('The source files have been modified. Please consider adding a CHANGELOG entry if necessary.') end swiftlint.lint_files # Checks if pull request is labeled as [WIP] -warn(“This pull request is marked as Work in Progress. DO NOT MERGE!“) if github.pr_title.include? “[WIP]” +warn('This pull request is marked as Work in Progress. DO NOT MERGE!') if github.pr_title.include? "[WIP]" +# Xcode summary +xcode_summary.report 'xcodebuild-ios.json' +xcode_summary.report 'xcodebuild-tvos.json' +xcode_summary.report 'xcodebuild-macos.json' +xcode_summary.report 'xcodebuild-watchos.json' diff --git a/Gemfile b/Gemfile index a414cca43..5ac028e3b 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,6 @@ source 'https://rubygems.org' gem 'xcpretty' gem 'danger' gem 'danger-swiftlint' +gem 'danger-xcode_summary' +gem 'xcpretty-json-formatter' + From 20c2f22cc932b2934eb8e6fb3502acd10690577a Mon Sep 17 00:00:00 2001 From: Joan Disho Date: Thu, 14 Jun 2018 19:07:40 +0200 Subject: [PATCH 171/201] create removeElement(_) in Array extension. (#479) * create removeElement(_) in Array extension. * Change `removeElement` to `removeWhere` to make it more flexible. --- .../Extensions/SwiftStdlib/ArrayExtensions.swift | 13 +++++++++++++ Tests/SwiftStdlibTests/ArrayExtensionsTests.swift | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index fbf44ef91..c06e44431 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -210,6 +210,19 @@ public extension Array { return self } + /// SwifterSwift: Removes the first element of the collection which satisfies the given predicate. + /// + /// [1, 2, 2, 3, 4, 2, 5].removeFirst { $0 % 2 == 0 } -> [1, 2, 3, 4, 2, 5] + /// ["h", "e", "l", "l", "o"].removeFirst { $0 == "e" } -> ["h", "l", "l", "o"] + /// + /// - Parameter predicate: A closure that takes an element as its argument and returns a Boolean value that indicates whether the passed element represents a match. + /// - Returns: The first element for which predicate returns true, after removing it. If no elements in the collection satisfy the given predicate, returns `nil`. + @discardableResult + public mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? { + guard let index = try index(where: predicate) else { return nil } + return remove(at: index) + } + } // MARK: - Methods (Equatable) diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index ed7e417f0..e446203f6 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -186,6 +186,20 @@ final class ArrayExtensionsTests: XCTestCase { XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) } + func testRemoveWhere() { + var array = [0, 1, 2, 0, 3, 4, 5, 0, 0] + array.removeFirst { $0 == 1 } + XCTAssertEqual(array, [0, 2, 0, 3, 4, 5, 0, 0]) + array = [] + XCTAssertNil(array.removeFirst { $0 == 10 }) + array = [2, 2, 1, 2, 3] + let removedElement = array.removeFirst { $0 == 2 } + XCTAssertEqual(array, [2, 1, 2, 3]) + XCTAssertEqual(removedElement, 2) + + XCTAssertThrowsError(try array.removeFirst(where: { _ in throw NSError() })) + } + func testRemoveAll() { var arr = [0, 1, 2, 0, 3, 4, 5, 0, 0] arr.removeAll(0) From 592f838710110d61d024edfbda091eb9eaac39e2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 15 Jun 2018 18:19:31 -0300 Subject: [PATCH 172/201] Edge insets extensions (#500) * Implementing some edge insets extensions. * Implementing tests for edge extensions. * Changelog and copyright. * Fixing docs. * Moving credits to inside the body. --- CHANGELOG.md | 9 ++-- .../UIKit/UIEdgeInsetsExtensions.swift | 49 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 12 +++++ .../UIEdgeInsetsExtensionsTests.swift | 43 ++++++++++++++++ .../UIGestureRecognizerExtensionsTests.swift | 2 +- 5 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift create mode 100644 Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 453b4d098..a1f978945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,19 +19,18 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **URL** - Added `deletingAllPathComponents()` and `deleteAllPathComponents()` to delete all path components from a URL. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `queryValue(for:)` to get the value of a query key from a URL. [#467](https://github.com/SwifterSwift/SwifterSwift/pull/467) by [jdisho](https://github.com/jdisho). - - **UITableView**: - Added `isValidIndexPath(_:)` method to check whether given IndexPath is valid within UITableView. [#441](https://github.com/SwifterSwift/SwifterSwift/pull/441) by [setoelkahfi](https://github.com/setoelkahfi). - Added `safeScrollToRow(at:at:animated:)` method to safely scroll UITableView to the given IndexPath. [#445](https://github.com/SwifterSwift/SwifterSwift/pull/445) by [setoelkahfi](https://github.com/setoelkahfi). - - **Optional**: - Added `isNilOrEmpty` property to check whether an optional is nil or empty collection. - **UIWindow**: - Added `switchRootViewController` method to switch root view controller with animation. [#494](https://github.com/SwifterSwift/SwifterSwift/pull/494) by [omaralbeik](https://github.com/omaralbeik). - - **Sequence** - added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). - - Added `single(where:)` to get the only element of a sequence that matches a given condition. [#483](https://github.com/SwifterSwift/SwifterSwift/pull/483) by [andlang](https://github.com/andlang). + - Added `single(where:)` to get the only element of a sequence that matches a given condition. [#483](https://github.com/SwifterSwift/SwifterSwift/pull/483) by [andlang](https://github.com/andlang) +- **UIEdgeInsets** + - Added `horizontal` and `vertical` properties. Also `init(inset:)` and `init(horizontal: vertical:)` initializers for convenience. [#500](https://github.com/SwifterSwift/SwifterSwift/pull/500) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). ### Changed - **UITableView**: @@ -113,7 +112,6 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **String** - Fixed UIView extension `addShadow` was not showing the shadow on view bug. [#420](https://github.com/SwifterSwift/SwifterSwift/pull/420) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - --- # [v4.2.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.2.0) @@ -1147,7 +1145,6 @@ DateExtensions: - **changing(component, value)**: Return date by changing a component - Fixed a bug in nearestFiveMinutes, nearestTenMinutes where date was always rounded always to next 5, 10 mins - --- ## v1.0.4 diff --git a/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift b/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift new file mode 100644 index 000000000..bac2164dc --- /dev/null +++ b/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift @@ -0,0 +1,49 @@ +// +// UIEdgeInsetsExtensions.swift +// SwifterSwift +// +// Created by Luciano Almeida on 15/06/18. +// Copyright © 2018 SwifterSwift +// +#if canImport(UIKit) +import UIKit + +// MARK: - Properties +extension UIEdgeInsets { + /// SwifterSwift: Return the vertical insets. The vertical insets is composed by top + bottom. + /// + public var vertical: CGFloat { + // Source: https://github.com/MessageKit/MessageKit/blob/master/Sources/Extensions/UIEdgeInsets%2BExtensions.swift + return top + bottom + } + + /// SwifterSwift: Return the horizontal insets. The horizontal insets is composed by left + right. + /// + public var horizontal: CGFloat { + // Source: https://github.com/MessageKit/MessageKit/blob/master/Sources/Extensions/UIEdgeInsets%2BExtensions.swift + return left + right + } + +} + +// MARK: - Methods +extension UIEdgeInsets { + /// SwifterSwift: Creates an `UIEdgeInsets` with the inset value applied to all (top, bottom, right, left) + /// + /// - Parameter inset: Inset to be applied in all the edges. + public init(inset: CGFloat) { + self.init(top: inset, left: inset, bottom: inset, right: inset) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` with the horizontal value equally divided and applied to right and left. + /// And the vertical value equally divided and applied to top and bottom. + /// + /// + /// - Parameter horizontal: Inset to be applied to right and left. + /// - Parameter vertical: Inset to be applied to top and bottom. + public init(horizontal: CGFloat, vertical: CGFloat) { + self.init(top: vertical/2, left: horizontal/2, bottom: vertical/2, right: horizontal/2) + } +} + +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 8f88b51c9..aadb7c3a0 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -407,6 +407,10 @@ B23678ED1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */; }; B23678EE1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */; }; B23678EF1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */; }; + B247BDE620D376EC00842ACC /* UIEdgeInsetsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */; }; + B247BDE720D376EC00842ACC /* UIEdgeInsetsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */; }; + B247BDE920D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */; }; + B247BDEA20D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -582,6 +586,8 @@ A9CD166720242AF900DBE263 /* UICollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UICollectionViewCell.xib; sourceTree = ""; }; A9FF467020245ABA0084C40F /* test.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = test.json; sourceTree = ""; }; B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftStdlibDeprecated.swift; sourceTree = ""; }; + B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensions.swift; sourceTree = ""; }; + B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -819,6 +825,7 @@ 42F53FEB2039C5AC0070DC11 /* UIStackViewExtensions.swift */, 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */, 0722CB3720C2E46B00C6C1B6 /* UIWindowExtensions.swift */, + B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */, ); path = UIKit; sourceTree = ""; @@ -903,6 +910,7 @@ 86B3F7AD208D3DF300BC297B /* UIScrollViewExtensionsTest.swift */, 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */, 0722CB3920C2E49900C6C1B6 /* UIWindowExtensionsTests.swift */, + B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */, ); path = UIKitTests; sourceTree = ""; @@ -1465,6 +1473,7 @@ 86B3F7AC208D3D5C00BC297B /* UIScrollViewExtensions.swift in Sources */, 07B7F2141F5EB43C00E6F910 /* FloatingPointExtensions.swift in Sources */, 07B7F19E1F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */, + B247BDE620D376EC00842ACC /* UIEdgeInsetsExtensions.swift in Sources */, 07B7F20F1F5EB43C00E6F910 /* DataExtensions.swift in Sources */, 07B7F19C1F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */, 07B7F1A51F5EB42000E6F910 /* UITextViewExtensions.swift in Sources */, @@ -1476,6 +1485,7 @@ buildActionMask = 2147483647; files = ( 07B7F2071F5EB43C00E6F910 /* SignedNumericExtensions.swift in Sources */, + B247BDE720D376EC00842ACC /* UIEdgeInsetsExtensions.swift in Sources */, 1875A8F820BDE50A00A6D258 /* SKNodeExtensions.swift in Sources */, B23678ED1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */, 0726D77A1F7C24830028CAB5 /* ColorExtensions.swift in Sources */, @@ -1711,6 +1721,7 @@ 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */, + B247BDE920D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */, 18C8E5E32074C67000F8AF51 /* SequenceExtensionsTests.swift in Sources */, 07C50D5D1F5EB05000F46E5A /* DictionaryExtensionsTests.swift in Sources */, 07C50D5B1F5EB05000F46E5A /* DataExtensionsTests.swift in Sources */, @@ -1743,6 +1754,7 @@ 07C50D561F5EB04700F46E5A /* UIViewExtensionsTests.swift in Sources */, 07C50D471F5EB04700F46E5A /* UIImageViewExtensionsTests.swift in Sources */, 07C50D421F5EB04700F46E5A /* UIBarButtonExtensionsTests.swift in Sources */, + B247BDEA20D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */, 077BA0BA1F6BEA6A00D9C4AC /* UserDefaultsExtensionsTests.swift in Sources */, 07C50D671F5EB05100F46E5A /* CharacterExtensionsTests.swift in Sources */, 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift new file mode 100644 index 000000000..11a8a34cc --- /dev/null +++ b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift @@ -0,0 +1,43 @@ +// +// UIEdgeInsetsExtensionsTests.swift +// SwifterSwift +// +// Created by Luciano Almeida on 15/06/18. +// Copyright © 2018 SwifterSwift +// + +#if !os(macOS) + +import XCTest +@testable import SwifterSwift + +final class UIEdgeInsetsExtensionsTests: XCTestCase { + + func testHorizontal() { + let inset = UIEdgeInsets(top: 30.0, left: 5.0, bottom: 5.0, right: 10.0) + XCTAssertEqual(inset.horizontal, 15.0) + } + + func testVertical() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 5.0, right: 10.0) + XCTAssertEqual(inset.horizontal, 20.0) + } + + func testInitInset() { + let inset = UIEdgeInsets(inset: 5.0) + XCTAssertEqual(inset.top, 5.0) + XCTAssertEqual(inset.bottom, 5.0) + XCTAssertEqual(inset.right, 5.0) + XCTAssertEqual(inset.left, 5.0) + } + + func testInitVerticalHorizontal() { + let inset = UIEdgeInsets(horizontal: 20.0, vertical: 10.0) + XCTAssertEqual(inset.top, 5.0) + XCTAssertEqual(inset.bottom, 5.0) + XCTAssertEqual(inset.right, 10.0) + XCTAssertEqual(inset.left, 10.0) + } +} + +#endif diff --git a/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift b/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift index a7a5d7d7e..ee1cf0d84 100644 --- a/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift +++ b/Tests/UIKitTests/UIGestureRecognizerExtensionsTests.swift @@ -10,7 +10,7 @@ import XCTest @testable import SwifterSwift -class UIGestureRecognizerExtensionsTests: XCTestCase { +final class UIGestureRecognizerExtensionsTests: XCTestCase { func testRemoveFromView() { let view = UIImageView() From b1e9cb4c3904909dde0a5c2eca1cec2b1a9dd04e Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sat, 16 Jun 2018 22:46:30 +0300 Subject: [PATCH 173/201] Complete jazzy docs to 100% (#502) --- .../Foundation/DateExtensions.swift | 10 +++++ .../Extensions/Shared/ColorExtensions.swift | 2 + .../SwiftStdlib/ArrayExtensions.swift | 37 +++++++++++-------- .../Deprecated/SwiftStdlibDeprecated.swift | 22 +++++------ .../SwiftStdlib/SignedIntegerExtensions.swift | 12 +++--- .../SwiftStdlib/SignedNumericExtensions.swift | 2 +- .../UIKit/UITextFieldExtensions.swift | 5 +++ .../Extensions/UIKit/UIViewExtensions.swift | 17 ++++++++- 8 files changed, 70 insertions(+), 37 deletions(-) diff --git a/Sources/Extensions/Foundation/DateExtensions.swift b/Sources/Extensions/Foundation/DateExtensions.swift index 1a797d579..dc4de90be 100755 --- a/Sources/Extensions/Foundation/DateExtensions.swift +++ b/Sources/Extensions/Foundation/DateExtensions.swift @@ -18,8 +18,13 @@ public extension Date { /// - oneLetter: 1 letter day abbreviation of day name. /// - full: Full day name. public enum DayNameStyle { + /// 3 letter day abbreviation of day name. case threeLetters + + /// 1 letter day abbreviation of day name. case oneLetter + + /// Full day name. case full } @@ -29,8 +34,13 @@ public extension Date { /// - oneLetter: 1 letter month abbreviation of month name. /// - full: Full month name. public enum MonthNameStyle { + /// 3 letter month abbreviation of month name. case threeLetters + + /// 1 letter month abbreviation of month name. case oneLetter + + /// Full month name. case full } diff --git a/Sources/Extensions/Shared/ColorExtensions.swift b/Sources/Extensions/Shared/ColorExtensions.swift index 99b805a9d..73357d662 100644 --- a/Sources/Extensions/Shared/ColorExtensions.swift +++ b/Sources/Extensions/Shared/ColorExtensions.swift @@ -8,11 +8,13 @@ #if canImport(UIKit) import UIKit +/// Color public typealias Color = UIColor #endif #if canImport(Cocoa) import Cocoa +/// Color public typealias Color = NSColor #endif diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index c06e44431..7d2fe78c4 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -34,13 +34,15 @@ public extension Array { swapAt(index, otherIndex) } - @discardableResult /// SwifterSwift: Keep elements of Array while condition is true. /// /// [0, 2, 4, 7].keep( where: {$0 % 2 == 0}) -> [0, 2, 4] /// /// - Parameter condition: condition to evaluate each element against. - public mutating func keep(while condition: (Element) throws -> Bool) rethrows -> [Element] { + /// - Returns: self after applying provided condition. + /// - Throws: provided condition exception. + @discardableResult + public mutating func keep(while condition: (Element) throws -> Bool) rethrows -> [Element] { for (index, element) in lazy.enumerated() where try !condition(element) { self = Array(self[startIndex.. [4,1,2,3] /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] /// - /// - Parameter places: The number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start become the end. - /// - /// - Returns: self after rotating + /// - Parameter places: The number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start become the end. + /// - Returns: self after rotating. + @discardableResult public mutating func rotate(by places: Int) -> [Element] { self = rotated(by: places) return self } - @discardableResult /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) /// /// [1, 2, 3, 4, 5].shuffle() // shuffles array /// - /// - Returns: self after shuffling + /// - Returns: self after shuffling. + @discardableResult public mutating func shuffle() -> [Element] { // http://stackoverflow.com/questions/37843647/shuffle-array-swift-3 guard count > 1 else { return self } @@ -190,21 +191,25 @@ public extension Array { }) } - @discardableResult /// SwifterSwift: Sort the array based on an optional keypath. /// - /// - Parameter path: Key path to sort. The key path type must be Comparable. - /// - Parameter ascending: If order must be ascending. + /// - Parameters: + /// - path: Key path to sort, must be Comparable. + /// - ascending: whether order is ascending or not. + /// - Returns: self after sorting. + @discardableResult public mutating func sort(by path: KeyPath, ascending: Bool = true) -> [Element] { self = sorted(by: path, ascending: ascending) return self } - @discardableResult /// SwifterSwift: Sort the array based on a keypath. /// - /// - Parameter path: Key path to sort. The key path type must be Comparable. - /// - Parameter ascending: If order must be ascending. + /// - Parameters: + /// - path: Key path to sort, must be Comparable. + /// - ascending: whether order is ascending or not. + /// - Returns: self after sorting. + @discardableResult public mutating func sort(by path: KeyPath, ascending: Bool = true) -> [Element] { self = sorted(by: path, ascending: ascending) return self @@ -244,7 +249,6 @@ public extension Array where Element: Equatable { return indices } - @discardableResult /// SwifterSwift: Remove all instances of an item from array. /// /// [1, 2, 2, 3, 4, 5].removeAll(2) -> [1, 3, 4, 5] @@ -252,12 +256,12 @@ public extension Array where Element: Equatable { /// /// - Parameter item: item to remove. /// - Returns: self after removing all instances of item. + @discardableResult public mutating func removeAll(_ item: Element) -> [Element] { self = filter { $0 != item } return self } - @discardableResult /// SwifterSwift: Remove all instances contained in items parameter from array. /// /// [1, 2, 2, 3, 4, 5].removeAll([2,5]) -> [1, 3, 4] @@ -265,6 +269,7 @@ public extension Array where Element: Equatable { /// /// - Parameter items: items to remove. /// - Returns: self after removing all instances of all items in given array. + @discardableResult public mutating func removeAll(_ items: [Element]) -> [Element] { guard !items.isEmpty else { return self } self = filter { !items.contains($0) } diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index 95757d3e8..c13199f6f 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -7,13 +7,13 @@ public extension Bool { - /// SwifterSwift: Return inversed value of bool. - /// - /// false.toggled -> true - /// true.toggled -> false - /// - @available(*, deprecated: 4.3, message: "Use !self instead.") - public var toggled: Bool { + /// SwifterSwift: Return inversed value of bool. + /// + /// false.toggled -> true + /// true.toggled -> false + /// + @available(*, deprecated: 4.3, message: "Use !self instead.") + public var toggled: Bool { return !self } @@ -21,7 +21,6 @@ public extension Bool { public extension Bool { - @discardableResult /// SwifterSwift: Toggle value for bool. /// /// var bool = false @@ -29,7 +28,8 @@ public extension Bool { /// print(bool) -> true /// /// - Returns: inversed value of bool. - @available(*, deprecated: 4.3, message: "Use !self instead.") + @available(*, deprecated: 4.3, message: "Use !self instead.") + @discardableResult public mutating func toggle() -> Bool { self = !self return self @@ -91,8 +91,6 @@ extension String { return map({ String($0) }).index(of: string) } - // - /// SwifterSwift: Array of strings separated by given string. /// /// "hello World".splited(by: " ") -> ["hello", "World"] @@ -128,7 +126,7 @@ public extension Array { /// /// - Parameter getKey: Clousure to define the key for each element. /// - Returns: A dictionary with values grouped with keys. - @available(*, deprecated, message: "Use 'Dictionary.init(grouping:by:)' instead.") + @available(*, deprecated, message: "Use 'Dictionary.init(grouping:by:)' instead.") public func groupByKey(keyForValue: (_ element: Element) throws -> K) rethrows -> [K: [Element]] { var group = [K: [Element]]() for value in self { diff --git a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift index eff9bfe8d..4706534f0 100644 --- a/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedIntegerExtensions.swift @@ -78,13 +78,13 @@ public extension SignedInteger { } #if canImport(Foundation) - @available(iOS 9.0, macOS 10.11, *) - /// SwifterSwift: Ordinal representation of an integer. + /// SwifterSwift: Ordinal representation of an integer. /// - /// print((12).ordinalString()) // prints "12th" - /// - /// - Parameter locale: Locale, default is .current. - /// - Returns: String ordinal representation of number in specified locale language. E.g. input 92, output in "en": "92nd" + /// print((12).ordinalString()) // prints "12th" + /// + /// - Parameter locale: locale, default is .current. + /// - Returns: string ordinal representation of number in specified locale language. E.g. input 92, output in "en": "92nd". + @available(iOS 9.0, macOS 10.11, *) public func ordinalString(locale: Locale = .current) -> String? { let formatter = NumberFormatter() formatter.locale = locale diff --git a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift index a9b1c1e6b..815f50ef3 100644 --- a/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/SignedNumericExtensions.swift @@ -28,13 +28,13 @@ public extension SignedNumeric { // MARK: - Methods public extension SignedNumeric { + #if canImport(Foundation) /// SwifterSwift: Spelled out representation of a number. /// /// print((12.32).spelledOutString()) // prints "twelve point three two" /// /// - Parameter locale: Locale, default is .current. /// - Returns: String representation of number spelled in specified locale language. E.g. input 92, output in "en": "ninety-two" - #if canImport(Foundation) public func spelledOutString(locale: Locale = .current) -> String? { let formatter = NumberFormatter() formatter.locale = locale diff --git a/Sources/Extensions/UIKit/UITextFieldExtensions.swift b/Sources/Extensions/UIKit/UITextFieldExtensions.swift index f785583d1..eca944d69 100755 --- a/Sources/Extensions/UIKit/UITextFieldExtensions.swift +++ b/Sources/Extensions/UIKit/UITextFieldExtensions.swift @@ -19,8 +19,13 @@ public extension UITextField { /// - password: UITextField is used to enter passwords. /// - generic: UITextField is used to enter generic text. public enum TextType { + /// UITextField is used to enter email addresses. case emailAddress + + /// UITextField is used to enter passwords. case password + + /// UITextField is used to enter generic text. case generic } diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index f112b7593..6ea6155a4 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -17,7 +17,10 @@ import UIKit /// - horizontal: Shake left and right. /// - vertical: Shake up and down. public enum ShakeDirection { + /// Shake left and right. case horizontal + + /// Shake up and down. case vertical } @@ -26,20 +29,30 @@ public enum ShakeDirection { /// - degrees: degrees. /// - radians: radians. public enum AngleUnit { + /// degrees. case degrees + + /// radians. case radians } /// SwifterSwift: Shake animations types. /// /// - linear: linear animation. -/// - easeIn: easeIn animation +/// - easeIn: easeIn animation. /// - easeOut: easeOut animation. /// - easeInOut: easeInOut animation. public enum ShakeAnimationType { + /// linear animation. case linear + + /// easeIn animation. case easeIn + + /// easeOut animation. case easeOut + + /// easeInOut animation. case easeInOut } @@ -84,7 +97,7 @@ public extension UIView { } } - // SwifterSwift: Height of view. + /// SwifterSwift: Height of view. public var height: CGFloat { get { return frame.size.height From a695f4c35c731a741f507b1310e81754451bbe77 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Mon, 18 Jun 2018 08:33:45 +0300 Subject: [PATCH 174/201] Closes #474 (#501) * Closes #474 * Refactor testDebounce in SwifterSwift --- CHANGELOG.md | 11 ++++++---- Sources/Extensions/SwifterSwift.swift | 3 +-- .../UIKit/UIStackViewExtensions.swift | 16 +++++++++++++++ Tests/SwifterSwiftTests.swift | 8 ++++---- .../UIStackViewExtensionsTest.swift | 20 ++++++++++++++++++- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1f978945..47553b848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S ### Added - **SKNode**: -- Added `descendants` method to get an array of all descendants of an SKNode. [#490](https://github.com/SwifterSwift/SwifterSwift/pull/490) by [oliviabrown9](https://github.com/oliviabrown9). + - Added `descendants` method to get an array of all descendants of an SKNode. [#490](https://github.com/SwifterSwift/SwifterSwift/pull/490) by [oliviabrown9](https://github.com/oliviabrown9). - **Comparable**: - Added `isBetween(min:max:)` and `clamped(min:max:)` to confirm a value is between bounds or limit it between bounds. [#466](https://github.com/SwifterSwift/SwifterSwift/pull/466) by [freak4pc](https://github.com/freak4pc). - **UIScrollView**: @@ -27,10 +27,13 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **UIWindow**: - Added `switchRootViewController` method to switch root view controller with animation. [#494](https://github.com/SwifterSwift/SwifterSwift/pull/494) by [omaralbeik](https://github.com/omaralbeik). - **Sequence** - - added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). - - Added `single(where:)` to get the only element of a sequence that matches a given condition. [#483](https://github.com/SwifterSwift/SwifterSwift/pull/483) by [andlang](https://github.com/andlang) + - Added `containsDuplicates()` to check whether a sequence contains duplicates. [#496](https://github.com/SwifterSwift/SwifterSwift/pull/496) by [@vyax](https://github.com/vyax). + - Added `single(where:)` to get the only element of a sequence that matches a given condition. [#483](https://github.com/SwifterSwift/SwifterSwift/pull/483) by [andlang](https://github.com/andlang). +- **UIStackView**: + - Added `addArrangedSubviews(_ views: )` to add an array of views to the end of the arrangedSubviews array. [#501](https://github.com/SwifterSwift/SwifterSwift/pull/501) by [omaralbeik](https://github.com/omaralbeik). + - Added `removeArrangedSubviews` to remove all views in stack’s array of arranged subviews. [#501](https://github.com/SwifterSwift/SwifterSwift/pull/501) by [omaralbeik](https://github.com/omaralbeik). - **UIEdgeInsets** - - Added `horizontal` and `vertical` properties. Also `init(inset:)` and `init(horizontal: vertical:)` initializers for convenience. [#500](https://github.com/SwifterSwift/SwifterSwift/pull/500) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). + - Added `horizontal` and `vertical` properties. Also `init(inset:)` and `init(horizontal: vertical:)` initializers for convenience. [#500](https://github.com/SwifterSwift/SwifterSwift/pull/500) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). ### Changed - **UITableView**: diff --git a/Sources/Extensions/SwifterSwift.swift b/Sources/Extensions/SwifterSwift.swift index 4f60068df..c27cc6097 100644 --- a/Sources/Extensions/SwifterSwift.swift +++ b/Sources/Extensions/SwifterSwift.swift @@ -288,9 +288,8 @@ public extension SwifterSwift { // http://stackoverflow.com/questions/27116684/how-can-i-debounce-a-method-call var lastFireTime = DispatchTime.now() let dispatchDelay = DispatchTimeInterval.milliseconds(millisecondsDelay) - + let dispatchTime: DispatchTime = lastFireTime + dispatchDelay return { - let dispatchTime: DispatchTime = lastFireTime + dispatchDelay queue.asyncAfter(deadline: dispatchTime) { let when: DispatchTime = lastFireTime + dispatchDelay let now = DispatchTime.now() diff --git a/Sources/Extensions/UIKit/UIStackViewExtensions.swift b/Sources/Extensions/UIKit/UIStackViewExtensions.swift index dc1a93e9c..2f53e6799 100644 --- a/Sources/Extensions/UIKit/UIStackViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIStackViewExtensions.swift @@ -32,6 +32,22 @@ public extension UIStackView { self.distribution = distribution } + /// SwifterSwift: Adds array of views to the end of the arrangedSubviews array. + /// + /// - Parameter views: views array. + public func addArrangedSubviews(_ views: [UIView]) { + for view in views { + addArrangedSubview(view) + } + } + + /// SwifterSwift: Removes all views in stack’s array of arranged subviews. + public func removeArrangedSubviews() { + for view in arrangedSubviews { + removeArrangedSubview(view) + } + } + } #endif diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 59c8ccaa9..2a104f7be 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -39,16 +39,16 @@ final class SwifterSwiftTests: XCTestCase { value += 1 } - let debouncedIncrementor = SwifterSwift.debounce(millisecondsDelay: 20, action: { + let debouncedIncrementor = SwifterSwift.debounce(millisecondsDelay: 20) { incrementor() - }) + } for index in 1...10 { debouncedIncrementor() if index == 10 { - SwifterSwift.delay(milliseconds: 30, completion: { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) { done.fulfill() - }) + } } } diff --git a/Tests/UIKitTests/UIStackViewExtensionsTest.swift b/Tests/UIKitTests/UIStackViewExtensionsTest.swift index 2033e23ea..b8b5e11db 100644 --- a/Tests/UIKitTests/UIStackViewExtensionsTest.swift +++ b/Tests/UIKitTests/UIStackViewExtensionsTest.swift @@ -11,7 +11,7 @@ import XCTest @testable import SwifterSwift -class UIStackViewExtensionsTest: XCTestCase { +final class UIStackViewExtensionsTest: XCTestCase { // MARK: - Initializers func testInitWithViews() { @@ -46,5 +46,23 @@ class UIStackViewExtensionsTest: XCTestCase { XCTAssertEqual(stack.spacing, 16.0) } + func testAddArrangedSubviews() { + let view1 = UIView() + let view2 = UIView() + let stack = UIStackView() + stack.addArrangedSubviews([view1, view2]) + XCTAssertEqual(stack.arrangedSubviews.count, 2) + } + + func testRemoveArrangedSubviews() { + let view1 = UIView() + let view2 = UIView() + let stack = UIStackView() + stack.addArrangedSubview(view1) + stack.addArrangedSubview(view2) + stack.removeArrangedSubviews() + XCTAssert(stack.arrangedSubviews.isEmpty) + } + } #endif From aa62de6d719323a5de8df0a0f6ccc48d757733e9 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Sun, 24 Jun 2018 15:18:54 +0300 Subject: [PATCH 175/201] Add new tests (#503) --- .../CoreGraphics/CGFloatExtensions.swift | 2 +- .../UINavigationControllerExtensions.swift | 8 +- .../UIKit/UISearchBarExtensions.swift | 2 +- .../Extensions/UIKit/UIViewExtensions.swift | 4 +- SwifterSwift.xcodeproj/project.pbxproj | 4 - .../FileManagerExtensionsTests.swift | 14 ++- .../NSAttributedStringExtensionsTests.swift | 14 ++- Tests/SharedTests/ColorExtensionsTests.swift | 9 ++ .../CollectionExtensionsTests.swift | 3 + Tests/SwifterSwiftTests.swift | 2 +- .../UIAlertControllerExtensionsTests.swift | 2 +- .../UICollectionViewExtensionsTests.swift | 11 +++ .../UIEdgeInsetsExtensionsTests.swift | 2 +- ...INavigationControllerExtensionsTests.swift | 31 +++++++ Tests/UIKitTests/UIViewExtensionsTests.swift | 91 +++++++++++++++++++ 15 files changed, 180 insertions(+), 19 deletions(-) diff --git a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift index 41bce3d2e..1ab12b954 100644 --- a/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGFloatExtensions.swift @@ -32,7 +32,7 @@ public extension CGFloat { /// SwifterSwift: Radian value of degree input. public var degreesToRadians: CGFloat { - return CGFloat.pi * self / 180.0 + return .pi * self / 180.0 } /// SwifterSwift: Floor of CGFloat value. diff --git a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift index 780c38816..211336724 100755 --- a/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UINavigationControllerExtensions.swift @@ -15,12 +15,14 @@ public extension UINavigationController { /// SwifterSwift: Pop ViewController with completion handler. /// - /// - Parameter completion: optional completion handler (default is nil). - public func popViewController(_ completion: (() -> Void)? = nil) { + /// - Parameters: + /// - animated: Set this value to true to animate the transition (default is true). + /// - completion: optional completion handler (default is nil). + public func popViewController(animated: Bool = true, _ completion: (() -> Void)? = nil) { // https://github.com/cotkjaer/UserInterface/blob/master/UserInterface/UIViewController.swift CATransaction.begin() CATransaction.setCompletionBlock(completion) - popViewController(animated: true) + popViewController(animated: animated) CATransaction.commit() } diff --git a/Sources/Extensions/UIKit/UISearchBarExtensions.swift b/Sources/Extensions/UIKit/UISearchBarExtensions.swift index 60f98cd55..7d40b3603 100644 --- a/Sources/Extensions/UIKit/UISearchBarExtensions.swift +++ b/Sources/Extensions/UIKit/UISearchBarExtensions.swift @@ -9,7 +9,7 @@ #if canImport(UIKit) import UIKit -#if !os(watchOS) +#if os(iOS) // MARK: - Properties public extension UISearchBar { diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 6ea6155a4..9c868e4e1 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -338,7 +338,7 @@ public extension UIView { /// - duration: animation duration in seconds (default is 1 second). /// - completion: optional completion handler to run with animation finishes (default is nil). public func rotate(byAngle angle: CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion: ((Bool) -> Void)? = nil) { - let angleWithType = (type == .degrees) ? CGFloat.pi * angle / 180.0 : angle + let angleWithType = (type == .degrees) ? .pi * angle / 180.0 : angle let aDuration = animated ? duration : 0 UIView.animate(withDuration: aDuration, delay: 0, options: .curveLinear, animations: { () -> Void in self.transform = self.transform.rotated(by: angleWithType) @@ -354,7 +354,7 @@ public extension UIView { /// - duration: animation duration in seconds (default is 1 second). /// - completion: optional completion handler to run with animation finishes (default is nil). public func rotate(toAngle angle: CGFloat, ofType type: AngleUnit, animated: Bool = false, duration: TimeInterval = 1, completion: ((Bool) -> Void)? = nil) { - let angleWithType = (type == .degrees) ? CGFloat.pi * angle / 180.0 : angle + let angleWithType = (type == .degrees) ? .pi * angle / 180.0 : angle let aDuration = animated ? duration : 0 UIView.animate(withDuration: aDuration, animations: { self.transform = self.transform.concatenating(CGAffineTransform(rotationAngle: angleWithType)) diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index aadb7c3a0..09423bd86 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -84,7 +84,6 @@ 07B7F1B01F5EB42000E6F910 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */; }; 07B7F1B11F5EB42000E6F910 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */; }; 07B7F1B21F5EB42000E6F910 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */; }; - 07B7F1B31F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */; }; 07B7F1B41F5EB42000E6F910 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */; }; 07B7F1B51F5EB42000E6F910 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */; }; 07B7F1B61F5EB42000E6F910 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */; }; @@ -105,7 +104,6 @@ 07B7F1C61F5EB42200E6F910 /* UINavigationBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1841F5EB41600E6F910 /* UINavigationBarExtensions.swift */; }; 07B7F1C71F5EB42200E6F910 /* UINavigationControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1851F5EB41600E6F910 /* UINavigationControllerExtensions.swift */; }; 07B7F1C81F5EB42200E6F910 /* UINavigationItemExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1861F5EB41600E6F910 /* UINavigationItemExtensions.swift */; }; - 07B7F1C91F5EB42200E6F910 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1871F5EB41600E6F910 /* UISearchBarExtensions.swift */; }; 07B7F1CA1F5EB42200E6F910 /* UISegmentedControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1881F5EB41600E6F910 /* UISegmentedControlExtensions.swift */; }; 07B7F1CB1F5EB42200E6F910 /* UISliderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F1891F5EB41600E6F910 /* UISliderExtensions.swift */; }; 07B7F1CC1F5EB42200E6F910 /* UIStoryboardExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B7F18A1F5EB41600E6F910 /* UIStoryboardExtensions.swift */; }; @@ -1523,7 +1521,6 @@ 07B7F1BC1F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */, 07B7F2371F5EB45200E6F910 /* CGSizeExtensions.swift in Sources */, 07B7F1FB1F5EB43C00E6F910 /* CharacterExtensions.swift in Sources */, - 07B7F1B31F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F2081F5EB43C00E6F910 /* StringExtensions.swift in Sources */, 07B7F2391F5EB45200E6F910 /* NSAttributedStringExtensions.swift in Sources */, 071306701FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, @@ -1589,7 +1586,6 @@ 07B7F1D21F5EB42200E6F910 /* UIViewControllerExtensions.swift in Sources */, 07B7F22B1F5EB45100E6F910 /* CGSizeExtensions.swift in Sources */, 07B7F1E91F5EB43B00E6F910 /* CharacterExtensions.swift in Sources */, - 07B7F1C91F5EB42200E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F1F61F5EB43B00E6F910 /* StringExtensions.swift in Sources */, 07B7F22D1F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, 071306711FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, diff --git a/Tests/FoundationTests/FileManagerExtensionsTests.swift b/Tests/FoundationTests/FileManagerExtensionsTests.swift index 3bf2a630e..f2b571e72 100644 --- a/Tests/FoundationTests/FileManagerExtensionsTests.swift +++ b/Tests/FoundationTests/FileManagerExtensionsTests.swift @@ -45,14 +45,12 @@ final class FileManagerExtensionsTests: XCTestCase { func testJSONFromFileWithFilename() { do { var filename = "test.json" // With extension - var json = try FileManager.default.jsonFromFile(withFilename: filename, - at: FileManagerExtensionsTests.self) + var json = try FileManager.default.jsonFromFile(withFilename: filename, at: FileManagerExtensionsTests.self) XCTAssertNotNil(json) filename = "test" // Without extension - json = try FileManager.default.jsonFromFile(withFilename: filename, - at: FileManagerExtensionsTests.self) + json = try FileManager.default.jsonFromFile(withFilename: filename, at: FileManagerExtensionsTests.self) XCTAssertNotNil(json) @@ -72,4 +70,12 @@ final class FileManagerExtensionsTests: XCTestCase { } } + func testInvalidFile() { + let filename = "another_test.not_json" + do { + let json = try FileManager.default.jsonFromFile(withFilename: filename, at: FileManagerExtensionsTests.self) + XCTAssertNil(json) + } catch {} + } + } diff --git a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift index c1af81553..5ad54552e 100644 --- a/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift +++ b/Tests/FoundationTests/NSAttributedStringExtensionsTests.swift @@ -170,7 +170,6 @@ final class NSAttributedStringExtensionsTests: XCTestCase { #endif #if !os(macOS) && !os(tvOS) - // MARK: - Operators func testAppending() { var string = NSAttributedString(string: "Test").italicized.underlined.struckthrough string += NSAttributedString(string: " Appending").bolded @@ -230,4 +229,17 @@ final class NSAttributedStringExtensionsTests: XCTestCase { } #endif + + #if !os(macOS) && !os(tvOS) + // MARK: - Operators + func testOperators() { + var string1 = NSAttributedString(string: "Test").italicized.underlined.struckthrough + let string2 = NSAttributedString(string: " Appending").bolded + XCTAssertEqual((string1 + string2).string, "Test Appending") + XCTAssertEqual((string1 + string2.string).string, "Test Appending") + + string1 += string2.string + XCTAssertEqual(string1.string, "Test Appending") + } + #endif } diff --git a/Tests/SharedTests/ColorExtensionsTests.swift b/Tests/SharedTests/ColorExtensionsTests.swift index 91835ae0a..8b3b8c60a 100644 --- a/Tests/SharedTests/ColorExtensionsTests.swift +++ b/Tests/SharedTests/ColorExtensionsTests.swift @@ -87,6 +87,15 @@ final class ColorExtensionsTests: XCTestCase { XCTAssertEqual(color.alpha, 1.0) } + #if !os(watchOS) + func testCoreImageColor() { + let color = Color.red + let coreImageColor = color.coreImageColor + XCTAssertNotNil(color.coreImageColor) + XCTAssertEqual(color.coreImageColor!, coreImageColor) + } + #endif + // MARK: - Test properties func testHsbaComponents() { var color = Color(hex: 0x00FF00, transparency: 1.0)! diff --git a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift index f66eb0b1b..ce5bb6d0a 100644 --- a/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/CollectionExtensionsTests.swift @@ -149,6 +149,9 @@ final class CollectionExtensionsTests: XCTestCase { func testAverage() { XCTAssertEqual([1.2, 2.3, 3.4, 4.5, 5.6].average(), 3.4) XCTAssertEqual([Double]().average(), 0) + + XCTAssertEqual([1, 2, 3, 4, 5].average(), 3) + XCTAssertEqual([Int]().average(), 0) } } diff --git a/Tests/SwifterSwiftTests.swift b/Tests/SwifterSwiftTests.swift index 2a104f7be..90755f886 100644 --- a/Tests/SwifterSwiftTests.swift +++ b/Tests/SwifterSwiftTests.swift @@ -54,7 +54,7 @@ final class SwifterSwiftTests: XCTestCase { XCTAssertEqual(value, 0, "Debounced function does not get executed right away") - waitForExpectations(timeout: 2, handler: { _ in + waitForExpectations(timeout: 2.5, handler: { _ in XCTAssertEqual(value, 1, "Value was incremented only once") }) } diff --git a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift index d369b8e6a..f335072b1 100644 --- a/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIAlertControllerExtensionsTests.swift @@ -6,7 +6,7 @@ // Copyright © 2017 SwifterSwift // -#if os(iOS) +#if os(iOS) || os(tvOS) import XCTest @testable import SwifterSwift diff --git a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift index 22ebd623e..e6589d1cc 100644 --- a/Tests/UIKitTests/UICollectionViewExtensionsTests.swift +++ b/Tests/UIKitTests/UICollectionViewExtensionsTests.swift @@ -11,6 +11,8 @@ import XCTest @testable import SwifterSwift +final private class TestCell: UICollectionViewCell {} + final class UICollectionViewExtensionsTests: XCTestCase { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) @@ -54,6 +56,15 @@ final class UICollectionViewExtensionsTests: XCTestCase { } } + #if os(iOS) + func testRegisterCellWithClass() { + let indexPath = IndexPath(row: 0, section: 0) + collectionView.register(cellWithClass: TestCell.self) + let cell = collectionView.dequeueReusableCell(withClass: TestCell.self, for: indexPath) + XCTAssertNotNil(cell) + } + #endif + #if os(iOS) func testRegisterCellWithNibUsingClass() { let indexPath = IndexPath(row: 0, section: 0) diff --git a/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift index 11a8a34cc..d135b7c4d 100644 --- a/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift +++ b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift @@ -20,7 +20,7 @@ final class UIEdgeInsetsExtensionsTests: XCTestCase { func testVertical() { let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 5.0, right: 10.0) - XCTAssertEqual(inset.horizontal, 20.0) + XCTAssertEqual(inset.vertical, 15.0) } func testInitInset() { diff --git a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift index cd71f27df..1ce6f3181 100644 --- a/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UINavigationControllerExtensionsTests.swift @@ -29,5 +29,36 @@ final class UINavigationControllerExtensionsTests: XCTestCase { waitForExpectations(timeout: 5, handler: nil) } + func testPopViewController() { + let rootVC = UIViewController() + let navigationController = UINavigationController(rootViewController: rootVC) + let vcToPush = UIViewController() + navigationController.pushViewController(vcToPush, animated: false) + XCTAssert(navigationController.viewControllers.count == 2) + + let exp = expectation(description: "pushCallback") + navigationController.popViewController(animated: false) { + XCTAssert(navigationController.viewControllers.count == 1) + XCTAssertEqual(navigationController.topViewController, rootVC) + exp.fulfill() + } + waitForExpectations(timeout: 5, handler: nil) + } + + func testMakeTransparent() { + let navigationController = UINavigationController(rootViewController: UIViewController()) + navigationController.makeTransparent(withTint: .red) + let navBar = navigationController.navigationBar + XCTAssertNotNil(navBar.shadowImage) + XCTAssert(navBar.isTranslucent) + XCTAssertEqual(navBar.tintColor, UIColor.red) + + let attrs = navBar.titleTextAttributes + XCTAssertNotNil(attrs) + let color = attrs![.foregroundColor] as? UIColor + XCTAssertNotNil(color) + XCTAssertEqual(color!, .red) + } + } #endif diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 476155535..21ae1d2e2 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -8,6 +8,8 @@ import XCTest @testable import SwifterSwift +// swiftlint:disable type_body_length, type_body_length + #if os(iOS) || os(tvOS) final class UIViewExtensionsTests: XCTestCase { @@ -205,6 +207,95 @@ final class UIViewExtensionsTests: XCTestCase { XCTAssertEqual(view.subviews.count, 2) } + func testFadeIn() { + let view1 = UIView() + view1.isHidden = true + view1.alpha = 0 + + view1.fadeIn(duration: 0, completion: nil) + XCTAssertFalse(view1.isHidden) + XCTAssertEqual(view1.alpha, 1) + + let fadeInExpectation = expectation(description: "Faded in") + + let view2 = UIView() + view2.alpha = 0 + XCTAssertFalse(view1.isHidden) + + view2.fadeIn(duration: 0.5) { _ in + fadeInExpectation.fulfill() + } + + XCTAssertEqual(view2.alpha, 1) + waitForExpectations(timeout: 0.5, handler: nil) + } + + func testFadeOut() { + let view1 = UIView() + view1.isHidden = true + + view1.fadeOut(duration: 0, completion: nil) + XCTAssertFalse(view1.isHidden) + XCTAssertEqual(view1.alpha, 0) + + let fadeOutExpectation = expectation(description: "Faded out") + + let view2 = UIView() + XCTAssertFalse(view1.isHidden) + + view2.fadeOut(duration: 0.5) { _ in + fadeOutExpectation.fulfill() + } + XCTAssertEqual(view2.alpha, 0) + waitForExpectations(timeout: 0.5, handler: nil) + } + + func testRotateByAngle() { + let view1 = UIView() + let transform1 = CGAffineTransform(rotationAngle: 2) + view1.rotate(byAngle: 2, ofType: .radians, animated: false, duration: 0, completion: nil) + XCTAssertEqual(view1.transform, transform1) + + let view2 = UIView() + let transform2 = CGAffineTransform(rotationAngle: .pi * 90.0 / 180.0) + view2.rotate(byAngle: 90, ofType: .degrees, animated: false, duration: 0, completion: nil) + XCTAssertEqual(view2.transform, transform2) + + let rotateExpectation = expectation(description: "view rotated") + + let view3 = UIView() + let transform3 = CGAffineTransform(rotationAngle: 2) + + view3.rotate(byAngle: 2, ofType: .radians, animated: true, duration: 0.5) { _ in + rotateExpectation.fulfill() + } + XCTAssertEqual(view3.transform, transform3) + waitForExpectations(timeout: 0.5, handler: nil) + } + + func testRotateToAngle() { + let view1 = UIView() + let transform1 = CGAffineTransform(rotationAngle: 2) + view1.rotate(toAngle: 2, ofType: .radians, animated: false, duration: 0, completion: nil) + XCTAssertEqual(view1.transform, transform1) + + let view2 = UIView() + let transform2 = CGAffineTransform(rotationAngle: .pi * 90.0 / 180.0) + view2.rotate(toAngle: 90, ofType: .degrees, animated: false, duration: 0, completion: nil) + XCTAssertEqual(view2.transform, transform2) + + let rotateExpectation = expectation(description: "view rotated") + + let view3 = UIView() + let transform3 = CGAffineTransform(rotationAngle: 2) + + view3.rotate(toAngle: 2, ofType: .radians, animated: true, duration: 0.5) { _ in + rotateExpectation.fulfill() + } + XCTAssertEqual(view3.transform, transform3) + waitForExpectations(timeout: 0.5, handler: nil) + } + func testRemoveSubviews() { let view = UIView() view.addSubviews([UIView(), UIView()]) From e095ebe46aed527b0158766d88bfc285b41ee64f Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Mon, 25 Jun 2018 00:11:18 +0200 Subject: [PATCH 176/201] Ensure that `UIGraphicsEndImageContext` is called. (#507) * Ensure that `UIGraphicsEndImageContext` is called. * Updated CHANGELOG * Fix CHANGELOG --- CHANGELOG.md | 1 + Sources/Extensions/UIKit/UIImageExtensions.swift | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47553b848..06e28c059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S ### Fixed - **UIImage**: - `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were ignoring an image's scale. [#446](https://github.com/SwifterSwift/SwifterSwift/pull/446) by [vyax](https://github.com/vyax) + - `init(color:size:)` fixed to ensure that `UIGraphicsEndImageContext` is always called after `UIGraphicsBeginImageContextWithOptions(_:_:_)` [#507](https://github.com/SwifterSwift/SwifterSwift/pull/507) by [guykogus](https://github.com/guykogus) >### Security diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index 2a43cb460..482d50f2b 100644 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -177,17 +177,19 @@ public extension UIImage { /// - size: image size. public convenience init(color: UIColor, size: CGSize) { UIGraphicsBeginImageContextWithOptions(size, false, 1) - color.setFill() - UIRectFill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) - guard let image = UIGraphicsGetImageFromCurrentImageContext() else { - self.init() - return + + defer { + UIGraphicsEndImageContext() } - UIGraphicsEndImageContext() - guard let aCgImage = image.cgImage else { + + color.setFill() + UIRectFill(CGRect(origin: .zero, size: size)) + + guard let aCgImage = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { self.init() return } + self.init(cgImage: aCgImage) } From a214d0707132d18f21ef4dd3ef21b41776f156bc Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 28 Jun 2018 18:23:01 +0300 Subject: [PATCH 177/201] v4.4 :rocket: --- .travis.yml | 2 +- CHANGELOG.md | 15 ++++++++++++--- README.md | 4 ++-- Sources/Info.plist | 2 +- SwifterSwift.podspec | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba8db8059..64c5a6fb8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.3 +osx_image: xcode9.4 env: global: diff --git a/CHANGELOG.md b/CHANGELOG.md index 06e28c059..4ebf6b80d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ # CHANGELOG The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. -# Upcoming release +> # Upcoming release +> +> ### Added +> ### Changed +> ### Deprecated +> ### Removed +> ### Fixed +> ### Security + +--- + +# [v4.4.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.4.0) ### Added - **SKNode**: @@ -63,8 +74,6 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were ignoring an image's scale. [#446](https://github.com/SwifterSwift/SwifterSwift/pull/446) by [vyax](https://github.com/vyax) - `init(color:size:)` fixed to ensure that `UIGraphicsEndImageContext` is always called after `UIGraphicsBeginImageContextWithOptions(_:_:_)` [#507](https://github.com/SwifterSwift/SwifterSwift/pull/507) by [guykogus](https://github.com/guykogus) ->### Security - --- # [v4.3.0](https://github.com/SwifterSwift/SwifterSwift/releases/tag/4.3.0) diff --git a/README.md b/README.md index 7fcb8184d..782d53cec 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![CocoaPods](https://img.shields.io/cocoapods/dt/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) [![CocoaPods](https://img.shields.io/cocoapods/dm/SwifterSwift.svg)](https://cocoapods.org/pods/SwifterSwift) [![Swift](https://img.shields.io/badge/Swift-4.1-orange.svg)](https://swift.org) -[![Xcode](https://img.shields.io/badge/Xcode-9.3-blue.svg)](https://developer.apple.com/xcode) +[![Xcode](https://img.shields.io/badge/Xcode-9.4-blue.svg)](https://developer.apple.com/xcode) [![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) [![Slack Channel](https://slackin-ppvrggbpgn.now.sh/badge.svg)](https://slackin-ppvrggbpgn.now.sh/) @@ -19,7 +19,7 @@ SwifterSwift is a collection of **over 500 native Swift extensions**, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS, watchOS and Linux. -### [Whats New in v4.3.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v430) +### [Whats New in v4.4.0?](https://github.com/SwifterSwift/SwifterSwift/blob/master/CHANGELOG.md#v440) ## Requirements: - **iOS** 8.0+ / **tvOS** 9.0+ / **watchOS** 2.0+ / **macOS** 10.10+ / **Ubuntu** 14.04+ diff --git a/Sources/Info.plist b/Sources/Info.plist index 0caec9254..9906166ab 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.3.0 + 4.4.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/SwifterSwift.podspec b/SwifterSwift.podspec index 843625114..dc5d7c091 100644 --- a/SwifterSwift.podspec +++ b/SwifterSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwifterSwift' - s.version = '4.3.0' + s.version = '4.4.0' s.summary = 'A handy collection of more than 500 native Swift extensions to boost your productivity.' s.description = <<-DESC SwifterSwift is a collection of over 500 native Swift extensions, with handy methods, syntactic sugar, and performance improvements for wide range of primitive data types, UIKit and Cocoa classes –over 500 in 1– for iOS, macOS, tvOS and watchOS. From d3c3fdba03cd876baf3c7f675f03ad7c3f32c811 Mon Sep 17 00:00:00 2001 From: Phoenix Date: Fri, 29 Jun 2018 20:01:38 +0800 Subject: [PATCH 178/201] Fix docs in ArrayExtensions and StringExtensions. (#511) --- Sources/Extensions/SwiftStdlib/ArrayExtensions.swift | 4 ++-- Sources/Extensions/SwiftStdlib/IntExtensions.swift | 2 +- .../Extensions/SwiftStdlib/StringExtensions.swift | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 7d2fe78c4..4d4ae90a5 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -292,8 +292,8 @@ public extension Array where Element: Equatable { /// SwifterSwift: Return array with all duplicate elements removed. /// - /// [1, 1, 2, 2, 3, 3, 3, 4, 5].duplicatesRemoved() -> [1, 2, 3, 4, 5]) - /// ["h", "e", "l", "l", "o"].duplicatesRemoved() -> ["h", "e", "l", "o"]) + /// [1, 1, 2, 2, 3, 3, 3, 4, 5].withoutDuplicates() -> [1, 2, 3, 4, 5]) + /// ["h", "e", "l", "l", "o"].withoutDuplicates() -> ["h", "e", "l", "o"]) /// /// - Returns: an array of unique elements. /// diff --git a/Sources/Extensions/SwiftStdlib/IntExtensions.swift b/Sources/Extensions/SwiftStdlib/IntExtensions.swift index 89e44e38c..1651faea6 100755 --- a/Sources/Extensions/SwiftStdlib/IntExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/IntExtensions.swift @@ -119,7 +119,7 @@ public extension Int { public func isPrime() -> Bool { // To improve speed on latter loop :) if self == 2 { - return true + return true } guard self > 1 && self % 2 != 0 else { diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 787d351d1..99933185c 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -566,8 +566,8 @@ public extension String { // swiftlint:disable next identifier_name /// SwifterSwift: Safely subscript string with index. /// - /// "Hello World!"[3] -> "l" - /// "Hello World!"[20] -> nil + /// "Hello World!"[safe: 3] -> "l" + /// "Hello World!"[safe: 20] -> nil /// /// - Parameter i: index. public subscript(safe i: Int) -> Character? { @@ -577,8 +577,8 @@ public extension String { /// SwifterSwift: Safely subscript string within a half-open range. /// - /// "Hello World!"[6..<11] -> "World" - /// "Hello World!"[21..<110] -> nil + /// "Hello World!"[safe: 6..<11] -> "World" + /// "Hello World!"[safe: 21..<110] -> nil /// /// - Parameter range: Half-open range. public subscript(safe range: CountableRange) -> String? { @@ -589,8 +589,8 @@ public extension String { /// SwifterSwift: Safely subscript string within a closed range. /// - /// "Hello World!"[6...11] -> "World!" - /// "Hello World!"[21...110] -> nil + /// "Hello World!"[safe: 6...11] -> "World!" + /// "Hello World!"[safe: 21...110] -> nil /// /// - Parameter range: Closed range. public subscript(safe range: ClosedRange) -> String? { From 3cb82030a13a40a751b60fc5c8802e31c998baea Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 11 Jul 2018 09:19:42 -0300 Subject: [PATCH 179/201] Changing rotate/rotated Array extensions to RangeReplacebleCollection extensions (#512) * Moving and refactoring rotate array extension to RangeReplacebleCollection * Updating docs. * Adding changelog entry * Change Range to PartialRangeFrom on to endIndex range. * Fix negative too big. * Changing rotation behavior. * Fix typo. * Fixing typos. * PR changes. --- CHANGELOG.md | 4 +- .../SwiftStdlib/ArrayExtensions.swift | 40 --------------- ...RangeReplaceableCollectionExtensions.swift | 51 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 +++++++ .../ArrayExtensionsTests.swift | 20 -------- .../RangeReplaceableCollectionTests.swift | 36 +++++++++++++ 6 files changed, 108 insertions(+), 61 deletions(-) create mode 100644 Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift create mode 100644 Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ebf6b80d..1452d59b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > # Upcoming release > > ### Added -> ### Changed +### Changed +- **RangeReplaceableCollection**: + - `rotate(by:)` and `rotated(by:)` array extensions now are more generic `RangeReplaceableCollection` extensions. [#512](https://github.com/SwifterSwift/SwifterSwift/pull/512) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida).z > ### Deprecated > ### Removed > ### Fixed diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 4d4ae90a5..5bedeb24e 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -96,46 +96,6 @@ public extension Array { return (matching, nonMatching) } - /// SwifterSwift: Returns a new rotated array by the given places. - /// - /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] - /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] - /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] - /// - /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. - /// - Returns: The new rotated array - public func rotated(by places: Int) -> [Element] { - //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate - guard places != 0 && places < count else { return self } - var array: [Element] = self - if places > 0 { - let range = (array.count - places).. [4,1,2,3] - /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] - /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] - /// - /// - Parameter places: The number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start become the end. - /// - Returns: self after rotating. - @discardableResult - public mutating func rotate(by places: Int) -> [Element] { - self = rotated(by: places) - return self - } - /// SwifterSwift: Shuffle array. (Using Fisher-Yates Algorithm) /// /// [1, 2, 3, 4, 5].shuffle() // shuffles array diff --git a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift new file mode 100644 index 000000000..569193c9d --- /dev/null +++ b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift @@ -0,0 +1,51 @@ +// +// RangeReplaceableCollectionExtensions.swift +// SwifterSwift +// +// Created by Luciano Almeida on 7/2/18. +// Copyright © 2018 SwifterSwift +// + +// MARK: - Methods +extension RangeReplaceableCollection { + + /// SwifterSwift: Returns a new rotated collection by the given places. + /// + /// [1, 2, 3, 4].rotated(by: 1) -> [4,1,2,3] + /// [1, 2, 3, 4].rotated(by: 3) -> [2,3,4,1] + /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] + /// + /// - Parameter places: Number of places that the array be rotated. If the value is positive the end becomes the start, if it negative it's that start becom the end. + /// - Returns: The new rotated collection. + public func rotated(by places: Int) -> Self { + //Inspired by: https://ruby-doc.org/core-2.2.0/Array.html#method-i-rotate + var copy = self + return copy.rotate(by: places) + } + + /// SwifterSwift: Rotate the collection by the given places. + /// + /// [1, 2, 3, 4].rotate(by: 1) -> [4,1,2,3] + /// [1, 2, 3, 4].rotate(by: 3) -> [2,3,4,1] + /// [1, 2, 3, 4].rotated(by: -1) -> [2,3,4,1] + /// + /// - Parameter places: The number of places that the array should be rotated. If the value is positive the end becomes the start, if it negative it's that start become the end. + /// - Returns: self after rotating. + @discardableResult + public mutating func rotate(by places: Int) -> Self { + guard places != 0 else { return self } + let placesToMove = places%count + if placesToMove > 0 { + let range = index(endIndex, offsetBy: -placesToMove)... + let slice = self[range] + removeSubrange(range) + insert(contentsOf: slice, at: startIndex) + } else { + let range = startIndex.. Date: Sat, 14 Jul 2018 11:08:28 -0300 Subject: [PATCH 180/201] Refactor some other array extensions (#516) * Moving removeFirst(where:) from array to rangereplaceble. * Moving indices(of:) to RandomAccessCollectionExtensions * Changelog updates * Changelog updates --- CHANGELOG.md | 5 ++- .../SwiftStdlib/ArrayExtensions.swift | 30 ------------------ .../RandomAccessCollectionExtensions.swift | 31 +++++++++++++++++++ ...RangeReplaceableCollectionExtensions.swift | 13 ++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 +++++++++++ .../ArrayExtensionsTests.swift | 19 ------------ ...andomAccessCollectionExtensionsTests.swift | 20 ++++++++++++ .../RangeReplaceableCollectionTests.swift | 14 +++++++++ 8 files changed, 100 insertions(+), 50 deletions(-) create mode 100644 Sources/Extensions/SwiftStdlib/RandomAccessCollectionExtensions.swift create mode 100644 Tests/SwiftStdlibTests/RandomAccessCollectionExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 1452d59b1..19dd16729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > ### Added ### Changed - **RangeReplaceableCollection**: - - `rotate(by:)` and `rotated(by:)` array extensions now are more generic `RangeReplaceableCollection` extensions. [#512](https://github.com/SwifterSwift/SwifterSwift/pull/512) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida).z + - `rotate(by:)` and `rotated(by:)` array extensions now are more generic `RangeReplaceableCollection` extensions. [#512](https://github.com/SwifterSwift/SwifterSwift/pull/512) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). + - `removeFirst(where:)` array extension now is more generic `RangeReplaceableCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **RandomAccessCollection**: + - `indices(of:)` array extension now is more generic `RandomAccessCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). > ### Deprecated > ### Removed > ### Fixed diff --git a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift index 5bedeb24e..6d51dbc72 100755 --- a/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/ArrayExtensions.swift @@ -174,41 +174,11 @@ public extension Array { self = sorted(by: path, ascending: ascending) return self } - - /// SwifterSwift: Removes the first element of the collection which satisfies the given predicate. - /// - /// [1, 2, 2, 3, 4, 2, 5].removeFirst { $0 % 2 == 0 } -> [1, 2, 3, 4, 2, 5] - /// ["h", "e", "l", "l", "o"].removeFirst { $0 == "e" } -> ["h", "l", "l", "o"] - /// - /// - Parameter predicate: A closure that takes an element as its argument and returns a Boolean value that indicates whether the passed element represents a match. - /// - Returns: The first element for which predicate returns true, after removing it. If no elements in the collection satisfy the given predicate, returns `nil`. - @discardableResult - public mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? { - guard let index = try index(where: predicate) else { return nil } - return remove(at: index) - } - } // MARK: - Methods (Equatable) public extension Array where Element: Equatable { - /// SwifterSwift: All indices of specified item. - /// - /// [1, 2, 2, 3, 4, 2, 5].indices(of 2) -> [1, 2, 5] - /// [1.2, 2.3, 4.5, 3.4, 4.5].indices(of 2.3) -> [1] - /// ["h", "e", "l", "l", "o"].indices(of "l") -> [2, 3] - /// - /// - Parameter item: item to check. - /// - Returns: an array with all indices of the given item. - public func indices(of item: Element) -> [Index] { - var indices: [Index] = [] - for index in startIndex.. [1, 3, 4, 5] diff --git a/Sources/Extensions/SwiftStdlib/RandomAccessCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RandomAccessCollectionExtensions.swift new file mode 100644 index 000000000..00c8724c0 --- /dev/null +++ b/Sources/Extensions/SwiftStdlib/RandomAccessCollectionExtensions.swift @@ -0,0 +1,31 @@ +// +// RandomAccessCollectionExtensions.swift +// SwifterSwift +// +// Created by Luciano Almeida on 7/13/18. +// Copyright © 2018 SwifterSwift +// + +extension RandomAccessCollection where Element: Equatable { + + /// SwifterSwift: All indices of specified item. + /// + /// [1, 2, 2, 3, 4, 2, 5].indices(of 2) -> [1, 2, 5] + /// [1.2, 2.3, 4.5, 3.4, 4.5].indices(of 2.3) -> [1] + /// ["h", "e", "l", "l", "o"].indices(of "l") -> [2, 3] + /// + /// - Parameter item: item to check. + /// - Returns: an array with all indices of the given item. + public func indices(of item: Element) -> [Index] { + var indices: [Index] = [] + var idx = startIndex + while idx < endIndex { + if self[idx] == item { + indices.append(idx) + } + formIndex(after: &idx) + } + return indices + } + +} diff --git a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift index 569193c9d..56b186dc9 100644 --- a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift @@ -48,4 +48,17 @@ extension RangeReplaceableCollection { } return self } + + /// SwifterSwift: Removes the first element of the collection which satisfies the given predicate. + /// + /// [1, 2, 2, 3, 4, 2, 5].removeFirst { $0 % 2 == 0 } -> [1, 2, 3, 4, 2, 5] + /// ["h", "e", "l", "l", "o"].removeFirst { $0 == "e" } -> ["h", "l", "l", "o"] + /// + /// - Parameter predicate: A closure that takes an element as its argument and returns a Boolean value that indicates whether the passed element represents a match. + /// - Returns: The first element for which predicate returns true, after removing it. If no elements in the collection satisfy the given predicate, returns `nil`. + @discardableResult + public mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? { + guard let index = try index(where: predicate) else { return nil } + return remove(at: index) + } } diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 6a111ca59..fd29a90fb 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -416,6 +416,13 @@ B247BDE720D376EC00842ACC /* UIEdgeInsetsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */; }; B247BDE920D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */; }; B247BDEA20D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */; }; + B29527AD20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */; }; + B29527AE20F99F9900E1F75D /* RandomAccessCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */; }; + B29527AF20F99F9900E1F75D /* RandomAccessCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */; }; + B29527B020F99F9A00E1F75D /* RandomAccessCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */; }; + B29527B220F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; + B29527B320F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; + B29527B420F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -595,6 +602,8 @@ B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftStdlibDeprecated.swift; sourceTree = ""; }; B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensions.swift; sourceTree = ""; }; B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensionsTests.swift; sourceTree = ""; }; + B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomAccessCollectionExtensions.swift; sourceTree = ""; }; + B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomAccessCollectionExtensionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -689,6 +698,7 @@ 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */, 07B7F1761F5EB41600E6F910 /* SignedNumericExtensions.swift */, B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */, + B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */, B23678EA1FB116680027C931 /* Deprecated */, ); path = SwiftStdlib; @@ -714,6 +724,7 @@ 9D9784DF1FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift */, 07FE50441F891C95000766AA /* SignedNumericExtensionsTests.swift */, B22EB2B820E9E814001EAE70 /* RangeReplaceableCollectionTests.swift */, + B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */, ); path = SwiftStdlibTests; sourceTree = ""; @@ -1464,6 +1475,7 @@ 07B7F19D1F5EB42000E6F910 /* UISearchBarExtensions.swift in Sources */, 07B7F21A1F5EB43C00E6F910 /* StringExtensions.swift in Sources */, 07B7F2331F5EB45100E6F910 /* NSAttributedStringExtensions.swift in Sources */, + B29527AD20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift in Sources */, 0713066F1FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, B22EB2B720E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */, @@ -1538,6 +1550,7 @@ 071306701FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1AD1F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, 077BA08B1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, + B29527AE20F99F9900E1F75D /* RandomAccessCollectionExtensions.swift in Sources */, 9D4914841F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, 07B7F2011F5EB43C00E6F910 /* FloatExtensions.swift in Sources */, 07B7F2001F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, @@ -1622,6 +1635,7 @@ 07B7F1EB1F5EB43B00E6F910 /* DataExtensions.swift in Sources */, 07B7F1C81F5EB42200E6F910 /* UINavigationItemExtensions.swift in Sources */, 07B7F1D11F5EB42200E6F910 /* UITextViewExtensions.swift in Sources */, + B29527AF20F99F9900E1F75D /* RandomAccessCollectionExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1659,6 +1673,7 @@ 07B7F1DF1F5EB43B00E6F910 /* IntExtensions.swift in Sources */, 07B7F2201F5EB44600E6F910 /* CGColorExtensions.swift in Sources */, 0726D77C1F7C24840028CAB5 /* ColorExtensions.swift in Sources */, + B29527B020F99F9A00E1F75D /* RandomAccessCollectionExtensions.swift in Sources */, 07B7F1D51F5EB43B00E6F910 /* ArrayExtensions.swift in Sources */, 7832C2B2209BB19300224EED /* ComparableExtensions.swift in Sources */, 07B7F21C1F5EB43E00E6F910 /* SwifterSwift.swift in Sources */, @@ -1727,6 +1742,7 @@ 182698AC1F8AB46E0052F21E /* CGColorExtensionsTests.swift in Sources */, 07C50D8F1F5EB06000F46E5A /* CLLocationExtensionsTests.swift in Sources */, 07C50D8D1F5EB06000F46E5A /* CGPointExtensionsTests.swift in Sources */, + B29527B220F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */, 07C50D3F1F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, 07C50D3D1F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */, 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, @@ -1788,6 +1804,7 @@ 07C50D501F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D4A1F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, 07C50D681F5EB05100F46E5A /* CollectionExtensionsTests.swift in Sources */, + B29527B320F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */, 07C50D4B1F5EB04700F46E5A /* UINavigationItemExtensionsTests.swift in Sources */, A94AA78B202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, 078916DF20760DA700AC0665 /* SignedIntegerExtensionsTests.swift in Sources */, @@ -1851,6 +1868,7 @@ 07C50D811F5EB05800F46E5A /* CGFloatExtensionsTests.swift in Sources */, 07FE50471F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, A94AA78C202819B400E229A5 /* FileManagerExtensionsTests.swift in Sources */, + B29527B420F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */, 078916DC2076077000AC0665 /* FloatingPointExtensionsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift index d5bbeec06..c1c5388a4 100644 --- a/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/ArrayExtensionsTests.swift @@ -161,25 +161,6 @@ final class ArrayExtensionsTests: XCTestCase { Person(name: "Wade", age: nil)]) } - func testIndices() { - XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 1), [0, 1, 5, 7]) - XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) - } - - func testRemoveWhere() { - var array = [0, 1, 2, 0, 3, 4, 5, 0, 0] - array.removeFirst { $0 == 1 } - XCTAssertEqual(array, [0, 2, 0, 3, 4, 5, 0, 0]) - array = [] - XCTAssertNil(array.removeFirst { $0 == 10 }) - array = [2, 2, 1, 2, 3] - let removedElement = array.removeFirst { $0 == 2 } - XCTAssertEqual(array, [2, 1, 2, 3]) - XCTAssertEqual(removedElement, 2) - - XCTAssertThrowsError(try array.removeFirst(where: { _ in throw NSError() })) - } - func testRemoveAll() { var arr = [0, 1, 2, 0, 3, 4, 5, 0, 0] arr.removeAll(0) diff --git a/Tests/SwiftStdlibTests/RandomAccessCollectionExtensionsTests.swift b/Tests/SwiftStdlibTests/RandomAccessCollectionExtensionsTests.swift new file mode 100644 index 000000000..a0f5a9b14 --- /dev/null +++ b/Tests/SwiftStdlibTests/RandomAccessCollectionExtensionsTests.swift @@ -0,0 +1,20 @@ +// +// RandomAccessCollectionExtensionsTests.swift +// SwifterSwift +// +// Created by Luciano Almeida on 7/14/18. +// Copyright © 2018 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +class RandomAccessCollectionExtensionsTests: XCTestCase { + + func testIndices() { + XCTAssertEqual([].indices(of: 5), []) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 5), []) + XCTAssertEqual([1, 1, 2, 3, 4, 1, 2, 1].indices(of: 1), [0, 1, 5, 7]) + XCTAssertEqual(["a", "b", "c", "b", "4", "1", "2", "1"].indices(of: "b"), [1, 3]) + } +} diff --git a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift index 2726ea1e8..fa76c520e 100644 --- a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift +++ b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift @@ -33,4 +33,18 @@ class RangeReplaceableCollectionTests: XCTestCase { array.rotate(by: -1) XCTAssertEqual(array, [4, 1, 2, 3]) } + + func testRemoveWhere() { + var array = [0, 1, 2, 0, 3, 4, 5, 0, 0] + array.removeFirst { $0 == 1 } + XCTAssertEqual(array, [0, 2, 0, 3, 4, 5, 0, 0]) + array = [] + XCTAssertNil(array.removeFirst { $0 == 10 }) + array = [2, 2, 1, 2, 3] + let removedElement = array.removeFirst { $0 == 2 } + XCTAssertEqual(array, [2, 1, 2, 3]) + XCTAssertEqual(removedElement, 2) + + XCTAssertThrowsError(try array.removeFirst(where: { _ in throw NSError() })) + } } From 70bd4a61bd756f94620ad7c31686d9afd3e90d41 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 15 Jul 2018 21:28:16 +0800 Subject: [PATCH 181/201] Use the scale factor of the device's main screen when scaling. (#515) --- CHANGELOG.md | 2 ++ Sources/Extensions/UIKit/UIImageExtensions.swift | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19dd16729..59a4f9b2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S > ### Deprecated > ### Removed > ### Fixed +- **UIImage**: +- Fixed `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were using image's scale as the scale factor. [#515](https://github.com/SwifterSwift/SwifterSwift/pull/515) by [VincentSit](https://github.com/VincentSit). > ### Security --- diff --git a/Sources/Extensions/UIKit/UIImageExtensions.swift b/Sources/Extensions/UIKit/UIImageExtensions.swift index 482d50f2b..d847e0ed1 100644 --- a/Sources/Extensions/UIKit/UIImageExtensions.swift +++ b/Sources/Extensions/UIKit/UIImageExtensions.swift @@ -69,12 +69,11 @@ public extension UIImage { /// - Parameters: /// - toHeight: new height. /// - opaque: flag indicating whether the bitmap is opaque. - /// - orientation: optional UIImage orientation (default is nil). /// - Returns: optional scaled UIImage (if applicable). - public func scaled(toHeight: CGFloat, opaque: Bool = false, with orientation: UIImageOrientation? = nil) -> UIImage? { + public func scaled(toHeight: CGFloat, opaque: Bool = false) -> UIImage? { let scale = toHeight / size.height let newWidth = size.width * scale - UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: toHeight), opaque, scale) + UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: toHeight), opaque, 0) draw(in: CGRect(x: 0, y: 0, width: newWidth, height: toHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() @@ -86,12 +85,11 @@ public extension UIImage { /// - Parameters: /// - toWidth: new width. /// - opaque: flag indicating whether the bitmap is opaque. - /// - orientation: optional UIImage orientation (default is nil). /// - Returns: optional scaled UIImage (if applicable). - public func scaled(toWidth: CGFloat, opaque: Bool = false, with orientation: UIImageOrientation? = nil) -> UIImage? { + public func scaled(toWidth: CGFloat, opaque: Bool = false) -> UIImage? { let scale = toWidth / size.width let newHeight = size.height * scale - UIGraphicsBeginImageContextWithOptions(CGSize(width: toWidth, height: newHeight), opaque, scale) + UIGraphicsBeginImageContextWithOptions(CGSize(width: toWidth, height: newHeight), opaque, 0) draw(in: CGRect(x: 0, y: 0, width: toWidth, height: newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() From b12528549d99cb7243a002d8bfc6f2bfa4965497 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 18 Jul 2018 22:44:09 -0300 Subject: [PATCH 182/201] Label the xcode summary with the platform. (#519) --- Dangerfile | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Dangerfile b/Dangerfile index ed7c46bb9..235213ab1 100644 --- a/Dangerfile +++ b/Dangerfile @@ -23,7 +23,29 @@ swiftlint.lint_files warn('This pull request is marked as Work in Progress. DO NOT MERGE!') if github.pr_title.include? "[WIP]" # Xcode summary -xcode_summary.report 'xcodebuild-ios.json' -xcode_summary.report 'xcodebuild-tvos.json' -xcode_summary.report 'xcodebuild-macos.json' -xcode_summary.report 'xcodebuild-watchos.json' +def summary(platform:) + xcode_summary.report "xcodebuild-#{platform}.json" +end + +def label_tests_summary(label:, platform:) + file_name = "xcodebuild-#{platform}.json" + json = File.read(file_name) + data = JSON.parse(json) + data["tests_summary_messages"].each { |message| + if !message.empty? + message.insert(1, " " + label + ":") + end + } + File.open(file_name,"w") do |f| + f.puts JSON.pretty_generate(data) + end +end + +label_tests_summary(label: "iOS", platform: "ios") +label_tests_summary(label: "tvOS", platform: "tvos") +label_tests_summary(label: "macOS", platform: "macos") + +summary(platform: "ios") +summary(platform: "tvos") +summary(platform: "macos") +summary(platform: "watchos") From c7b87ce78ce6bee1e4bf4f79390fe849d784ab64 Mon Sep 17 00:00:00 2001 From: Marco Capano Date: Thu, 19 Jul 2018 05:36:41 +0200 Subject: [PATCH 183/201] Updating CONTRIBUTING.md for Adding Test. (#518) * Updating CONTRIBUTING.md for Adding Test. Separated rules about adding tests in a dedicated section. Fixes #588 * Update CONTRIBUTING.md with review suggestions I've edited some lines based on the review of the previous commit. --- CONTRIBUTING.md | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ce7088d1..ee8197902 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,7 @@ This document contains information and guidelines about contributing to this pro - [Asking Questions](#asking-questions) - [Ways to Contribute](#ways-to-contribute) - [Adding new Extensions](#adding-new-extensions) +- [Adding Tests](#adding-tests) - [Adding documentation](#adding-documentation) - [Adding changelog entries](#adding-changelog-entries) - [Reporting Issues](#reporting-issues) @@ -76,16 +77,9 @@ public extension SomeType { - Instance methods & type methods - Initializers - Structs -- All extensions should be tested. +- All extensions should be tested. See [Adding Tests](#adding-tests) to know more. - Files are named based on the type that the contained extensions extend. - (example: all String extensions are found in "**StringExtensions.swift**" file) -- All extensions files and test files have a one to one relation. - - (example: all tests for "**StringExtensions.swift**" are found in the "**StringExtensionsTests.swift**" file) -- There should be a one to one relationship between extensions and their backing tests. -- Tests should be named using the same API of the extension it backs. - - (example: `DateExtensions` method `isBetween` is named `testIsBetween`) -- All test files are named based on the extensions which it tests. - - (example: all String extensions tests are found in "**StringExtensionsTests.swift**" file) - Extensions and tests are ordered inside files in the following order: ```swift @@ -106,6 +100,24 @@ public extension SomeType {} --- +## Adding Tests + +Please follow these guidelines before submitting a pull request with new tests: + +- Every extended SwifterSwift type should have one specific subclass of XCTestCase. +- There should be a one to one relationship between methods/properties and their backing tests. +- Tests should be named using the same API of the extension it backs. + - (example: `DateExtensions` method `isBetween` is named `testIsBetween`) +- All test files are named based on the extensions which it tests. + - (example: all String extensions tests are found in "**StringExtensionsTests.swift**" file) +- The subclass should be marked as final. +- All extensions files and test files have a one to one relationship. + - (example: all tests for "**StringExtensions.swift**" are found in the "**StringExtensionsTests.swift**" file) +- SwifterSwift source files should not be added to the test target directly, but you should rather import SwifterSwift into the test target by using: @testable import SwifterSwift +- Tests are ordered inside files in the same order as extensions. See [Adding new Extensions](#adding-new-extensions) to know more. + +--- + ## Adding documentation Use the following template to add documentation for extensions From 817a58012f2fbc6d297c99092949c45c37a8609f Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Thu, 19 Jul 2018 14:47:27 +0300 Subject: [PATCH 184/201] Fixes #514 (#517) --- CHANGELOG.md | 23 +++++++---- .../Deprecated/SwiftStdlibDeprecated.swift | 14 +++++++ .../SwiftStdlib/StringExtensions.swift | 12 +++--- .../StringExtensionsTests.swift | 38 +++++++++++++++++-- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59a4f9b2a..1fdc6ba94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,30 @@ # CHANGELOG The changelog for **SwifterSwift**. Also see the [releases](https://github.com/SwifterSwift/SwifterSwift/releases) on GitHub. -> # Upcoming release -> -> ### Added +# Upcoming release + +### Added + ### Changed - **RangeReplaceableCollection**: - `rotate(by:)` and `rotated(by:)` array extensions now are more generic `RangeReplaceableCollection` extensions. [#512](https://github.com/SwifterSwift/SwifterSwift/pull/512) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - `removeFirst(where:)` array extension now is more generic `RangeReplaceableCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **RandomAccessCollection**: - `indices(of:)` array extension now is more generic `RandomAccessCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). -> ### Deprecated -> ### Removed -> ### Fixed + +### Fixed - **UIImage**: - Fixed `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were using image's scale as the scale factor. [#515](https://github.com/SwifterSwift/SwifterSwift/pull/515) by [VincentSit](https://github.com/VincentSit). -> ### Security +- **String**: + - Used [RFC 5322](http://emailregex.com/) in `isValidEmail`, an email address regex that 99.99% works. [#517](https://github.com/SwifterSwift/SwifterSwift/pull/517) by [Omar Albeik](https://github.com/omaralbeik) + +### Deprecated +- **String**: + - `isEmail` property has been renamed to `isValidEmail`. + +### Removed + +### Security --- diff --git a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift index c13199f6f..3f991df84 100644 --- a/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift +++ b/Sources/Extensions/SwiftStdlib/Deprecated/SwiftStdlibDeprecated.swift @@ -39,6 +39,20 @@ public extension Bool { extension String { + #if canImport(Foundation) + /// SwifterSwift: Check if string is valid email format. + /// **Note that this property does not validate the email address against an email server. It merely attempts to determine whether its format is suitable for an email address.**. + /// + /// "john@doe.com".isEmail -> true + /// + @available(*, deprecated: 4.5.0, message: "Use isValidEmail instead", renamed: "isValidEmail") + public var isEmail: Bool { + // http://emailregex.com/ + let regex = "^(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$" + return range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil + } + #endif + /// SwifterSwift: Number of characters in string. /// /// "Hello world!".length -> 12 diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 99933185c..845af6ba7 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -158,12 +158,14 @@ public extension String { #if canImport(Foundation) /// SwifterSwift: Check if string is valid email format. /// - /// "john@doe.com".isEmail -> true + /// - Note: Note that this property does not validate the email address against an email server. It merely attempts to determine whether its format is suitable for an email address. /// - public var isEmail: Bool { - // http://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift - return range(of: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", - options: .regularExpression, range: nil, locale: nil) != nil + /// "john@doe.com".isValidEmail -> true + /// + public var isValidEmail: Bool { + // http://emailregex.com/ + let regex = "^(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$" + return range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil } #endif diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index 06b70505f..a856bce1f 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -74,10 +74,40 @@ final class StringExtensionsTests: XCTestCase { XCTAssertFalse("abc".isAlphaNumeric) } - func testIsEmail() { - XCTAssert("john@appleseed.com".isEmail) - XCTAssertFalse("john@appleseedcom".isEmail) - XCTAssertFalse("johnappleseed.com".isEmail) + func testisValidEmail() { + // https://blogs.msdn.microsoft.com/testing123/2009/02/06/email-address-test-cases/ + + XCTAssert("email@domain.com".isValidEmail) + XCTAssert("firstname.lastname@domain.com".isValidEmail) + XCTAssert("email@subdomain.domain.com".isValidEmail) + XCTAssert("firstname+lastname@domain.com".isValidEmail) + XCTAssert("email@123.123.123.123".isValidEmail) + XCTAssert("email@[123.123.123.123]".isValidEmail) + XCTAssert("\"email\"@domain.com".isValidEmail) + XCTAssert("1234567890@domain.com".isValidEmail) + XCTAssert("email@domain-one.com".isValidEmail) + XCTAssert("_______@domain.com".isValidEmail) + XCTAssert("email@domain.name".isValidEmail) + XCTAssert("email@domain.co.jp".isValidEmail) + XCTAssert("firstname-lastname@domain.com".isValidEmail) + + XCTAssertFalse("".isValidEmail) + XCTAssertFalse("plainaddress".isValidEmail) + XCTAssertFalse("#@%^%#$@#$@#.com".isValidEmail) + XCTAssertFalse("@domain.com".isValidEmail) + XCTAssertFalse("Joe Smith ".isValidEmail) + XCTAssertFalse("email.domain.com".isValidEmail) + XCTAssertFalse("email@domain@domain.com".isValidEmail) + XCTAssertFalse(".email@domain.com".isValidEmail) + XCTAssertFalse("email.@domain.com".isValidEmail) + XCTAssertFalse("email..email@domain.com".isValidEmail) + XCTAssertFalse("email@domain.com (Joe Smith)".isValidEmail) + XCTAssertFalse("email@domain".isValidEmail) + XCTAssertFalse("email@-domain.com".isValidEmail) + XCTAssertFalse(" email@domain.com".isValidEmail) + XCTAssertFalse("email@domain.com ".isValidEmail) + XCTAssertFalse("\nemail@domain.com".isValidEmail) + XCTAssertFalse("nemail@domain.com \n\n".isValidEmail) } func testIsValidUrl() { From 8f853c0cf506d87b19692c51cbfb194877577dc8 Mon Sep 17 00:00:00 2001 From: moyerr Date: Fri, 27 Jul 2018 03:24:29 -0400 Subject: [PATCH 185/201] UIView: add and remove multiple gesture recognizers at once with array of UIGestureRecognizer (#523) --- CHANGELOG.md | 3 ++ .../Extensions/UIKit/UIViewExtensions.swift | 24 +++++++++++++ Tests/UIKitTests/UIViewExtensionsTests.swift | 35 +++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fdc6ba94..051f6de85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **UIView** + - Added `addGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to add multiple gesture recognizers to a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) + - Added `removeGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to remove multiple gesture recognizers from a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index 9c868e4e1..a2c982c98 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -329,6 +329,30 @@ public extension UIView { gestureRecognizers?.forEach(removeGestureRecognizer) } + /// SwifterSwift: Attaches gesture recognizers to the view. + /// + /// Attaching gesture recognizers to a view defines the scope of the represented + /// gesture, causing it to receive touches hit-tested to that view and all of its + /// subviews. The view establishes a strong reference to the gesture recognizers. + /// + /// - Parameter gestureRecognizers: The array of gesture recognizers to be added to the view. + public func addGestureRecognizers(_ gestureRecognizers: [UIGestureRecognizer]) { + for recognizer in gestureRecognizers { + addGestureRecognizer(recognizer) + } + } + + /// SwifterSwift: Detaches gesture recognizers from the receiving view. + /// + /// This method releases gestureRecognizers in addition to detaching them from the view. + /// + /// - Parameter gestureRecognizers: The array of gesture recognizers to be removed from the view. + public func removeGestureRecognizers(_ gestureRecognizers: [UIGestureRecognizer]) { + for recognizer in gestureRecognizers { + removeGestureRecognizer(recognizer) + } + } + /// SwifterSwift: Rotate view by angle on relative axis. /// /// - Parameters: diff --git a/Tests/UIKitTests/UIViewExtensionsTests.swift b/Tests/UIKitTests/UIViewExtensionsTests.swift index 21ae1d2e2..007a717cf 100644 --- a/Tests/UIKitTests/UIViewExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewExtensionsTests.swift @@ -316,6 +316,41 @@ final class UIViewExtensionsTests: XCTestCase { XCTAssertEqual(view.gestureRecognizers!.count, 0) } + func testAddGestureRecognizers() { + let view = UIView() + + XCTAssertNil(view.gestureRecognizers) + + let tap = UITapGestureRecognizer(target: nil, action: nil) + let pan = UIPanGestureRecognizer(target: nil, action: nil) + let swipe = UISwipeGestureRecognizer(target: nil, action: nil) + + view.addGestureRecognizers([tap, pan, swipe]) + + XCTAssertNotNil(view.gestureRecognizers) + XCTAssertEqual(view.gestureRecognizers!.count, 3) + } + + func testRemoveGestureRecognizersVariadic() { + let view = UIView() + + XCTAssertNil(view.gestureRecognizers) + + let tap = UITapGestureRecognizer(target: nil, action: nil) + let pan = UIPanGestureRecognizer(target: nil, action: nil) + let swipe = UISwipeGestureRecognizer(target: nil, action: nil) + + view.addGestureRecognizers([tap, pan, swipe]) + + XCTAssertNotNil(view.gestureRecognizers) + XCTAssertEqual(view.gestureRecognizers!.count, 3) + + view.removeGestureRecognizers([tap, pan, swipe]) + + XCTAssertNotNil(view.gestureRecognizers) + XCTAssert(view.gestureRecognizers!.isEmpty) + } + func testAnchor() { let view = UIView() let subview = UIView() From 25a5524bd03db0f2df095fd21eb3d06be6ce4a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20H=C3=A4rtwig?= Date: Sat, 28 Jul 2018 18:12:15 +0200 Subject: [PATCH 186/201] Add 'removeValueForRandomKey()' to Dictionary and 'removeRandomElement()' to RangeReplaceableCollection (#497) --- CHANGELOG.md | 4 ++++ .../SwiftStdlib/DictionaryExtensions.swift | 7 +++++++ .../RangeReplaceableCollectionExtensions.swift | 6 ++++++ SwifterSwift.xcodeproj/project.pbxproj | 12 +++++++----- .../SwiftStdlibTests/DictionaryExtensionsTests.swift | 11 +++++++++++ .../RangeReplaceableCollectionTests.swift | 11 +++++++++++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 051f6de85..837c5fb27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **Dictionary**: + - Added `removeValueForRandomKey()` to remove a value for a random key from a dictionary. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax). +- **RangeReplaceableCollection**: + - Added `removeRandomElement()` to remove a random element from a collection. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax). - **UIView** - Added `addGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to add multiple gesture recognizers to a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) - Added `removeGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to remove multiple gesture recognizers from a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 99b8d0620..5d4a5fca0 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -34,6 +34,13 @@ public extension Dictionary { keys.forEach { removeValue(forKey: $0) } } + /// SwifterSwift: Remove a value for a random key from the dictionary. + @discardableResult public mutating func removeValueForRandomKey() -> Value? { + guard !isEmpty else { return nil } + let key = Array(keys)[Int(arc4random_uniform(UInt32(keys.count)))] + return removeValue(forKey: key) + } + /// SwifterSwift: JSON Data from dictionary. /// /// - Parameter prettify: set true to prettify data (default is false). diff --git a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift index 56b186dc9..7c1c781d0 100644 --- a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift @@ -61,4 +61,10 @@ extension RangeReplaceableCollection { guard let index = try index(where: predicate) else { return nil } return remove(at: index) } + + /// SwifterSwift: Remove a random value from the collection. + @discardableResult public mutating func removeRandomElement() -> Element? { + guard !isEmpty else { return nil } + return remove(at: index(startIndex, offsetBy: numericCast(arc4random_uniform(numericCast(count))))) + } } diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index fd29a90fb..5c5c22831 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -383,6 +383,8 @@ 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; + 9D7D898020D729ED0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */; }; + 9D7D898220D729EE0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */; }; 9D9784DB1FCAE3D200D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; 9D9784DC1FCAE42600D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; 9D9784DD1FCAE42600D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; @@ -403,9 +405,7 @@ A9FF467420245AC90084C40F /* test.json in Resources */ = {isa = PBXBuildFile; fileRef = A9FF467020245ABA0084C40F /* test.json */; }; B22EB2B720E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; B22EB2B920E9E814001EAE70 /* RangeReplaceableCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B820E9E814001EAE70 /* RangeReplaceableCollectionTests.swift */; }; - B22EB2BA20E9E81B001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; B22EB2BB20E9E81C001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; - B22EB2BC20E9E81C001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; B22EB2BD20E9EA1F001EAE70 /* RangeReplaceableCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B820E9E814001EAE70 /* RangeReplaceableCollectionTests.swift */; }; B22EB2BE20E9EA20001EAE70 /* RangeReplaceableCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B820E9E814001EAE70 /* RangeReplaceableCollectionTests.swift */; }; B23678EC1FB116AD0027C931 /* SwiftStdlibDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = B23678EB1FB116AD0027C931 /* SwiftStdlibDeprecated.swift */; }; @@ -591,6 +591,7 @@ 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; + 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeReplaceableCollectionExtensions.swift; sourceTree = ""; }; 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensions.swift; sourceTree = ""; }; 9D9784DF1FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensionsTests.swift; sourceTree = ""; }; A94AA78620280F9100E229A5 /* FileManagerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerExtensions.swift; sourceTree = ""; }; @@ -692,6 +693,7 @@ 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */, 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */, 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */, + 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */, 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */, 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */, 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */, @@ -1208,7 +1210,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0900; - LastUpgradeCheck = 0930; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = SwifterSwift; TargetAttributes = { 07898B5C1F278D7600558C97 = { @@ -1528,6 +1530,7 @@ 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */, 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, + 9D7D898220D729EE0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */, 7832C2B0209BB19300224EED /* ComparableExtensions.swift in Sources */, 077BA0901F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1B71F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, @@ -1558,7 +1561,6 @@ 074EAF1C1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, 07B7F1A81F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F2341F5EB45200E6F910 /* CGColorExtensions.swift in Sources */, - B22EB2BA20E9E81B001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */, 07B7F21E1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, 70269A2C1FB478D100C6C2D0 /* CalendarExtensions.swift in Sources */, 07B7F2041F5EB43C00E6F910 /* LocaleExtensions.swift in Sources */, @@ -1665,7 +1667,7 @@ 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, 1875A8FA20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */, - B22EB2BC20E9E81C001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */, + 9D7D898020D729ED0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */, 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */, 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */, diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 09cb2eec8..965a53558 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -26,6 +26,17 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertFalse(dict.keys.contains("key2")) } + func testRemoveElementForRandomKey() { + var emptyDict = [String: String]() + XCTAssertNil(emptyDict.removeValueForRandomKey()) + + var dict = ["key1": "value1", "key2": "value2", "key3": "value3"] + let elements = dict.count + let removedElement = dict.removeValueForRandomKey() + XCTAssertEqual(elements - 1, dict.count) + XCTAssertFalse(dict.contains(where: {$0.value == removedElement})) + } + func testJsonData() { let dict = ["key": "value"] diff --git a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift index fa76c520e..5f8865961 100644 --- a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift +++ b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift @@ -47,4 +47,15 @@ class RangeReplaceableCollectionTests: XCTestCase { XCTAssertThrowsError(try array.removeFirst(where: { _ in throw NSError() })) } + + func testRemoveRandomElement() { + var emptyArray = [Int]() + XCTAssertNil(emptyArray.removeRandomElement()) + + var array = [1, 2, 3] + let elements = array.count + let removedElement = array.removeRandomElement()! + XCTAssertEqual(elements - 1, array.count) + XCTAssertFalse(array.contains(removedElement)) + } } From a5bd99a6c1dab3194879ffd490f60ceae59e0e4b Mon Sep 17 00:00:00 2001 From: Marco Capano Date: Wed, 1 Aug 2018 14:24:08 +0200 Subject: [PATCH 187/201] Provide syntactic sugar for working with ChildViewControllers (#530) * Added utility methods to easily add and remove child view controllers. Also added tests. * Update CHANGELOG.md * Update UIViewControllerExtensions.swift * Changed naming off the add and remove extensions on UIViewController. Added a test case for calling remove on a view controller with no parent. * changed method naming * Improved tests to use XCTAssertEqual when possible * Update CHANGELOG.md * Fixed some swxftlint warnings. * Swiftlint fix * Added containerView in the documentation as requested * Update CHANGELOG.md --- CHANGELOG.md | 3 ++ ...RangeReplaceableCollectionExtensions.swift | 2 +- .../UIKit/UIViewControllerExtensions.swift | 19 +++++++++ .../UIViewControllerExtensionsTests.swift | 41 +++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 837c5fb27..476f71fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **UIView** - Added `addGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to add multiple gesture recognizers to a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) - Added `removeGestureRecognizers(_:)` which accepts an array of `UIGestureRecognizer` to remove multiple gesture recognizers from a view with one call. [#523](https://github.com/SwifterSwift/SwifterSwift/pull/523) by [moyerr](https://github.com/moyerr) +- **UIViewController** + - Added `addChildViewController(_:toContainerView)` to easily add child view controllers. Accepts a `UIViewController` and a `UIView` to add the child's view to. + - Added `removeViewAndControllerFromParentViewController()` to remove a `UIViewController` from its parent. ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift index 7c1c781d0..7a447acb1 100644 --- a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift @@ -61,7 +61,7 @@ extension RangeReplaceableCollection { guard let index = try index(where: predicate) else { return nil } return remove(at: index) } - + /// SwifterSwift: Remove a random value from the collection. @discardableResult public mutating func removeRandomElement() -> Element? { guard !isEmpty else { return nil } diff --git a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift index 9b873b2ca..8ee2d9e72 100755 --- a/Sources/Extensions/UIKit/UIViewControllerExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewControllerExtensions.swift @@ -78,6 +78,25 @@ public extension UIViewController { return alertController } + /// SwifterSwift: Helper method to add a UIViewController as a childViewController. + /// + /// - Parameters: + /// - child: the view controller to add as a child + /// - containerView: the containerView for the child viewcontroller's root view. + public func addChildViewController(_ child: UIViewController, toContainerView containerView: UIView) { + addChildViewController(child) + containerView.addSubview(child.view) + child.didMove(toParentViewController: self) + } + + /// SwifterSwift: Helper method to remove a UIViewController from its parent. + public func removeViewAndControllerFromParentViewController() { + guard parent != nil else { return } + + willMove(toParentViewController: nil) + removeFromParentViewController() + view.removeFromSuperview() + } } #endif diff --git a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift index 06e6f2dc3..f4a53a19a 100644 --- a/Tests/UIKitTests/UIViewControllerExtensionsTests.swift +++ b/Tests/UIKitTests/UIViewControllerExtensionsTests.swift @@ -78,5 +78,46 @@ final class UIViewControllerExtensionsTests: XCTestCase { XCTAssertEqual(alertController.preferredAction, alertController.actions[preferredButtonIndex]) } + func testAddChildViewController() { + let parentViewController = UIViewController() + let childViewController = UIViewController() + + XCTAssert(parentViewController.childViewControllers.isEmpty) + XCTAssertNil(childViewController.parent) + + parentViewController.addChildViewController(childViewController, toContainerView: parentViewController.view) + + XCTAssertEqual(parentViewController.childViewControllers, [childViewController]) + XCTAssertNotNil(childViewController.parent) + XCTAssertEqual(childViewController.parent, parentViewController) + } + + func testRemoveChildViewController() { + let parentViewController = UIViewController() + let childViewController = UIViewController() + + parentViewController.addChildViewController(childViewController) + parentViewController.view.addSubview(childViewController.view) + childViewController.didMove(toParentViewController: parentViewController) + + XCTAssertEqual(parentViewController.childViewControllers, [childViewController]) + XCTAssertNotNil(childViewController.parent) + XCTAssertEqual(childViewController.parent, parentViewController) + + childViewController.removeViewAndControllerFromParentViewController() + + XCTAssert(parentViewController.childViewControllers.isEmpty) + XCTAssertNil(childViewController.parent) + } + + func testRemoveChildViewControllerWithNoParent() { + let childViewController = UIViewController() + XCTAssertNil(childViewController.parent) + + childViewController.removeViewAndControllerFromParentViewController() + + XCTAssertNil(childViewController.parent) + } + } #endif From e41d61479f93baddfd2235e22afd717220d71b0c Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 5 Aug 2018 05:29:06 +0800 Subject: [PATCH 188/201] Added utility methods to easily create an UIEdgeInsets based on current value and adjusted by given offset. Also added tests and docs. (#532) --- CHANGELOG.md | 2 + .../UIKit/UIEdgeInsetsExtensions.swift | 54 ++++++++ .../UIEdgeInsetsExtensionsTests.swift | 119 ++++++++++++++++++ 3 files changed, 175 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 476f71fe2..be6630a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **UIViewController** - Added `addChildViewController(_:toContainerView)` to easily add child view controllers. Accepts a `UIViewController` and a `UIView` to add the child's view to. - Added `removeViewAndControllerFromParentViewController()` to remove a `UIViewController` from its parent. +- **UIEdgeInsets** + - Added `insetBy(top:)`, `insetBy(left:)`, `insetBy(bottom:)`, `insetBy(right:)`, `insetBy(horizontal:)` and `insetBy(vertical:)` to creates an `UIEdgeInsets` based on current value and adjusted by given offset. [#532](https://github.com/SwifterSwift/SwifterSwift/pull/532) by [VincentSit](https://github.com/VincentSit). ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift b/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift index bac2164dc..2cd387eb7 100644 --- a/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift +++ b/Sources/Extensions/UIKit/UIEdgeInsetsExtensions.swift @@ -44,6 +44,60 @@ extension UIEdgeInsets { public init(horizontal: CGFloat, vertical: CGFloat) { self.init(top: vertical/2, left: horizontal/2, bottom: vertical/2, right: horizontal/2) } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and top offset. + /// + /// - Parameters: + /// - top: Offset to be applied in to the top edge. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(top: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: self.top + top, left: left, bottom: bottom, right: right) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and left offset. + /// + /// - Parameters: + /// - left: Offset to be applied in to the left edge. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(left: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: top, left: self.left + left, bottom: bottom, right: right) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and bottom offset. + /// + /// - Parameters: + /// - bottom: Offset to be applied in to the bottom edge. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(bottom: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: top, left: left, bottom: self.bottom + bottom, right: right) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and right offset. + /// + /// - Parameters: + /// - right: Offset to be applied in to the right edge. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(right: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: top, left: left, bottom: bottom, right: self.right + right) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and horizontal value equally divided and applied to right offset and left offset. + /// + /// - Parameters: + /// - horizontal: Offset to be applied to right and left. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(horizontal: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: top, left: left + horizontal/2, bottom: bottom, right: right + horizontal/2) + } + + /// SwifterSwift: Creates an `UIEdgeInsets` based on current value and vertical value equally divided and applied to top and bottom. + /// + /// - Parameters: + /// - vertical: Offset to be applied to top and bottom. + /// - Returns: UIEdgeInsets offset with given offset. + public func insetBy(vertical: CGFloat) -> UIEdgeInsets { + return UIEdgeInsets(top: top + vertical/2, left: left, bottom: bottom + vertical/2, right: right) + } } #endif diff --git a/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift index d135b7c4d..35d27e790 100644 --- a/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift +++ b/Tests/UIKitTests/UIEdgeInsetsExtensionsTests.swift @@ -38,6 +38,125 @@ final class UIEdgeInsetsExtensionsTests: XCTestCase { XCTAssertEqual(inset.right, 10.0) XCTAssertEqual(inset.left, 10.0) } + + func testInsetByTop() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByTop = inset.insetBy(top: 5.0) + XCTAssertNotEqual(inset, insetByTop) + XCTAssertEqual(insetByTop.top, 15.0) + XCTAssertEqual(insetByTop.left, 10.0) + XCTAssertEqual(insetByTop.bottom, 10.0) + XCTAssertEqual(insetByTop.right, 10.0) + + let negativeInsetByTop = inset.insetBy(top: -5.0) + XCTAssertNotEqual(inset, negativeInsetByTop) + XCTAssertEqual(negativeInsetByTop.top, 5.0) + XCTAssertEqual(negativeInsetByTop.left, 10.0) + XCTAssertEqual(negativeInsetByTop.bottom, 10.0) + XCTAssertEqual(negativeInsetByTop.right, 10.0) + } + + func testInsetByLeft() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByLeft = inset.insetBy(left: 5.0) + XCTAssertNotEqual(inset, insetByLeft) + XCTAssertEqual(insetByLeft.top, 10.0) + XCTAssertEqual(insetByLeft.left, 15.0) + XCTAssertEqual(insetByLeft.bottom, 10.0) + XCTAssertEqual(insetByLeft.right, 10.0) + + let negativeInsetByLeft = inset.insetBy(left: -5.0) + XCTAssertNotEqual(inset, negativeInsetByLeft) + XCTAssertEqual(negativeInsetByLeft.top, 10.0) + XCTAssertEqual(negativeInsetByLeft.left, 5.0) + XCTAssertEqual(negativeInsetByLeft.bottom, 10.0) + XCTAssertEqual(negativeInsetByLeft.right, 10.0) + } + + func testInsetByBottom() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByBottom = inset.insetBy(bottom: 5.0) + XCTAssertNotEqual(inset, insetByBottom) + XCTAssertEqual(insetByBottom.top, 10.0) + XCTAssertEqual(insetByBottom.left, 10.0) + XCTAssertEqual(insetByBottom.bottom, 15.0) + XCTAssertEqual(insetByBottom.right, 10.0) + + let negativeInsetByBottom = inset.insetBy(bottom: -5.0) + XCTAssertNotEqual(inset, negativeInsetByBottom) + XCTAssertEqual(negativeInsetByBottom.top, 10.0) + XCTAssertEqual(negativeInsetByBottom.left, 10.0) + XCTAssertEqual(negativeInsetByBottom.bottom, 5.0) + XCTAssertEqual(negativeInsetByBottom.right, 10.0) + } + + func testInsetByRight() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByRight = inset.insetBy(right: 5.0) + XCTAssertNotEqual(inset, insetByRight) + XCTAssertEqual(insetByRight.top, 10.0) + XCTAssertEqual(insetByRight.left, 10.0) + XCTAssertEqual(insetByRight.bottom, 10.0) + XCTAssertEqual(insetByRight.right, 15.0) + + let negativeInsetByRight = inset.insetBy(right: -5.0) + XCTAssertNotEqual(inset, negativeInsetByRight) + XCTAssertEqual(negativeInsetByRight.top, 10.0) + XCTAssertEqual(negativeInsetByRight.left, 10.0) + XCTAssertEqual(negativeInsetByRight.bottom, 10.0) + XCTAssertEqual(negativeInsetByRight.right, 5.0) + } + + func testInsetByHorizontal() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByHorizontal = inset.insetBy(horizontal: 5.0) + XCTAssertNotEqual(inset, insetByHorizontal) + XCTAssertEqual(insetByHorizontal.left, 12.5) + XCTAssertEqual(insetByHorizontal.right, 12.5) + XCTAssertEqual(insetByHorizontal.top, 10.0) + XCTAssertEqual(insetByHorizontal.bottom, 10.0) + + let negativeInsetByHorizontal = inset.insetBy(horizontal: -5.0) + XCTAssertNotEqual(inset, negativeInsetByHorizontal) + XCTAssertEqual(negativeInsetByHorizontal.left, 7.5) + XCTAssertEqual(negativeInsetByHorizontal.right, 7.5) + XCTAssertEqual(negativeInsetByHorizontal.top, 10.0) + XCTAssertEqual(negativeInsetByHorizontal.bottom, 10.0) + } + + func testInsetByVertical() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let insetByVertical = inset.insetBy(vertical: 5.0) + XCTAssertNotEqual(inset, insetByVertical) + XCTAssertEqual(insetByVertical.left, 10.0) + XCTAssertEqual(insetByVertical.right, 10.0) + XCTAssertEqual(insetByVertical.top, 12.5) + XCTAssertEqual(insetByVertical.bottom, 12.5) + + let negativeInsetByVertical = inset.insetBy(vertical: -5.0) + XCTAssertNotEqual(inset, negativeInsetByVertical) + XCTAssertEqual(negativeInsetByVertical.left, 10.0) + XCTAssertEqual(negativeInsetByVertical.right, 10.0) + XCTAssertEqual(negativeInsetByVertical.top, 7.5) + XCTAssertEqual(negativeInsetByVertical.bottom, 7.5) + } + + func testInsetComposing() { + let inset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0) + let composedInset = inset.insetBy(bottom: 5.0).insetBy(horizontal: 5.0) + XCTAssertNotEqual(inset, composedInset) + XCTAssertEqual(composedInset.left, 12.5) + XCTAssertEqual(composedInset.right, 12.5) + XCTAssertEqual(composedInset.top, 10) + XCTAssertEqual(composedInset.bottom, 15.0) + + let negativeComposedInset = inset.insetBy(bottom: -5.0).insetBy(horizontal: -5.0) + XCTAssertNotEqual(inset, negativeComposedInset) + XCTAssertEqual(negativeComposedInset.left, 7.5) + XCTAssertEqual(negativeComposedInset.right, 7.5) + XCTAssertEqual(negativeComposedInset.top, 10) + XCTAssertEqual(negativeComposedInset.bottom, 5.0) + } } #endif From e63ac52811c8e670d58e8afc8879d70802bb1691 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 8 Aug 2018 13:45:59 -0300 Subject: [PATCH 189/201] Collection initializer with an expression. (#537) * Collection initializer with an expression. * Updating changelog * Adding spacing between sections * fix typo * Adding file to targets. * Fixing PR comments. * Fix typo * Fixing tests. --- CHANGELOG.md | 2 ++ ...RangeReplaceableCollectionExtensions.swift | 23 +++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 10 ++++---- .../RangeReplaceableCollectionTests.swift | 10 ++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be6630a4c..6b538e947 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Added `removeViewAndControllerFromParentViewController()` to remove a `UIViewController` from its parent. - **UIEdgeInsets** - Added `insetBy(top:)`, `insetBy(left:)`, `insetBy(bottom:)`, `insetBy(right:)`, `insetBy(horizontal:)` and `insetBy(vertical:)` to creates an `UIEdgeInsets` based on current value and adjusted by given offset. [#532](https://github.com/SwifterSwift/SwifterSwift/pull/532) by [VincentSit](https://github.com/VincentSit). +- **RangeReplaceableCollection** + - `init(expression:count:)` to create a collection of a given count initialized with an expression.[#537](https://github.com/SwifterSwift/SwifterSwift/pull/537) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift index 7a447acb1..981b0cb9d 100644 --- a/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/RangeReplaceableCollectionExtensions.swift @@ -6,6 +6,29 @@ // Copyright © 2018 SwifterSwift // +// MARK: - Initializers +extension RangeReplaceableCollection { + /// Creates a new collection of a given size where for each position of the collection the value will be the result + /// of a call of the given expression. + /// + /// let values = Array(expression: "Value", count: 3) + /// print(values) + /// // Prints "["Value", "Value", "Value"]" + /// + /// - Parameters: + /// - expression: The expression to execute for each position of the collection. + /// - count: The count of the collection. + public init(expression: @autoclosure () throws -> Element, count: Int) rethrows { + self.init() + if count > 0 { //swiftlint:disable:this empty_count + reserveCapacity(count) + while self.count < count { + append(try expression()) + } + } + } +} + // MARK: - Methods extension RangeReplaceableCollection { diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 5c5c22831..1a35c2441 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -383,8 +383,6 @@ 9D4914891F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148A1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */; }; - 9D7D898020D729ED0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */; }; - 9D7D898220D729EE0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */; }; 9D9784DB1FCAE3D200D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; 9D9784DC1FCAE42600D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; 9D9784DD1FCAE42600D988E7 /* StringProtocolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */; }; @@ -423,6 +421,8 @@ B29527B220F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; B29527B320F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; B29527B420F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; + B2EEA14A211A7AC900EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; + B2EEA14B211A7ACA00EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -591,7 +591,6 @@ 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIGestureRecognizerExtensionsTests.swift; sourceTree = ""; }; 9D4914821F85138E00F3868F /* NSPredicateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensions.swift; sourceTree = ""; }; 9D4914881F8515D100F3868F /* NSPredicateExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicateExtensionsTests.swift; sourceTree = ""; }; - 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeReplaceableCollectionExtensions.swift; sourceTree = ""; }; 9D9784DA1FCAE3D200D988E7 /* StringProtocolExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensions.swift; sourceTree = ""; }; 9D9784DF1FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocolExtensionsTests.swift; sourceTree = ""; }; A94AA78620280F9100E229A5 /* FileManagerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerExtensions.swift; sourceTree = ""; }; @@ -693,7 +692,6 @@ 07B7F1711F5EB41600E6F910 /* FloatingPointExtensions.swift */, 07B7F1721F5EB41600E6F910 /* IntExtensions.swift */, 07B7F1741F5EB41600E6F910 /* OptionalExtensions.swift */, - 9D67686020CFE4F300D618CA /* RangeReplaceableCollectionExtensions.swift */, 18C8E5DD2074C58100F8AF51 /* SequenceExtensions.swift */, 07B7F1751F5EB41600E6F910 /* SignedIntegerExtensions.swift */, 07B7F1771F5EB41600E6F910 /* StringExtensions.swift */, @@ -1530,7 +1528,7 @@ 07B7F2361F5EB45200E6F910 /* CGPointExtensions.swift in Sources */, 07B7F1AB1F5EB42000E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1B91F5EB42000E6F910 /* UITableViewExtensions.swift in Sources */, - 9D7D898220D729EE0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */, + B2EEA14B211A7ACA00EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */, 7832C2B0209BB19300224EED /* ComparableExtensions.swift in Sources */, 077BA0901F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, 07B7F1B71F5EB42000E6F910 /* UISwitchExtensions.swift in Sources */, @@ -1645,6 +1643,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B2EEA14A211A7AC900EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */, 07B7F1E01F5EB43B00E6F910 /* LocaleExtensions.swift in Sources */, 07B7F1DA1F5EB43B00E6F910 /* DateExtensions.swift in Sources */, 07B7F1D81F5EB43B00E6F910 /* CollectionExtensions.swift in Sources */, @@ -1667,7 +1666,6 @@ 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, 1875A8FA20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */, - 9D7D898020D729ED0004F55C /* RangeReplaceableCollectionExtensions.swift in Sources */, 278CA08D1F9A9232004918BD /* NSImageExtensions.swift in Sources */, 07B7F1E21F5EB43B00E6F910 /* SignedIntegerExtensions.swift in Sources */, 07B7F1E51F5EB43B00E6F910 /* URLExtensions.swift in Sources */, diff --git a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift index 5f8865961..bddec31b1 100644 --- a/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift +++ b/Tests/SwiftStdlibTests/RangeReplaceableCollectionTests.swift @@ -11,6 +11,16 @@ import XCTest class RangeReplaceableCollectionTests: XCTestCase { + func testInitExpressionOfSize() { + var array = [1, 2, 3] + let newArray = [Int](expression: array.removeLast(), count: array.count) + XCTAssertEqual(newArray, [3, 2, 1]) + XCTAssertTrue(array.isEmpty) + let empty = [Int](expression: 1, count: 0) + XCTAssertTrue(empty.isEmpty) + + } + func testRotated() { let array: [Int] = [1, 2, 3, 4] XCTAssertEqual(array.rotated(by: 0), [1, 2, 3, 4]) From 6bd425646b2204677e9d7371df07ba4e284cc418 Mon Sep 17 00:00:00 2001 From: Ratul sharker Date: Thu, 9 Aug 2018 23:17:42 +0600 Subject: [PATCH 190/201] UIRefreshControl extension added to begin refresh programatically. (#525) * UIRefreshControl extension added to begin refresh programatically. * Update CHANGELOG.md * Following things are done 1. code minimized removing the init from the CGPoint initialization 2. removing intermediate size access from frame. 3. added one more test case which checking that the refreshControl is currently refreshing or not. * Following things are done 1. New two parameter added to provide better control provide to the method caller. 2. SendActions option added which can be controlled by a parameter. 3. Unnecessary frame creation is removed from Unit test. 4. New test function added for UIRefreshControl added as Property (iOS 10+). * Remove `UIRefreshControlExtensions.swift` from rebuilding for the test target. * Following things are done 1. CHANGELOG.md extra line removed. 2. .init() replaced with () form test 3. Documentation updated. 4. Fourth parameter `sendAction` is now optional. 5. import statements are now cleaned. * Test case with `sendAction:` true parameter. * Two tests merged into one test mehtod. --- CHANGELOG.md | 2 + .../UIKit/UIRefreshControlExtensions.swift | 36 +++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 9 +++++ .../UIRefreshControlExntesionsTests.swift | 39 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 Sources/Extensions/UIKit/UIRefreshControlExtensions.swift create mode 100644 Tests/UIKitTests/UIRefreshControlExntesionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b538e947..7eafbde5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +-**UIRefreshControl**: + - `beginRefresh(in tableView:, animated:, sendAction:)` UIRefreshControl extension to begin refresh programatically. [#525](https://github.com/SwifterSwift/SwifterSwift/pull/525) by [ratulSharker](https://github.com/ratulSharker) - **Dictionary**: - Added `removeValueForRandomKey()` to remove a value for a random key from a dictionary. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax). - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/UIKit/UIRefreshControlExtensions.swift b/Sources/Extensions/UIKit/UIRefreshControlExtensions.swift new file mode 100644 index 000000000..762736cdb --- /dev/null +++ b/Sources/Extensions/UIKit/UIRefreshControlExtensions.swift @@ -0,0 +1,36 @@ +// +// UIRefreshControlExtensions.swift +// SwifterSwift +// +// Created by ratul sharker on 7/24/18. +// Copyright © 2018 SwifterSwift +// + +#if os(iOS) +import UIKit + +// MARK: - Methods +public extension UIRefreshControl { + + /// SwifterSwift: Programatically begin refresh control inside of UITableView. + /// + /// - Parameters: + /// - tableView: UITableView instance, inside which the refresh control is contained. + /// - animated: Boolean, indicates that is the content offset changing should be animated or not. + /// - sendAction: Boolean, indicates that should it fire sendActions method for valueChanged UIControlEvents + public func beginRefreshing(in tableView: UITableView, animated: Bool, sendAction: Bool = false) { + //https://stackoverflow.com/questions/14718850/uirefreshcontrol-beginrefreshing-not-working-when-uitableviewcontroller-is-ins/14719658#14719658 + assert(superview == tableView, "Refresh control does not belong to the receiving table view") + + beginRefreshing() + let offsetPoint = CGPoint(x: 0, y: -frame.height) + tableView.setContentOffset(offsetPoint, animated: animated) + + if sendAction { + sendActions(for: .valueChanged) + } + } + +} + +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index 1a35c2441..dcc498b14 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -421,8 +421,11 @@ B29527B220F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; B29527B320F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; B29527B420F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */; }; + CA1317542106D35E002F1B0D /* UIRefreshControlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA1317532106D35E002F1B0D /* UIRefreshControlExtensions.swift */; }; + CA1317582106D4F5002F1B0D /* UIRefreshControlExntesionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA1317562106D4F5002F1B0D /* UIRefreshControlExntesionsTests.swift */; }; B2EEA14A211A7AC900EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; B2EEA14B211A7ACA00EF7F8E /* RangeReplaceableCollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22EB2B620E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift */; }; + /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -604,6 +607,8 @@ B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsetsExtensionsTests.swift; sourceTree = ""; }; B29527AC20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomAccessCollectionExtensions.swift; sourceTree = ""; }; B29527B120F9A04900E1F75D /* RandomAccessCollectionExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomAccessCollectionExtensionsTests.swift; sourceTree = ""; }; + CA1317532106D35E002F1B0D /* UIRefreshControlExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIRefreshControlExtensions.swift; sourceTree = ""; }; + CA1317562106D4F5002F1B0D /* UIRefreshControlExntesionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIRefreshControlExntesionsTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -846,6 +851,7 @@ 86B3F7AB208D3D5C00BC297B /* UIScrollViewExtensions.swift */, 0722CB3720C2E46B00C6C1B6 /* UIWindowExtensions.swift */, B247BDE520D376EC00842ACC /* UIEdgeInsetsExtensions.swift */, + CA1317532106D35E002F1B0D /* UIRefreshControlExtensions.swift */, ); path = UIKit; sourceTree = ""; @@ -931,6 +937,7 @@ 90693554208B545100407C4D /* UIGestureRecognizerExtensionsTests.swift */, 0722CB3920C2E49900C6C1B6 /* UIWindowExtensionsTests.swift */, B247BDE820D37AFE00842ACC /* UIEdgeInsetsExtensionsTests.swift */, + CA1317562106D4F5002F1B0D /* UIRefreshControlExntesionsTests.swift */, ); path = UIKitTests; sourceTree = ""; @@ -1486,6 +1493,7 @@ 07B7F2121F5EB43C00E6F910 /* DoubleExtensions.swift in Sources */, 07B7F2171F5EB43C00E6F910 /* OptionalExtensions.swift in Sources */, 074EAF1B1F7BA68B00C74636 /* UIFontExtensions.swift in Sources */, + CA1317542106D35E002F1B0D /* UIRefreshControlExtensions.swift in Sources */, 07B7F1921F5EB42000E6F910 /* UIAlertControllerExtensions.swift in Sources */, 07B7F22E1F5EB45100E6F910 /* CGColorExtensions.swift in Sources */, 07B7F21F1F5EB43F00E6F910 /* SwifterSwift.swift in Sources */, @@ -1729,6 +1737,7 @@ 07C50D3E1F5EB04700F46E5A /* UITextViewExtensionsTests.swift in Sources */, 074EAF1F1F7BA74700C74636 /* UIFontExtensionsTest.swift in Sources */, 07C50D301F5EB04700F46E5A /* UIImageExtensionsTests.swift in Sources */, + CA1317582106D4F5002F1B0D /* UIRefreshControlExntesionsTests.swift in Sources */, 07C50D3A1F5EB04700F46E5A /* UISwitchExtensionsTests.swift in Sources */, 07C50D341F5EB04700F46E5A /* UINavigationControllerExtensionsTests.swift in Sources */, 752AC7A520BC9FF500659E76 /* SpriteKitTests.swift in Sources */, diff --git a/Tests/UIKitTests/UIRefreshControlExntesionsTests.swift b/Tests/UIKitTests/UIRefreshControlExntesionsTests.swift new file mode 100644 index 000000000..6aa8e6311 --- /dev/null +++ b/Tests/UIKitTests/UIRefreshControlExntesionsTests.swift @@ -0,0 +1,39 @@ +// +// UIRefreshControlExntesionsTests.swift +// SwifterSwift +// +// Created by ratul sharker on 7/24/18. +// Copyright © 2018 SwifterSwift +// + +#if os(iOS) + +import XCTest +@testable import SwifterSwift + +final class UIRefreshControlExtensionTests: XCTestCase { + + func testBeginRefreshAsRefreshControlSubview() { + let tableView = UITableView() + XCTAssertEqual(tableView.contentOffset, .zero) + let refreshControl = UIRefreshControl() + tableView.addSubview(refreshControl) + refreshControl.beginRefreshing(in: tableView, animated: true) + + XCTAssertTrue(refreshControl.isRefreshing) + XCTAssertEqual(tableView.contentOffset.y, -refreshControl.frame.height) + + if #available(iOS 10.0, *) { + let anotherTableview = UITableView() + XCTAssertEqual(anotherTableview.contentOffset, .zero) + anotherTableview.refreshControl = UIRefreshControl() + anotherTableview.refreshControl?.beginRefreshing(in: anotherTableview, animated: true, sendAction: true) + + XCTAssertTrue(anotherTableview.refreshControl!.isRefreshing) + XCTAssertEqual(anotherTableview.contentOffset.y, -anotherTableview.refreshControl!.frame.height) + } + } + +} + +#endif From 58be3ee57c3b73d358603991d7092bca11ae9598 Mon Sep 17 00:00:00 2001 From: happiehappie Date: Sun, 12 Aug 2018 00:40:44 +0800 Subject: [PATCH 191/201] Add method for first char uppercased in String (#505) * Add method that returns a string with first character uppercased * update Changelog * Added comments * Update spacing for consistency * Update changelog # * Added unit test * Complied to Danger/Swiftlint for whitespace, update return parameter to be non-optional * Update comment example * Update test case and return value * Update test case * update extension var to be a method --- CHANGELOG.md | 2 ++ .../Extensions/SwiftStdlib/StringExtensions.swift | 12 +++++++++++- .../SwiftStdlibTests/StringExtensionsTests.swift | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eafbde5d..ac79d939a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Added `removeFromView()` method to remove recognizer from the view the recognizer is attached to. [#456](https://github.com/SwifterSwift/SwifterSwift/pull/456) by [mmdock](https://github.com/mmdock) - **Character**: - Added `randomAlphanumeric()` method to generate a random alphanumeric Character. [#462](https://github.com/SwifterSwift/SwifterSwift/pull/462) by [oliviabrown9](https://github.com/oliviabrown9) +- **String**: + - Added `firstCharacterUppercased()` method to return a string with only the first character uppercased. [#505](https://github.com/SwifterSwift/SwifterSwift/pull/505) by [happiehappie](https://github.com/happiehappie) - **UITextView**: - Added `wrapToContent()` method which will remove insets, offsets, paddings which lies within UITextView's `bounds` and `contenSize`. [#458](https://github.com/SwifterSwift/SwifterSwift/pull/458) by [ratulSharker](https://github.com/ratulSharker) - **URL** diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 845af6ba7..769b52744 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -105,7 +105,7 @@ public extension String { return String(first) } - #if canImport(Foundation) + #if canImport(Foundation) /// SwifterSwift: Check if string contains one or more letters. /// /// "123abc".hasLetters -> true @@ -637,6 +637,16 @@ public extension String { self = first + rest } + /// SwifterSwift: First character of string uppercased(if applicable) while keeping the original string. + /// + /// "hello world".firstCharacterUppercased() -> "Hello world" + /// "".firstCharacterUppercased() -> "" + /// + public mutating func firstCharacterUppercased() { + guard let first = first else { return } + self = String(first).uppercased() + dropFirst() + } + /// SwifterSwift: Check if string contains only unique characters. /// public func hasUniqueCharacters() -> Bool { diff --git a/Tests/SwiftStdlibTests/StringExtensionsTests.swift b/Tests/SwiftStdlibTests/StringExtensionsTests.swift index a856bce1f..566c49266 100644 --- a/Tests/SwiftStdlibTests/StringExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/StringExtensionsTests.swift @@ -353,6 +353,21 @@ final class StringExtensionsTests: XCTestCase { XCTAssertEqual(str, "helloworld") } + func testFirstCharacterUppercased() { + var str = "hello test" + str.firstCharacterUppercased() + XCTAssertEqual(str, "Hello test") + + str = "helloworld" + str.firstCharacterUppercased() + XCTAssertEqual(str, "Helloworld") + + str = "" + str.firstCharacterUppercased() + XCTAssertEqual(str, "") + + } + func testHasUniqueCharacters() { XCTAssert("swift".hasUniqueCharacters()) XCTAssertFalse("language".hasUniqueCharacters()) From b0e512a09451d1f3c40232a8c1370505fc9886f6 Mon Sep 17 00:00:00 2001 From: Victor Telitsyn <8170445+viktart@users.noreply.github.com> Date: Sat, 11 Aug 2018 21:39:54 +0300 Subject: [PATCH 192/201] Added '?=' Optional operator (ConditionalAssignment) to assign to 'nil' optionals only (#538) --- CHANGELOG.md | 2 ++ .../SwiftStdlib/OptionalExtensions.swift | 17 +++++++++++++++++ .../OptionalExtensionsTests.swift | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac79d939a..0287c770c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Added `insetBy(top:)`, `insetBy(left:)`, `insetBy(bottom:)`, `insetBy(right:)`, `insetBy(horizontal:)` and `insetBy(vertical:)` to creates an `UIEdgeInsets` based on current value and adjusted by given offset. [#532](https://github.com/SwifterSwift/SwifterSwift/pull/532) by [VincentSit](https://github.com/VincentSit). - **RangeReplaceableCollection** - `init(expression:count:)` to create a collection of a given count initialized with an expression.[#537](https://github.com/SwifterSwift/SwifterSwift/pull/537) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **Optional**: + - Added `?=` operator to assign to nil optionals only. ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift index 3ed386197..ea9e139ea 100644 --- a/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/OptionalExtensions.swift @@ -74,6 +74,22 @@ public extension Optional { lhs = rhs } + /// SwifterSwift: Assign an optional value to a variable only if the variable is nil. + /// + /// var someText: String? = nil + /// let newText = "Foo" + /// let defaultText = "Bar" + /// someText ?= newText //someText is now "Foo" because it was nil before + /// someText ?= defaultText //someText doesn't change its value because it's not nil + /// + /// - Parameters: + /// - lhs: Any? + /// - rhs: Any? + public static func ?= (lhs: inout Optional, rhs: @autoclosure () -> Optional) { + if lhs == nil { + lhs = rhs() + } + } } // MARK: - Methods (Collection) @@ -89,3 +105,4 @@ public extension Optional where Wrapped: Collection { // MARK: - Operators infix operator ??= : AssignmentPrecedence +infix operator ?= : AssignmentPrecedence diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index c783148f8..235b19259 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -63,6 +63,24 @@ final class OptionalExtensionsTests: XCTestCase { XCTAssert(parameters[key2] == parameter2) } + func testConditionalAssignment() { + var text1: String? + text1 ?= "newText1" + XCTAssertEqual(text1, "newText1") + + var text2: String? = "text2" + text2 ?= "newText2" + XCTAssertEqual(text2, "text2") + + var text3: String? + text3 ?= nil + XCTAssertEqual(text3, nil) + + var text4: String? = "text4" + text4 ?= nil + XCTAssertEqual(text4, "text4") + } + func testIsNilOrEmpty() { let nilArray: [String]? = nil XCTAssertTrue(nilArray.isNilOrEmpty) From 115e4a0ba125cfe9ee03b05e1f131acb062a7e1b Mon Sep 17 00:00:00 2001 From: Victor Telitsyn <8170445+viktart@users.noreply.github.com> Date: Sun, 12 Aug 2018 05:50:13 +0300 Subject: [PATCH 193/201] Performance imporvement in UIView fillToSuperview() (#540) --- CHANGELOG.md | 2 ++ Sources/Extensions/UIKit/UIViewExtensions.swift | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0287c770c..4d9331062 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `removeFirst(where:)` array extension now is more generic `RangeReplaceableCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **RandomAccessCollection**: - `indices(of:)` array extension now is more generic `RandomAccessCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). +- **UIView**: + - `fillToSuperview()` should be more performant. ### Fixed - **UIImage**: diff --git a/Sources/Extensions/UIKit/UIViewExtensions.swift b/Sources/Extensions/UIKit/UIViewExtensions.swift index a2c982c98..e82ace25c 100755 --- a/Sources/Extensions/UIKit/UIViewExtensions.swift +++ b/Sources/Extensions/UIKit/UIViewExtensions.swift @@ -457,10 +457,11 @@ public extension UIView { // https://videos.letsbuildthatapp.com/ translatesAutoresizingMaskIntoConstraints = false if let superview = superview { - leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true - rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true - topAnchor.constraint(equalTo: superview.topAnchor).isActive = true - bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true + let left = leftAnchor.constraint(equalTo: superview.leftAnchor) + let right = rightAnchor.constraint(equalTo: superview.rightAnchor) + let top = topAnchor.constraint(equalTo: superview.topAnchor) + let bottom = bottomAnchor.constraint(equalTo: superview.bottomAnchor) + NSLayoutConstraint.activate([left, right, top, bottom]) } } From 0a7e9652de52624e86a1d1a566d1c978f88a0af0 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 12 Aug 2018 00:38:42 -0300 Subject: [PATCH 194/201] Fixing changelog entries. (#541) --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d9331062..74cb375e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **RangeReplaceableCollection** - `init(expression:count:)` to create a collection of a given count initialized with an expression.[#537](https://github.com/SwifterSwift/SwifterSwift/pull/537) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **Optional**: - - Added `?=` operator to assign to nil optionals only. + - Added `?=` operator to assign to nil optionals only. [#538](https://github.com/SwifterSwift/SwifterSwift/pull/538) by [viktart](https://github.com/viktart) ### Changed - **RangeReplaceableCollection**: @@ -30,7 +30,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **RandomAccessCollection**: - `indices(of:)` array extension now is more generic `RandomAccessCollection` extensions. [#516](https://github.com/SwifterSwift/SwifterSwift/pull/516) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **UIView**: - - `fillToSuperview()` should be more performant. + - Improved performance in `fillToSuperview()` UIView extension. [#540](https://github.com/SwifterSwift/SwifterSwift/pull/540) by [viktart](https://github.com/viktart) ### Fixed - **UIImage**: From ab408668763b78554a7c7bc5e9c7171ba9261c01 Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Sun, 12 Aug 2018 17:13:01 +0200 Subject: [PATCH 195/201] Fix SwiftLint warnings (#543) --- Sources/Extensions/UIKit/UICollectionViewExtensions.swift | 2 +- Sources/Extensions/UIKit/UITableViewExtensions.swift | 2 +- Tests/SwiftStdlibTests/OptionalExtensionsTests.swift | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift index 562cc16b0..c534383b1 100644 --- a/Sources/Extensions/UIKit/UICollectionViewExtensions.swift +++ b/Sources/Extensions/UIKit/UICollectionViewExtensions.swift @@ -139,7 +139,7 @@ public extension UICollectionView { /// - bundleClass: Class in which the Bundle instance will be based on. public func register(nibWithCellClass name: T.Type, at bundleClass: AnyClass? = nil) { let identifier = String(describing: name) - var bundle: Bundle? = nil + var bundle: Bundle? if let bundleName = bundleClass { bundle = Bundle(for: bundleName) diff --git a/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Sources/Extensions/UIKit/UITableViewExtensions.swift index bff1d6d1f..5af08fcdf 100644 --- a/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -164,7 +164,7 @@ public extension UITableView { /// - bundleClass: Class in which the Bundle instance will be based on. public func register(nibWithCellClass name: T.Type, at bundleClass: AnyClass? = nil) { let identifier = String(describing: name) - var bundle: Bundle? = nil + var bundle: Bundle? if let bundleName = bundleClass { bundle = Bundle(for: bundleName) diff --git a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift index 235b19259..f95f3a435 100644 --- a/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/OptionalExtensionsTests.swift @@ -16,7 +16,7 @@ private enum OptionalTestError: Error { final class OptionalExtensionsTests: XCTestCase { func testUnwrappedOrDefault() { - var str: String? = nil + var str: String? XCTAssertEqual(str.unwrapped(or: "swift"), "swift") str = "swifterswift" @@ -32,7 +32,7 @@ final class OptionalExtensionsTests: XCTestCase { } func testRunBlock() { - var str: String? = nil + var str: String? var didRun = false str.run { _ in didRun = true From 890f0d5a21cf4eaa5413eb3cf40cd39e5a1d1d08 Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Mon, 13 Aug 2018 01:14:23 +0200 Subject: [PATCH 196/201] Data extension for converting to a JSON object (#542) --- CHANGELOG.md | 2 ++ .../Foundation/DataExtensions.swift | 11 ++++++++++ .../FoundationTests/DataExtensionsTests.swift | 20 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74cb375e4..463abb9db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `init(expression:count:)` to create a collection of a given count initialized with an expression.[#537](https://github.com/SwifterSwift/SwifterSwift/pull/537) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). - **Optional**: - Added `?=` operator to assign to nil optionals only. [#538](https://github.com/SwifterSwift/SwifterSwift/pull/538) by [viktart](https://github.com/viktart) +- **Data**: + - Added `jsonObject(options:)` to convert a data object into a JSON object. [#542](https://github.com/SwifterSwift/SwifterSwift/pull/542) by [guykogus](https://github.com/guykogus) ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/Foundation/DataExtensions.swift b/Sources/Extensions/Foundation/DataExtensions.swift index 40968e53d..c745ae1c6 100644 --- a/Sources/Extensions/Foundation/DataExtensions.swift +++ b/Sources/Extensions/Foundation/DataExtensions.swift @@ -31,5 +31,16 @@ public extension Data { return String(data: self, encoding: encoding) } + /// SwifterSwift: Returns a Foundation object from given JSON data. + /// + /// - Parameter options: Options for reading the JSON data and creating the Foundation object. + /// + /// For possible values, see `JSONSerialization.ReadingOptions`. + /// - Returns: A Foundation object from the JSON data in the receiver, or `nil` if an error occurs. + /// - Throws: An `NSError` if the receiver does not represent a valid JSON object. + public func jsonObject(options: JSONSerialization.ReadingOptions = []) throws -> Any { + return try JSONSerialization.jsonObject(with: self, options: options) + } + } #endif diff --git a/Tests/FoundationTests/DataExtensionsTests.swift b/Tests/FoundationTests/DataExtensionsTests.swift index fdd047958..877a6359e 100644 --- a/Tests/FoundationTests/DataExtensionsTests.swift +++ b/Tests/FoundationTests/DataExtensionsTests.swift @@ -25,4 +25,24 @@ final class DataExtensionsTests: XCTestCase { XCTAssertEqual(bytes?.count, 5) } + func testJsonObject() { + let invalidData = "hello".data(using: .utf8) + XCTAssertThrowsError(try invalidData?.jsonObject()) + XCTAssertThrowsError(try invalidData?.jsonObject(options: [.allowFragments])) + + let stringData = "\"hello\"".data(using: .utf8) + XCTAssertThrowsError(try stringData?.jsonObject()) + XCTAssertEqual((try? stringData?.jsonObject(options: [.allowFragments])) as? String, "hello") + + let objectData = "{\"message\": \"hello\"}".data(using: .utf8) + let object = (try? objectData?.jsonObject()) as? [String: String] + XCTAssertNotNil(object) + XCTAssertEqual(object?["message"], "hello") + + let arrayData = "[\"hello\"]".data(using: .utf8) + let array = (try? arrayData?.jsonObject()) as? [String] + XCTAssertNotNil(array) + XCTAssertEqual(array?.first, "hello") + } + } From eb9b297c7ce3c3cf8660479f43ef315aaed5b7b6 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 13 Aug 2018 00:33:37 +0100 Subject: [PATCH 197/201] Adds new method on URL called droppedScheme (#528) * Adds new method on URL called droppedScheme Resolves: #464 --- CHANGELOG.md | 3 +++ .../Extensions/Foundation/URLExtensions.swift | 15 ++++++++++++++ .../FoundationTests/URLExtensionsTests.swift | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 463abb9db..d7ebd5b12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **Data**: - Added `jsonObject(options:)` to convert a data object into a JSON object. [#542](https://github.com/SwifterSwift/SwifterSwift/pull/542) by [guykogus](https://github.com/guykogus) +- **URL** + - Added `droppedScheme()` which returns new `URL` that does not have scheme. [#528](https://github.com/SwifterSwift/SwifterSwift/pull/528) by [sammy-sc](https://github.com/sammy-SC) + ### Changed - **RangeReplaceableCollection**: - `rotate(by:)` and `rotated(by:)` array extensions now are more generic `RangeReplaceableCollection` extensions. [#512](https://github.com/SwifterSwift/SwifterSwift/pull/512) by [LucianoPAlmeida](https://github.com/LucianoPAlmeida). diff --git a/Sources/Extensions/Foundation/URLExtensions.swift b/Sources/Extensions/Foundation/URLExtensions.swift index 497340181..ced990383 100644 --- a/Sources/Extensions/Foundation/URLExtensions.swift +++ b/Sources/Extensions/Foundation/URLExtensions.swift @@ -102,6 +102,21 @@ public extension URL { } } + /// SwifterSwift: Generates new URL that does not have scheme. + /// + /// let url = URL(string: "https://domain.com")! + /// print(url.droppedScheme()) // prints "domain.com" + public func droppedScheme() -> URL? { + if let scheme = self.scheme { + let droppedScheme = String(self.absoluteString.dropFirst(scheme.count + 3)) + return URL(string: droppedScheme) + } + + guard host != nil else { return self } + + let droppedScheme = String(absoluteString.dropFirst(2)) + return URL(string: droppedScheme) + } } // MARK: - Methods diff --git a/Tests/FoundationTests/URLExtensionsTests.swift b/Tests/FoundationTests/URLExtensionsTests.swift index eab900393..4e96bdfb9 100644 --- a/Tests/FoundationTests/URLExtensionsTests.swift +++ b/Tests/FoundationTests/URLExtensionsTests.swift @@ -71,4 +71,24 @@ final class URLExtensionsTests: XCTestCase { } #endif + func testDropScheme() { + let urls: [String: String?] = [ + "https://domain.com/path/other/": "domain.com/path/other/", + "https://domain.com": "domain.com", + "http://domain.com": "domain.com", + "file://domain.com/image.jpeg": "domain.com/image.jpeg", + "://apple.com": "apple.com", + "//apple.com": "apple.com", + "apple.com": "apple.com", + "http://": nil, + "//": "//" + ] + + urls.forEach { input, expected in + guard let url = URL(string: input) else { return XCTFail("Failed to initialize URL.") } + XCTAssertEqual(url.droppedScheme()?.absoluteString, + expected, + "input url: \(input)") + } + } } From d511e6f0a02a416cdc557e672ef1168429d18a98 Mon Sep 17 00:00:00 2001 From: moyerr Date: Mon, 13 Aug 2018 10:45:21 -0400 Subject: [PATCH 198/201] CGVector Extensions (#527) * Added CGVectorExtensions * Unit tests for CGVector extensions * Tweaked documentation * Updated Changelog for CGVector Extensions * Addressed SwiftLint issues * Added canImport(CoreGraphics), added file to proper targets * Addressed requested changes in PR * Disable SwiftLint shorthand_operator rule in implementation of the vector-scalar compound op * Fixed SwiftLint issues * Addressed comments --- CHANGELOG.md | 6 + .../CoreGraphics/CGVectorExtensions.swift | 103 ++++++++++++++++++ SwifterSwift.xcodeproj/project.pbxproj | 18 +++ .../CGVectorExtensionsTests.swift | 93 ++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 Sources/Extensions/CoreGraphics/CGVectorExtensions.swift create mode 100644 Tests/CoreGraphicsTests/CGVectorExtensionsTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ebd5b12..804976580 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S # Upcoming release ### Added +- **CGVector** + - Added `angle` computed property to get the angle of the vector (in radians). [#527](https://github.com/SwifterSwift/SwifterSwift/pull/527) by [moyerr](https://github.com/moyerr) + - Added `magnitude` computed property to get the magnitude (or length) of the vector. [#527](https://github.com/SwifterSwift/SwifterSwift/pull/527) by [moyerr](https://github.com/moyerr) + - Added scalar multiplication of CGFloat and CGVector via standard multiplication operator (\*). [#527](https://github.com/SwifterSwift/SwifterSwift/pull/527) by [moyerr](https://github.com/moyerr) + - Added negation of vectors via prefix (-) operator. [#527](https://github.com/SwifterSwift/SwifterSwift/pull/527) by [moyerr](https://github.com/moyerr) + - Added `init(angle:magnitude:)` to create vectors based on their angle and magnitude. [#527](https://github.com/SwifterSwift/SwifterSwift/pull/527) by [moyerr](https://github.com/moyerr) -**UIRefreshControl**: - `beginRefresh(in tableView:, animated:, sendAction:)` UIRefreshControl extension to begin refresh programatically. [#525](https://github.com/SwifterSwift/SwifterSwift/pull/525) by [ratulSharker](https://github.com/ratulSharker) - **Dictionary**: diff --git a/Sources/Extensions/CoreGraphics/CGVectorExtensions.swift b/Sources/Extensions/CoreGraphics/CGVectorExtensions.swift new file mode 100644 index 000000000..5760783da --- /dev/null +++ b/Sources/Extensions/CoreGraphics/CGVectorExtensions.swift @@ -0,0 +1,103 @@ +// +// CGVectorExtensions.swift +// SwifterSwift +// +// Created by Robbie Moyer on 7/25/18. +// Copyright © 2018 SwifterSwift +// + +#if canImport(CoreGraphics) +import CoreGraphics + +// MARK: - Properties +public extension CGVector { + + /// SwifterSwift: The angle of rotation (in radians) of the vector. + /// The range of the angle is -π to π; an angle of 0 points to the right. + /// + /// https://en.wikipedia.org/wiki/Atan2 + public var angle: CGFloat { + return atan2(dy, dx) + } + + /// SwifterSwift: The magnitude (or length) of the vector. + /// + /// https://en.wikipedia.org/wiki/Euclidean_vector#Length + public var magnitude: CGFloat { + return sqrt((dx * dx) + (dy * dy)) + } +} + +// MARK: - Initializers +public extension CGVector { + + /// SwifterSwift: Creates a vector with the given magnitude and angle. + /// + /// https://www.grc.nasa.gov/WWW/K-12/airplane/vectpart.html + /// + /// let vector = CGVector(angle: .pi, magnitude: 1) + /// + /// - Parameters: + /// - angle: The angle of rotation (in radians) counterclockwise from the positive x-axis. + /// - magnitude: The lenth of the vector. + /// + public init(angle: CGFloat, magnitude: CGFloat) { + self.init(dx: magnitude * cos(angle), dy: magnitude * sin(angle)) + } +} + +// MARK: - Operators +public extension CGVector { + + /// SwifterSwift: Multiplies a scalar and a vector (commutative). + /// + /// let vector = CGVector(dx: 1, dy: 1) + /// let largerVector = vector * 2 + /// + /// - Parameters: + /// - vector: The vector to be multiplied + /// - scalar: The scale by which the vector will be multiplied + /// - Returns: The vector with its magnitude scaled + public static func * (vector: CGVector, scalar: CGFloat) -> CGVector { + return CGVector(dx: vector.dx * scalar, dy: vector.dy * scalar) + } + + /// SwifterSwift: Multiplies a scalar and a vector (commutative). + /// + /// let vector = CGVector(dx: 1, dy: 1) + /// let largerVector = 2 * vector + /// + /// - Parameters: + /// - scalar: The scalar by which the vector will be multiplied + /// - vector: The vector to be multiplied + /// - Returns: The vector with its magnitude scaled + public static func * (scalar: CGFloat, vector: CGVector) -> CGVector { + return CGVector(dx: scalar * vector.dx, dy: scalar * vector.dy) + } + + /// SwifterSwift: Compound assignment operator for vector-scalr multiplication + /// + /// var vector = CGVector(dx: 1, dy: 1) + /// vector *= 2 + /// + /// - Parameters: + /// - vector: The vector to be multiplied + /// - scalar: The scale by which the vector will be multiplied + public static func *= (vector: inout CGVector, scalar: CGFloat) { + // swiftlint:disable next shorthand_operator + vector = vector * scalar + } + + /// SwifterSwift: Negates the vector. The direction is reversed, but magnitude + /// remains the same. + /// + /// let vector = CGVector(dx: 1, dy: 1) + /// let reversedVector = -vector + /// + /// - Parameter vector: The vector to be negated + /// - Returns: The negated vector + public static prefix func - (vector: CGVector) -> CGVector { + return CGVector(dx: -vector.dx, dy: -vector.dy) + } +} +#endif diff --git a/SwifterSwift.xcodeproj/project.pbxproj b/SwifterSwift.xcodeproj/project.pbxproj index dcc498b14..a0681a678 100644 --- a/SwifterSwift.xcodeproj/project.pbxproj +++ b/SwifterSwift.xcodeproj/project.pbxproj @@ -355,6 +355,13 @@ 70269A301FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A311FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; 70269A321FB47B0C00C6C2D0 /* CalendarExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */; }; + 734307F82108C2240029CD16 /* CGVectorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F72108C2240029CD16 /* CGVectorExtensions.swift */; }; + 734307FB2108C85B0029CD16 /* CGVectorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F92108C7F80029CD16 /* CGVectorExtensionsTests.swift */; }; + 734307FD2108C85D0029CD16 /* CGVectorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F92108C7F80029CD16 /* CGVectorExtensionsTests.swift */; }; + 734307FE2108C85E0029CD16 /* CGVectorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F92108C7F80029CD16 /* CGVectorExtensionsTests.swift */; }; + 734308082108E4630029CD16 /* CGVectorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F72108C2240029CD16 /* CGVectorExtensions.swift */; }; + 734308092108E4640029CD16 /* CGVectorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F72108C2240029CD16 /* CGVectorExtensions.swift */; }; + 7343080A2108E4650029CD16 /* CGVectorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734307F72108C2240029CD16 /* CGVectorExtensions.swift */; }; 752AC7A020BC975E00659E76 /* SKNodeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */; }; 752AC7A520BC9FF500659E76 /* SpriteKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */; }; 752AC7A620BCA04100659E76 /* SpriteKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */; }; @@ -582,6 +589,8 @@ 42F53FEF2039C7140070DC11 /* UIStackViewExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensionsTest.swift; sourceTree = ""; }; 70269A2A1FB478D100C6C2D0 /* CalendarExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensions.swift; sourceTree = ""; }; 70269A2F1FB47B0C00C6C2D0 /* CalendarExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarExtensionTest.swift; sourceTree = ""; }; + 734307F72108C2240029CD16 /* CGVectorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGVectorExtensions.swift; sourceTree = ""; }; + 734307F92108C7F80029CD16 /* CGVectorExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGVectorExtensionsTests.swift; sourceTree = ""; }; 752AC79F20BC975E00659E76 /* SKNodeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKNodeExtensions.swift; sourceTree = ""; }; 752AC7A420BC9FF500659E76 /* SpriteKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteKitTests.swift; sourceTree = ""; }; 7832C2AE209BB19300224EED /* ComparableExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparableExtensions.swift; sourceTree = ""; }; @@ -966,6 +975,7 @@ 07B7F15E1F5EB41600E6F910 /* CGFloatExtensions.swift */, 07B7F15F1F5EB41600E6F910 /* CGPointExtensions.swift */, 07B7F1601F5EB41600E6F910 /* CGSizeExtensions.swift */, + 734307F72108C2240029CD16 /* CGVectorExtensions.swift */, ); path = CoreGraphics; sourceTree = ""; @@ -977,6 +987,7 @@ 07C50D261F5EB03200F46E5A /* CGPointExtensionsTests.swift */, 07C50D271F5EB03200F46E5A /* CGSizeExtensionsTests.swift */, 185BDE601F8AAEFD00140E19 /* CGColorExtensionsTests.swift */, + 734307F92108C7F80029CD16 /* CGVectorExtensionsTests.swift */, ); path = CoreGraphicsTests; sourceTree = ""; @@ -1485,6 +1496,7 @@ B29527AD20F99E9700E1F75D /* RandomAccessCollectionExtensions.swift in Sources */, 0713066F1FB597920023A9D8 /* FoundationDeprecated.swift in Sources */, 07B7F1971F5EB42000E6F910 /* UIImageExtensions.swift in Sources */, + 734307F82108C2240029CD16 /* CGVectorExtensions.swift in Sources */, B22EB2B720E9E720001EAE70 /* RangeReplaceableCollectionExtensions.swift in Sources */, 077BA08A1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 9D4914831F85138E00F3868F /* NSPredicateExtensions.swift in Sources */, @@ -1550,6 +1562,7 @@ 07B7F1B51F5EB42000E6F910 /* UISliderExtensions.swift in Sources */, 07B7F1A91F5EB42000E6F910 /* UIBarButtonItemExtensions.swift in Sources */, 07B7F1B81F5EB42000E6F910 /* UITabBarExtensions.swift in Sources */, + 734308082108E4630029CD16 /* CGVectorExtensions.swift in Sources */, 078CE2A0207643F8001720DF /* UIKitDeprecated.swift in Sources */, 07B7F1BC1F5EB42000E6F910 /* UIViewControllerExtensions.swift in Sources */, 07B7F2371F5EB45200E6F910 /* CGSizeExtensions.swift in Sources */, @@ -1601,6 +1614,7 @@ 07B7F1F11F5EB43B00E6F910 /* IntExtensions.swift in Sources */, 07B7F1ED1F5EB43B00E6F910 /* DictionaryExtensions.swift in Sources */, 07B7F22A1F5EB45100E6F910 /* CGPointExtensions.swift in Sources */, + 734308092108E4640029CD16 /* CGVectorExtensions.swift in Sources */, 07B7F1C11F5EB42200E6F910 /* UICollectionViewExtensions.swift in Sources */, 07B7F1CF1F5EB42200E6F910 /* UITableViewExtensions.swift in Sources */, 077BA0911F6BE83600D9C4AC /* UserDefaultsExtensions.swift in Sources */, @@ -1671,6 +1685,7 @@ 077BA08D1F6BE81F00D9C4AC /* URLRequestExtensions.swift in Sources */, 18C8E5E12074C60C00F8AF51 /* SequenceExtensions.swift in Sources */, 784C75302051BD4A001C48DD /* MKPolylineExtensions.swift in Sources */, + 7343080A2108E4650029CD16 /* CGVectorExtensions.swift in Sources */, 07B7F1E31F5EB43B00E6F910 /* SignedNumericExtensions.swift in Sources */, 07B7F2241F5EB44600E6F910 /* CLLocationExtensions.swift in Sources */, 1875A8FA20BDE50D00A6D258 /* SKNodeExtensions.swift in Sources */, @@ -1755,6 +1770,7 @@ 07C50D3F1F5EB04700F46E5A /* UIViewControllerExtensionsTests.swift in Sources */, 07C50D3D1F5EB04700F46E5A /* UITextFieldExtensionsTests.swift in Sources */, 07C50D641F5EB05000F46E5A /* URLExtensionsTests.swift in Sources */, + 734307FB2108C85B0029CD16 /* CGVectorExtensionsTests.swift in Sources */, 07C50D2B1F5EB04600F46E5A /* UIAlertControllerExtensionsTests.swift in Sources */, 07C50D5E1F5EB05000F46E5A /* DoubleExtensionsTests.swift in Sources */, 86B3F7AE208D3DF300BC297B /* UIScrollViewExtensionsTest.swift in Sources */, @@ -1803,6 +1819,7 @@ 07C50D661F5EB05100F46E5A /* BoolExtensionsTests.swift in Sources */, 07FE50461F891C95000766AA /* SignedNumericExtensionsTests.swift in Sources */, 07C50D4F1F5EB04700F46E5A /* UIStoryboardExtensionsTests.swift in Sources */, + 734307FD2108C85D0029CD16 /* CGVectorExtensionsTests.swift in Sources */, 9D9784E51FCAE6DD00D988E7 /* StringProtocolExtensionsTests.swift in Sources */, 07C50D4C1F5EB04700F46E5A /* UISearchBarExtensionsTests.swift in Sources */, 07C50D871F5EB06000F46E5A /* CGFloatExtensionsTests.swift in Sources */, @@ -1840,6 +1857,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 734307FE2108C85E0029CD16 /* CGVectorExtensionsTests.swift in Sources */, 9D49148B1F8515D100F3868F /* NSPredicateExtensionsTests.swift in Sources */, 07C50D731F5EB05100F46E5A /* ArrayExtensionsTests.swift in Sources */, 07D8960B1F5EC80800FC894D /* SwifterSwiftTests.swift in Sources */, diff --git a/Tests/CoreGraphicsTests/CGVectorExtensionsTests.swift b/Tests/CoreGraphicsTests/CGVectorExtensionsTests.swift new file mode 100644 index 000000000..8b6df4a6f --- /dev/null +++ b/Tests/CoreGraphicsTests/CGVectorExtensionsTests.swift @@ -0,0 +1,93 @@ +// +// CGVectorExtensionsTests.swift +// SwifterSwift +// +// Created by Robbie Moyer on 7/25/18. +// Copyright © 2018 SwifterSwift +// + +import XCTest +@testable import SwifterSwift + +final class CGVectorExtensionsTests: XCTestCase { + + func testAngle() { + let vector1 = CGVector(dx: 1, dy: 1) // pi/4 + let vector2 = CGVector(dx: 1, dy: 0) // 0 + let vector3 = CGVector(dx: 0, dy: 1) // pi/2 + let vector4 = CGVector(dx: -1, dy: 0) // pi + let vector5 = CGVector(dx: 0, dy: -1) // -pi/2 + let vector6 = CGVector(dx: -1, dy: -1) // -3pi/4 + let vector7 = CGVector(dx: 1, dy: -1) // -pi/4 + let vector8 = CGVector(dx: -1, dy: 1) // 3pi/4 + + XCTAssertEqual(vector1.angle, .pi/4) + XCTAssertEqual(vector2.angle, 0) + XCTAssertEqual(vector3.angle, .pi/2) + XCTAssertEqual(vector4.angle, .pi) + XCTAssertEqual(vector5.angle, -(.pi/2)) + XCTAssertEqual(vector6.angle, -(3 * .pi/4)) + XCTAssertEqual(vector7.angle, -(.pi/4)) + XCTAssertEqual(vector8.angle, 3 * .pi/4) + } + + func testMagnitude() { + let vector1 = CGVector(dx: 3, dy: 4) + let vector2 = CGVector(dx: 1, dy: 1) + let vector3 = CGVector(dx: 20, dy: 0) + let vector4 = CGVector(dx: 5, dy: 12) + let vector5 = CGVector(dx: 8, dy: 15) + + XCTAssertEqual(vector1.magnitude, 5) + XCTAssertEqual(vector2.magnitude, sqrt(2)) + XCTAssertEqual(vector3.magnitude, 20) + XCTAssertEqual(vector4.magnitude, 13) + XCTAssertEqual(vector5.magnitude, 17) + } + + func testScalarMultiplication() { + let vector = CGVector(dx: 3, dy: 4) + + XCTAssertEqual(2 * vector, vector * 2) + XCTAssertEqual(0 * vector, .zero) + XCTAssertEqual(1 * vector, vector) + XCTAssertEqual(-1 * vector, CGVector(dx: -3, dy: -4)) + XCTAssertEqual(3 * vector, CGVector(dx: 9, dy: 12)) + + var mutableVector = CGVector(dx: 3, dy: 4) + + XCTAssertEqual(vector, mutableVector) + + mutableVector *= 5 + + XCTAssertEqual(mutableVector, CGVector(dx: 15, dy: 20)) + XCTAssertEqual(mutableVector, vector * 5) + } + + func testNegation() { + let vector = CGVector(dx: 3, dy: -4) + + XCTAssertEqual(-vector, CGVector(dx: -3, dy: 4)) + } + + func testInitWithAngleAndMagnitude() { + let vector1 = CGVector(angle: .pi/4, magnitude: sqrt(2)) + let vector2 = CGVector(angle: .pi, magnitude: 1) + let vector3 = CGVector(angle: .pi/6, magnitude: 2) + let vector4 = CGVector(angle: .pi/3, magnitude: 2) + + let cgFloatPrecision: CGFloat = 0.000000000000001 + + XCTAssertEqual(vector1.dx, 1, accuracy: cgFloatPrecision) + XCTAssertEqual(vector1.dy, 1, accuracy: cgFloatPrecision) + + XCTAssertEqual(vector2.dx, -1, accuracy: cgFloatPrecision) + XCTAssertEqual(vector2.dy, 0, accuracy: cgFloatPrecision) + + XCTAssertEqual(vector3.dx, sqrt(3), accuracy: cgFloatPrecision) + XCTAssertEqual(vector3.dy, 1, accuracy: cgFloatPrecision) + + XCTAssertEqual(vector4.dx, 1, accuracy: cgFloatPrecision) + XCTAssertEqual(vector4.dy, sqrt(3), accuracy: cgFloatPrecision) + } +} From 6f2c9fb8b2eef056cbac047f9e2d8ddc5b1ccab7 Mon Sep 17 00:00:00 2001 From: kldaniel Date: Tue, 14 Aug 2018 13:47:00 +0200 Subject: [PATCH 199/201] Add operators for CGSize (#536) * Add CGSize operators * Unit tests for CGSize operators and update changelog * Fix trailing whitespace and invalid // MARK format * Modify CGSize operators ( +=, -=, *= ) to use in place mutation instead of creating a brand new CGSize struct. Fix indentation in changelog. --- CHANGELOG.md | 9 ++ .../CoreGraphics/CGSizeExtensions.swift | 137 ++++++++++++++++++ .../CGSizeExtensionsTests.swift | 69 +++++++++ 3 files changed, 215 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 804976580..d47f0902b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,15 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - **URL** - Added `droppedScheme()` which returns new `URL` that does not have scheme. [#528](https://github.com/SwifterSwift/SwifterSwift/pull/528) by [sammy-sc](https://github.com/sammy-SC) +- **CGSize** + - Added operator `+` to return the addition of two CGSize. + - Added operator `+=` to add a CGSize to another. + - Added operator `-` to return the subtraction of two CGSize. + - Added operator `-=` to subtract a CGSize from another. + - Added operator `CGSize * CGSize` to return the multiplication of two CGSize. + - Added operator `CGSize * CGFloat` and `CGFloat * CGSize` to return the multiplication of a CGSize and a CGFloat value. + - Added operator `CGSize *= CGSize` to multiply a CGSize with another one. + - Added operator `CGSize *= CGFloat` to multiply a CGSize with a CGFloat value. ### Changed - **RangeReplaceableCollection**: diff --git a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift index 2fb43f951..a452e9f0d 100644 --- a/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift +++ b/Sources/Extensions/CoreGraphics/CGSizeExtensions.swift @@ -50,5 +50,142 @@ public extension CGSize { return CGSize(width: aWidth, height: aHeight) } +} + +// MARK: - Operators +public extension CGSize { + + /// SwifterSwift: Add two CGSize + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// let result = sizeA + sizeB + /// //result = CGSize(width: 8, height: 14) + /// + /// - Parameters: + /// - lhs: CGSize to add to. + /// - rhs: CGSize to add. + /// - Returns: The result comes from the addition of the two given CGSize struct. + public static func + (lhs: CGSize, rhs: CGSize) -> CGSize { + return CGSize(width: lhs.width + rhs.width, height: lhs.height + rhs.height) + } + + /// SwifterSwift: Add a CGSize to self. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// sizeA += sizeB + /// //sizeA = CGPoint(width: 8, height: 14) + /// + /// - Parameters: + /// - lhs: self + /// - rhs: CGSize to add. + public static func += (lhs: inout CGSize, rhs: CGSize) { + lhs.width += rhs.width + lhs.height += rhs.height + } + + /// SwifterSwift: Subtract two CGSize + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// let result = sizeA - sizeB + /// //result = CGSize(width: 2, height: 6) + /// + /// - Parameters: + /// - lhs: CGSize to subtract from. + /// - rhs: CGSize to subtract. + /// - Returns: The result comes from the subtract of the two given CGSize struct. + public static func - (lhs: CGSize, rhs: CGSize) -> CGSize { + return CGSize(width: lhs.width - rhs.width, height: lhs.height - rhs.height) + } + + /// SwifterSwift: Subtract a CGSize from self. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// sizeA -= sizeB + /// //sizeA = CGPoint(width: 2, height: 6) + /// + /// - Parameters: + /// - lhs: self + /// - rhs: CGSize to subtract. + public static func -= (lhs: inout CGSize, rhs: CGSize) { + lhs.width -= rhs.width + lhs.height -= rhs.height + } + + /// SwifterSwift: Multiply two CGSize + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// let result = sizeA * sizeB + /// //result = CGSize(width: 15, height: 40) + /// + /// - Parameters: + /// - lhs: CGSize to multiply. + /// - rhs: CGSize to multiply with. + /// - Returns: The result comes from the multiplication of the two given CGSize structs. + public static func * (lhs: CGSize, rhs: CGSize) -> CGSize { + return CGSize(width: lhs.width * rhs.width, height: lhs.height * rhs.height) + } + + /// SwifterSwift: Multiply a CGSize with a scalar. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let result = sizeA * 5 + /// //result = CGSize(width: 25, height: 50) + /// + /// - Parameters: + /// - lhs: CGSize to multiply. + /// - scalar: scalar value. + /// - Returns: The result comes from the multiplication of the given CGSize and scalar. + public static func * (lhs: CGSize, scalar: CGFloat) -> CGSize { + return CGSize(width: lhs.width * scalar, height: lhs.height * scalar) + } + + /// SwifterSwift: Multiply a CGSize with a scalar. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let result = 5 * sizeA + /// //result = CGSize(width: 25, height: 50) + /// + /// - Parameters: + /// - scalar: scalar value. + /// - rhs: CGSize to multiply. + /// - Returns: The result comes from the multiplication of the given scalar and CGSize. + public static func * (scalar: CGFloat, rhs: CGSize) -> CGSize { + return CGSize(width: scalar * rhs.width, height: scalar * rhs.height) + } + + /// SwifterSwift: Multiply self with a CGSize. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// let sizeB = CGSize(width: 3, height: 4) + /// sizeA *= sizeB + /// //result = CGSize(width: 15, height: 40) + /// + /// - Parameters: + /// - lhs: self. + /// - rhs: CGSize to multiply. + public static func *= (lhs: inout CGSize, rhs: CGSize) { + lhs.width *= rhs.width + lhs.height *= rhs.height + } + + /// SwifterSwift: Multiply self with a scalar. + /// + /// let sizeA = CGSize(width: 5, height: 10) + /// sizeA *= 3 + /// //result = CGSize(width: 15, height: 30) + /// + /// - Parameters: + /// - lhs: self. + /// - scalar: scalar value. + public static func *= (lhs: inout CGSize, scalar: CGFloat) { + lhs.width *= scalar + lhs.height *= scalar + } + } #endif diff --git a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift index 8ff4561e9..6fed269be 100644 --- a/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift +++ b/Tests/CoreGraphicsTests/CGSizeExtensionsTests.swift @@ -27,4 +27,73 @@ final class CGSizeExtensionsTests: XCTestCase { XCTAssertEqual(newRect.height, 60) } + func testAdd() { + let sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + let result = sizeA + sizeB + XCTAssertEqual(result.width, 8) + XCTAssertEqual(result.height, 14) + } + + func testAddEqual() { + var sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + sizeA += sizeB + XCTAssertEqual(sizeA.width, 8) + XCTAssertEqual(sizeA.height, 14) + } + + func testSubtract() { + let sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + let result = sizeA - sizeB + XCTAssertEqual(result.width, 2) + XCTAssertEqual(result.height, 6) + } + + func testSubtractEqual() { + var sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + sizeA -= sizeB + XCTAssertEqual(sizeA.width, 2) + XCTAssertEqual(sizeA.height, 6) + } + + func testMultiplyCGSize() { + let sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + let result = sizeA * sizeB + XCTAssertEqual(result.width, 15) + XCTAssertEqual(result.height, 40) + } + + func testMultiplyScalarRight() { + let sizeA = CGSize(width: 5, height: 10) + let result = sizeA * 4 + XCTAssertEqual(result.width, 20) + XCTAssertEqual(result.height, 40) + } + + func testMultiplyScalarLeft() { + let sizeA = CGSize(width: 5, height: 10) + let result = 5 * sizeA + XCTAssertEqual(result.width, 25) + XCTAssertEqual(result.height, 50) + } + + func testMultiplyEqualCGSize() { + var sizeA = CGSize(width: 5, height: 10) + let sizeB = CGSize(width: 3, height: 4) + sizeA *= sizeB + XCTAssertEqual(sizeA.width, 15) + XCTAssertEqual(sizeA.height, 40) + } + + func testMultiplyEqualScalar() { + var sizeA = CGSize(width: 5, height: 0) + sizeA *= 4 + XCTAssertEqual(sizeA.width, 20) + XCTAssertEqual(sizeA.height, 0) + } + } From fb19497bd3972aff97d5560c6f99615bb08ac178 Mon Sep 17 00:00:00 2001 From: Omar Albeik Date: Wed, 15 Aug 2018 00:54:36 +0300 Subject: [PATCH 200/201] Fix unicodeArray (#544) --- CHANGELOG.md | 1 + Sources/Extensions/SwiftStdlib/StringExtensions.swift | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d47f0902b..089fae260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - Fixed `scaled(toWidth:, with orientation:)` and `scaled(toHeight:, with orientation:)` were using image's scale as the scale factor. [#515](https://github.com/SwifterSwift/SwifterSwift/pull/515) by [VincentSit](https://github.com/VincentSit). - **String**: - Used [RFC 5322](http://emailregex.com/) in `isValidEmail`, an email address regex that 99.99% works. [#517](https://github.com/SwifterSwift/SwifterSwift/pull/517) by [Omar Albeik](https://github.com/omaralbeik) + - Fixed `unicodeArray()` not returning the correct unicode value due to Swift 4.2 new hashing system. [#544](https://github.com/SwifterSwift/SwifterSwift/pull/544) by [Omar Albeik](https://github.com/omaralbeik) ### Deprecated - **String**: diff --git a/Sources/Extensions/SwiftStdlib/StringExtensions.swift b/Sources/Extensions/SwiftStdlib/StringExtensions.swift index 769b52744..8ac6b922e 100755 --- a/Sources/Extensions/SwiftStdlib/StringExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/StringExtensions.swift @@ -499,11 +499,11 @@ public extension String { /// SwifterSwift: Array with unicodes for all characters in a string. /// - /// "SwifterSwift".unicodeArray -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] + /// "SwifterSwift".unicodeArray() -> [83, 119, 105, 102, 116, 101, 114, 83, 119, 105, 102, 116] /// /// - Returns: The unicodes for all characters in a string. public func unicodeArray() -> [Int] { - return unicodeScalars.map { $0.hashValue } + return unicodeScalars.map { Int($0.value) } } #if canImport(Foundation) From 9eb6259faf6689a161825cc91cccec0c82edea8d Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Thu, 16 Aug 2018 08:47:30 +0200 Subject: [PATCH 201/201] Create mapping functions for Dictionary (#546) * Create `map` and `compactMap` functions for `Dictionary` that return a new `Dictionary`, rather than an `Array`. * Change method names to avoid clashing with the built in `map` and `compactMap` functions. --- CHANGELOG.md | 2 ++ .../SwiftStdlib/DictionaryExtensions.swift | 17 ++++++++++ .../DictionaryExtensionsTests.swift | 32 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 089fae260..962caa7a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S - `beginRefresh(in tableView:, animated:, sendAction:)` UIRefreshControl extension to begin refresh programatically. [#525](https://github.com/SwifterSwift/SwifterSwift/pull/525) by [ratulSharker](https://github.com/ratulSharker) - **Dictionary**: - Added `removeValueForRandomKey()` to remove a value for a random key from a dictionary. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax). + - Added `mapKeysAndValues(_:)` to map a `Dictionary` into a `Dictionary` with different (or same) `Key` and `Value` types. [#546](https://github.com/SwifterSwift/SwifterSwift/pull/546) by [guykogus](https://github.com/guykogus) + - Added `compactMapKeysAndValues(_:)` to map a `Dictionary` into a `Dictionary`, excluding `nil` results, with different (or same) `Key` and `Value` types. [#546](https://github.com/SwifterSwift/SwifterSwift/pull/546) by [guykogus](https://github.com/guykogus) - **RangeReplaceableCollection**: - Added `removeRandomElement()` to remove a random element from a collection. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax). - **UIView** diff --git a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift index 5d4a5fca0..2611f816b 100644 --- a/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift +++ b/Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift @@ -177,3 +177,20 @@ public extension Dictionary { } } + +extension Dictionary { + /// SwifterSwift: Returns a dictionary containing the results of mapping the given closure over the sequence’s elements. + /// - Parameter transform: A mapping closure. `transform` accepts an element of this sequence as its parameter and returns a transformed value of the same or of a different type. + /// - Returns: A dictionary containing the transformed elements of this sequence. + func mapKeysAndValues(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> [K: V] { + return [K: V](uniqueKeysWithValues: try map(transform)) + } + + /// SwifterSwift: Returns a dictionary containing the non-`nil` results of calling the given transformation with each element of this sequence. + /// - Parameter transform: A closure that accepts an element of this sequence as its argument and returns an optional value. + /// - Returns: A dictionary of the non-`nil` results of calling `transform` with each element of the sequence. + /// - Complexity: *O(m + n)*, where _m_ is the length of this sequence and _n_ is the length of the result. + func compactMapKeysAndValues(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> [K: V] { + return [K: V](uniqueKeysWithValues: try compactMap(transform)) + } +} diff --git a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift index 965a53558..7df5a5d4b 100644 --- a/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift +++ b/Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift @@ -102,4 +102,36 @@ final class DictionaryExtensionsTests: XCTestCase { XCTAssertFalse(dict.keys.contains("key2")) } + func testMapKeysAndValues() { + let intToString = [0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9"] + + let stringToInt: [String: Int] = intToString.mapKeysAndValues { (key, value) in + return (String(describing: key), Int(value)!) + } + + XCTAssertEqual(stringToInt, ["0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9]) + } + + func testCompactMapKeysAndValues() { + // swiftlint:disable:next nesting + enum IntWord: String { + case zero + case one + case two + } + + let strings = [ + 0: "zero", + 1: "one", + 2: "two", + 3: "three" + ] + let words: [String: IntWord] = strings.compactMapKeysAndValues { (key, value) in + guard let word = IntWord(rawValue: value) else { return nil } + return (String(describing: key), word) + } + + XCTAssertEqual(words, ["0": .zero, "1": .one, "2": .two]) + } + }