From 04e3bc27e273925298a8a48d64d912e2b783303a Mon Sep 17 00:00:00 2001 From: Lucas Farah Date: Tue, 12 Sep 2017 21:28:31 -0400 Subject: [PATCH 1/4] Swift 4 --- EZSwiftExtensions.xcodeproj/project.pbxproj | 16 +++-- EZSwiftExtensionsTests/ArrayTests.swift | 5 +- EZSwiftExtensionsTests/DictionaryTests.swift | 8 +-- .../NSAttributedStringTests.swift | 12 ++-- EZSwiftExtensionsTests/StringTests.swift | 19 +++--- Sources/ArrayExtensions.swift | 4 +- Sources/DictionaryExtensions.swift | 10 +++- Sources/FloatingPointExtensions.swift | 4 +- Sources/NSAttributedStringExtensions.swift | 10 ++-- Sources/StringExtensions.swift | 60 +++++++++---------- Sources/UIViewExtensions.swift | 14 ++--- 11 files changed, 86 insertions(+), 76 deletions(-) diff --git a/EZSwiftExtensions.xcodeproj/project.pbxproj b/EZSwiftExtensions.xcodeproj/project.pbxproj index 2ff6c642..c578ff98 100644 --- a/EZSwiftExtensions.xcodeproj/project.pbxproj +++ b/EZSwiftExtensions.xcodeproj/project.pbxproj @@ -825,11 +825,11 @@ }; B5DC86A81C0ED06700972D0A = { CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; B5DC86B21C0ED06700972D0A = { CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; }; }; @@ -1498,7 +1498,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions.EZSwiftExtensions; PRODUCT_NAME = EZSwiftExtensions; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -1518,7 +1519,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions.EZSwiftExtensions; PRODUCT_NAME = EZSwiftExtensions; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -1530,7 +1532,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions.EZSwiftExtensionsTests; PRODUCT_NAME = EZSwiftExtensionsTest; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_HOST = ""; }; name = Debug; @@ -1542,7 +1545,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions.EZSwiftExtensionsTests; PRODUCT_NAME = EZSwiftExtensionsTest; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; TEST_HOST = ""; }; name = Release; diff --git a/EZSwiftExtensionsTests/ArrayTests.swift b/EZSwiftExtensionsTests/ArrayTests.swift index 9a8c841e..7b6e575f 100644 --- a/EZSwiftExtensionsTests/ArrayTests.swift +++ b/EZSwiftExtensionsTests/ArrayTests.swift @@ -225,9 +225,10 @@ class ArrayTests: XCTestCase { XCTAssertEqual(totalIndexes, 10) XCTAssertEqual(totalNumbers, 20) - emptyArray.forEachEnumerated { _ in XCTFail() } + emptyArray.forEachEnumerated { _,_ in XCTFail() } let copyArray = someArray - copyArray.forEachEnumerated { XCTAssertTrue(someArray[$0.0] == $0.1) } +// copyArray.forEachEnumerated { XCTAssertTrue(someArray[$0.0] == $0.1) } + XCTFail() } func testUnion() { diff --git a/EZSwiftExtensionsTests/DictionaryTests.swift b/EZSwiftExtensionsTests/DictionaryTests.swift index 1745f05a..85a89148 100644 --- a/EZSwiftExtensionsTests/DictionaryTests.swift +++ b/EZSwiftExtensionsTests/DictionaryTests.swift @@ -82,10 +82,10 @@ class DictionaryTests: XCTestCase { } func testFilter() { - let secondFiltered = secondDic.filter { key, value in key != "five" } - - XCTAssertTrue(secondFiltered.has("four")) - XCTAssertEqual(secondFiltered.count, 1) +// let secondFiltered = secondDic.filter { key, value in key != "five" } + XCTFail() +// XCTAssertTrue(secondFiltered.has("four")) +// XCTAssertEqual(secondFiltered.count, 1) } diff --git a/EZSwiftExtensionsTests/NSAttributedStringTests.swift b/EZSwiftExtensionsTests/NSAttributedStringTests.swift index 719f1c80..5e05c2f3 100644 --- a/EZSwiftExtensionsTests/NSAttributedStringTests.swift +++ b/EZSwiftExtensionsTests/NSAttributedStringTests.swift @@ -14,7 +14,7 @@ import EZSwiftExtensions class NSAttributedStringTests: XCTestCase { let testAttributedString = NSAttributedString(string: "Swift Attributed String", - attributes: [String:Any]()) + attributes: [:]) override func setUp() { super.setUp() } @@ -30,7 +30,7 @@ class NSAttributedStringTests: XCTestCase { let boldString = testAttributedString.bold() let newAttributesSeen = boldString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, boldString.length)) - XCTAssertEqual(newAttributesSeen[NSFontAttributeName] as! UIFont, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) + XCTAssertEqual(newAttributesSeen[NSAttributedStringKey.font] as! UIFont, UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)) } #endif @@ -41,7 +41,7 @@ class NSAttributedStringTests: XCTestCase { let underLineString = testAttributedString.underline() let newAttributesSeen = underLineString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, underLineString.length)) - XCTAssertEqual(newAttributesSeen[NSUnderlineStyleAttributeName] as! Int, NSUnderlineStyle.styleSingle.rawValue) + XCTAssertEqual(newAttributesSeen[NSAttributedStringKey.underlineStyle] as! Int, NSUnderlineStyle.styleSingle.rawValue) } #endif @@ -52,14 +52,14 @@ class NSAttributedStringTests: XCTestCase { let italicString = testAttributedString.italic() let newAttributesSeen = italicString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, italicString.length)) - XCTAssertEqual(newAttributesSeen[NSFontAttributeName] as! UIFont, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) + XCTAssertEqual(newAttributesSeen[NSAttributedStringKey.font] as! UIFont, UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)) } func testStrikethrough() { let strikeThroughString = testAttributedString.strikethrough() let newAttributesSeen = strikeThroughString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, strikeThroughString.length)) - XCTAssertEqual(newAttributesSeen[NSStrikethroughStyleAttributeName] as! NSNumber, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) + XCTAssertEqual(newAttributesSeen[NSAttributedStringKey.strikethroughStyle] as! NSNumber, NSNumber(value: NSUnderlineStyle.styleSingle.rawValue as Int)) } #endif @@ -71,7 +71,7 @@ class NSAttributedStringTests: XCTestCase { let coloredString = testAttributedString.color(grayColor) let newAttributesSeen = coloredString.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, coloredString.length)) - XCTAssertEqual(newAttributesSeen[NSForegroundColorAttributeName] as! UIColor, grayColor) + XCTAssertEqual(newAttributesSeen[NSAttributedStringKey.foregroundColor] as! UIColor, grayColor) } func testAppending() { diff --git a/EZSwiftExtensionsTests/StringTests.swift b/EZSwiftExtensionsTests/StringTests.swift index 6e9ad090..41b2c1d4 100644 --- a/EZSwiftExtensionsTests/StringTests.swift +++ b/EZSwiftExtensionsTests/StringTests.swift @@ -349,7 +349,8 @@ class StringTests: XCTestCase { let testString = "H3yH0L3tsG0" let expectedResult = ["3","0","3","0"] - XCTAssertEqual(testString.matchesForRegexInText("[0-9]"), expectedResult) +// XCTAssertEqual(testString.matchesForRegexInText("[0-9]"), expectedResult) + XCTFail() } func testIsNumber() { @@ -371,16 +372,16 @@ class StringTests: XCTestCase { let testString = "meh" let testString2 = "✅" - let boldResult = NSAttributedString(string: testString, attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) - let boldResult2 = NSAttributedString(string: testString2, attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) - let underlineResult = NSAttributedString(string: testString, attributes: [NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue]) - let underlineResult2 = NSAttributedString(string: testString2, attributes: [NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue]) + let boldResult = NSAttributedString(string: testString, attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) + let boldResult2 = NSAttributedString(string: testString2, attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) + let underlineResult = NSAttributedString(string: testString, attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) + let underlineResult2 = NSAttributedString(string: testString2, attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) - let italicResult = NSAttributedString(string: testString, attributes: [NSFontAttributeName: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) - let italicResult2 = NSAttributedString(string: testString2, attributes: [NSFontAttributeName: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) + let italicResult = NSAttributedString(string: testString, attributes: [NSAttributedStringKey.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) + let italicResult2 = NSAttributedString(string: testString2, attributes: [NSAttributedStringKey.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) - let colorResult = NSAttributedString(string: testString, attributes: [NSForegroundColorAttributeName: UIColor.green]) - let colorResult2 = NSAttributedString(string: testString2, attributes: [NSForegroundColorAttributeName: UIColor.green]) + let colorResult = NSAttributedString(string: testString, attributes: [NSAttributedStringKey.foregroundColor: UIColor.green]) + let colorResult2 = NSAttributedString(string: testString2, attributes: [NSAttributedStringKey.foregroundColor: UIColor.green]) XCTAssertEqual(testString.bold(), boldResult) XCTAssertEqual(testString.underline(), underlineResult) diff --git a/Sources/ArrayExtensions.swift b/Sources/ArrayExtensions.swift index f69995c4..574ddf4b 100644 --- a/Sources/ArrayExtensions.swift +++ b/Sources/ArrayExtensions.swift @@ -73,7 +73,7 @@ extension Array { var j: Int for i in 0..<(count-2) { j = Int(arc4random_uniform(UInt32(count - i))) - if i != i+j { swap(&self[i], &self[i+j]) } + if i != i+j { self.swapAt(i, i+j) } } } @@ -220,7 +220,7 @@ extension Array where Element: Hashable { extension Collection where Indices.Iterator.Element == Index { /// Returns the element at the specified index if it is within bounds, otherwise nil. - public subscript (safe index: Index) -> Generator.Element? { + public subscript (safe index: Index) -> Iterator.Element? { return indices.contains(index) ? self[index] : nil } } diff --git a/Sources/DictionaryExtensions.swift b/Sources/DictionaryExtensions.swift index 710fca98..f7670df9 100644 --- a/Sources/DictionaryExtensions.swift +++ b/Sources/DictionaryExtensions.swift @@ -19,7 +19,9 @@ extension Dictionary { public func union(_ dictionaries: Dictionary...) -> Dictionary { var result = self dictionaries.forEach { (dictionary) -> Void in - dictionary.forEach { (key, value) -> Void in + dictionary.forEach { (arg) -> Void in + + let (key, value) = arg result[key] = value } } @@ -38,9 +40,11 @@ extension Dictionary { } // Intersection - return filtered.filter { (key: K, value: V) -> Bool in + return filtered.filter { (arg: (key: K, value: V)) -> Bool in // check for [key: value] in all the dictionaries - dictionaries.testAll { $0.has(key) && $0[key] == value } + + let (key, value) = arg + return dictionaries.testAll { $0.has(key) && $0[key] == value } } } diff --git a/Sources/FloatingPointExtensions.swift b/Sources/FloatingPointExtensions.swift index bc5a2a92..a884399d 100644 --- a/Sources/FloatingPointExtensions.swift +++ b/Sources/FloatingPointExtensions.swift @@ -14,7 +14,7 @@ extension FloatingPoint { public func rounded(toPlaces places: Int) -> Self { guard places >= 0 else { return self } var divisor: Self = 1 - for _ in 0.. Self { guard places >= 0 else { return self } var divisor: Self = 1 - for _ in 0..) -> String { let start = characters.index(startIndex, offsetBy: integerRange.lowerBound) let end = characters.index(startIndex, offsetBy: integerRange.upperBound) - return self[start.. Range? { - let from16 = utf16.startIndex.advanced(by: nsRange.location) - let to16 = from16.advanced(by: nsRange.length) - if let from = String.Index(from16, within: self), - let to = String.Index(to16, within: self) { - return from ..< to - } - return nil - } +// internal func rangeFromNSRange(_ nsRange: NSRange) -> Range? { +// let from16 = utf16.startIndex + nsRange.location +// let to16 = from16 + nsRange.length +// if let from = String.Index(from16, within: self), +// let to = String.Index(to16, within: self) { +// return from ..< to +// } +// return nil +// } /// EZSE: Find matches of regular expression in string - public func matchesForRegexInText(_ regex: String!) -> [String] { - let regex = try? NSRegularExpression(pattern: regex, options: []) - let results = regex?.matches(in: self, options: [], range: NSRange(location: 0, length: self.length)) ?? [] - return results.map { self.substring(with: self.rangeFromNSRange($0.range)!) } - } +// public func matchesForRegexInText(_ regex: String!) -> [String] { +// let regex = try? NSRegularExpression(pattern: regex, options: []) +// let results = regex?.matches(in: self, options: [], range: NSRange(location: 0, length: self.length)) ?? [] +// return results.map { self.substring(with: self.rangeFromNSRange($0.range)!) } +// } /// EZSE: Checks if String contains Email public var isEmail: Bool { @@ -368,7 +368,7 @@ extension String { ///EZSE: Returns bold NSAttributedString public func bold() -> NSAttributedString { - let boldString = NSMutableAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) + let boldString = NSMutableAttributedString(string: self, attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)]) return boldString } @@ -376,7 +376,7 @@ extension String { ///EZSE: Returns underlined NSAttributedString public func underline() -> NSAttributedString { - let underlineString = NSAttributedString(string: self, attributes: [NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue]) + let underlineString = NSAttributedString(string: self, attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) return underlineString } @@ -384,7 +384,7 @@ extension String { ///EZSE: Returns italic NSAttributedString public func italic() -> NSAttributedString { - let italicString = NSMutableAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) + let italicString = NSMutableAttributedString(string: self, attributes: [NSAttributedStringKey.font: UIFont.italicSystemFont(ofSize: UIFont.systemFontSize)]) return italicString } @@ -393,16 +393,16 @@ extension String { #if os(iOS) ///EZSE: Returns hight of rendered string - public func height(_ width: CGFloat, font: UIFont, lineBreakMode: NSLineBreakMode?) -> CGFloat { - var attrib: [String: AnyObject] = [NSFontAttributeName: font] - if lineBreakMode != nil { - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.lineBreakMode = lineBreakMode! - attrib.updateValue(paragraphStyle, forKey: NSParagraphStyleAttributeName) - } - let size = CGSize(width: width, height: CGFloat(Double.greatestFiniteMagnitude)) - return ceil((self as NSString).boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:attrib, context: nil).height) - } +// public func height(_ width: CGFloat, font: UIFont, lineBreakMode: NSLineBreakMode?) -> CGFloat { +// var attrib: [String: AnyObject] = [NSAttributedStringKey.font.rawValue: font] +// if lineBreakMode != nil { +// let paragraphStyle = NSMutableParagraphStyle() +// paragraphStyle.lineBreakMode = lineBreakMode! +// attrib.updateValue(paragraphStyle, forKey: NSAttributedStringKey.paragraphStyle.rawValue) +// } +// let size = CGSize(width: width, height: CGFloat(Double.greatestFiniteMagnitude)) +// return ceil((self as NSString).boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:attrib, context: nil).height) +// } #endif @@ -410,7 +410,7 @@ extension String { ///EZSE: Returns NSAttributedString public func color(_ color: UIColor) -> NSAttributedString { - let colorString = NSMutableAttributedString(string: self, attributes: [NSForegroundColorAttributeName: color]) + let colorString = NSMutableAttributedString(string: self, attributes: [NSAttributedStringKey.foregroundColor: color]) return colorString } @@ -429,7 +429,7 @@ extension String { } let attrText = NSMutableAttributedString(string: self) for range in ranges { - attrText.addAttribute(NSForegroundColorAttributeName, value: color, range: range) + attrText.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range) } return attrText } diff --git a/Sources/UIViewExtensions.swift b/Sources/UIViewExtensions.swift index c2cc1885..76464c82 100644 --- a/Sources/UIViewExtensions.swift +++ b/Sources/UIViewExtensions.swift @@ -445,12 +445,12 @@ extension UIView { } //EZSE: Reverse pop, good for button animations - public func reversePop() { - setScale(x: 0.9, y: 0.9) - UIView.animate(withDuration: 0.05, delay: 0, options: UIViewAnimationOptions.allowUserInteraction, animations: { [weak self] _ in - self?.setScale(x: 1, y: 1) - }) - } +// public func reversePop() { +// setScale(x: 0.9, y: 0.9) +// UIView.animate(withDuration: 0.05, delay: 0, options: UIViewAnimationOptions.allowUserInteraction, animations: { [weak self] _ in +// self?.setScale(x: 1, y: 1) +// }) +// } } //TODO: add this to readme @@ -609,7 +609,7 @@ extension UIView { // MARK: Fade Extensions -private let UIViewDefaultFadeDuration: TimeInterval = 0.4 +public let UIViewDefaultFadeDuration: TimeInterval = 0.4 extension UIView { ///EZSE: Fade in with duration, delay and completion block. From 60303b59bdbe097f9e82b7b24dfc8aafcfb53090 Mon Sep 17 00:00:00 2001 From: Steven_Cheung <251748706@qq.com> Date: Wed, 27 Dec 2017 22:52:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=A7=BB=E9=99=A4swift=204=20=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EZSwiftExtensions.xcodeproj/project.pbxproj | 4 +- .../project.pbxproj | 4 +- Sources/ArrayExtensions.swift | 8 -- Sources/BlockButton.swift | 6 +- Sources/BlockLongPress.swift | 2 +- Sources/BlockPan.swift | 2 +- Sources/BlockPinch.swift | 2 +- Sources/BlockSwipe.swift | 5 +- Sources/BlockTap.swift | 2 +- Sources/CollectionsExtension.swift | 1 + Sources/DictionaryExtensions.swift | 16 +-- Sources/DoubleExtensions.swift | 11 -- Sources/EZSwiftFunctions.swift | 11 +- Sources/FloatingPointExtensions.swift | 4 +- Sources/IntExtensions.swift | 2 +- Sources/NSAttributedStringExtensions.swift | 9 +- Sources/StringExtensions.swift | 123 +++++++++--------- Sources/UIButtonExtensions.swift | 6 +- Sources/UIFontExtensions.swift | 26 ++-- Sources/UIImageExtensions.swift | 2 +- Sources/UIImageViewExtensions.swift | 3 - Sources/UILabelExtensions.swift | 10 +- Sources/UISliderExtensions.swift | 2 +- Sources/UITextFieldExtensions.swift | 16 +-- Sources/UITextViewExtensions.swift | 5 - Sources/UIViewControllerExtensions.swift | 13 +- Sources/UIViewExtensions.swift | 12 +- Sources/URLExtensions.swift | 3 +- 28 files changed, 132 insertions(+), 178 deletions(-) diff --git a/EZSwiftExtensions.xcodeproj/project.pbxproj b/EZSwiftExtensions.xcodeproj/project.pbxproj index c578ff98..9e061001 100644 --- a/EZSwiftExtensions.xcodeproj/project.pbxproj +++ b/EZSwiftExtensions.xcodeproj/project.pbxproj @@ -1434,7 +1434,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -1476,7 +1476,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; diff --git a/EZSwiftExtensionsExample.xcodeproj/project.pbxproj b/EZSwiftExtensionsExample.xcodeproj/project.pbxproj index 494cd5fb..e15b3b95 100644 --- a/EZSwiftExtensionsExample.xcodeproj/project.pbxproj +++ b/EZSwiftExtensionsExample.xcodeproj/project.pbxproj @@ -467,7 +467,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions; PRODUCT_NAME = EZSwiftExtensionsExample; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -480,7 +480,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.gbf.EZSwiftExtensions; PRODUCT_NAME = EZSwiftExtensionsExample; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Sources/ArrayExtensions.swift b/Sources/ArrayExtensions.swift index 574ddf4b..0a43b3cc 100644 --- a/Sources/ArrayExtensions.swift +++ b/Sources/ArrayExtensions.swift @@ -217,14 +217,6 @@ extension Array where Element: Hashable { } } -extension Collection where Indices.Iterator.Element == Index { - - /// Returns the element at the specified index if it is within bounds, otherwise nil. - public subscript (safe index: Index) -> Iterator.Element? { - return indices.contains(index) ? self[index] : nil - } -} - // MARK: - Deprecated 1.8 extension Array { diff --git a/Sources/BlockButton.swift b/Sources/BlockButton.swift index 4fc9ca37..587f5995 100755 --- a/Sources/BlockButton.swift +++ b/Sources/BlockButton.swift @@ -78,13 +78,13 @@ open class BlockButton: UIButton { // MARK: Action - open func didPressed(_ sender: BlockButton) { + @objc open func didPressed(_ sender: BlockButton) { action?(sender) } // MARK: Highlight - open func highlight() { + @objc open func highlight() { if action == nil { return } @@ -107,7 +107,7 @@ open class BlockButton: UIButton { self.highlightLayer = highlightLayer } - open func unhighlight() { + @objc open func unhighlight() { if action == nil { return } diff --git a/Sources/BlockLongPress.swift b/Sources/BlockLongPress.swift index 50479f99..52d64b94 100755 --- a/Sources/BlockLongPress.swift +++ b/Sources/BlockLongPress.swift @@ -24,7 +24,7 @@ open class BlockLongPress: UILongPressGestureRecognizer { addTarget(self, action: #selector(BlockLongPress.didLongPressed(_:))) } - open func didLongPressed(_ longPress: UILongPressGestureRecognizer) { + @objc open func didLongPressed(_ longPress: UILongPressGestureRecognizer) { if longPress.state == UIGestureRecognizerState.began { longPressAction?(longPress) } diff --git a/Sources/BlockPan.swift b/Sources/BlockPan.swift index 93b335d0..ca20ec8b 100755 --- a/Sources/BlockPan.swift +++ b/Sources/BlockPan.swift @@ -24,7 +24,7 @@ open class BlockPan: UIPanGestureRecognizer { self.addTarget(self, action: #selector(BlockPan.didPan(_:))) } - open func didPan (_ pan: UIPanGestureRecognizer) { + @objc open func didPan (_ pan: UIPanGestureRecognizer) { panAction? (pan) } } diff --git a/Sources/BlockPinch.swift b/Sources/BlockPinch.swift index 1bd0f10b..553fd438 100755 --- a/Sources/BlockPinch.swift +++ b/Sources/BlockPinch.swift @@ -24,7 +24,7 @@ open class BlockPinch: UIPinchGestureRecognizer { self.addTarget(self, action: #selector(BlockPinch.didPinch(_:))) } - open func didPinch (_ pinch: UIPinchGestureRecognizer) { + @objc open func didPinch (_ pinch: UIPinchGestureRecognizer) { pinchAction? (pinch) } } diff --git a/Sources/BlockSwipe.swift b/Sources/BlockSwipe.swift index 410c5a2a..41768267 100755 --- a/Sources/BlockSwipe.swift +++ b/Sources/BlockSwipe.swift @@ -18,8 +18,7 @@ open class BlockSwipe: UISwipeGestureRecognizer { super.init(target: target, action: action) } - public convenience init ( - direction: UISwipeGestureRecognizerDirection, + public convenience init (direction: UISwipeGestureRecognizerDirection, fingerCount: Int = 1, action: ((UISwipeGestureRecognizer) -> Void)?) { self.init() @@ -35,7 +34,7 @@ open class BlockSwipe: UISwipeGestureRecognizer { addTarget(self, action: #selector(BlockSwipe.didSwipe(_:))) } - open func didSwipe (_ swipe: UISwipeGestureRecognizer) { + @objc open func didSwipe (_ swipe: UISwipeGestureRecognizer) { swipeAction? (swipe) } } diff --git a/Sources/BlockTap.swift b/Sources/BlockTap.swift index 4c5e94e1..df8d40e1 100755 --- a/Sources/BlockTap.swift +++ b/Sources/BlockTap.swift @@ -35,7 +35,7 @@ open class BlockTap: UITapGestureRecognizer { self.addTarget(self, action: #selector(BlockTap.didTap(_:))) } - open func didTap (_ tap: UITapGestureRecognizer) { + @objc open func didTap (_ tap: UITapGestureRecognizer) { tapAction? (tap) } } diff --git a/Sources/CollectionsExtension.swift b/Sources/CollectionsExtension.swift index 307b6a74..db0a24c3 100644 --- a/Sources/CollectionsExtension.swift +++ b/Sources/CollectionsExtension.swift @@ -27,6 +27,7 @@ extension Collection { return res } + /// EZSE : Helper method to get an array of collection indices private func indicesArray() -> [Self.Index] { var indicesArray: [Self.Index] = [] diff --git a/Sources/DictionaryExtensions.swift b/Sources/DictionaryExtensions.swift index f7670df9..6f458fe1 100644 --- a/Sources/DictionaryExtensions.swift +++ b/Sources/DictionaryExtensions.swift @@ -19,9 +19,7 @@ extension Dictionary { public func union(_ dictionaries: Dictionary...) -> Dictionary { var result = self dictionaries.forEach { (dictionary) -> Void in - dictionary.forEach { (arg) -> Void in - - let (key, value) = arg + dictionary.forEach { (key, value) -> Void in result[key] = value } } @@ -30,7 +28,7 @@ extension Dictionary { /// EZSE: Intersection of self and the input dictionaries. /// Two dictionaries are considered equal if they contain the same [key: value] copules. - public func intersection(_ dictionaries: [K: V]...) -> [K: V] where K: Equatable, V: Equatable { + public func intersection(_ dictionaries: [K: V]...) -> [K: V] { // Casts self from [Key: Value] to [K: V] let filtered = mapFilter { (item, value) -> (K, V)? in if let item = item as? K, let value = value as? V { @@ -40,11 +38,12 @@ extension Dictionary { } // Intersection + return filtered.filter { (arg: (key: K, value: V)) -> Bool in // check for [key: value] in all the dictionaries let (key, value) = arg - return dictionaries.testAll { $0.has(key) && $0[key] == value } + return dictionaries.testAll { $0.has(key) && $0[key] == value as! _OptionalNilComparisonType } } } @@ -123,10 +122,7 @@ extension Dictionary { /// EZSE: Unserialize JSON string into Dictionary public static func constructFromJSON (json: String) -> Dictionary? { - if let data = (try? JSONSerialization.jsonObject( - with: json.data(using: String.Encoding.utf8, - allowLossyConversion: true)!, - options: JSONSerialization.ReadingOptions.mutableContainers)) as? Dictionary { + if let data = (try? JSONSerialization.jsonObject(with: json.data(using: String.Encoding.utf8, allowLossyConversion: true)!, options: JSONSerialization.ReadingOptions.mutableContainers)) as? Dictionary { return data } else { return nil @@ -178,6 +174,6 @@ public func & (first: [K: V], second: [K: V]) -> [K: V] { } /// EZSE: Union operator -public func | (first: [K: V], second: [K: V]) -> [K: V] { +public func | (first: [K: V], second: [K: V]) -> [K: V] { return first.union(second) } diff --git a/Sources/DoubleExtensions.swift b/Sources/DoubleExtensions.swift index d3f53f17..8da3db02 100644 --- a/Sources/DoubleExtensions.swift +++ b/Sources/DoubleExtensions.swift @@ -6,13 +6,7 @@ // Copyright © 2015 Goktug Yilmaz. All rights reserved. // -import Foundation - -precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence } -infix operator ** : PowerPrecedence - extension Double { - /// EZSE: Converts Double to String public var toString: String { return String(self) } @@ -25,11 +19,6 @@ extension Double { public var toCGFloat: CGFloat { return CGFloat(self) } #endif - - /// EZSE: Creating the exponent operator - static public func ** (lhs: Double, rhs: Double) -> Double { - return pow(lhs, rhs) - } } // MARK: - Deprecated 1.8 diff --git a/Sources/EZSwiftFunctions.swift b/Sources/EZSwiftFunctions.swift index 9ab223a5..4d6b6e77 100644 --- a/Sources/EZSwiftFunctions.swift +++ b/Sources/EZSwiftFunctions.swift @@ -202,7 +202,7 @@ public struct ez { /// EZSE: Calls action when a screen shot is taken public static func detectScreenShot(_ action: @escaping () -> Void) { let mainQueue = OperationQueue.main - NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { _ in + NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in // executes after screenshot action() } @@ -254,10 +254,7 @@ public struct ez { } /// EZSE: Runs every second, to cancel use: timer.invalidate() - @discardableResult public static func runThisEvery( - seconds: TimeInterval, - startAfterSeconds: TimeInterval, - handler: @escaping (CFRunLoopTimer?) -> Void) -> Timer { + @discardableResult public static func runThisEvery(seconds: TimeInterval, startAfterSeconds: TimeInterval, handler: @escaping (CFRunLoopTimer?) -> Void) -> Timer { let fireDate = startAfterSeconds + CFAbsoluteTimeGetCurrent() let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, seconds, 0, 0, handler) CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes) @@ -344,7 +341,7 @@ public struct ez { json = nil } - if error != nil { + if let _ = error { return nil } else { return json @@ -363,7 +360,7 @@ public struct ez { URLSession.shared.dataTask( with: URLRequest(url: requestURL), - completionHandler: { data, _, err in + completionHandler: { data, response, err in if let e = err { error?(e as NSError) } else { diff --git a/Sources/FloatingPointExtensions.swift b/Sources/FloatingPointExtensions.swift index a884399d..bc3c8326 100644 --- a/Sources/FloatingPointExtensions.swift +++ b/Sources/FloatingPointExtensions.swift @@ -14,7 +14,7 @@ extension FloatingPoint { public func rounded(toPlaces places: Int) -> Self { guard places >= 0 else { return self } var divisor: Self = 1 - for _ in 0.. Self { guard places >= 0 else { return self } var divisor: Self = 1 - for _ in 0.. NSAttributedString { - let ns = NSMutableAttributedString(attributedString: left) - ns.append(right) - return ns -} #endif diff --git a/Sources/StringExtensions.swift b/Sources/StringExtensions.swift index 7e89ac08..276852ea 100644 --- a/Sources/StringExtensions.swift +++ b/Sources/StringExtensions.swift @@ -6,6 +6,7 @@ // Copyright (c) 2015 Goktug Yilmaz. All rights reserved. // // swiftlint:disable line_length +// swiftlint:disable trailing_whitespace #if os(OSX) import AppKit @@ -36,14 +37,14 @@ extension String { /// EZSE: Cut string from integerIndex to the end public subscript(integerIndex: Int) -> Character { - let index = characters.index(startIndex, offsetBy: integerIndex) + let index = self.index(startIndex, offsetBy: integerIndex) return self[index] } /// EZSE: Cut string from range public subscript(integerRange: Range) -> String { - let start = characters.index(startIndex, offsetBy: integerRange.lowerBound) - let end = characters.index(startIndex, offsetBy: integerRange.upperBound) + let start = self.index(startIndex, offsetBy: integerRange.lowerBound) + let end = self.index(startIndex, offsetBy: integerRange.upperBound) return String(self[start.. 0 else { return } + guard self.count > 0 else { return } self.replaceSubrange(startIndex...startIndex, with: String(self[startIndex]).capitalized) } /// EZSE: Capitalizes first character of String, returns a new string public func capitalizedFirst() -> String { - guard characters.count > 0 else { return self } + guard self.count > 0 else { return self } var result = self result.replaceSubrange(startIndex...startIndex, with: String(self[startIndex]).capitalized) @@ -79,14 +80,14 @@ extension String { /// EZSE: Uppercases first 'count' characters of String public mutating func uppercasePrefix(_ count: Int) { - guard characters.count > 0 && count > 0 else { return } + guard self.count > 0 && count > 0 else { return } self.replaceSubrange(startIndex.. String { - guard characters.count > 0 && count > 0 else { return self } + guard self.count > 0 && count > 0 else { return self } var result = self result.replaceSubrange(startIndex.. 0 && count > 0 else { return } + guard self.count > 0 && count > 0 else { return } self.replaceSubrange(self.index(endIndex, offsetBy: -min(count, length)).. String { - guard characters.count > 0 && count > 0 else { return self } + guard self.count > 0 && count > 0 else { return self } var result = self - result.replaceSubrange(characters.index(endIndex, offsetBy: -min(count, length))..) { let from = max(range.lowerBound, 0), to = min(range.upperBound, length) - guard characters.count > 0 && (0.. 0 && (0..) -> String { let from = max(range.lowerBound, 0), to = min(range.upperBound, length) - guard characters.count > 0 && (0.. 0 && (0.. 0 else { return } + guard self.count > 0 else { return } self.replaceSubrange(startIndex...startIndex, with: String(self[startIndex]).lowercased()) } /// EZSE: Lowercases first character of String, returns a new string public func lowercasedFirst() -> String { - guard characters.count > 0 else { return self } + guard self.count > 0 else { return self } var result = self result.replaceSubrange(startIndex...startIndex, with: String(self[startIndex]).lowercased()) return result @@ -143,40 +144,40 @@ extension String { /// EZSE: Lowercases first 'count' characters of String public mutating func lowercasePrefix(_ count: Int) { - guard characters.count > 0 && count > 0 else { return } + guard self.count > 0 && count > 0 else { return } self.replaceSubrange(startIndex.. String { - guard characters.count > 0 && count > 0 else { return self } + guard self.count > 0 && count > 0 else { return self } var result = self - result.replaceSubrange(startIndex.. 0 && count > 0 else { return } + guard self.count > 0 && count > 0 else { return } self.replaceSubrange(self.index(endIndex, offsetBy: -min(count, length)).. String { - guard characters.count > 0 && count > 0 else { return self } + guard self.count > 0 && count > 0 else { return self } var result = self - result.replaceSubrange(characters.index(endIndex, offsetBy: -min(count, length))..) { let from = max(range.lowerBound, 0), to = min(range.upperBound, length) - guard characters.count > 0 && (0.. 0 && (0..) -> String { let from = max(range.lowerBound, 0), to = min(range.upperBound, length) - guard characters.count > 0 && (0.. 0 && (0.. Range? { -// let from16 = utf16.startIndex + nsRange.location -// let to16 = from16 + nsRange.length -// if let from = String.Index(from16, within: self), -// let to = String.Index(to16, within: self) { -// return from ..< to -// } -// return nil -// } + internal func rangeFromNSRange(_ nsRange: NSRange) -> Range? { + + let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location) + let to16 = utf16.index(from16, offsetBy: nsRange.length) + if let from = String.Index(from16, within: self), + let to = String.Index(to16, within: self) { + return from ..< to + } + return nil + } /// EZSE: Find matches of regular expression in string -// public func matchesForRegexInText(_ regex: String!) -> [String] { -// let regex = try? NSRegularExpression(pattern: regex, options: []) -// let results = regex?.matches(in: self, options: [], range: NSRange(location: 0, length: self.length)) ?? [] -// return results.map { self.substring(with: self.rangeFromNSRange($0.range)!) } -// } + public func matchesForRegexInText(_ regex: String!) -> [String] { + let regex = try? NSRegularExpression(pattern: regex, options: []) + let results = regex?.matches(in: self, options: [], range: NSRange(location: 0, length: self.length)) ?? [] + return results.map { String(self[self.rangeFromNSRange($0.range)!]) } + } /// EZSE: Checks if String contains Email public var isEmail: Bool { @@ -283,7 +285,7 @@ extension String { /// EZSE: Returns if String is a number public func isNumber() -> Bool { - if NumberFormatter().number(from: self) != nil { + if let _ = NumberFormatter().number(from: self) { return true } return false @@ -302,7 +304,8 @@ extension String { let text = self if let detector = detector { - detector.enumerateMatches(in: text, options: [], range: NSRange(location: 0, length: text.characters.count), using: {(result: NSTextCheckingResult?, _, _) -> Void in + detector.enumerateMatches(in: text, options: [], range: NSRange(location: 0, length: text.count), using: { + (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer) -> Void in if let result = result, let url = result.url { urls.append(url) } @@ -355,8 +358,10 @@ extension String { ///EZSE: Returns the first index of the occurency of the character in String public func getIndexOf(_ char: Character) -> Int? { - for (index, c) in characters.enumerated() where c == char { - return index + for (index, c) in self.enumerated() { + if c == char { + return index + } } return nil } @@ -393,16 +398,16 @@ extension String { #if os(iOS) ///EZSE: Returns hight of rendered string -// public func height(_ width: CGFloat, font: UIFont, lineBreakMode: NSLineBreakMode?) -> CGFloat { -// var attrib: [String: AnyObject] = [NSAttributedStringKey.font.rawValue: font] -// if lineBreakMode != nil { -// let paragraphStyle = NSMutableParagraphStyle() -// paragraphStyle.lineBreakMode = lineBreakMode! -// attrib.updateValue(paragraphStyle, forKey: NSAttributedStringKey.paragraphStyle.rawValue) -// } -// let size = CGSize(width: width, height: CGFloat(Double.greatestFiniteMagnitude)) -// return ceil((self as NSString).boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:attrib, context: nil).height) -// } + public func height(_ width: CGFloat, font: UIFont, lineBreakMode: NSLineBreakMode?) -> CGFloat { + var attrib: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font] + if lineBreakMode != nil { + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.lineBreakMode = lineBreakMode! + attrib.updateValue(paragraphStyle, forKey: NSAttributedStringKey.paragraphStyle) + } + let size = CGSize(width: width, height: CGFloat(Double.greatestFiniteMagnitude)) + return ceil((self as NSString).boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:attrib, context: nil).height) + } #endif diff --git a/Sources/UIButtonExtensions.swift b/Sources/UIButtonExtensions.swift index 01029997..868ffdf9 100644 --- a/Sources/UIButtonExtensions.swift +++ b/Sources/UIButtonExtensions.swift @@ -11,14 +11,16 @@ import UIKit extension UIButton { + /// EZSwiftExtensions - /// EZSwiftExtensions: Convenience constructor for UIButton. + // swiftlint:disable function_parameter_count public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, target: AnyObject, action: Selector) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) addTarget(target, action: action, for: UIControlEvents.touchUpInside) } + // swiftlint:enable function_parameter_count - /// EZSwiftExtensions: Set a background color for the button. + /// EZSwiftExtensions public func setBackgroundColor(_ color: UIColor, forState: UIControlState) { UIGraphicsBeginImageContext(CGSize(width: 1, height: 1)) UIGraphicsGetCurrentContext()?.setFillColor(color.cgColor) diff --git a/Sources/UIFontExtensions.swift b/Sources/UIFontExtensions.swift index 1541a1e0..a0082c38 100644 --- a/Sources/UIFontExtensions.swift +++ b/Sources/UIFontExtensions.swift @@ -33,19 +33,19 @@ public enum FontType: String { /// EZSwiftExtensions public enum FontName: String { - case HelveticaNeue - case Helvetica - case Futura - case Menlo - case Avenir - case AvenirNext - case Didot - case AmericanTypewriter - case Baskerville - case Geneva - case GillSans - case SanFranciscoDisplay - case Seravek + case HelveticaNeue = "HelveticaNeue" + case Helvetica = "Helvetica" + case Futura = "Futura" + case Menlo = "Menlo" + case Avenir = "Avenir" + case AvenirNext = "AvenirNext" + case Didot = "Didot" + case AmericanTypewriter = "AmericanTypewriter" + case Baskerville = "Baskerville" + case Geneva = "Geneva" + case GillSans = "GillSans" + case SanFranciscoDisplay = "SanFranciscoDisplay" + case Seravek = "Seravek" } extension UIFont { diff --git a/Sources/UIImageExtensions.swift b/Sources/UIImageExtensions.swift index c53678f0..f7e02b24 100644 --- a/Sources/UIImageExtensions.swift +++ b/Sources/UIImageExtensions.swift @@ -13,7 +13,7 @@ import UIKit extension UIImage { /// EZSE: Returns base64 string - public var base64: String { + var base64: String { return UIImageJPEGRepresentation(self, 1.0)!.base64EncodedString() } diff --git a/Sources/UIImageViewExtensions.swift b/Sources/UIImageViewExtensions.swift index 9b35ffe6..d5104585 100644 --- a/Sources/UIImageViewExtensions.swift +++ b/Sources/UIImageViewExtensions.swift @@ -12,9 +12,6 @@ import UIKit extension UIImageView { - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) { - self.init(frame: CGRect(x: x, y: y, width: w, height: h)) - } /// EZSwiftExtensions public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, imageName: String) { diff --git a/Sources/UILabelExtensions.swift b/Sources/UILabelExtensions.swift index 3c473edc..5f7b1b17 100644 --- a/Sources/UILabelExtensions.swift +++ b/Sources/UILabelExtensions.swift @@ -11,17 +11,9 @@ import UIKit extension UILabel { - - /// EZSE: Initialize Label with a font, color and alignment. - public convenience init(font: UIFont, color: UIColor, alignment: NSTextAlignment) { - self.init() - self.font = font - self.textColor = color - self.textAlignment = alignment - } /// EZSwiftExtensions - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat = 17) { + public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) font = UIFont.HelveticaNeue(type: FontType.None, size: fontSize) backgroundColor = UIColor.clear diff --git a/Sources/UISliderExtensions.swift b/Sources/UISliderExtensions.swift index c472a098..a38d794d 100644 --- a/Sources/UISliderExtensions.swift +++ b/Sources/UISliderExtensions.swift @@ -15,7 +15,7 @@ extension UISlider { public func setValue(_ value: Float, duration: Double) { UIView.animate(withDuration: duration, animations: { () -> Void in self.setValue(self.value, animated: true) - }, completion: { (_) -> Void in + }, completion: { (bool) -> Void in UIView.animate(withDuration: duration, animations: { () -> Void in self.setValue(value, animated: true) }, completion: nil) diff --git a/Sources/UITextFieldExtensions.swift b/Sources/UITextFieldExtensions.swift index bbbb61f0..c2f1e30e 100644 --- a/Sources/UITextFieldExtensions.swift +++ b/Sources/UITextFieldExtensions.swift @@ -5,7 +5,6 @@ // Created by Wang Yu on 6/26/16. // Copyright © 2016 Goktug Yilmaz. All rights reserved. // -// swiftlint:disable line_length #if os(iOS) || os(tvOS) @@ -15,11 +14,6 @@ extension UITextField { /// EZSE: Regular exp for email static let emailRegex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])" - /// EZSwiftExtensions: Automatically sets these values: backgroundColor = clearColor, textColor = ThemeNicknameColor, clipsToBounds = true, - /// textAlignment = Left, userInteractionEnabled = true, editable = false, scrollEnabled = false, font = ThemeFontName, fontsize = 17 - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) { - self.init(x: x, y: y, w: w, h: h, fontSize: 17) - } /// EZSwiftExtensions: Automatically sets these values: backgroundColor = clearColor, textColor = ThemeNicknameColor, clipsToBounds = true, /// textAlignment = Left, userInteractionEnabled = true, editable = false, scrollEnabled = false, font = ThemeFontName @@ -65,15 +59,15 @@ extension UITextField { func validateLength(ofCount count: Int, option: UITextField.textFieldValidationOptions) -> Bool { switch option { case .equalTo: - return self.text!.characters.count == count + return self.text!.count == count case .greaterThan: - return self.text!.characters.count > count + return self.text!.count > count case .greaterThanOrEqualTo: - return self.text!.characters.count >= count + return self.text!.count >= count case .lessThan: - return self.text!.characters.count < count + return self.text!.count < count case .lessThanOrEqualTo: - return self.text!.characters.count <= count + return self.text!.count <= count } } diff --git a/Sources/UITextViewExtensions.swift b/Sources/UITextViewExtensions.swift index 1d044048..488a4643 100644 --- a/Sources/UITextViewExtensions.swift +++ b/Sources/UITextViewExtensions.swift @@ -11,11 +11,6 @@ import UIKit extension UITextView { - /// EZSwiftExtensions: Automatically sets these values: backgroundColor = clearColor, textColor = ThemeNicknameColor, clipsToBounds = true, - /// textAlignment = Left, userInteractionEnabled = true, editable = false, scrollEnabled = false, font = ThemeFontName, fontsize = 17 - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) { - self.init(x: x, y: y, w: w, h: h, fontSize: 17) - } /// EZSwiftExtensions: Automatically sets these values: backgroundColor = clearColor, textColor = ThemeNicknameColor, clipsToBounds = true, /// textAlignment = Left, userInteractionEnabled = true, editable = false, scrollEnabled = false, font = ThemeFontName diff --git a/Sources/UIViewControllerExtensions.swift b/Sources/UIViewControllerExtensions.swift index 107e5a6a..657b7812 100644 --- a/Sources/UIViewControllerExtensions.swift +++ b/Sources/UIViewControllerExtensions.swift @@ -4,6 +4,7 @@ // // Created by Goktug Yilmaz on 15/07/15. // Copyright (c) 2015 Goktug Yilmaz. All rights reserved. +// swiftlint:disable trailing_whitespace #if os(iOS) || os(tvOS) @@ -77,7 +78,7 @@ extension UIViewController { self.removeNotificationObserver(NSNotification.Name.UIKeyboardDidHide.rawValue) } - open func keyboardDidShowNotification(_ notification: Notification) { + @objc open func keyboardDidShowNotification(_ notification: Notification) { if let nInfo = (notification as NSNotification).userInfo, let value = nInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let frame = value.cgRectValue @@ -85,7 +86,7 @@ extension UIViewController { } } - open func keyboardWillShowNotification(_ notification: Notification) { + @objc open func keyboardWillShowNotification(_ notification: Notification) { if let nInfo = (notification as NSNotification).userInfo, let value = nInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let frame = value.cgRectValue @@ -93,7 +94,7 @@ extension UIViewController { } } - open func keyboardWillHideNotification(_ notification: Notification) { + @objc open func keyboardWillHideNotification(_ notification: Notification) { if let nInfo = (notification as NSNotification).userInfo, let value = nInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let frame = value.cgRectValue @@ -101,7 +102,7 @@ extension UIViewController { } } - open func keyboardDidHideNotification(_ notification: Notification) { + @objc open func keyboardDidHideNotification(_ notification: Notification) { if let nInfo = (notification as NSNotification).userInfo, let value = nInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let frame = value.cgRectValue @@ -135,7 +136,7 @@ extension UIViewController { #endif //EZSE: Dismisses keyboard - open func dismissKeyboard() { + @objc open func dismissKeyboard() { view.endEditing(true) } @@ -230,7 +231,7 @@ extension UIViewController { } /// EZSE: Hide or show navigation bar - public var isNavBarHidden: Bool { + public var isNavBarHidden:Bool { get { return (navigationController?.isNavigationBarHidden)! } diff --git a/Sources/UIViewExtensions.swift b/Sources/UIViewExtensions.swift index 76464c82..07c32303 100644 --- a/Sources/UIViewExtensions.swift +++ b/Sources/UIViewExtensions.swift @@ -445,12 +445,12 @@ extension UIView { } //EZSE: Reverse pop, good for button animations -// public func reversePop() { -// setScale(x: 0.9, y: 0.9) -// UIView.animate(withDuration: 0.05, delay: 0, options: UIViewAnimationOptions.allowUserInteraction, animations: { [weak self] _ in -// self?.setScale(x: 1, y: 1) -// }) -// } + public func reversePop() { + setScale(x: 0.9, y: 0.9) + UIView.animate(withDuration: 0.05, delay: 0, options: .allowUserInteraction, animations: {[weak self] in + self?.setScale(x: 1, y: 1) + }, completion: { (bool) in }) + } } //TODO: add this to readme diff --git a/Sources/URLExtensions.swift b/Sources/URLExtensions.swift index 5e34837d..ddc4e747 100644 --- a/Sources/URLExtensions.swift +++ b/Sources/URLExtensions.swift @@ -7,6 +7,7 @@ // Copyright (c) 2016 Goktug Yilmaz. All rights reserved. // // swiftlint:disable line_length +// swiftlint:disable trailing_whitespace #if os(iOS) || os(tvOS) @@ -32,7 +33,7 @@ extension URL { let request = NSMutableURLRequest(url: self, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeoutInterval) request.httpMethod = "HEAD" request.setValue("", forHTTPHeaderField: "Accept-Encoding") - URLSession.shared.dataTask(with: request as URLRequest) { (_, response, _) in + URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in let contentLength: Int64 = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown DispatchQueue.global(qos: .default).async(execute: { completionHandler(contentLength) From 2daa79e708df5793d191c95ad4fae6d7f9347533 Mon Sep 17 00:00:00 2001 From: Lucas Farah Date: Wed, 14 Mar 2018 11:33:15 -0300 Subject: [PATCH 3/4] Better port based on Steven's PR --- EZSwiftExtensionsTests/ArrayTests.swift | 2 +- EZSwiftExtensionsTests/DictionaryTests.swift | 8 -------- EZSwiftExtensionsTests/NSObjectTests.swift | 2 +- EZSwiftExtensionsTests/StringTests.swift | 3 +-- Sources/ArrayExtensions.swift | 8 ++++++++ Sources/DictionaryExtensions.swift | 4 ++-- Sources/DoubleExtensions.swift | 11 +++++++++++ Sources/NSAttributedStringExtensions.swift | 7 +++++++ Sources/UIButtonExtensions.swift | 2 -- Sources/UIImageViewExtensions.swift | 9 +++++---- Sources/UILabelExtensions.swift | 10 +++++++++- Sources/UITextFieldExtensions.swift | 3 +-- Sources/UIViewExtensions.swift | 2 +- 13 files changed, 47 insertions(+), 24 deletions(-) diff --git a/EZSwiftExtensionsTests/ArrayTests.swift b/EZSwiftExtensionsTests/ArrayTests.swift index 7b6e575f..a452e6e0 100644 --- a/EZSwiftExtensionsTests/ArrayTests.swift +++ b/EZSwiftExtensionsTests/ArrayTests.swift @@ -326,7 +326,7 @@ class ArrayTests: XCTestCase { let arr = [1, 2, 3, 4, 5] let squaredArr = arr.parallelizedMap { (x) in x * x} XCTAssertEqual(squaredArr.map{$0!}, [1, 4, 9, 16, 25]) - + let doubledArr = arr.parallelizedMap { (x) in 2 * x} XCTAssertEqual(doubledArr.map{$0!}, [2, 4, 6, 8, 10]) } diff --git a/EZSwiftExtensionsTests/DictionaryTests.swift b/EZSwiftExtensionsTests/DictionaryTests.swift index 85a89148..7a37fc4f 100644 --- a/EZSwiftExtensionsTests/DictionaryTests.swift +++ b/EZSwiftExtensionsTests/DictionaryTests.swift @@ -81,14 +81,6 @@ class DictionaryTests: XCTestCase { XCTAssertEqual(thirdMappedDic["seven"], "seven * 2 = 14") } - func testFilter() { -// let secondFiltered = secondDic.filter { key, value in key != "five" } - XCTFail() -// XCTAssertTrue(secondFiltered.has("four")) -// XCTAssertEqual(secondFiltered.count, 1) - - } - func testDicToJSON() { let dic: Dictionary = ["foo":"bar"] let json = dic.formatJSON() diff --git a/EZSwiftExtensionsTests/NSObjectTests.swift b/EZSwiftExtensionsTests/NSObjectTests.swift index f795a95e..1ea33fbb 100644 --- a/EZSwiftExtensionsTests/NSObjectTests.swift +++ b/EZSwiftExtensionsTests/NSObjectTests.swift @@ -29,7 +29,7 @@ class NSObjectTests: XCTestCase { XCTAssertEqual(nsStringObject.className, "__NSCFString") let intObj = 5 as NSObject - XCTAssertEqual(intObj.className, "_SwiftTypePreservingNSNumber") + XCTAssertEqual(intObj.className, "__NSCFNumber") let userDefinedObject = UserDefinedClass() as NSObject XCTAssertEqual(userDefinedObject.className, "UserDefinedClass") diff --git a/EZSwiftExtensionsTests/StringTests.swift b/EZSwiftExtensionsTests/StringTests.swift index 41b2c1d4..2139fe39 100644 --- a/EZSwiftExtensionsTests/StringTests.swift +++ b/EZSwiftExtensionsTests/StringTests.swift @@ -349,8 +349,7 @@ class StringTests: XCTestCase { let testString = "H3yH0L3tsG0" let expectedResult = ["3","0","3","0"] -// XCTAssertEqual(testString.matchesForRegexInText("[0-9]"), expectedResult) - XCTFail() + XCTAssertEqual(testString.matchesForRegexInText("[0-9]"), expectedResult) } func testIsNumber() { diff --git a/Sources/ArrayExtensions.swift b/Sources/ArrayExtensions.swift index 0a43b3cc..574ddf4b 100644 --- a/Sources/ArrayExtensions.swift +++ b/Sources/ArrayExtensions.swift @@ -217,6 +217,14 @@ extension Array where Element: Hashable { } } +extension Collection where Indices.Iterator.Element == Index { + + /// Returns the element at the specified index if it is within bounds, otherwise nil. + public subscript (safe index: Index) -> Iterator.Element? { + return indices.contains(index) ? self[index] : nil + } +} + // MARK: - Deprecated 1.8 extension Array { diff --git a/Sources/DictionaryExtensions.swift b/Sources/DictionaryExtensions.swift index 6f458fe1..efc75b2c 100644 --- a/Sources/DictionaryExtensions.swift +++ b/Sources/DictionaryExtensions.swift @@ -28,7 +28,7 @@ extension Dictionary { /// EZSE: Intersection of self and the input dictionaries. /// Two dictionaries are considered equal if they contain the same [key: value] copules. - public func intersection(_ dictionaries: [K: V]...) -> [K: V] { + public func intersection(_ dictionaries: [K: V]...) -> [K: V] { // Casts self from [Key: Value] to [K: V] let filtered = mapFilter { (item, value) -> (K, V)? in if let item = item as? K, let value = value as? V { @@ -43,7 +43,7 @@ extension Dictionary { // check for [key: value] in all the dictionaries let (key, value) = arg - return dictionaries.testAll { $0.has(key) && $0[key] == value as! _OptionalNilComparisonType } + return dictionaries.testAll { $0.has(key) && $0[key] == value } } } diff --git a/Sources/DoubleExtensions.swift b/Sources/DoubleExtensions.swift index 8da3db02..d3f53f17 100644 --- a/Sources/DoubleExtensions.swift +++ b/Sources/DoubleExtensions.swift @@ -6,7 +6,13 @@ // Copyright © 2015 Goktug Yilmaz. All rights reserved. // +import Foundation + +precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence } +infix operator ** : PowerPrecedence + extension Double { + /// EZSE: Converts Double to String public var toString: String { return String(self) } @@ -19,6 +25,11 @@ extension Double { public var toCGFloat: CGFloat { return CGFloat(self) } #endif + + /// EZSE: Creating the exponent operator + static public func ** (lhs: Double, rhs: Double) -> Double { + return pow(lhs, rhs) + } } // MARK: - Deprecated 1.8 diff --git a/Sources/NSAttributedStringExtensions.swift b/Sources/NSAttributedStringExtensions.swift index 8b486413..14b2ea11 100644 --- a/Sources/NSAttributedStringExtensions.swift +++ b/Sources/NSAttributedStringExtensions.swift @@ -73,5 +73,12 @@ public func += (left: inout NSAttributedString, right: NSAttributedString) { ns.append(right) left = ns } + +/// EZSE: Sum of one NSAttributedString with another NSAttributedString +public func + (left: NSAttributedString, right: NSAttributedString) -> NSAttributedString { + let ns = NSMutableAttributedString(attributedString: left) + ns.append(right) + return ns +} #endif diff --git a/Sources/UIButtonExtensions.swift b/Sources/UIButtonExtensions.swift index 868ffdf9..37b368b0 100644 --- a/Sources/UIButtonExtensions.swift +++ b/Sources/UIButtonExtensions.swift @@ -13,12 +13,10 @@ import UIKit extension UIButton { /// EZSwiftExtensions - // swiftlint:disable function_parameter_count public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, target: AnyObject, action: Selector) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) addTarget(target, action: action, for: UIControlEvents.touchUpInside) } - // swiftlint:enable function_parameter_count /// EZSwiftExtensions public func setBackgroundColor(_ color: UIColor, forState: UIControlState) { diff --git a/Sources/UIImageViewExtensions.swift b/Sources/UIImageViewExtensions.swift index d5104585..93f4cb3a 100644 --- a/Sources/UIImageViewExtensions.swift +++ b/Sources/UIImageViewExtensions.swift @@ -11,12 +11,13 @@ import UIKit extension UIImageView { - - + /// EZSwiftExtensions - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, imageName: String) { + public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, imageName: String? = nil) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) - image = UIImage(named: imageName) + if let name = imageName { + self.image = UIImage(named: name) + } } /// EZSwiftExtensions diff --git a/Sources/UILabelExtensions.swift b/Sources/UILabelExtensions.swift index 5f7b1b17..3c473edc 100644 --- a/Sources/UILabelExtensions.swift +++ b/Sources/UILabelExtensions.swift @@ -11,9 +11,17 @@ import UIKit extension UILabel { + + /// EZSE: Initialize Label with a font, color and alignment. + public convenience init(font: UIFont, color: UIColor, alignment: NSTextAlignment) { + self.init() + self.font = font + self.textColor = color + self.textAlignment = alignment + } /// EZSwiftExtensions - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat) { + public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat = 17) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) font = UIFont.HelveticaNeue(type: FontType.None, size: fontSize) backgroundColor = UIColor.clear diff --git a/Sources/UITextFieldExtensions.swift b/Sources/UITextFieldExtensions.swift index c2f1e30e..c00a763c 100644 --- a/Sources/UITextFieldExtensions.swift +++ b/Sources/UITextFieldExtensions.swift @@ -14,10 +14,9 @@ extension UITextField { /// EZSE: Regular exp for email static let emailRegex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])" - /// EZSwiftExtensions: Automatically sets these values: backgroundColor = clearColor, textColor = ThemeNicknameColor, clipsToBounds = true, /// textAlignment = Left, userInteractionEnabled = true, editable = false, scrollEnabled = false, font = ThemeFontName - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat) { + public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, fontSize: CGFloat = 20) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) font = UIFont.HelveticaNeue(type: FontType.None, size: fontSize) backgroundColor = UIColor.clear diff --git a/Sources/UIViewExtensions.swift b/Sources/UIViewExtensions.swift index 07c32303..8d1d0ead 100644 --- a/Sources/UIViewExtensions.swift +++ b/Sources/UIViewExtensions.swift @@ -13,7 +13,7 @@ import UIKit // MARK: Custom UIView Initilizers extension UIView { /// EZSwiftExtensions - public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) { + @objc public convenience init(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) { self.init(frame: CGRect(x: x, y: y, width: w, height: h)) } From 9e7f8448bd760b77abdd576923d3500c52a1e344 Mon Sep 17 00:00:00 2001 From: Simple4 Date: Thu, 3 May 2018 07:33:14 +0800 Subject: [PATCH 4/4] Swift4 minor fix (#475) * Fix MacOS target build error * Fix test * Update travis-ci xcode version * Fix warnings --- .swift-version | 2 +- .travis.yml | 2 +- EZSwiftExtensionsTests/ArrayTests.swift | 3 +-- EZSwiftExtensionsTests/UITextFieldTests.swift | 2 +- Sources/ArrayExtensions.swift | 2 +- Sources/StringExtensions.swift | 4 ++++ 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.swift-version b/.swift-version index 9f55b2cc..5186d070 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -3.0 +4.0 diff --git a/.travis.yml b/.travis.yml index b46f1054..0b588edd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -osx_image: xcode8.3 +osx_image: xcode9.2 language: objective-c rvm: 2.2.2 cache: cocoapods diff --git a/EZSwiftExtensionsTests/ArrayTests.swift b/EZSwiftExtensionsTests/ArrayTests.swift index a452e6e0..bcaead10 100644 --- a/EZSwiftExtensionsTests/ArrayTests.swift +++ b/EZSwiftExtensionsTests/ArrayTests.swift @@ -227,8 +227,7 @@ class ArrayTests: XCTestCase { emptyArray.forEachEnumerated { _,_ in XCTFail() } let copyArray = someArray -// copyArray.forEachEnumerated { XCTAssertTrue(someArray[$0.0] == $0.1) } - XCTFail() + copyArray.forEachEnumerated { XCTAssertTrue(someArray[$0] == $1) } } func testUnion() { diff --git a/EZSwiftExtensionsTests/UITextFieldTests.swift b/EZSwiftExtensionsTests/UITextFieldTests.swift index aedc56c4..10a26e12 100644 --- a/EZSwiftExtensionsTests/UITextFieldTests.swift +++ b/EZSwiftExtensionsTests/UITextFieldTests.swift @@ -76,7 +76,7 @@ class UITextFieldTests: XCTestCase { // valid format textField.text = "lol@lol.lol" - let acceptableSpecialChars = "!#$%&'*+-/=?^_`{|}~".characters + let acceptableSpecialChars = "!#$%&'*+-/=?^_`{|}~" XCTAssertTrue(textField.validateEmail()) for specialChar in acceptableSpecialChars { textField.text = "lol\(specialChar)lol@lol.lol" diff --git a/Sources/ArrayExtensions.swift b/Sources/ArrayExtensions.swift index 574ddf4b..ade0127e 100644 --- a/Sources/ArrayExtensions.swift +++ b/Sources/ArrayExtensions.swift @@ -217,7 +217,7 @@ extension Array where Element: Hashable { } } -extension Collection where Indices.Iterator.Element == Index { +extension Collection { /// Returns the element at the specified index if it is within bounds, otherwise nil. public subscript (safe index: Index) -> Iterator.Element? { diff --git a/Sources/StringExtensions.swift b/Sources/StringExtensions.swift index 276852ea..55fece9d 100644 --- a/Sources/StringExtensions.swift +++ b/Sources/StringExtensions.swift @@ -379,12 +379,16 @@ extension String { #endif + #if os(iOS) + ///EZSE: Returns underlined NSAttributedString public func underline() -> NSAttributedString { let underlineString = NSAttributedString(string: self, attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) return underlineString } + #endif + #if os(iOS) ///EZSE: Returns italic NSAttributedString