From 579239346f48432113661fe56cb97c0aef10504e Mon Sep 17 00:00:00 2001 From: Alexey Gerasimov Date: Fri, 5 May 2017 19:41:41 +0300 Subject: [PATCH] Usefull extensions added --- .../project.pbxproj | 30 +++++++- .../Extensions/Array+Extensions.swift | 75 +++++++++++++++++++ .../Extensions/String+Extensions.swift | 29 +++++++ .../UIAlertController+Extensions.swift | 39 ++++++++++ .../Extensions/UIView+Extensions.swift | 56 ++++++++++++++ .../Protocols/AlertRepresentable.swift | 36 +++++++++ 6 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 LeadKitAdditions/LeadKitAdditions/Extensions/Array+Extensions.swift create mode 100644 LeadKitAdditions/LeadKitAdditions/Extensions/String+Extensions.swift create mode 100644 LeadKitAdditions/LeadKitAdditions/Extensions/UIAlertController+Extensions.swift create mode 100644 LeadKitAdditions/LeadKitAdditions/Extensions/UIView+Extensions.swift create mode 100644 LeadKitAdditions/LeadKitAdditions/Protocols/AlertRepresentable.swift diff --git a/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj b/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj index ef8b0fc..35f5d71 100644 --- a/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj +++ b/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj @@ -30,6 +30,11 @@ EF05EDFD1EB0D77400CAE7B6 /* ApiNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */; }; EF05EE021EB206C000CAE7B6 /* LoadingBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE011EB206C000CAE7B6 /* LoadingBarButton.swift */; }; EF05EE041EB21A2D00CAE7B6 /* ApiErrorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE031EB21A2D00CAE7B6 /* ApiErrorProtocol.swift */; }; + EFBE57C51EBCCE410040E00A /* AlertRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57C41EBCCE410040E00A /* AlertRepresentable.swift */; }; + EFBE57C71EBCCF560040E00A /* UIAlertController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57C61EBCCF560040E00A /* UIAlertController+Extensions.swift */; }; + EFBE57C91EBCD5730040E00A /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57C81EBCD5730040E00A /* UIView+Extensions.swift */; }; + EFBE57CB1EBCD6480040E00A /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57CA1EBCD6480040E00A /* String+Extensions.swift */; }; + EFBE57CD1EBCD6C00040E00A /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFBE57CC1EBCD6C00040E00A /* Array+Extensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -60,6 +65,11 @@ EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiNetworkService.swift; sourceTree = ""; }; EF05EE011EB206C000CAE7B6 /* LoadingBarButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingBarButton.swift; sourceTree = ""; }; EF05EE031EB21A2D00CAE7B6 /* ApiErrorProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiErrorProtocol.swift; sourceTree = ""; }; + EFBE57C41EBCCE410040E00A /* AlertRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertRepresentable.swift; sourceTree = ""; }; + EFBE57C61EBCCF560040E00A /* UIAlertController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Extensions.swift"; sourceTree = ""; }; + EFBE57C81EBCD5730040E00A /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; }; + EFBE57CA1EBCD6480040E00A /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; }; + EFBE57CC1EBCD6C00040E00A /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -103,12 +113,13 @@ CAE698E51E968820000394B0 /* LeadKitAdditions */ = { isa = PBXGroup; children = ( - EF05EDDB1EAFA6FA00CAE7B6 /* Controllers */, CAE698EE1E968B72000394B0 /* Classes */, + EF05EDDB1EAFA6FA00CAE7B6 /* Controllers */, CAE699011E9693DE000394B0 /* Enums */, CAE698F81E968F56000394B0 /* Extensions */, CAE698E71E968820000394B0 /* Info.plist */, CAE698E61E968820000394B0 /* LeadKitAdditions.h */, + EFBE57C31EBCCE270040E00A /* Protocols */, CAE698F31E968E28000394B0 /* Services */, ); path = LeadKitAdditions; @@ -138,8 +149,12 @@ CAE698F81E968F56000394B0 /* Extensions */ = { isa = PBXGroup; children = ( + EFBE57CC1EBCD6C00040E00A /* Array+Extensions.swift */, EF05EDB51EAF704800CAE7B6 /* Observable+Extensions.swift */, + EFBE57CA1EBCD6480040E00A /* String+Extensions.swift */, + EFBE57C61EBCCF560040E00A /* UIAlertController+Extensions.swift */, EF05EDF71EB0D5A600CAE7B6 /* UIBarButtonItem+Extensions.swift */, + EFBE57C81EBCD5730040E00A /* UIView+Extensions.swift */, EF05EDB61EAF704800CAE7B6 /* UserDefaults+UserService.swift */, ); path = Extensions; @@ -210,6 +225,14 @@ path = Network; sourceTree = ""; }; + EFBE57C31EBCCE270040E00A /* Protocols */ = { + isa = PBXGroup; + children = ( + EFBE57C41EBCCE410040E00A /* AlertRepresentable.swift */, + ); + path = Protocols; + sourceTree = ""; + }; F8A65FEC7C0EB4B93746E50F /* Pods */ = { isa = PBXGroup; children = ( @@ -370,19 +393,24 @@ EF05EDC61EAF70EB00CAE7B6 /* TouchIDService.swift in Sources */, EF05EDE31EAFA7A600CAE7B6 /* BasePassCodeViewModel.swift in Sources */, EF05EDBB1EAF705500CAE7B6 /* ApiError.swift in Sources */, + EFBE57C91EBCD5730040E00A /* UIView+Extensions.swift in Sources */, EF05EDE91EAFA8A000CAE7B6 /* PassCodeHolderProtocol.swift in Sources */, EF05EDFD1EB0D77400CAE7B6 /* ApiNetworkService.swift in Sources */, + EFBE57CD1EBCD6C00040E00A /* Array+Extensions.swift in Sources */, EF05EDF81EB0D5A600CAE7B6 /* UIBarButtonItem+Extensions.swift in Sources */, EF05EDED1EAFA96D00CAE7B6 /* PassCodeHolder.swift in Sources */, EF05EDB71EAF704800CAE7B6 /* Observable+Extensions.swift in Sources */, EF05EDC01EAF706200CAE7B6 /* ApiResponse.swift in Sources */, EF05EDBC1EAF705500CAE7B6 /* ConnectionError.swift in Sources */, EF05EE021EB206C000CAE7B6 /* LoadingBarButton.swift in Sources */, + EFBE57CB1EBCD6480040E00A /* String+Extensions.swift in Sources */, + EFBE57C71EBCCF560040E00A /* UIAlertController+Extensions.swift in Sources */, EF05EDEB1EAFA8E600CAE7B6 /* PassCodeError.swift in Sources */, EF05EDB41EAF703A00CAE7B6 /* BaseUserService.swift in Sources */, EF05EDE51EAFA80D00CAE7B6 /* PassCodeConfiguration.swift in Sources */, EF05EDFC1EB0D77400CAE7B6 /* DefaultNetworkService.swift in Sources */, EF05EDC81EAF91D500CAE7B6 /* BasePassCodeService.swift in Sources */, + EFBE57C51EBCCE410040E00A /* AlertRepresentable.swift in Sources */, EF05EDC11EAF706200CAE7B6 /* BaseDateFormatter.swift in Sources */, EF05EDE71EAFA87300CAE7B6 /* PassCodeValidationResult.swift in Sources */, ); diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/Array+Extensions.swift b/LeadKitAdditions/LeadKitAdditions/Extensions/Array+Extensions.swift new file mode 100644 index 0000000..4a62eaf --- /dev/null +++ b/LeadKitAdditions/LeadKitAdditions/Extensions/Array+Extensions.swift @@ -0,0 +1,75 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension Array where Element: Equatable { + + public func union(values: [Array.Element]...) -> Array { + var result = self + + for array in values { + for value in array { + if !result.contains(value) { + result.append(value) + } + } + } + + return result + } + + public func intersection(values: [Array.Element]...) -> Array { + var result = self + var intersection = Array() + + for (index, value) in values.enumerated() { + if index > 0 { + result = intersection + intersection = Array() + } + + value.forEach { item in + if result.contains(item) && !intersection.contains(item) { + intersection.append(item) + } + } + } + + return intersection + } + + public func subtract(values: [Array.Element]...) -> Array { + var result = Array() + + elements: for item in self { + for value in values { + if value.contains(item) { + continue elements + } + } + + result.append(item) + } + + return result + } + +} diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/String+Extensions.swift b/LeadKitAdditions/LeadKitAdditions/Extensions/String+Extensions.swift new file mode 100644 index 0000000..8e12667 --- /dev/null +++ b/LeadKitAdditions/LeadKitAdditions/Extensions/String+Extensions.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension String { + + public var nilIfEmpty: String? { + return isEmpty ? nil : self + } + +} diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/UIAlertController+Extensions.swift b/LeadKitAdditions/LeadKitAdditions/Extensions/UIAlertController+Extensions.swift new file mode 100644 index 0000000..2ccd6dd --- /dev/null +++ b/LeadKitAdditions/LeadKitAdditions/Extensions/UIAlertController+Extensions.swift @@ -0,0 +1,39 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import UIKit + +extension UIAlertController { + + public static func alert(item: AlertRepresentable, actions: VoidBlock?...) -> UIAlertController { + let alert = UIAlertController(title: item.title, message: item.text, preferredStyle: .alert) + + zip(item.actionTitles, actions + [nil]) + .map { (title, action) in + UIAlertAction(title: title, style: .default, handler: { _ in action?() }) + } + .forEach { alert.addAction($0) } + + return alert + } + +} diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/UIView+Extensions.swift b/LeadKitAdditions/LeadKitAdditions/Extensions/UIView+Extensions.swift new file mode 100644 index 0000000..a983215 --- /dev/null +++ b/LeadKitAdditions/LeadKitAdditions/Extensions/UIView+Extensions.swift @@ -0,0 +1,56 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import UIKit + +extension UIView { + + public func setToCenter(withSize size: CGSize? = nil) { + guard let parent = superview else { + return + } + + translatesAutoresizingMaskIntoConstraints = false + + guard let size = size else { + scaleToFill() + return + } + + centerXAnchor.constraint(equalTo: parent.centerXAnchor).isActive = true + centerYAnchor.constraint(equalTo: parent.centerYAnchor).isActive = true + heightAnchor.constraint(equalToConstant: size.height).isActive = true + widthAnchor.constraint(equalToConstant: size.width).isActive = true + } + + private func scaleToFill() { + guard let superview = superview else { + return + } + + topAnchor.constraint(equalTo: superview.topAnchor).isActive = true + bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true + leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true + rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true + } + +} diff --git a/LeadKitAdditions/LeadKitAdditions/Protocols/AlertRepresentable.swift b/LeadKitAdditions/LeadKitAdditions/Protocols/AlertRepresentable.swift new file mode 100644 index 0000000..b9d1a13 --- /dev/null +++ b/LeadKitAdditions/LeadKitAdditions/Protocols/AlertRepresentable.swift @@ -0,0 +1,36 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public protocol AlertRepresentable { + var title: String { get } + var text: String { get } + var actionTitle: String { get } + var actionTitles: [String] { get } +} + +public extension AlertRepresentable { + + var actionTitles: [String] { + return [actionTitle] + } + +}