From 80bca8bdac95b2b572104e9a012a610d795fd8b2 Mon Sep 17 00:00:00 2001 From: "tattn (Tatsuya Tanaka)" Date: Sat, 6 Apr 2019 15:59:04 +0900 Subject: [PATCH 1/2] Swift 5 support --- Sources/Array+.swift | 12 ++++++------ Sources/Comparable+.swift | 4 ++-- Sources/Error+.swift | 6 +++--- Sources/NSObject+.swift | 6 +++--- Sources/NibInstantiatable.swift | 16 ++++++++-------- Sources/ScopeMethod.swift | 4 ++-- Sources/StoryboardInstantiatable.swift | 8 ++++---- Sources/String+.swift | 10 +++++----- Sources/TargetedExtension.swift | 4 ++-- Sources/UIApplication+.swift | 4 ++-- Sources/UICollectionView+.swift | 12 ++++++------ Sources/UIColor+.swift | 8 ++++---- Sources/UIImage+.swift | 16 ++++++++-------- Sources/UITableView+.swift | 6 +++--- Sources/UIView+.swift | 14 ++++++++++++-- Sources/UIViewController+.swift | 6 +++--- SwiftExtensions.xcodeproj/project.pbxproj | 11 +++++------ 17 files changed, 78 insertions(+), 69 deletions(-) diff --git a/Sources/Array+.swift b/Sources/Array+.swift index ba7f6df..edbfaf4 100644 --- a/Sources/Array+.swift +++ b/Sources/Array+.swift @@ -10,26 +10,26 @@ import Foundation public extension Array where Element: Equatable { @discardableResult - public mutating func remove(_ element: Element) -> Index? { - guard let index = index(of: element) else { return nil } + mutating func remove(_ element: Element) -> Index? { + guard let index = firstIndex(of: element) else { return nil } remove(at: index) return index } @discardableResult - public mutating func remove(_ elements: [Element]) -> [Index] { + mutating func remove(_ elements: [Element]) -> [Index] { return elements.compactMap { remove($0) } } } public extension Array where Element: Hashable { - public mutating func unify() { + mutating func unify() { self = unified() } } public extension Collection where Element: Hashable { - public func unified() -> [Element] { + func unified() -> [Element] { return reduce(into: []) { if !$0.contains($1) { $0.append($1) @@ -39,7 +39,7 @@ public extension Collection where Element: Hashable { } public extension Collection { - public subscript(safe index: Index) -> Element? { + subscript(safe index: Index) -> Element? { return startIndex <= index && index < endIndex ? self[index] : nil } } diff --git a/Sources/Comparable+.swift b/Sources/Comparable+.swift index a442a9c..b3b9b6f 100644 --- a/Sources/Comparable+.swift +++ b/Sources/Comparable+.swift @@ -8,8 +8,8 @@ import Foundation -extension Comparable { - public func clamped(min: Self, max: Self) -> Self { +public extension Comparable { + func clamped(min: Self, max: Self) -> Self { if self < min { return min } if self > max { return max } return self diff --git a/Sources/Error+.swift b/Sources/Error+.swift index 293029b..7e1498c 100644 --- a/Sources/Error+.swift +++ b/Sources/Error+.swift @@ -8,7 +8,7 @@ import Foundation -extension Error { - public var code: Int { return (self as NSError).code } - public var domain: String { return (self as NSError).domain } +public extension Error { + var code: Int { return (self as NSError).code } + var domain: String { return (self as NSError).domain } } diff --git a/Sources/NSObject+.swift b/Sources/NSObject+.swift index f40964e..2f63fe7 100644 --- a/Sources/NSObject+.swift +++ b/Sources/NSObject+.swift @@ -14,11 +14,11 @@ public protocol ClassNameProtocol { } public extension ClassNameProtocol { - public static var className: String { + static var className: String { return String(describing: self) } - public var className: String { + var className: String { return type(of: self).className } } @@ -26,7 +26,7 @@ public extension ClassNameProtocol { extension NSObject: ClassNameProtocol {} public extension NSObjectProtocol { - public var describedProperty: String { + var describedProperty: String { let mirror = Mirror(reflecting: self) return mirror.children.map { element -> String in let key = element.label ?? "Unknown" diff --git a/Sources/NibInstantiatable.swift b/Sources/NibInstantiatable.swift index c12f27a..826fee4 100644 --- a/Sources/NibInstantiatable.swift +++ b/Sources/NibInstantiatable.swift @@ -17,15 +17,15 @@ public protocol NibInstantiatable { } public extension NibInstantiatable where Self: NSObject { - public static var nibName: String { return className } - public static var nibBundle: Bundle { return Bundle(for: self) } - public static var nibOwner: Any? { return self } - public static var nibOptions: [UINib.OptionsKey: Any]? { return nil } - public static var instantiateIndex: Int { return 0 } + static var nibName: String { return className } + static var nibBundle: Bundle { return Bundle(for: self) } + static var nibOwner: Any? { return self } + static var nibOptions: [UINib.OptionsKey: Any]? { return nil } + static var instantiateIndex: Int { return 0 } } public extension NibInstantiatable where Self: UIView { - public static func instantiate() -> Self { + static func instantiate() -> Self { let nib = UINib(nibName: nibName, bundle: nibBundle) return nib.instantiate(withOwner: nibOwner, options: nibOptions)[instantiateIndex] as! Self } @@ -36,9 +36,9 @@ public protocol EmbeddedNibInstantiatable { } public extension EmbeddedNibInstantiatable where Self: UIView, Embedded: UIView { - public var embedded: Embedded { return subviews[0] as! Embedded } + var embedded: Embedded { return subviews[0] as! Embedded } - public func configureEmbededView() { + func configureEmbededView() { let view = Embedded.instantiate() insertSubview(view, at: 0) view.fillSuperview() diff --git a/Sources/ScopeMethod.swift b/Sources/ScopeMethod.swift index a599505..4fd82af 100644 --- a/Sources/ScopeMethod.swift +++ b/Sources/ScopeMethod.swift @@ -12,7 +12,7 @@ public protocol Appliable {} public extension Appliable { @discardableResult - public func apply(closure: (Self) -> Void) -> Self { + func apply(closure: (Self) -> Void) -> Self { closure(self) return self } @@ -22,7 +22,7 @@ public protocol Runnable {} public extension Runnable { @discardableResult - public func run(closure: (Self) -> T) -> T { + func run(closure: (Self) -> T) -> T { return closure(self) } } diff --git a/Sources/StoryboardInstantiatable.swift b/Sources/StoryboardInstantiatable.swift index 0c92fd2..13cd483 100644 --- a/Sources/StoryboardInstantiatable.swift +++ b/Sources/StoryboardInstantiatable.swift @@ -20,11 +20,11 @@ public protocol StoryboardInstantiatable { } public extension StoryboardInstantiatable where Self: NSObject { - public static var storyboardName: String { + static var storyboardName: String { return className } - public static var storyboardBundle: Bundle { + static var storyboardBundle: Bundle { return Bundle(for: self) } @@ -32,13 +32,13 @@ public extension StoryboardInstantiatable where Self: NSObject { return UIStoryboard(name: storyboardName, bundle: storyboardBundle) } - public static var instantiateType: StoryboardInstantiateType { + static var instantiateType: StoryboardInstantiateType { return .identifier(className) } } public extension StoryboardInstantiatable where Self: UIViewController { - public static func instantiate() -> Self { + static func instantiate() -> Self { switch instantiateType { case .initial: return storyboard.instantiateInitialViewController() as! Self diff --git a/Sources/String+.swift b/Sources/String+.swift index e8f12a4..8dc8cef 100644 --- a/Sources/String+.swift +++ b/Sources/String+.swift @@ -9,17 +9,17 @@ import Foundation public extension String { - public var localized: String { + var localized: String { return NSLocalizedString(self, comment: self) } - public func localized(withTableName tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "") -> String { + func localized(withTableName tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "") -> String { return NSLocalizedString(self, tableName: tableName, bundle: bundle, value: value, comment: self) } } public extension String { - public var url: URL? { + var url: URL? { return URL(string: self) } } @@ -54,11 +54,11 @@ public extension String { } public extension String { - public var halfWidth: String { + var halfWidth: String { return transformFullWidthToHalfWidth(reverse: false) } - public var fullWidth: String { + var fullWidth: String { return transformFullWidthToHalfWidth(reverse: true) } diff --git a/Sources/TargetedExtension.swift b/Sources/TargetedExtension.swift index 2ed83e0..44a3d4d 100644 --- a/Sources/TargetedExtension.swift +++ b/Sources/TargetedExtension.swift @@ -22,11 +22,11 @@ public protocol TargetedExtensionCompatible { } public extension TargetedExtensionCompatible where Self == Compatible { - public static var ex: TargetedExtension.Type { + static var ex: TargetedExtension.Type { return TargetedExtension.self } - public var ex: TargetedExtension { + var ex: TargetedExtension { return TargetedExtension(self) } } diff --git a/Sources/UIApplication+.swift b/Sources/UIApplication+.swift index 74cc236..417936b 100644 --- a/Sources/UIApplication+.swift +++ b/Sources/UIApplication+.swift @@ -9,7 +9,7 @@ import UIKit public extension UIApplication { - public var topViewController: UIViewController? { + var topViewController: UIViewController? { guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil } while let presentedViewController = topViewController.presentedViewController { @@ -19,7 +19,7 @@ public extension UIApplication { } - public var topNavigationController: UINavigationController? { + var topNavigationController: UINavigationController? { return topViewController as? UINavigationController } } diff --git a/Sources/UICollectionView+.swift b/Sources/UICollectionView+.swift index b26ace4..2b70f98 100644 --- a/Sources/UICollectionView+.swift +++ b/Sources/UICollectionView+.swift @@ -9,17 +9,17 @@ import UIKit public extension UICollectionView { - public func register(cellType: UICollectionViewCell.Type, bundle: Bundle? = nil) { + func register(cellType: UICollectionViewCell.Type, bundle: Bundle? = nil) { let className = cellType.className let nib = UINib(nibName: className, bundle: bundle) register(nib, forCellWithReuseIdentifier: className) } - public func register(cellTypes: [UICollectionViewCell.Type], bundle: Bundle? = nil) { + func register(cellTypes: [UICollectionViewCell.Type], bundle: Bundle? = nil) { cellTypes.forEach { register(cellType: $0, bundle: bundle) } } - public func register(reusableViewType: UICollectionReusableView.Type, + func register(reusableViewType: UICollectionReusableView.Type, ofKind kind: String = UICollectionView.elementKindSectionHeader, bundle: Bundle? = nil) { let className = reusableViewType.className @@ -27,18 +27,18 @@ public extension UICollectionView { register(nib, forSupplementaryViewOfKind: kind, withReuseIdentifier: className) } - public func register(reusableViewTypes: [UICollectionReusableView.Type], + func register(reusableViewTypes: [UICollectionReusableView.Type], ofKind kind: String = UICollectionView.elementKindSectionHeader, bundle: Bundle? = nil) { reusableViewTypes.forEach { register(reusableViewType: $0, ofKind: kind, bundle: bundle) } } - public func dequeueReusableCell(with type: T.Type, + func dequeueReusableCell(with type: T.Type, for indexPath: IndexPath) -> T { return dequeueReusableCell(withReuseIdentifier: type.className, for: indexPath) as! T } - public func dequeueReusableView(with type: T.Type, + func dequeueReusableView(with type: T.Type, for indexPath: IndexPath, ofKind kind: String = UICollectionView.elementKindSectionHeader) -> T { return dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: type.className, for: indexPath) as! T diff --git a/Sources/UIColor+.swift b/Sources/UIColor+.swift index 75a4db2..4686e4e 100644 --- a/Sources/UIColor+.swift +++ b/Sources/UIColor+.swift @@ -9,14 +9,14 @@ import UIKit public extension UIColor { - public convenience init(hex: Int, alpha: Double = 1.0) { + convenience init(hex: Int, alpha: Double = 1.0) { let r = CGFloat((hex & 0xFF0000) >> 16) / 255.0 let g = CGFloat((hex & 0x00FF00) >> 8) / 255.0 let b = CGFloat(hex & 0x0000FF) / 255.0 self.init(red: r, green: g, blue: b, alpha: CGFloat(alpha)) } - public convenience init?(rgbHexString: String, alpha: Double = 1.0) { + convenience init?(rgbHexString: String, alpha: Double = 1.0) { let scanner = Scanner(string: rgbHexString.replacingOccurrences(of: "#", with: "")) var rgbHex: UInt32 = 0 guard scanner.scanHexInt32(&rgbHex) else { @@ -33,7 +33,7 @@ public extension UIColor { } public extension UIColor { - public struct Components { + struct Components { var _base: UIColor public var rgba: (CGFloat, CGFloat, CGFloat, CGFloat) { var r: CGFloat = 0; var g: CGFloat = 0; var b: CGFloat = 0; var a: CGFloat = 0 @@ -46,7 +46,7 @@ public extension UIColor { return (h, s, v) } } - public var components: UIColor.Components { + var components: UIColor.Components { return Components(_base: self) } } diff --git a/Sources/UIImage+.swift b/Sources/UIImage+.swift index 183d212..2237d0e 100644 --- a/Sources/UIImage+.swift +++ b/Sources/UIImage+.swift @@ -9,7 +9,7 @@ import UIKit public extension UIImage { - public convenience init(color: UIColor, size: CGSize) { + convenience init(color: UIColor, size: CGSize) { UIGraphicsBeginImageContext(size) guard let context: CGContext = UIGraphicsGetCurrentContext() else { self.init() @@ -32,7 +32,7 @@ public extension UIImage { } } - public func image(withTint color: UIColor) -> UIImage { + func image(withTint color: UIColor) -> UIImage { let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIGraphicsBeginImageContextWithOptions(rect.size, false, 0) @@ -53,7 +53,7 @@ public extension UIImage { return image } - public func cropping(to rect: CGRect) -> UIImage? { + func cropping(to rect: CGRect) -> UIImage? { let originalRect = CGRect( x: rect.origin.x * scale, y: rect.origin.y * scale, @@ -67,7 +67,7 @@ public extension UIImage { return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation) } - public func resize(to newSize: CGSize) -> UIImage? { + func resize(to newSize: CGSize) -> UIImage? { UIGraphicsBeginImageContext(CGSize( width: newSize.width * scale, height: newSize.height * scale @@ -82,7 +82,7 @@ public extension UIImage { return UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation) } - public func resize(to newSize: CGSize, scalingMode: ScalingMode) -> UIImage? { + func resize(to newSize: CGSize, scalingMode: ScalingMode) -> UIImage? { let aspectRatio = scalingMode.aspectRatio(between: newSize, and: size) let scaledImageRect = CGRect(x: (newSize.width - size.width * aspectRatio) / 2.0, @@ -96,15 +96,15 @@ public extension UIImage { return UIGraphicsGetImageFromCurrentImageContext() } - public func toJPEG(quarity: CGFloat = 1.0) -> Data? { + func toJPEG(quarity: CGFloat = 1.0) -> Data? { return self.jpegData(compressionQuality: quarity) } - public func toPNG(quarity: CGFloat = 1.0) -> Data? { + func toPNG(quarity: CGFloat = 1.0) -> Data? { return self.pngData() } - public func rounded() -> UIImage? { + func rounded() -> UIImage? { let imageView = UIImageView(image: self) imageView.layer.cornerRadius = min(size.height/2, size.width/2) imageView.layer.masksToBounds = true diff --git a/Sources/UITableView+.swift b/Sources/UITableView+.swift index 2b133ae..9692914 100644 --- a/Sources/UITableView+.swift +++ b/Sources/UITableView+.swift @@ -9,17 +9,17 @@ import UIKit public extension UITableView { - public func register(cellType: UITableViewCell.Type, bundle: Bundle? = nil) { + func register(cellType: UITableViewCell.Type, bundle: Bundle? = nil) { let className = cellType.className let nib = UINib(nibName: className, bundle: bundle) register(nib, forCellReuseIdentifier: className) } - public func register(cellTypes: [UITableViewCell.Type], bundle: Bundle? = nil) { + func register(cellTypes: [UITableViewCell.Type], bundle: Bundle? = nil) { cellTypes.forEach { register(cellType: $0, bundle: bundle) } } - public func dequeueReusableCell(with type: T.Type, for indexPath: IndexPath) -> T { + func dequeueReusableCell(with type: T.Type, for indexPath: IndexPath) -> T { return self.dequeueReusableCell(withIdentifier: type.className, for: indexPath) as! T } } diff --git a/Sources/UIView+.swift b/Sources/UIView+.swift index c24fafb..f8ff307 100644 --- a/Sources/UIView+.swift +++ b/Sources/UIView+.swift @@ -9,13 +9,14 @@ import UIKit public extension UIView { - public func fillSuperview() { + func fillSuperview() { guard let superview = self.superview else { return } translatesAutoresizingMaskIntoConstraints = superview.translatesAutoresizingMaskIntoConstraints if translatesAutoresizingMaskIntoConstraints { autoresizingMask = [.flexibleWidth, .flexibleHeight] frame = superview.bounds } else { + topAnchor.constraint(equalTo: superview.topAnchor).isActive = true bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true @@ -23,7 +24,7 @@ public extension UIView { } } - public var viewController: UIViewController? { + var viewController: UIViewController? { var parent: UIResponder? = self while parent != nil { parent = parent?.next @@ -33,4 +34,13 @@ public extension UIView { } return nil } + + func takeScreenshot() -> UIImage? { + UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) + drawHierarchy(in: bounds, afterScreenUpdates: true) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return image + } } diff --git a/Sources/UIViewController+.swift b/Sources/UIViewController+.swift index 1c35600..8dff486 100644 --- a/Sources/UIViewController+.swift +++ b/Sources/UIViewController+.swift @@ -9,7 +9,7 @@ import UIKit public extension UIViewController { - public func addChildView(_ child: UIViewController, layoutOption: LayoutOption = .fill) { + func addChildView(_ child: UIViewController, layoutOption: LayoutOption = .fill) { loadViewIfNeeded() child.loadViewIfNeeded() @@ -19,7 +19,7 @@ public extension UIViewController { child.didMove(toParent: self) } - public func remove() { + func remove() { willMove(toParent: nil) view.removeFromSuperview() removeFromParent() @@ -34,7 +34,7 @@ public extension UIViewController { } } - public enum LayoutOption { + enum LayoutOption { case fill case custom((UIView, UIView) -> Void) } diff --git a/SwiftExtensions.xcodeproj/project.pbxproj b/SwiftExtensions.xcodeproj/project.pbxproj index 883f192..16afba6 100644 --- a/SwiftExtensions.xcodeproj/project.pbxproj +++ b/SwiftExtensions.xcodeproj/project.pbxproj @@ -292,12 +292,12 @@ TargetAttributes = { 244F63DA1FE0310E00E3C372 = { CreatedOnToolsVersion = 9.1; - LastSwiftMigration = 1010; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; 244F63E31FE0310E00E3C372 = { CreatedOnToolsVersion = 9.1; - LastSwiftMigration = 1010; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; }; @@ -309,6 +309,7 @@ knownRegions = ( en, ja, + Base, ); mainGroup = 244F63D11FE0310E00E3C372; productRefGroup = 244F63DC1FE0310E00E3C372 /* Products */; @@ -480,6 +481,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -535,6 +537,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -559,7 +562,6 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -581,7 +583,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.github.tattn.SwiftExtensions; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -595,7 +596,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.github.tattn.SwiftExtensionsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -609,7 +609,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.github.tattn.SwiftExtensionsTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; From fe91b6c7f91534e7f5cb8aee0332695006cf5be9 Mon Sep 17 00:00:00 2001 From: "tattn (Tatsuya Tanaka)" Date: Sat, 6 Apr 2019 16:09:10 +0900 Subject: [PATCH 2/2] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f044dec..9ad2125 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ SwiftExtensions [![Build Status](https://app.bitrise.io/app/e58694b1fa46a551/status.svg?token=E2FYmP02umcT9pjF4NKDSw)](https://app.bitrise.io/app/e58694b1fa46a551) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Swift Version](https://img.shields.io/badge/Swift-4-F16D39.svg)](https://developer.apple.com/swift) +[![Swift Version](https://img.shields.io/badge/Swift-5-F16D39.svg)](https://developer.apple.com/swift) My favorite Swift extensions.