diff --git a/CHANGELOG.md b/CHANGELOG.md index 2066e38e..01aacae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,42 +1,19 @@ # Changelog -## 0.5.6 +## 0.6.0 +- **New**: Swift 4 support & dependencies update -- **Fix**: Clear tableview if placeholder is shown +## 0.5.18 +- **Fix**: EmptyCell first appearance setup fix -## 0.5.7 +## 0.5.17 +- **Fix**: EmptyCell reusing appearance fix +- **Fix**: SeparatorCell reusing separators fix -- **Add**: String extension `localizedComponent(value:stringOne:stringTwo:stringMany:)` +## 0.5.16 -## 0.5.8 - -- **Fix**: Synchronization over `NSRecursiveLock` for request count tracker in NetworkService - -## 0.5.9 - -- **Fix**: One-two-many fixed for values more than 99 - -## 0.5.10 - -- **Fix**: `Public` modifier for `SpinnerView` - -## 0.5.11 - -- **[Breaking Change]**: rename initializer from `init(initialFrom:)` to `init(resetFrom:)` in `ResettableType` -- **Add**: `SeparatorCell` with `SeparatorCellViewModel` -- **Add**: `AnyBaseTableRow` for type-erasure -- **Add**: `EmptyCellRow` for empty cell with static height - -## 0.5.12 - -- **Fix**: Update type of `viewModel` in `ConfigurableController` to `ImplicitlyUwrappedOptional` instead of `ViewModelT` - -## 0.5.13 - -- **Change**: Remove type erasure behavior from `AnyBaseTableRow` -- **Change**: Rename `AnyBaseTableRow` class to `SeparatorRowBox` -- **Change**: Move `anyRow` property from `EmptyCellRow` to `TableRow` extension and rename it to `separatorRowBox`. -- **Change**: Move `configure(extreme: middle:)` method from `TableDirector` extension to `Array` extension and rename it to `configureSeparators(extreme: middle:)` +- **Change**: Rename `AppearanceProtocol` to `AppearanceConfigurable` +- **Add**: `subscript(safe:)` subscript to `Array` extension for safe access to element by index ## 0.5.15 @@ -45,14 +22,43 @@ - **Add**: `Appearance` to `EmptyCell` - **Remove**: `SeparatorCellViewModel`. -## 0.5.16 +## 0.5.13 + +- **Change**: Remove type erasure behavior from `AnyBaseTableRow` +- **Change**: Rename `AnyBaseTableRow` class to `SeparatorRowBox` +- **Change**: Move `anyRow` property from `EmptyCellRow` to `TableRow` extension and rename it to `separatorRowBox`. +- **Change**: Move `configure(extreme: middle:)` method from `TableDirector` extension to `Array` extension and rename it to `configureSeparators(extreme: middle:)` + +## 0.5.12 + +- **Fix**: Update type of `viewModel` in `ConfigurableController` to `ImplicitlyUwrappedOptional` instead of `ViewModelT` + +## 0.5.11 + +- **[Breaking Change]**: rename initializer from `init(initialFrom:)` to `init(resetFrom:)` in `ResettableType` +- **Add**: `SeparatorCell` with `SeparatorCellViewModel` +- **Add**: `AnyBaseTableRow` for type-erasure +- **Add**: `EmptyCellRow` for empty cell with static height + +## 0.5.10 + +- **Fix**: `Public` modifier for `SpinnerView` + +## 0.5.9 + +- **Fix**: One-two-many fixed for values more than 99 + +## 0.5.8 + +- **Fix**: Synchronization over `NSRecursiveLock` for request count tracker in NetworkService + +## 0.5.7 + +- **Add**: String extension `localizedComponent(value:stringOne:stringTwo:stringMany:)` + +## 0.5.6 + +- **Fix**: Clear tableview if placeholder is shown -- **Change**: Rename `AppearanceProtocol` to `AppearanceConfigurable` -- **Add**: `subscript(safe:)` subscript to `Array` extension for safe access to element by index -## 0.5.17 -- **Fix**: EmptyCell reusing appearance fix -- **Fix**: SeparatorCell reusing separators fix -## 0.5.18 -- **Fix**: EmptyCell first appearance setup fix diff --git a/LeadKit.podspec b/LeadKit.podspec index 3672e1da..cadea6cb 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.5.18" + s.version = "0.6.0" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" @@ -84,13 +84,13 @@ Pod::Spec.new do |s| "Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift" ] - ss.dependency "CocoaLumberjack/Swift", '~> 3.1.0' - ss.dependency "RxSwift", '3.4.0' - ss.dependency "RxCocoa", '3.4.0' - ss.dependency "RxAlamofire", '3.0.2' - ss.dependency "ObjectMapper", '~> 2.2' + ss.dependency "CocoaLumberjack/Swift", '~> 3.3.0' + ss.dependency "RxSwift", '4.0.0' + ss.dependency "RxCocoa", '4.0.0' + ss.dependency "RxAlamofire", '4.0.0' + ss.dependency "ObjectMapper", '~> 3.0.0' - ss.ios.dependency "TableKit", '~> 2.3.1' + ss.ios.dependency "TableKit", '~> 2.5.0' ss.ios.dependency "UIScrollView-InfiniteScroll", '~> 1.0.0' end @@ -110,11 +110,11 @@ Pod::Spec.new do |s| "Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift" ] - ss.dependency "CocoaLumberjack/Swift", '~> 3.1.0' - ss.dependency "RxSwift", '3.4.0' - ss.dependency "RxCocoa", '3.4.0' - ss.dependency "RxAlamofire", '3.0.2' - ss.dependency "ObjectMapper", '~> 2.2' + ss.dependency "CocoaLumberjack/Swift", '~> 3.3.0' + ss.dependency "RxSwift", '4.0.0' + ss.dependency "RxCocoa", '4.0.0' + ss.dependency "RxAlamofire", '4.0.0' + ss.dependency "ObjectMapper", '~> 3.0.0' end s.default_subspec = 'Core' diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 74fe356b..8297957b 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -572,7 +572,7 @@ 67186B201EB247A200CFAFFB /* LeadKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeadKit.h; sourceTree = ""; }; 67186B281EB248F100CFAFFB /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 67186B411EB24AA000CFAFFB /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = ""; }; + 67186B411EB24AA000CFAFFB /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 67186C1A1EB24B7800CFAFFB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 674AF55B1EC45B1600038A8F /* UIActivityIndicatorView+LoadingIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIActivityIndicatorView+LoadingIndicator.swift"; sourceTree = ""; }; 6771DFD71EE99EBA002DCDAE /* DateFormattingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateFormattingService.swift; sourceTree = ""; }; @@ -1572,7 +1572,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Touch Instinct"; TargetAttributes = { 67186B271EB248F100CFAFFB = { @@ -2583,7 +2583,7 @@ PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -2607,7 +2607,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOS"; PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -2627,7 +2627,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -2645,7 +2645,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -2671,7 +2671,7 @@ SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; @@ -2698,7 +2698,7 @@ PRODUCT_NAME = LeadKit; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; @@ -2725,7 +2725,7 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -2751,7 +2751,7 @@ PRODUCT_NAME = LeadKit; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -2773,7 +2773,7 @@ SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TVOS_DEPLOYMENT_TARGET = 10.2; }; name = Debug; @@ -2792,7 +2792,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TVOS_DEPLOYMENT_TARGET = 10.2; }; name = Release; @@ -2819,7 +2819,7 @@ PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -2844,7 +2844,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOS-Extensions"; PRODUCT_NAME = LeadKit; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -2862,7 +2862,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOS-ExtensionsTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -2879,7 +2879,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ru.touchin.LeadKit-iOS-ExtensionsTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -2891,14 +2891,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -2941,14 +2947,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/Podfile b/Podfile index 25498f6e..d7268a90 100644 --- a/Podfile +++ b/Podfile @@ -1,9 +1,9 @@ abstract_target 'LeadKit' do - pod "CocoaLumberjack/Swift", '~> 3.1.0' - pod "RxSwift", '3.4.0' - pod "RxCocoa", '3.4.0' - pod "RxAlamofire", '3.0.2' - pod "ObjectMapper", '~> 2.2' + pod "CocoaLumberjack/Swift", '~> 3.3.0' + pod "RxSwift", '4.0.0' + pod "RxCocoa", '4.0.0' + pod "RxAlamofire", '4.0.0' + pod "ObjectMapper", '~> 3.0.0' inhibit_all_warnings! @@ -12,7 +12,7 @@ abstract_target 'LeadKit' do use_frameworks! - pod "TableKit", '~> 2.3.1' + pod "TableKit", '~> 2.5.0' pod "UIScrollView-InfiniteScroll", '~> 1.0.0' target 'LeadKit iOSTests' do diff --git a/Podfile.lock b/Podfile.lock index 0318a20b..482a38d2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,39 +1,39 @@ PODS: - - Alamofire (4.4.0) - - CocoaLumberjack/Default (3.1.0) - - CocoaLumberjack/Swift (3.1.0): + - Alamofire (4.5.1) + - CocoaLumberjack/Default (3.3.0) + - CocoaLumberjack/Swift (3.3.0): - CocoaLumberjack/Default - - ObjectMapper (2.2.6) - - RxAlamofire (3.0.2): - - RxAlamofire/Core (= 3.0.2) - - RxAlamofire/Core (3.0.2): - - Alamofire (~> 4.0) - - RxSwift (~> 3.0) - - RxCocoa (3.4.0): - - RxSwift (~> 3.4) - - RxSwift (3.4.0) - - TableKit (2.3.1) - - UIScrollView-InfiniteScroll (1.0.1) + - ObjectMapper (3.0.0) + - RxAlamofire (4.0.0): + - RxAlamofire/Core (= 4.0.0) + - RxAlamofire/Core (4.0.0): + - Alamofire (~> 4.5) + - RxSwift (~> 4.0) + - RxCocoa (4.0.0): + - RxSwift (~> 4.0) + - RxSwift (4.0.0) + - TableKit (2.5.0) + - UIScrollView-InfiniteScroll (1.0.2) DEPENDENCIES: - - CocoaLumberjack/Swift (~> 3.1.0) - - ObjectMapper (~> 2.2) - - RxAlamofire (= 3.0.2) - - RxCocoa (= 3.4.0) - - RxSwift (= 3.4.0) - - TableKit (~> 2.3.1) + - CocoaLumberjack/Swift (~> 3.3.0) + - ObjectMapper (~> 3.0.0) + - RxAlamofire (= 4.0.0) + - RxCocoa (= 4.0.0) + - RxSwift (= 4.0.0) + - TableKit (~> 2.5.0) - UIScrollView-InfiniteScroll (~> 1.0.0) SPEC CHECKSUMS: - Alamofire: dc44b1600b800eb63da6a19039a0083d62a6a62d - CocoaLumberjack: 8311463ddf9ee86a06ef92a071dd656c89244500 - ObjectMapper: 042708195cc46c20871cbcbec0453826398273fd - RxAlamofire: bc53604b29fd2d220cfaa490c736cc4500819f34 - RxCocoa: d14ef6b6029e1ddc6e966508c09289090de68ff9 - RxSwift: 3789a1af753002a14edecdb698a2424624296a9c - TableKit: 02e041b443f75fa3e9f1ee6024d4b256305bd904 - UIScrollView-InfiniteScroll: a90df4ba4a7ca1926128ade34a850ddbdf74c564 + Alamofire: 2d95912bf4c34f164fdfc335872e8c312acaea4a + CocoaLumberjack: 3c8c74683302f9012bb168e1c4b7ae3c0b558431 + ObjectMapper: 92230db59bf8f341a5c3a3cf0b9fbdde3cf0d87f + RxAlamofire: 6ea579ac53bf14cb4bc7049a3866e5a769989b1d + RxCocoa: d62846ca96495d862fa4c59ea7d87e5031d7340e + RxSwift: fd680d75283beb5e2559486f3c0ff852f0d35334 + TableKit: 42d4dff2944f273cdeec2ef6352064eb6a9a355b + UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9 -PODFILE CHECKSUM: 911be4683d2ba9315350d42e9576f7517da3f756 +PODFILE CHECKSUM: ef8520adc4869bbbf0cf4cf70ab5757b0c95be1f COCOAPODS: 1.3.1 diff --git a/Sources/Classes/Pagination/PaginationViewModel.swift b/Sources/Classes/Pagination/PaginationViewModel.swift index 75407802..14178ae3 100644 --- a/Sources/Classes/Pagination/PaginationViewModel.swift +++ b/Sources/Classes/Pagination/PaginationViewModel.swift @@ -100,7 +100,7 @@ public final class PaginationViewModel { case .retry: reload(isRetry: true) case .next: - if case .exhausted(_) = internalState.value { + if case .exhausted = internalState.value { fatalError("You shouldn't call load(.next) after got .exhausted state!") } diff --git a/Sources/Extensions/CGContext/CGContext+Initializers.swift b/Sources/Extensions/CGContext/CGContext+Initializers.swift index 6ce1352d..52f0f21a 100644 --- a/Sources/Extensions/CGContext/CGContext+Initializers.swift +++ b/Sources/Extensions/CGContext/CGContext+Initializers.swift @@ -22,7 +22,7 @@ import CoreGraphics -extension CGBitmapInfo { +public extension CGBitmapInfo { // The bitmapInfo value are hard-coded to prevent an "unsupported parameter combination" error diff --git a/Sources/Extensions/Sequence/Sequence+ConcurrentMap.swift b/Sources/Extensions/Sequence/Sequence+ConcurrentMap.swift index 6d41ed36..a2b29025 100644 --- a/Sources/Extensions/Sequence/Sequence+ConcurrentMap.swift +++ b/Sources/Extensions/Sequence/Sequence+ConcurrentMap.swift @@ -59,7 +59,7 @@ public extension Sequence { .map { (idx: $0.idx, results: try array[$0.range].map(transform)) } } .toArray() - .map { $0.sorted { $0.0.idx < $0.1.idx }.flatMap { $0.results } } + .map { $0.sorted { $0.idx < $1.idx }.flatMap { $0.results } } } } diff --git a/Sources/Extensions/String/String+SizeCalculation.swift b/Sources/Extensions/String/String+SizeCalculation.swift index 7bda846d..82ca358f 100644 --- a/Sources/Extensions/String/String+SizeCalculation.swift +++ b/Sources/Extensions/String/String+SizeCalculation.swift @@ -65,7 +65,7 @@ public extension String { - returns: string size calculation result */ - func size(withAttributes attributes: [String: AnyObject]?, + func size(withAttributes attributes: [NSAttributedStringKey: AnyObject]?, maxWidth: CGFloat = CGFloat.greatestFiniteMagnitude, maxHeight: CGFloat = CGFloat.greatestFiniteMagnitude) -> StringSizeCalculationResult { @@ -74,7 +74,7 @@ public extension String { attributes: attributes, context: nil).size - let fontLineHeight = (attributes?[NSFontAttributeName] as? UIFont)?.lineHeight + let fontLineHeight = (attributes?[NSAttributedStringKey.font] as? UIFont)?.lineHeight return StringSizeCalculationResult(size: size, fontLineHeight: fontLineHeight) } diff --git a/Sources/Functions/Any+TypeName.swift b/Sources/Functions/Any+TypeName.swift index e117bd83..d4f41a59 100644 --- a/Sources/Functions/Any+TypeName.swift +++ b/Sources/Functions/Any+TypeName.swift @@ -26,11 +26,11 @@ import Foundation /// /// - Parameter type: an object type /// - Returns: string representation of object type -public func className(of type: T) -> String { - let clsName = String(describing: type(of: type)) +public func className(of givenType: T) -> String { + let clsName = String(describing: type(of: givenType)) if let typeRange = clsName.range(of: ".Type") { - return clsName.substring(to: typeRange.lowerBound) + return String(clsName[..CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass