diff --git a/ACKategories.xcodeproj/project.pbxproj b/ACKategories.xcodeproj/project.pbxproj index 2ab7139a..518a2e36 100644 --- a/ACKategories.xcodeproj/project.pbxproj +++ b/ACKategories.xcodeproj/project.pbxproj @@ -18,20 +18,27 @@ 691F858B202A00E700DA4FAD /* ConditionalAssignmentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691F858A202A00E700DA4FAD /* ConditionalAssignmentTests.swift */; }; 691F858F202A077700DA4FAD /* UIButtonExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691F858E202A077700DA4FAD /* UIButtonExtensions.swift */; }; 691F8592202A083E00DA4FAD /* UIView+SafeAreaCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691F8591202A083E00DA4FAD /* UIView+SafeAreaCompat.swift */; }; + 6925242620D142C800228289 /* NumberFormatterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242520D142C800228289 /* NumberFormatterExtensions.swift */; }; + 6925242820D142E200228289 /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242720D142E200228289 /* DictionaryExtensions.swift */; }; + 6925242A20D1434A00228289 /* CollectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242920D1434A00228289 /* CollectionExtensions.swift */; }; + 6925242C20D1439300228289 /* BundleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242B20D1439300228289 /* BundleExtensions.swift */; }; + 6925242E20D143DE00228289 /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242D20D143DE00228289 /* ArrayExtensions.swift */; }; + 6925243020D1440800228289 /* TimeIntervalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925242F20D1440800228289 /* TimeIntervalExtensions.swift */; }; + 6925243220D1455F00228289 /* UIStackViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925243120D1455F00228289 /* UIStackViewExtensions.swift */; }; + 6925243520D145F600228289 /* UIStackViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925243320D145F200228289 /* UIStackViewTests.swift */; }; + 6925243720D1470B00228289 /* DateExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925243620D1470B00228289 /* DateExtensions.swift */; }; + 6925243A20D1472300228289 /* DateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6925243820D1471F00228289 /* DateTests.swift */; }; 69306C512029C48300BBE8F0 /* UISearchBarExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C422029C48200BBE8F0 /* UISearchBarExtensions.swift */; }; - 69306C522029C48300BBE8F0 /* UIColor+Extra.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C432029C48200BBE8F0 /* UIColor+Extra.swift */; }; + 69306C522029C48300BBE8F0 /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C432029C48200BBE8F0 /* UIColorExtensions.swift */; }; 69306C532029C48300BBE8F0 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C442029C48200BBE8F0 /* UserDefaultsExtensions.swift */; }; 69306C542029C48300BBE8F0 /* TableAndCollectionViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C452029C48200BBE8F0 /* TableAndCollectionViewExtensions.swift */; }; - 69306C552029C48300BBE8F0 /* FoundationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C462029C48200BBE8F0 /* FoundationExtensions.swift */; }; 69306C562029C48300BBE8F0 /* TableHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C472029C48200BBE8F0 /* TableHeaderFooterView.swift */; }; 69306C572029C48300BBE8F0 /* UIControl+Blocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C482029C48200BBE8F0 /* UIControl+Blocks.swift */; }; 69306C582029C48300BBE8F0 /* ConditionalAssignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C492029C48200BBE8F0 /* ConditionalAssignment.swift */; }; 69306C592029C48300BBE8F0 /* UIControlEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4A2029C48200BBE8F0 /* UIControlEvents.swift */; }; - 69306C5A2029C48300BBE8F0 /* String+Extra.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4B2029C48200BBE8F0 /* String+Extra.swift */; }; + 69306C5A2029C48300BBE8F0 /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4B2029C48200BBE8F0 /* StringExtensions.swift */; }; 69306C5B2029C48300BBE8F0 /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4C2029C48200BBE8F0 /* UIImageExtensions.swift */; }; 69306C5C2029C48300BBE8F0 /* UIViewController+SafeAreaCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4D2029C48200BBE8F0 /* UIViewController+SafeAreaCompat.swift */; }; - 69306C5D2029C48300BBE8F0 /* SafeSubscript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4E2029C48200BBE8F0 /* SafeSubscript.swift */; }; - 69306C5E2029C48300BBE8F0 /* UIButton+FixedIntrinsicContentSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C4F2029C48200BBE8F0 /* UIButton+FixedIntrinsicContentSize.swift */; }; 69306C6B2029C4F800BBE8F0 /* ACKategories.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D253FF781F0A65610079215C /* ACKategories.framework */; }; 69306C832029C92B00BBE8F0 /* ColorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C762029C6EF00BBE8F0 /* ColorTests.swift */; }; 69306C842029C92B00BBE8F0 /* ControlBlocksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69306C732029C6EF00BBE8F0 /* ControlBlocksTests.swift */; }; @@ -97,20 +104,27 @@ 691F858A202A00E700DA4FAD /* ConditionalAssignmentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalAssignmentTests.swift; sourceTree = ""; }; 691F858E202A077700DA4FAD /* UIButtonExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonExtensions.swift; sourceTree = ""; }; 691F8591202A083E00DA4FAD /* UIView+SafeAreaCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+SafeAreaCompat.swift"; sourceTree = ""; }; + 6925242520D142C800228289 /* NumberFormatterExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberFormatterExtensions.swift; sourceTree = ""; }; + 6925242720D142E200228289 /* DictionaryExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; }; + 6925242920D1434A00228289 /* CollectionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionExtensions.swift; sourceTree = ""; }; + 6925242B20D1439300228289 /* BundleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleExtensions.swift; sourceTree = ""; }; + 6925242D20D143DE00228289 /* ArrayExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; }; + 6925242F20D1440800228289 /* TimeIntervalExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtensions.swift; sourceTree = ""; }; + 6925243120D1455F00228289 /* UIStackViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewExtensions.swift; sourceTree = ""; }; + 6925243320D145F200228289 /* UIStackViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackViewTests.swift; sourceTree = ""; }; + 6925243620D1470B00228289 /* DateExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExtensions.swift; sourceTree = ""; }; + 6925243820D1471F00228289 /* DateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTests.swift; sourceTree = ""; }; 69306C422029C48200BBE8F0 /* UISearchBarExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UISearchBarExtensions.swift; sourceTree = ""; }; - 69306C432029C48200BBE8F0 /* UIColor+Extra.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extra.swift"; sourceTree = ""; }; + 69306C432029C48200BBE8F0 /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; }; 69306C442029C48200BBE8F0 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = ""; }; 69306C452029C48200BBE8F0 /* TableAndCollectionViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableAndCollectionViewExtensions.swift; sourceTree = ""; }; - 69306C462029C48200BBE8F0 /* FoundationExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationExtensions.swift; sourceTree = ""; }; 69306C472029C48200BBE8F0 /* TableHeaderFooterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableHeaderFooterView.swift; sourceTree = ""; }; 69306C482029C48200BBE8F0 /* UIControl+Blocks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIControl+Blocks.swift"; sourceTree = ""; }; 69306C492029C48200BBE8F0 /* ConditionalAssignment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConditionalAssignment.swift; sourceTree = ""; }; 69306C4A2029C48200BBE8F0 /* UIControlEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIControlEvents.swift; sourceTree = ""; }; - 69306C4B2029C48200BBE8F0 /* String+Extra.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extra.swift"; sourceTree = ""; }; + 69306C4B2029C48200BBE8F0 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; }; 69306C4C2029C48200BBE8F0 /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; }; 69306C4D2029C48200BBE8F0 /* UIViewController+SafeAreaCompat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+SafeAreaCompat.swift"; sourceTree = ""; }; - 69306C4E2029C48200BBE8F0 /* SafeSubscript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafeSubscript.swift; sourceTree = ""; }; - 69306C4F2029C48200BBE8F0 /* UIButton+FixedIntrinsicContentSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIButton+FixedIntrinsicContentSize.swift"; sourceTree = ""; }; 69306C502029C48200BBE8F0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69306C602029C48B00BBE8F0 /* ACKategories.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = ACKategories.podspec; sourceTree = ""; }; 69306C662029C4F800BBE8F0 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -196,23 +210,28 @@ 69306C412029C48200BBE8F0 /* ACKategories */ = { isa = PBXGroup; children = ( + 6925242D20D143DE00228289 /* ArrayExtensions.swift */, + 6925242B20D1439300228289 /* BundleExtensions.swift */, + 6925242920D1434A00228289 /* CollectionExtensions.swift */, 69306C492029C48200BBE8F0 /* ConditionalAssignment.swift */, - 69306C462029C48200BBE8F0 /* FoundationExtensions.swift */, + 6925243620D1470B00228289 /* DateExtensions.swift */, + 6925242720D142E200228289 /* DictionaryExtensions.swift */, D2FF92C3202BA8DD00C1A129 /* NSAttributedStringExtensions.swift */, 6939359E2080AB2800EDA582 /* NSMutableParagraphStyleExtensions.swift */, - 69306C4E2029C48200BBE8F0 /* SafeSubscript.swift */, - 69306C4B2029C48200BBE8F0 /* String+Extra.swift */, + 6925242520D142C800228289 /* NumberFormatterExtensions.swift */, + 69306C4B2029C48200BBE8F0 /* StringExtensions.swift */, 69306C452029C48200BBE8F0 /* TableAndCollectionViewExtensions.swift */, 69306C472029C48200BBE8F0 /* TableHeaderFooterView.swift */, - 69306C4F2029C48200BBE8F0 /* UIButton+FixedIntrinsicContentSize.swift */, + 6925242F20D1440800228289 /* TimeIntervalExtensions.swift */, 691F858E202A077700DA4FAD /* UIButtonExtensions.swift */, - 69306C432029C48200BBE8F0 /* UIColor+Extra.swift */, + 69306C432029C48200BBE8F0 /* UIColorExtensions.swift */, 69306C482029C48200BBE8F0 /* UIControl+Blocks.swift */, 69306C4A2029C48200BBE8F0 /* UIControlEvents.swift */, 6939359C2080AA6100EDA582 /* UIDeviceExtensions.swift */, 69306C4C2029C48200BBE8F0 /* UIImageExtensions.swift */, 693935A02080AB5A00EDA582 /* UILabelExtensions.swift */, 69306C422029C48200BBE8F0 /* UISearchBarExtensions.swift */, + 6925243120D1455F00228289 /* UIStackViewExtensions.swift */, 8829F99220A87C4A00354A87 /* UIView+LayerShortcuts.swift */, 691F8591202A083E00DA4FAD /* UIView+SafeAreaCompat.swift */, 6939359720809F3D00EDA582 /* UIViewController+Children.swift */, @@ -233,6 +252,8 @@ 69306C752029C6EF00BBE8F0 /* StringTests.swift */, 693935992080A34400EDA582 /* UIViewControllerChildrenTests.swift */, 691F85632029DE5500DA4FAD /* Supporting files */, + 6925243320D145F200228289 /* UIStackViewTests.swift */, + 6925243820D1471F00228289 /* DateTests.swift */, ); name = UnitTests; path = Tests; @@ -418,7 +439,9 @@ buildActionMask = 2147483647; files = ( 69306C832029C92B00BBE8F0 /* ColorTests.swift in Sources */, + 6925243520D145F600228289 /* UIStackViewTests.swift in Sources */, 6939359B2080A34C00EDA582 /* UIViewControllerChildrenTests.swift in Sources */, + 6925243A20D1472300228289 /* DateTests.swift in Sources */, 691F858B202A00E700DA4FAD /* ConditionalAssignmentTests.swift in Sources */, 69306C872029C92B00BBE8F0 /* StringTests.swift in Sources */, 69306C842029C92B00BBE8F0 /* ControlBlocksTests.swift in Sources */, @@ -430,28 +453,33 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6925242A20D1434A00228289 /* CollectionExtensions.swift in Sources */, 691F858F202A077700DA4FAD /* UIButtonExtensions.swift in Sources */, 6939359D2080AA6100EDA582 /* UIDeviceExtensions.swift in Sources */, 6939359820809F3D00EDA582 /* UIViewController+Children.swift in Sources */, 69306C5C2029C48300BBE8F0 /* UIViewController+SafeAreaCompat.swift in Sources */, - 69306C522029C48300BBE8F0 /* UIColor+Extra.swift in Sources */, + 6925243720D1470B00228289 /* DateExtensions.swift in Sources */, + 6925242C20D1439300228289 /* BundleExtensions.swift in Sources */, + 69306C522029C48300BBE8F0 /* UIColorExtensions.swift in Sources */, 69306C5B2029C48300BBE8F0 /* UIImageExtensions.swift in Sources */, - 69306C552029C48300BBE8F0 /* FoundationExtensions.swift in Sources */, 69306C592029C48300BBE8F0 /* UIControlEvents.swift in Sources */, - 69306C5A2029C48300BBE8F0 /* String+Extra.swift in Sources */, + 69306C5A2029C48300BBE8F0 /* StringExtensions.swift in Sources */, 69306C512029C48300BBE8F0 /* UISearchBarExtensions.swift in Sources */, + 6925243220D1455F00228289 /* UIStackViewExtensions.swift in Sources */, 69306C582029C48300BBE8F0 /* ConditionalAssignment.swift in Sources */, + 6925242820D142E200228289 /* DictionaryExtensions.swift in Sources */, 693935A12080AB5A00EDA582 /* UILabelExtensions.swift in Sources */, 69306C532029C48300BBE8F0 /* UserDefaultsExtensions.swift in Sources */, 6939359F2080AB2800EDA582 /* NSMutableParagraphStyleExtensions.swift in Sources */, 8829F99320A87C4A00354A87 /* UIView+LayerShortcuts.swift in Sources */, 691F8592202A083E00DA4FAD /* UIView+SafeAreaCompat.swift in Sources */, - 69306C5D2029C48300BBE8F0 /* SafeSubscript.swift in Sources */, D2FF92C4202BA8DE00C1A129 /* NSAttributedStringExtensions.swift in Sources */, 69306C542029C48300BBE8F0 /* TableAndCollectionViewExtensions.swift in Sources */, - 69306C5E2029C48300BBE8F0 /* UIButton+FixedIntrinsicContentSize.swift in Sources */, + 6925242620D142C800228289 /* NumberFormatterExtensions.swift in Sources */, 69306C572029C48300BBE8F0 /* UIControl+Blocks.swift in Sources */, + 6925242E20D143DE00228289 /* ArrayExtensions.swift in Sources */, 69306C562029C48300BBE8F0 /* TableHeaderFooterView.swift in Sources */, + 6925243020D1440800228289 /* TimeIntervalExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ACKategories/SafeSubscript.swift b/ACKategories/ArrayExtensions.swift similarity index 66% rename from ACKategories/SafeSubscript.swift rename to ACKategories/ArrayExtensions.swift index 68f892b8..385d5271 100644 --- a/ACKategories/SafeSubscript.swift +++ b/ACKategories/ArrayExtensions.swift @@ -11,3 +11,12 @@ extension Array: SafeRandomAccessCollection { return indices ~= index ? self[index] : nil } } + +extension Array where Element: Equatable { + /// Remove given object + public mutating func remove(object: Element) { + if let index = index(of: object) { + remove(at: index) + } + } +} diff --git a/ACKategories/BundleExtensions.swift b/ACKategories/BundleExtensions.swift new file mode 100644 index 00000000..68c41234 --- /dev/null +++ b/ACKategories/BundleExtensions.swift @@ -0,0 +1,12 @@ +import Foundation + +extension Bundle { + /// Get receipt data + public var receiptData: Data? { return appStoreReceiptURL.flatMap { try? Data(contentsOf: $0) } } + + /// Get `CFBundleShortVersionString` + public var version: String? { return infoDictionary?["CFBundleShortVersionString"] as? String } + + /// Get `CFBundleVersion` + public var buildNumber: Int? { return (infoDictionary?["CFBundleVersion"] as? String).flatMap { Int($0) } } +} diff --git a/ACKategories/CollectionExtensions.swift b/ACKategories/CollectionExtensions.swift new file mode 100644 index 00000000..c7d04a65 --- /dev/null +++ b/ACKategories/CollectionExtensions.swift @@ -0,0 +1,13 @@ +import Foundation + +extension Optional where Wrapped: Collection { + /// Return `true` if `self` is empty or nil + public var isEmpty: Bool { + switch self { + case .none: + return true + case .some(let value): + return value.isEmpty + } + } +} diff --git a/ACKategories/DateExtensions.swift b/ACKategories/DateExtensions.swift new file mode 100644 index 00000000..a17522d5 --- /dev/null +++ b/ACKategories/DateExtensions.swift @@ -0,0 +1,21 @@ +import Foundation + +extension Date { + /// Seconds from date + public var second: Int { return Calendar.current.component(.second, from: self) } + + /// Minutes from date + public var minute: Int { return Calendar.current.component(.minute, from: self) } + + /// Hours from date in 24-hour format + public var hour: Int { return Calendar.current.component(.hour, from: self) } + + /// Days from date + public var day: Int { return Calendar.current.component(.day, from: self) } + + /// Months from date + public var month: Int { return Calendar.current.component(.month, from: self) } + + /// Year from date + public var year: Int { return Calendar.current.component(.year, from: self) } +} diff --git a/ACKategories/FoundationExtensions.swift b/ACKategories/DictionaryExtensions.swift similarity index 50% rename from ACKategories/FoundationExtensions.swift rename to ACKategories/DictionaryExtensions.swift index ea344d45..200ec7ad 100644 --- a/ACKategories/FoundationExtensions.swift +++ b/ACKategories/DictionaryExtensions.swift @@ -11,7 +11,6 @@ extension Optional: OptionalProtocol { } extension Dictionary where Value: OptionalProtocol { - /// Removes nils from dictionary public var nilsRemoved: [Key: Value.WrappedValue] { return self.reduce([:]) { acc, element -> [Key: Value.WrappedValue] in @@ -45,62 +44,9 @@ extension Dictionary where Value: OptionalProtocol { } } -extension Optional where Wrapped: Collection { - /// Return `true` if `self` is empty or nil - public var isEmpty: Bool { - switch self { - case .none: - return true - case .some(let value): - return value.isEmpty - } - } -} - -extension NumberFormatter { - public func string(from number: Int) -> String? { - return string(from: NSNumber(value: number)) - } - - public func string(from double: Double) -> String? { - return string(from: NSNumber(value: double)) - } -} - /// Merge two dictionaries, if `lhs` contains same key as `rhs` it will be overwritten by `rhs` value public func + (lhs: [Key: Value], rhs: [Key: Value]) -> [Key: Value] { var result = lhs for (k, v) in rhs { result.updateValue(v, forKey: k) } return result } - -extension Array where Element: Equatable { - /// Remove given object - public mutating func remove(object: Element) { - if let index = index(of: object) { - remove(at: index) - } - } -} - -extension Bundle { - /// Get receipt data - public var receiptData: Data? { return appStoreReceiptURL.flatMap { try? Data(contentsOf: $0) } } - - /// Get `CFBundleShortVersionString` - public var version: String? { return infoDictionary?["CFBundleShortVersionString"] as? String } - - /// Get `CFBundleVersion` - public var buildNumber: Int? { return (infoDictionary?["CFBundleVersion"] as? String).flatMap { Int($0) } } -} - -extension TimeInterval { - /// One minute - public static var minute: TimeInterval { return TimeInterval(60) } - - /// One hour - public static var hour: TimeInterval { return minute * 60 } - - /// One day - public static var day: TimeInterval { return hour * 24 } -} diff --git a/ACKategories/NSAttributedStringExtensions.swift b/ACKategories/NSAttributedStringExtensions.swift index 9ff00349..ca3747c5 100644 --- a/ACKategories/NSAttributedStringExtensions.swift +++ b/ACKategories/NSAttributedStringExtensions.swift @@ -1,11 +1,3 @@ -// -// NSAttributedStringExtensions.swift -// ACKategories -// -// Created by Josef Dolezal on 04/02/2018. -// Copyright © 2018 Josef Dolezal. All rights reserved. -// - import Foundation public extension NSAttributedString { diff --git a/ACKategories/NSMutableParagraphStyleExtensions.swift b/ACKategories/NSMutableParagraphStyleExtensions.swift index 3917cab8..5507294f 100644 --- a/ACKategories/NSMutableParagraphStyleExtensions.swift +++ b/ACKategories/NSMutableParagraphStyleExtensions.swift @@ -1,11 +1,3 @@ -// -// NSMutableParagraphStyleExtensions.swift -// ACKategories -// -// Created by Jakub Olejník on 13/04/2018. -// Copyright © 2018 Josef Dolezal. All rights reserved. -// - import UIKit extension NSMutableParagraphStyle { diff --git a/ACKategories/NumberFormatterExtensions.swift b/ACKategories/NumberFormatterExtensions.swift new file mode 100644 index 00000000..3a5461ba --- /dev/null +++ b/ACKategories/NumberFormatterExtensions.swift @@ -0,0 +1,11 @@ +import Foundation + +extension NumberFormatter { + public func string(from number: Int) -> String? { + return string(from: NSNumber(value: number)) + } + + public func string(from double: Double) -> String? { + return string(from: NSNumber(value: double)) + } +} diff --git a/ACKategories/String+Extra.swift b/ACKategories/StringExtensions.swift similarity index 100% rename from ACKategories/String+Extra.swift rename to ACKategories/StringExtensions.swift diff --git a/ACKategories/TimeIntervalExtensions.swift b/ACKategories/TimeIntervalExtensions.swift new file mode 100644 index 00000000..2c841660 --- /dev/null +++ b/ACKategories/TimeIntervalExtensions.swift @@ -0,0 +1,12 @@ +import Foundation + +extension TimeInterval { + /// One minute + public static var minute: TimeInterval { return TimeInterval(60) } + + /// One hour + public static var hour: TimeInterval { return minute * 60 } + + /// One day + public static var day: TimeInterval { return hour * 24 } +} diff --git a/ACKategories/UIButton+FixedIntrinsicContentSize.swift b/ACKategories/UIButton+FixedIntrinsicContentSize.swift deleted file mode 100644 index e95a65ad..00000000 --- a/ACKategories/UIButton+FixedIntrinsicContentSize.swift +++ /dev/null @@ -1,10 +0,0 @@ -import UIKit - -extension UIButton { - open override var intrinsicContentSize: CGSize { - let size = super.intrinsicContentSize - let width = size.width + titleEdgeInsets.left + titleEdgeInsets.right - let height = size.height + titleEdgeInsets.top + titleEdgeInsets.bottom - return CGSize(width: width, height: height) - } -} diff --git a/ACKategories/UIButtonExtensions.swift b/ACKategories/UIButtonExtensions.swift index d5b6b04c..699b8b04 100644 --- a/ACKategories/UIButtonExtensions.swift +++ b/ACKategories/UIButtonExtensions.swift @@ -1,11 +1,3 @@ -// -// UIButtonExtensions.swift -// ACKategories -// -// Created by Jakub Olejník on 06/02/2018. -// Copyright © 2018 Josef Dolezal. All rights reserved. -// - import UIKit extension UIButton { @@ -18,3 +10,12 @@ extension UIButton { titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(totalHeight - titleSize.height), right: 0) } } + +extension UIButton { + open override var intrinsicContentSize: CGSize { + let size = super.intrinsicContentSize + let width = size.width + titleEdgeInsets.left + titleEdgeInsets.right + let height = size.height + titleEdgeInsets.top + titleEdgeInsets.bottom + return CGSize(width: width, height: height) + } +} diff --git a/ACKategories/UIColor+Extra.swift b/ACKategories/UIColorExtensions.swift similarity index 100% rename from ACKategories/UIColor+Extra.swift rename to ACKategories/UIColorExtensions.swift diff --git a/ACKategories/UIStackViewExtensions.swift b/ACKategories/UIStackViewExtensions.swift new file mode 100644 index 00000000..bbfa35fd --- /dev/null +++ b/ACKategories/UIStackViewExtensions.swift @@ -0,0 +1,9 @@ +import UIKit + +@available(iOS 9.0, *) +extension UIStackView { + /// Remove all arranged subviews + public func removeAllArrangedSubviews() { + arrangedSubviews.forEach { removeArrangedSubview($0); $0.removeFromSuperview() } + } +} diff --git a/Tests/DateTests.swift b/Tests/DateTests.swift new file mode 100644 index 00000000..ba39592d --- /dev/null +++ b/Tests/DateTests.swift @@ -0,0 +1,64 @@ +// +// DateTests.swift +// ACKategories +// +// Created by Jakub Olejník on 13/06/2018. +// Copyright © 2018 Ackee, s.r.o. All rights reserved. +// + +import XCTest +import ACKategories + +final class DateTests: XCTestCase { + + var date: Date! + + override func setUp() { + super.setUp() + + date = Date() + } + + func testCorrectSecond() { + let df = DateFormatter() + df.dateFormat = "s" + + XCTAssertEqual(Int(df.string(from: date)), date.second) + } + + func testCorrectMinute() { + let df = DateFormatter() + df.dateFormat = "m" + + XCTAssertEqual(Int(df.string(from: date)), date.minute) + } + + func testCorrectHour() { + let df = DateFormatter() + df.dateFormat = "H" + + XCTAssertEqual(Int(df.string(from: date)), date.hour) + } + + func testCorrectDay() { + let df = DateFormatter() + df.dateFormat = "d" + + XCTAssertEqual(Int(df.string(from: date)), date.day) + } + + func testCorrectMonth() { + let df = DateFormatter() + df.dateFormat = "M" + + XCTAssertEqual(Int(df.string(from: date)), date.month) + } + + func testCorrectYear() { + let df = DateFormatter() + df.dateFormat = "YYYY" + + XCTAssertEqual(Int(df.string(from: date)), date.year) + } +} + diff --git a/Tests/UIStackViewTests.swift b/Tests/UIStackViewTests.swift new file mode 100644 index 00000000..1047dca0 --- /dev/null +++ b/Tests/UIStackViewTests.swift @@ -0,0 +1,28 @@ +// +// UIStackViewTests.swift +// ACKategories +// +// Created by Jakub Olejník on 13/06/2018. +// Copyright © 2018 Ackee, s.r.o. All rights reserved. +// + +import XCTest +import ACKategories + +final class UIStackViewTests: XCTestCase { + + func testViewsAreRemoved() { + let views = (0..<10).map { _ in UIView() } + let stack = UIStackView(arrangedSubviews: views) + + XCTAssertEqual(views.count, stack.arrangedSubviews.count) + + views.forEach { XCTAssertEqual(stack, $0.superview) } + + stack.removeAllArrangedSubviews() + + XCTAssertEqual(0, stack.arrangedSubviews.count) + views.forEach { XCTAssertNil($0.superview) } + } + +}